Browse Source

[web] Migrate "Manage Template" option in editor left menu to BS5 (#21799)

* Update manage template modal to BS5

* Update `ManageTemplateButton` to BS5

* Update `OLFormControl` prop types so it has its `as` props

* Update `LeftMenuButton` to BS5

* Fixup linting

* Update `ManageTemplateModalBody` style:

* Bold label
* Correct rows in BS3

* Set spinner color to `text-muted` instead of blue

* `npm run format:fix`

GitOrigin-RevId: c5311e4786b2859a8b7cf567d19cd3d7614dd3db
Antoine Clausse 1 year ago
parent
commit
bf26ef58a2

+ 1 - 1
services/web/frontend/js/features/source-editor/components/command-tooltip/href-tooltip.tsx

@@ -92,7 +92,7 @@ export const HrefTooltipContent: FC = () => {
             htmlSize={50}
             placeholder="https://…"
             value={url}
-            ref={element => {
+            ref={(element: HTMLInputElement) => {
               inputRef.current = element
             }}
             autoComplete="off"

+ 7 - 3
services/web/frontend/js/features/ui/components/bootstrap-5/form/form-control.tsx

@@ -1,16 +1,20 @@
-import { forwardRef } from 'react'
+import React, { forwardRef } from 'react'
 import {
   Form,
   FormControlProps as BS5FormControlProps,
 } from 'react-bootstrap-5'
 import classnames from 'classnames'
+import type { BsPrefixRefForwardingComponent } from 'react-bootstrap-5/helpers'
 
-type FormControlProps = BS5FormControlProps & {
+export type OLBS5FormControlProps = BS5FormControlProps & {
   prepend?: React.ReactNode
   append?: React.ReactNode
 }
 
-const FormControl = forwardRef<HTMLInputElement, FormControlProps>(
+const FormControl: BsPrefixRefForwardingComponent<
+  'input',
+  OLBS5FormControlProps
+> = forwardRef<HTMLInputElement, OLBS5FormControlProps>(
   ({ prepend, append, className, ...props }, ref) => {
     if (prepend || append) {
       const wrapperClassNames = classnames('form-control-wrapper', {

+ 73 - 69
services/web/frontend/js/features/ui/components/ol/ol-form-control.tsx

@@ -1,12 +1,15 @@
 import { forwardRef, ComponentProps, useCallback } from 'react'
 import { getAriaAndDataProps } from '@/features/utils/bootstrap-5'
-import FormControl from '@/features/ui/components/bootstrap-5/form/form-control'
+import FormControl, {
+  type OLBS5FormControlProps,
+} from '@/features/ui/components/bootstrap-5/form/form-control'
 import BS3FormControl from '@/features/ui/components/bootstrap-3/form/form-control'
 import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
 import OLSpinner from '@/features/ui/components/ol/ol-spinner'
 import Icon from '@/shared/components/icon'
+import type { BsPrefixRefForwardingComponent } from 'react-bootstrap-5/helpers'
 
-type OLFormControlProps = ComponentProps<typeof FormControl> & {
+type OLFormControlProps = OLBS5FormControlProps & {
   bs3Props?: Record<string, unknown>
   'data-ol-dirty'?: unknown
   'main-field'?: any // For the CM6's benefit in the editor search panel
@@ -17,77 +20,78 @@ type BS3FormControlProps = ComponentProps<typeof BS3FormControl> & {
   'main-field'?: any
 }
 
-const OLFormControl = forwardRef<HTMLInputElement, OLFormControlProps>(
-  (props, ref) => {
-    const { bs3Props, append, ...rest } = props
+const OLFormControl: BsPrefixRefForwardingComponent<
+  'input',
+  OLFormControlProps
+> = forwardRef<HTMLInputElement, OLFormControlProps>((props, ref) => {
+  const { bs3Props, append, ...rest } = props
 
-    // Use a callback so that the ref passed to the BS3 FormControl is stable
-    const bs3InputRef = useCallback(
-      (inputElement: HTMLInputElement) => {
-        if (typeof ref === 'function') {
-          ref(inputElement)
-        } else if (ref) {
-          ref.current = inputElement
-        }
-      },
-      [ref]
-    )
+  // Use a callback so that the ref passed to the BS3 FormControl is stable
+  const bs3InputRef = useCallback(
+    (inputElement: HTMLInputElement) => {
+      if (typeof ref === 'function') {
+        ref(inputElement)
+      } else if (ref) {
+        ref.current = inputElement
+      }
+    },
+    [ref]
+  )
 
-    let bs3FormControlProps: BS3FormControlProps = {
-      inputRef: bs3InputRef,
-      componentClass: rest.as,
-      bsSize: rest.size,
-      id: rest.id,
-      name: rest.name,
-      className: rest.className,
-      style: rest.style,
-      type: rest.type,
-      value: rest.value,
-      defaultValue: rest.defaultValue,
-      required: rest.required,
-      disabled: rest.disabled,
-      placeholder: rest.placeholder,
-      readOnly: rest.readOnly,
-      autoComplete: rest.autoComplete,
-      autoFocus: rest.autoFocus,
-      minLength: rest.minLength,
-      maxLength: rest.maxLength,
-      onChange: rest.onChange as BS3FormControlProps['onChange'],
-      onKeyDown: rest.onKeyDown as BS3FormControlProps['onKeyDown'],
-      onFocus: rest.onFocus as BS3FormControlProps['onFocus'],
-      onBlur: rest.onBlur as BS3FormControlProps['onBlur'],
-      onInvalid: rest.onInvalid as BS3FormControlProps['onInvalid'],
-      prepend: rest.prepend,
-      size: rest.htmlSize,
-      'main-field': rest['main-field'],
-      ...bs3Props,
-    }
+  let bs3FormControlProps: BS3FormControlProps = {
+    inputRef: bs3InputRef,
+    componentClass: rest.as,
+    bsSize: rest.size,
+    id: rest.id,
+    name: rest.name,
+    className: rest.className,
+    style: rest.style,
+    type: rest.type,
+    value: rest.value,
+    defaultValue: rest.defaultValue,
+    required: rest.required,
+    disabled: rest.disabled,
+    placeholder: rest.placeholder,
+    readOnly: rest.readOnly,
+    autoComplete: rest.autoComplete,
+    autoFocus: rest.autoFocus,
+    minLength: rest.minLength,
+    maxLength: rest.maxLength,
+    onChange: rest.onChange as BS3FormControlProps['onChange'],
+    onKeyDown: rest.onKeyDown as BS3FormControlProps['onKeyDown'],
+    onFocus: rest.onFocus as BS3FormControlProps['onFocus'],
+    onBlur: rest.onBlur as BS3FormControlProps['onBlur'],
+    onInvalid: rest.onInvalid as BS3FormControlProps['onInvalid'],
+    prepend: rest.prepend,
+    size: rest.htmlSize,
+    'main-field': rest['main-field'],
+    ...bs3Props,
+  }
 
-    bs3FormControlProps = {
-      ...bs3FormControlProps,
-      ...getAriaAndDataProps(rest),
-      'data-ol-dirty': rest['data-ol-dirty'],
-    } as typeof bs3FormControlProps & Record<string, unknown>
+  bs3FormControlProps = {
+    ...bs3FormControlProps,
+    ...getAriaAndDataProps(rest),
+    'data-ol-dirty': rest['data-ol-dirty'],
+  } as typeof bs3FormControlProps & Record<string, unknown>
 
-    return (
-      <BootstrapVersionSwitcher
-        bs3={
-          <BS3FormControl
-            {...bs3FormControlProps}
-            append={rest.loading ? <Icon type="spinner" spin /> : append}
-          />
-        }
-        bs5={
-          <FormControl
-            ref={ref}
-            {...rest}
-            append={rest.loading ? <OLSpinner size="sm" /> : append}
-          />
-        }
-      />
-    )
-  }
-)
+  return (
+    <BootstrapVersionSwitcher
+      bs3={
+        <BS3FormControl
+          {...bs3FormControlProps}
+          append={rest.loading ? <Icon type="spinner" spin /> : append}
+        />
+      }
+      bs5={
+        <FormControl
+          ref={ref}
+          {...rest}
+          append={rest.loading ? <OLSpinner size="sm" /> : append}
+        />
+      }
+    />
+  )
+})
 OLFormControl.displayName = 'OLFormControl'
 
 export default OLFormControl