@wordpress/components 30.2.1-next.f34ab90e9.0 → 30.2.2-next.e256d081a.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -1
- package/build/context/context-connect.js.map +1 -1
- package/build/tabs/styles.js +5 -5
- package/build/tabs/styles.js.map +1 -1
- package/build/utils/font-size.js.map +1 -1
- package/build/utils/get-valid-children.js.map +1 -1
- package/build/validated-form-controls/control-with-error.js +16 -16
- package/build/validated-form-controls/control-with-error.js.map +1 -1
- package/build-module/context/context-connect.js.map +1 -1
- package/build-module/tabs/styles.js +6 -6
- package/build-module/tabs/styles.js.map +1 -1
- package/build-module/utils/font-size.js.map +1 -1
- package/build-module/utils/get-valid-children.js.map +1 -1
- package/build-module/validated-form-controls/control-with-error.js +16 -16
- package/build-module/validated-form-controls/control-with-error.js.map +1 -1
- package/build-types/context/context-connect.d.ts +2 -2
- package/build-types/context/context-connect.d.ts.map +1 -1
- package/build-types/tabs/styles.d.ts.map +1 -1
- package/build-types/utils/font-size.d.ts +2 -2
- package/build-types/utils/font-size.d.ts.map +1 -1
- package/build-types/utils/get-valid-children.d.ts +2 -2
- package/build-types/utils/get-valid-children.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/stories/overview.story.d.ts.map +1 -1
- package/build-types/validated-form-controls/control-with-error.d.ts.map +1 -1
- package/build-types/validated-form-controls/test/control-with-error.d.ts +2 -0
- package/build-types/validated-form-controls/test/control-with-error.d.ts.map +1 -0
- package/package.json +19 -19
- package/src/context/context-connect.ts +2 -2
- package/src/tabs/styles.ts +2 -1
- package/src/tools-panel/stories/index.story.tsx +3 -3
- package/src/utils/font-size.ts +2 -2
- package/src/utils/get-valid-children.ts +4 -2
- package/src/validated-form-controls/components/stories/overview.story.tsx +109 -27
- package/src/validated-form-controls/control-with-error.tsx +19 -18
- package/src/validated-form-controls/test/control-with-error.tsx +224 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["__","cloneElement","forwardRef","useEffect","useState","withIgnoreIMEEvents","ValidityIndicator","Fragment","_Fragment","jsxs","_jsxs","jsx","_jsx","appendRequiredIndicator","label","required","markWhenOptional","children","UnforwardedControlWithError","onValidate","customValidity","getValidityTarget","forwardedRef","errorMessage","setErrorMessage","statusMessage","setStatusMessage","isTouched","setIsTouched","validityTarget","showValidationMessage","validationMessage","addEventListener","removeEventListener","type","setCustomValidity","undefined","timer","setTimeout","message","clearTimeout","_customValidity$messa","onBlur","event","relatedTarget","currentTarget","contains","validity","valid","onChange","args","props","onKeyDown","key","className","ref","ControlWithError"],"sources":["@wordpress/components/src/validated-form-controls/control-with-error.tsx"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { __ } from '@wordpress/i18n';\n\n/**\n * External dependencies\n */\nimport {\n\tcloneElement,\n\tforwardRef,\n\tuseEffect,\n\tuseState,\n} from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { withIgnoreIMEEvents } from '../utils/with-ignore-ime-events';\nimport type { ValidatedControlProps } from './components/types';\nimport { ValidityIndicator } from './validity-indicator';\n\nfunction appendRequiredIndicator(\n\tlabel: React.ReactNode,\n\trequired: boolean | undefined,\n\tmarkWhenOptional: boolean | undefined\n) {\n\tif ( required && ! markWhenOptional ) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{ label } { `(${ __( 'Required' ) })` }\n\t\t\t</>\n\t\t);\n\t}\n\tif ( ! required && markWhenOptional ) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{ label } { `(${ __( 'Optional' ) })` }\n\t\t\t</>\n\t\t);\n\t}\n\treturn label;\n}\n\n/**\n * HTML elements that support the Constraint Validation API.\n *\n * Here, we exclude HTMLButtonElement because although it does technically support the API,\n * normal buttons are actually exempted from any validation.\n * @see https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Forms/Form_validation\n * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLButtonElement/willValidate\n */\ntype ValidityTarget =\n\t| HTMLFieldSetElement\n\t| HTMLInputElement\n\t| HTMLSelectElement\n\t| HTMLTextAreaElement;\n\nfunction UnforwardedControlWithError< C extends React.ReactElement >(\n\t{\n\t\trequired,\n\t\tmarkWhenOptional,\n\t\tonValidate,\n\t\tcustomValidity,\n\t\tgetValidityTarget,\n\t\tchildren,\n\t}: {\n\t\t/**\n\t\t * Whether the control is required.\n\t\t */\n\t\trequired?: boolean;\n\t\t/**\n\t\t * Label the control as \"optional\" when _not_ `required`, instead of the inverse.\n\t\t */\n\t\tmarkWhenOptional?: boolean;\n\t\t/**\n\t\t * The callback to run when the input should be validated.\n\t\t */\n\t\tonValidate?: () => void;\n\t\tcustomValidity?: ValidatedControlProps< unknown >[ 'customValidity' ];\n\t\t/**\n\t\t * A function that returns the actual element on which the validity data should be applied.\n\t\t */\n\t\tgetValidityTarget: () => ValidityTarget | null | undefined;\n\t\t/**\n\t\t * The control component to apply validation to.\n\t\t */\n\t\tchildren: C;\n\t},\n\tforwardedRef: React.ForwardedRef< HTMLDivElement >\n) {\n\tconst [ errorMessage, setErrorMessage ] = useState< string | undefined >();\n\tconst [ statusMessage, setStatusMessage ] = useState<\n\t\t| {\n\t\t\t\ttype: 'validating' | 'valid';\n\t\t\t\tmessage?: string;\n\t\t }\n\t\t| undefined\n\t>();\n\tconst [ isTouched, setIsTouched ] = useState( false );\n\n\t// Ensure that error messages are visible after user attemps to submit a form\n\t// with multiple invalid fields.\n\tuseEffect( () => {\n\t\tconst validityTarget = getValidityTarget();\n\t\tconst showValidationMessage = () =>\n\t\t\tsetErrorMessage( validityTarget?.validationMessage );\n\n\t\tvalidityTarget?.addEventListener( 'invalid', showValidationMessage );\n\n\t\treturn () => {\n\t\t\tvalidityTarget?.removeEventListener(\n\t\t\t\t'invalid',\n\t\t\t\tshowValidationMessage\n\t\t\t);\n\t\t};\n\t} );\n\n\tuseEffect( () => {\n\t\tif ( ! isTouched ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst validityTarget = getValidityTarget();\n\n\t\tif ( ! customValidity?.type ) {\n\t\t\tvalidityTarget?.setCustomValidity( '' );\n\t\t\tsetErrorMessage( validityTarget?.validationMessage );\n\t\t\tsetStatusMessage( undefined );\n\t\t\treturn;\n\t\t}\n\n\t\tswitch ( customValidity.type ) {\n\t\t\tcase 'validating': {\n\t\t\t\t// Wait before showing a validating state.\n\t\t\t\tconst timer = setTimeout( () => {\n\t\t\t\t\tsetStatusMessage( {\n\t\t\t\t\t\ttype: 'validating',\n\t\t\t\t\t\tmessage: customValidity.message,\n\t\t\t\t\t} );\n\t\t\t\t}, 1000 );\n\n\t\t\t\treturn () => clearTimeout( timer );\n\t\t\t}\n\t\t\tcase 'valid': {\n\t\t\t\tvalidityTarget?.setCustomValidity( '' );\n\t\t\t\tsetErrorMessage( validityTarget?.validationMessage );\n\n\t\t\t\tsetStatusMessage( {\n\t\t\t\t\ttype: 'valid',\n\t\t\t\t\tmessage: customValidity.message,\n\t\t\t\t} );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase 'invalid': {\n\t\t\t\tvalidityTarget?.setCustomValidity(\n\t\t\t\t\tcustomValidity.message ?? ''\n\t\t\t\t);\n\t\t\t\tsetErrorMessage( validityTarget?.validationMessage );\n\n\t\t\t\tsetStatusMessage( undefined );\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\t}, [\n\t\tisTouched,\n\t\tcustomValidity?.type,\n\t\tcustomValidity?.message,\n\t\tgetValidityTarget,\n\t] );\n\n\tconst onBlur = ( event: React.FocusEvent< HTMLDivElement > ) => {\n\t\t// Only consider \"blurred from the component\" if focus has fully left the wrapping div.\n\t\t// This prevents unnecessary blurs from components with multiple focusable elements.\n\t\tif (\n\t\t\t! event.relatedTarget ||\n\t\t\t! event.currentTarget.contains( event.relatedTarget )\n\t\t) {\n\t\t\tsetIsTouched( true );\n\n\t\t\tconst validityTarget = getValidityTarget();\n\n\t\t\t// Prevents a double flash of the native error tooltip when the control is already showing one.\n\t\t\tif ( ! validityTarget?.validity.valid ) {\n\t\t\t\tif ( ! errorMessage ) {\n\t\t\t\t\tsetErrorMessage( validityTarget?.validationMessage );\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tonValidate?.();\n\t\t}\n\t};\n\n\tconst onChange = ( ...args: unknown[] ) => {\n\t\tchildren.props.onChange?.( ...args );\n\n\t\t// Only validate incrementally if the field has blurred at least once,\n\t\t// or currently has an error message.\n\t\tif ( isTouched || errorMessage ) {\n\t\t\tonValidate?.();\n\t\t}\n\t};\n\n\tconst onKeyDown = ( event: React.KeyboardEvent< HTMLDivElement > ) => {\n\t\t// Ensures that custom validators are triggered when the user submits by pressing Enter,\n\t\t// without ever blurring the control.\n\t\tif ( event.key === 'Enter' ) {\n\t\t\tonValidate?.();\n\t\t}\n\t};\n\n\treturn (\n\t\t// Disable reason: Just listening to a bubbled event, not for interaction.\n\t\t// eslint-disable-next-line jsx-a11y/no-static-element-interactions\n\t\t<div\n\t\t\tclassName=\"components-validated-control\"\n\t\t\tref={ forwardedRef }\n\t\t\tonBlur={ onBlur }\n\t\t\tonKeyDown={ withIgnoreIMEEvents( onKeyDown ) }\n\t\t>\n\t\t\t{ cloneElement( children, {\n\t\t\t\tlabel: appendRequiredIndicator(\n\t\t\t\t\tchildren.props.label,\n\t\t\t\t\trequired,\n\t\t\t\t\tmarkWhenOptional\n\t\t\t\t),\n\t\t\t\tonChange,\n\t\t\t\trequired,\n\t\t\t} ) }\n\t\t\t<div aria-live=\"polite\">\n\t\t\t\t{ errorMessage && (\n\t\t\t\t\t<ValidityIndicator\n\t\t\t\t\t\ttype=\"invalid\"\n\t\t\t\t\t\tmessage={ errorMessage }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t\t{ ! errorMessage && statusMessage && (\n\t\t\t\t\t<ValidityIndicator\n\t\t\t\t\t\ttype={ statusMessage.type }\n\t\t\t\t\t\tmessage={ statusMessage.message }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport const ControlWithError = forwardRef( UnforwardedControlWithError );\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["usePrevious","__","cloneElement","forwardRef","useEffect","useState","withIgnoreIMEEvents","ValidityIndicator","Fragment","_Fragment","jsxs","_jsxs","jsx","_jsx","appendRequiredIndicator","label","required","markWhenOptional","children","UnforwardedControlWithError","onValidate","customValidity","getValidityTarget","forwardedRef","errorMessage","setErrorMessage","statusMessage","setStatusMessage","isTouched","setIsTouched","previousCustomValidityType","type","validityTarget","showValidationMessage","validationMessage","addEventListener","removeEventListener","setCustomValidity","undefined","timer","setTimeout","message","clearTimeout","_customValidity$messa","onBlur","event","relatedTarget","currentTarget","contains","onChange","args","props","onKeyDown","key","className","ref","ControlWithError"],"sources":["@wordpress/components/src/validated-form-controls/control-with-error.tsx"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { usePrevious } from '@wordpress/compose';\nimport { __ } from '@wordpress/i18n';\nimport {\n\tcloneElement,\n\tforwardRef,\n\tuseEffect,\n\tuseState,\n} from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { withIgnoreIMEEvents } from '../utils/with-ignore-ime-events';\nimport type { ValidatedControlProps } from './components/types';\nimport { ValidityIndicator } from './validity-indicator';\n\nfunction appendRequiredIndicator(\n\tlabel: React.ReactNode,\n\trequired: boolean | undefined,\n\tmarkWhenOptional: boolean | undefined\n) {\n\tif ( required && ! markWhenOptional ) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{ label } { `(${ __( 'Required' ) })` }\n\t\t\t</>\n\t\t);\n\t}\n\tif ( ! required && markWhenOptional ) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{ label } { `(${ __( 'Optional' ) })` }\n\t\t\t</>\n\t\t);\n\t}\n\treturn label;\n}\n\n/**\n * HTML elements that support the Constraint Validation API.\n *\n * Here, we exclude HTMLButtonElement because although it does technically support the API,\n * normal buttons are actually exempted from any validation.\n * @see https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Forms/Form_validation\n * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLButtonElement/willValidate\n */\ntype ValidityTarget =\n\t| HTMLFieldSetElement\n\t| HTMLInputElement\n\t| HTMLSelectElement\n\t| HTMLTextAreaElement;\n\nfunction UnforwardedControlWithError< C extends React.ReactElement >(\n\t{\n\t\trequired,\n\t\tmarkWhenOptional,\n\t\tonValidate,\n\t\tcustomValidity,\n\t\tgetValidityTarget,\n\t\tchildren,\n\t}: {\n\t\t/**\n\t\t * Whether the control is required.\n\t\t */\n\t\trequired?: boolean;\n\t\t/**\n\t\t * Label the control as \"optional\" when _not_ `required`, instead of the inverse.\n\t\t */\n\t\tmarkWhenOptional?: boolean;\n\t\t/**\n\t\t * The callback to run when the input should be validated.\n\t\t */\n\t\tonValidate?: () => void;\n\t\tcustomValidity?: ValidatedControlProps< unknown >[ 'customValidity' ];\n\t\t/**\n\t\t * A function that returns the actual element on which the validity data should be applied.\n\t\t */\n\t\tgetValidityTarget: () => ValidityTarget | null | undefined;\n\t\t/**\n\t\t * The control component to apply validation to.\n\t\t */\n\t\tchildren: C;\n\t},\n\tforwardedRef: React.ForwardedRef< HTMLDivElement >\n) {\n\tconst [ errorMessage, setErrorMessage ] = useState< string | undefined >();\n\tconst [ statusMessage, setStatusMessage ] = useState<\n\t\t| {\n\t\t\t\ttype: 'validating' | 'valid';\n\t\t\t\tmessage?: string;\n\t\t }\n\t\t| undefined\n\t>();\n\tconst [ isTouched, setIsTouched ] = useState( false );\n\tconst previousCustomValidityType = usePrevious( customValidity?.type );\n\n\t// Ensure that error messages are visible after user attemps to submit a form\n\t// with multiple invalid fields.\n\tuseEffect( () => {\n\t\tconst validityTarget = getValidityTarget();\n\t\tconst showValidationMessage = () =>\n\t\t\tsetErrorMessage( validityTarget?.validationMessage );\n\n\t\tvalidityTarget?.addEventListener( 'invalid', showValidationMessage );\n\n\t\treturn () => {\n\t\t\tvalidityTarget?.removeEventListener(\n\t\t\t\t'invalid',\n\t\t\t\tshowValidationMessage\n\t\t\t);\n\t\t};\n\t} );\n\n\tuseEffect( (): ReturnType< React.EffectCallback > => {\n\t\tif ( ! isTouched ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst validityTarget = getValidityTarget();\n\n\t\tif ( ! customValidity?.type ) {\n\t\t\tvalidityTarget?.setCustomValidity( '' );\n\t\t\tsetErrorMessage( validityTarget?.validationMessage );\n\t\t\tsetStatusMessage( undefined );\n\t\t\treturn;\n\t\t}\n\n\t\tswitch ( customValidity.type ) {\n\t\t\tcase 'validating': {\n\t\t\t\t// Wait before showing a validating state.\n\t\t\t\tconst timer = setTimeout( () => {\n\t\t\t\t\tvalidityTarget?.setCustomValidity( '' );\n\t\t\t\t\tsetErrorMessage( undefined );\n\n\t\t\t\t\tsetStatusMessage( {\n\t\t\t\t\t\ttype: 'validating',\n\t\t\t\t\t\tmessage: customValidity.message,\n\t\t\t\t\t} );\n\t\t\t\t}, 1000 );\n\n\t\t\t\treturn () => clearTimeout( timer );\n\t\t\t}\n\t\t\tcase 'valid': {\n\t\t\t\t// Ensures that we wait for any async responses before showing\n\t\t\t\t// a synchronously valid state.\n\t\t\t\tif ( previousCustomValidityType === 'valid' ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tvalidityTarget?.setCustomValidity( '' );\n\t\t\t\tsetErrorMessage( validityTarget?.validationMessage );\n\n\t\t\t\tsetStatusMessage( {\n\t\t\t\t\ttype: 'valid',\n\t\t\t\t\tmessage: customValidity.message,\n\t\t\t\t} );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'invalid': {\n\t\t\t\tvalidityTarget?.setCustomValidity(\n\t\t\t\t\tcustomValidity.message ?? ''\n\t\t\t\t);\n\t\t\t\tsetErrorMessage( validityTarget?.validationMessage );\n\n\t\t\t\tsetStatusMessage( undefined );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}, [\n\t\tisTouched,\n\t\tcustomValidity?.type,\n\t\tcustomValidity?.message,\n\t\tgetValidityTarget,\n\t\tpreviousCustomValidityType,\n\t] );\n\n\tconst onBlur = ( event: React.FocusEvent< HTMLDivElement > ) => {\n\t\tif ( isTouched ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Only consider \"blurred from the component\" if focus has fully left the wrapping div.\n\t\t// This prevents unnecessary blurs from components with multiple focusable elements.\n\t\tif (\n\t\t\t! event.relatedTarget ||\n\t\t\t! event.currentTarget.contains( event.relatedTarget )\n\t\t) {\n\t\t\tsetIsTouched( true );\n\t\t\tonValidate?.();\n\t\t}\n\t};\n\n\tconst onChange = ( ...args: unknown[] ) => {\n\t\tchildren.props.onChange?.( ...args );\n\n\t\t// Only validate incrementally if the field has blurred at least once,\n\t\t// or currently has an error message.\n\t\tif ( isTouched || errorMessage ) {\n\t\t\tonValidate?.();\n\t\t}\n\t};\n\n\tconst onKeyDown = ( event: React.KeyboardEvent< HTMLDivElement > ) => {\n\t\t// Ensures that custom validators are triggered when the user submits by pressing Enter,\n\t\t// without ever blurring the control.\n\t\tif ( event.key === 'Enter' ) {\n\t\t\tonValidate?.();\n\t\t}\n\t};\n\n\treturn (\n\t\t// Disable reason: Just listening to a bubbled event, not for interaction.\n\t\t// eslint-disable-next-line jsx-a11y/no-static-element-interactions\n\t\t<div\n\t\t\tclassName=\"components-validated-control\"\n\t\t\tref={ forwardedRef }\n\t\t\tonBlur={ onBlur }\n\t\t\tonKeyDown={ withIgnoreIMEEvents( onKeyDown ) }\n\t\t>\n\t\t\t{ cloneElement( children, {\n\t\t\t\tlabel: appendRequiredIndicator(\n\t\t\t\t\tchildren.props.label,\n\t\t\t\t\trequired,\n\t\t\t\t\tmarkWhenOptional\n\t\t\t\t),\n\t\t\t\tonChange,\n\t\t\t\trequired,\n\t\t\t} ) }\n\t\t\t<div aria-live=\"polite\">\n\t\t\t\t{ errorMessage && (\n\t\t\t\t\t<ValidityIndicator\n\t\t\t\t\t\ttype=\"invalid\"\n\t\t\t\t\t\tmessage={ errorMessage }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t\t{ ! errorMessage && statusMessage && (\n\t\t\t\t\t<ValidityIndicator\n\t\t\t\t\t\ttype={ statusMessage.type }\n\t\t\t\t\t\tmessage={ statusMessage.message }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport const ControlWithError = forwardRef( UnforwardedControlWithError );\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import type { ForwardedRef,
|
|
4
|
+
import type { ForwardedRef, ReactElement, ReactNode } from 'react';
|
|
5
5
|
import type { WordPressComponentFromProps } from '.';
|
|
6
6
|
type AcceptsTwoArgs<F extends (...args: any) => any, ErrorMessage = never> = Parameters<F>['length'] extends 2 ? {} : ErrorMessage;
|
|
7
7
|
/**
|
|
@@ -28,7 +28,7 @@ export declare function contextConnectWithoutRef<P>(Component: (props: P) => JSX
|
|
|
28
28
|
* @param Component The component to retrieve a namespace from.
|
|
29
29
|
* @return The connected namespaces.
|
|
30
30
|
*/
|
|
31
|
-
export declare function getConnectNamespace(Component:
|
|
31
|
+
export declare function getConnectNamespace(Component: ReactElement | number | string | undefined | {}): string[];
|
|
32
32
|
/**
|
|
33
33
|
* Checks to see if a component is connected within the Context system.
|
|
34
34
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-connect.d.ts","sourceRoot":"","sources":["../../src/context/context-connect.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"context-connect.d.ts","sourceRoot":"","sources":["../../src/context/context-connect.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAanE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,GAAG,CAAC;AAErD,KAAK,cAAc,CAClB,CAAC,SAAS,CAAE,GAAG,IAAI,EAAE,GAAG,KAAM,GAAG,EACjC,YAAY,GAAG,KAAK,IACjB,UAAU,CAAE,CAAC,CAAE,CAAE,QAAQ,CAAE,SAAS,CAAC,GAAG,EAAE,GAAG,YAAY,CAAC;AAM9D;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC7B,CAAC,SAAS,CAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,YAAY,CAAE,GAAG,CAAE,KAAM,GAAG,CAAC,OAAO,GAAG,IAAI,EAExE,SAAS,EAAE,CAAC,GACX,cAAc,CACb,CAAC,EACD,8HAA8H,CAC9H,EACF,SAAS,EAAE,MAAM,2MAGjB;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAE,CAAC,EAC1C,SAAS,EAAE,CAAE,KAAK,EAAE,CAAC,KAAM,GAAG,CAAC,OAAO,GAAG,IAAI,EAC7C,SAAS,EAAE,MAAM,yCAGjB;AAgDD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAClC,SAAS,EAAE,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,EAAE,GACxD,MAAM,EAAE,CAoBV;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAClC,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,GACtB,OAAO,CAeT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/tabs/styles.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAS1C,eAAO,MAAM,aAAa;;;;;;UAuIzB,CAAC;AAEF,eAAO,MAAM,GAAG;;;;;;
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/tabs/styles.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAS1C,eAAO,MAAM,aAAa;;;;;;UAuIzB,CAAC;AAEF,eAAO,MAAM,GAAG;;;;;;UAiFf,CAAC;AAEF,eAAO,MAAM,WAAW;;SA/Md,MAAO,WACb;2GA0NH,CAAC;AAEF,eAAO,MAAM,UAAU;;UAuBtB,CAAC;AAEF,eAAO,MAAM,QAAQ;;;;;;UAapB,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import type { CSSProperties
|
|
4
|
+
import type { CSSProperties } from 'react';
|
|
5
5
|
export type HeadingSize = 1 | 2 | 3 | 4 | 5 | 6 | '1' | '2' | '3' | '4' | '5' | '6';
|
|
6
6
|
export declare const BASE_FONT_SIZE = 13;
|
|
7
7
|
export declare const PRESET_FONT_SIZES: {
|
|
@@ -14,5 +14,5 @@ export declare const PRESET_FONT_SIZES: {
|
|
|
14
14
|
};
|
|
15
15
|
export declare const HEADING_FONT_SIZES: HeadingSize[];
|
|
16
16
|
export declare function getFontSize(size?: CSSProperties['fontSize'] | keyof typeof PRESET_FONT_SIZES): string;
|
|
17
|
-
export declare function getHeadingFontSize(size?:
|
|
17
|
+
export declare function getHeadingFontSize(size?: number | string): string;
|
|
18
18
|
//# sourceMappingURL=font-size.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"font-size.d.ts","sourceRoot":"","sources":["../../src/utils/font-size.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"font-size.d.ts","sourceRoot":"","sources":["../../src/utils/font-size.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAO3C,MAAM,MAAM,WAAW,GACpB,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACD,GAAG,GACH,GAAG,GACH,GAAG,GACH,GAAG,GACH,GAAG,GACH,GAAG,CAAC;AAEP,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC,eAAO,MAAM,iBAAiB;;;;;;;CAO7B,CAAC;AAEF,eAAO,MAAM,kBAAkB,eAG5B,CAAC;AAEJ,wBAAgB,WAAW,CAC1B,IAAI,GACD,aAAa,CAAE,UAAU,CAAE,GAC3B,MAAM,OAAO,iBAAkC,GAChD,MAAM,CAiBR;AAED,wBAAgB,kBAAkB,CAAE,IAAI,GAAE,MAAM,GAAG,MAAU,GAAI,MAAM,CAOtE"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import type { ReactNode,
|
|
4
|
+
import type { ReactNode, ReactElement, ReactPortal } from 'react';
|
|
5
5
|
/**
|
|
6
6
|
* Gets a collection of available children elements from a React component's children prop.
|
|
7
7
|
*
|
|
@@ -9,5 +9,5 @@ import type { ReactNode, ReactChild, ReactFragment, ReactPortal } from 'react';
|
|
|
9
9
|
*
|
|
10
10
|
* @return An array of available children.
|
|
11
11
|
*/
|
|
12
|
-
export declare function getValidChildren(children: ReactNode): Array<
|
|
12
|
+
export declare function getValidChildren(children: ReactNode): Array<ReactElement | number | string | Iterable<ReactNode> | ReactPortal>;
|
|
13
13
|
//# sourceMappingURL=get-valid-children.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-valid-children.d.ts","sourceRoot":"","sources":["../../src/utils/get-valid-children.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"get-valid-children.d.ts","sourceRoot":"","sources":["../../src/utils/get-valid-children.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAOlE;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC/B,QAAQ,EAAE,SAAS,GACjB,KAAK,CACP,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAE,SAAS,CAAE,GAAG,WAAW,CACpE,CAQA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overview.story.d.ts","sourceRoot":"","sources":["../../../../src/validated-form-controls/components/stories/overview.story.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"overview.story.d.ts","sourceRoot":"","sources":["../../../../src/validated-form-controls/components/stories/overview.story.tsx"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AASvD;;GAEG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,IAAI,CAAC;AAE3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAE,OAAO,gBAAgB,CAIxC,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAE,OAAO,gBAAgB,CAAE,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,KA0DlC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,EAAE,KAmCrC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAE,OAAO,qBAAqB,CA8DnE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-with-error.d.ts","sourceRoot":"","sources":["../../src/validated-form-controls/control-with-error.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"control-with-error.d.ts","sourceRoot":"","sources":["../../src/validated-form-controls/control-with-error.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAyBhE;;;;;;;GAOG;AACH,KAAK,cAAc,GAChB,mBAAmB,GACnB,gBAAgB,GAChB,iBAAiB,GACjB,mBAAmB,CAAC;AAoMvB,eAAO,MAAM,gBAAgB;IAzL3B;;OAEG;eACQ,OAAO;IAClB;;OAEG;uBACgB,OAAO;IAC1B;;OAEG;iBACU,MAAM,IAAI;qBACN,qBAAqB,CAAE,OAAO,CAAE,CAAE,gBAAgB,CAAE;IACrE;;OAEG;uBACgB,MAAM,cAAc,GAAG,IAAI,GAAG,SAAS;IAC1D;;OAEG;;kDAsKoE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-with-error.d.ts","sourceRoot":"","sources":["../../../src/validated-form-controls/test/control-with-error.tsx"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/components",
|
|
3
|
-
"version": "30.2.
|
|
3
|
+
"version": "30.2.2-next.e256d081a.0",
|
|
4
4
|
"description": "UI components for WordPress.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -44,23 +44,23 @@
|
|
|
44
44
|
"@types/gradient-parser": "1.1.0",
|
|
45
45
|
"@types/highlight-words-core": "1.2.1",
|
|
46
46
|
"@use-gesture/react": "^10.3.1",
|
|
47
|
-
"@wordpress/a11y": "^4.29.1-next.
|
|
48
|
-
"@wordpress/compose": "^7.29.1-next.
|
|
49
|
-
"@wordpress/date": "^5.
|
|
50
|
-
"@wordpress/deprecated": "^4.29.1-next.
|
|
51
|
-
"@wordpress/dom": "^4.29.1-next.
|
|
52
|
-
"@wordpress/element": "^6.29.1-next.
|
|
53
|
-
"@wordpress/escape-html": "^3.29.1-next.
|
|
54
|
-
"@wordpress/hooks": "^4.29.1-next.
|
|
55
|
-
"@wordpress/html-entities": "^4.29.1-next.
|
|
56
|
-
"@wordpress/i18n": "^6.2.1-next.
|
|
57
|
-
"@wordpress/icons": "^10.29.1-next.
|
|
58
|
-
"@wordpress/is-shallow-equal": "^5.29.1-next.
|
|
59
|
-
"@wordpress/keycodes": "^4.29.1-next.
|
|
60
|
-
"@wordpress/primitives": "^4.29.1-next.
|
|
61
|
-
"@wordpress/private-apis": "^1.29.1-next.
|
|
62
|
-
"@wordpress/rich-text": "^7.29.1-next.
|
|
63
|
-
"@wordpress/warning": "^3.29.1-next.
|
|
47
|
+
"@wordpress/a11y": "^4.29.1-next.e256d081a.0",
|
|
48
|
+
"@wordpress/compose": "^7.29.1-next.e256d081a.0",
|
|
49
|
+
"@wordpress/date": "^5.30.1-next.e256d081a.0",
|
|
50
|
+
"@wordpress/deprecated": "^4.29.1-next.e256d081a.0",
|
|
51
|
+
"@wordpress/dom": "^4.29.1-next.e256d081a.0",
|
|
52
|
+
"@wordpress/element": "^6.29.1-next.e256d081a.0",
|
|
53
|
+
"@wordpress/escape-html": "^3.29.1-next.e256d081a.0",
|
|
54
|
+
"@wordpress/hooks": "^4.29.1-next.e256d081a.0",
|
|
55
|
+
"@wordpress/html-entities": "^4.29.1-next.e256d081a.0",
|
|
56
|
+
"@wordpress/i18n": "^6.2.1-next.e256d081a.0",
|
|
57
|
+
"@wordpress/icons": "^10.29.1-next.e256d081a.0",
|
|
58
|
+
"@wordpress/is-shallow-equal": "^5.29.1-next.e256d081a.0",
|
|
59
|
+
"@wordpress/keycodes": "^4.29.1-next.e256d081a.0",
|
|
60
|
+
"@wordpress/primitives": "^4.29.1-next.e256d081a.0",
|
|
61
|
+
"@wordpress/private-apis": "^1.29.1-next.e256d081a.0",
|
|
62
|
+
"@wordpress/rich-text": "^7.29.1-next.e256d081a.0",
|
|
63
|
+
"@wordpress/warning": "^3.29.1-next.e256d081a.0",
|
|
64
64
|
"change-case": "^4.1.2",
|
|
65
65
|
"clsx": "^2.1.1",
|
|
66
66
|
"colord": "^2.7.0",
|
|
@@ -86,5 +86,5 @@
|
|
|
86
86
|
"publishConfig": {
|
|
87
87
|
"access": "public"
|
|
88
88
|
},
|
|
89
|
-
"gitHead": "
|
|
89
|
+
"gitHead": "7d529ba9a461795d5f1572d3856de33f744287c2"
|
|
90
90
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import type { ForwardedRef,
|
|
4
|
+
import type { ForwardedRef, ReactElement, ReactNode } from 'react';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* WordPress dependencies
|
|
@@ -114,7 +114,7 @@ function _contextConnect<
|
|
|
114
114
|
* @return The connected namespaces.
|
|
115
115
|
*/
|
|
116
116
|
export function getConnectNamespace(
|
|
117
|
-
Component:
|
|
117
|
+
Component: ReactElement | number | string | undefined | {}
|
|
118
118
|
): string[] {
|
|
119
119
|
if ( ! Component ) {
|
|
120
120
|
return [];
|
package/src/tabs/styles.ts
CHANGED
|
@@ -7,7 +7,7 @@ import * as Ariakit from '@ariakit/react';
|
|
|
7
7
|
/**
|
|
8
8
|
* Internal dependencies
|
|
9
9
|
*/
|
|
10
|
-
import { COLORS, CONFIG } from '../utils';
|
|
10
|
+
import { COLORS, CONFIG, font } from '../utils';
|
|
11
11
|
import { space } from '../utils/space';
|
|
12
12
|
import Icon from '../icon';
|
|
13
13
|
|
|
@@ -163,6 +163,7 @@ export const Tab = styled( Ariakit.Tab )`
|
|
|
163
163
|
cursor: pointer;
|
|
164
164
|
line-height: 1.2; // Characters in some languages (e.g. Japanese) may have a native higher line-height.
|
|
165
165
|
font-weight: 400;
|
|
166
|
+
font-size: ${ font( 'default.fontSize' ) };
|
|
166
167
|
color: ${ COLORS.theme.foreground };
|
|
167
168
|
|
|
168
169
|
&[aria-disabled='true'] {
|
|
@@ -54,7 +54,7 @@ export const Default: StoryFn< typeof ToolsPanel > = ( {
|
|
|
54
54
|
const [ height, setHeight ] = useState< string | undefined >();
|
|
55
55
|
const [ minHeight, setMinHeight ] = useState< string | undefined >();
|
|
56
56
|
const [ width, setWidth ] = useState< string | undefined >();
|
|
57
|
-
const [ scale, setScale ] = useState<
|
|
57
|
+
const [ scale, setScale ] = useState< number | string | undefined >();
|
|
58
58
|
|
|
59
59
|
const resetAll: typeof resetAllProp = ( filters ) => {
|
|
60
60
|
setHeight( undefined );
|
|
@@ -414,7 +414,7 @@ export const WithConditionalDefaultControl: StoryFn< typeof ToolsPanel > = ( {
|
|
|
414
414
|
} ) => {
|
|
415
415
|
const [ attributes, setAttributes ] = useState< {
|
|
416
416
|
height?: string;
|
|
417
|
-
scale?:
|
|
417
|
+
scale?: number | string;
|
|
418
418
|
} >( {} );
|
|
419
419
|
const { height, scale } = attributes;
|
|
420
420
|
|
|
@@ -512,7 +512,7 @@ export const WithConditionallyRenderedControl: StoryFn<
|
|
|
512
512
|
> = ( { resetAll: resetAllProp, panelId, ...props } ) => {
|
|
513
513
|
const [ attributes, setAttributes ] = useState< {
|
|
514
514
|
height?: string;
|
|
515
|
-
scale?:
|
|
515
|
+
scale?: number | string;
|
|
516
516
|
} >( {} );
|
|
517
517
|
const { height, scale } = attributes;
|
|
518
518
|
|
package/src/utils/font-size.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import type { CSSProperties
|
|
4
|
+
import type { CSSProperties } from 'react';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Internal dependencies
|
|
@@ -61,7 +61,7 @@ export function getFontSize(
|
|
|
61
61
|
return `calc(${ ratio } * ${ CONFIG.fontSize })`;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
export function getHeadingFontSize( size:
|
|
64
|
+
export function getHeadingFontSize( size: number | string = 3 ): string {
|
|
65
65
|
if ( ! HEADING_FONT_SIZES.includes( size as HeadingSize ) ) {
|
|
66
66
|
return getFontSize( size );
|
|
67
67
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import type { ReactNode,
|
|
4
|
+
import type { ReactNode, ReactElement, ReactPortal } from 'react';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* WordPress dependencies
|
|
@@ -17,7 +17,9 @@ import { Children, isValidElement } from '@wordpress/element';
|
|
|
17
17
|
*/
|
|
18
18
|
export function getValidChildren(
|
|
19
19
|
children: ReactNode
|
|
20
|
-
): Array<
|
|
20
|
+
): Array<
|
|
21
|
+
ReactElement | number | string | Iterable< ReactNode > | ReactPortal
|
|
22
|
+
> {
|
|
21
23
|
if ( typeof children === 'string' ) {
|
|
22
24
|
return [ children ];
|
|
23
25
|
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
5
|
+
import { expect, userEvent, waitFor, within } from '@storybook/test';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
|
-
*
|
|
8
|
+
* WordPress dependencies
|
|
8
9
|
*/
|
|
9
|
-
import
|
|
10
|
+
import { useRef, useCallback, useState } from '@wordpress/element';
|
|
11
|
+
import { debounce } from '@wordpress/compose';
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* Internal dependencies
|
|
@@ -14,7 +16,6 @@ import type { Meta, StoryObj } from '@storybook/react';
|
|
|
14
16
|
import { ValidatedInputControl } from '..';
|
|
15
17
|
import { formDecorator } from './story-utils';
|
|
16
18
|
import type { ControlWithError } from '../../control-with-error';
|
|
17
|
-
import { debounce } from '@wordpress/compose';
|
|
18
19
|
|
|
19
20
|
const meta: Meta< typeof ControlWithError > = {
|
|
20
21
|
title: 'Components/Selection & Input/Validated Form Controls/Overview',
|
|
@@ -166,24 +167,19 @@ export const AsyncValidation: StoryObj< typeof ValidatedInputControl > = {
|
|
|
166
167
|
} );
|
|
167
168
|
|
|
168
169
|
clearTimeout( timeoutRef.current );
|
|
169
|
-
timeoutRef.current = setTimeout(
|
|
170
|
-
()
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
},
|
|
183
|
-
// Mimics a random server response time.
|
|
184
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
185
|
-
Math.random() < 0.5 ? 1500 : 300
|
|
186
|
-
);
|
|
170
|
+
timeoutRef.current = setTimeout( () => {
|
|
171
|
+
if ( v?.toString().toLowerCase() === 'error' ) {
|
|
172
|
+
setCustomValidity( {
|
|
173
|
+
type: 'invalid',
|
|
174
|
+
message: 'The word "error" is not allowed.',
|
|
175
|
+
} );
|
|
176
|
+
} else {
|
|
177
|
+
setCustomValidity( {
|
|
178
|
+
type: 'valid',
|
|
179
|
+
message: 'Validated',
|
|
180
|
+
} );
|
|
181
|
+
}
|
|
182
|
+
}, 1500 );
|
|
187
183
|
}, 500 ),
|
|
188
184
|
[]
|
|
189
185
|
);
|
|
@@ -200,9 +196,95 @@ export const AsyncValidation: StoryObj< typeof ValidatedInputControl > = {
|
|
|
200
196
|
/>
|
|
201
197
|
);
|
|
202
198
|
},
|
|
199
|
+
args: {
|
|
200
|
+
label: 'Text',
|
|
201
|
+
help: 'The word "error" will trigger an error asynchronously.',
|
|
202
|
+
required: true,
|
|
203
|
+
},
|
|
203
204
|
};
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
205
|
+
|
|
206
|
+
// Not exported - Only for testing purposes.
|
|
207
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
208
|
+
const AsyncValidationWithTest: StoryObj< typeof ValidatedInputControl > = {
|
|
209
|
+
...AsyncValidation,
|
|
210
|
+
play: async ( { canvasElement } ) => {
|
|
211
|
+
const canvas = within( canvasElement );
|
|
212
|
+
await userEvent.click( canvas.getByRole( 'textbox' ) );
|
|
213
|
+
await userEvent.type( canvas.getByRole( 'textbox' ), 'valid text', {
|
|
214
|
+
delay: 10,
|
|
215
|
+
} );
|
|
216
|
+
await userEvent.tab();
|
|
217
|
+
|
|
218
|
+
await waitFor(
|
|
219
|
+
() => {
|
|
220
|
+
expect( canvas.getByText( 'Validated' ) ).toBeVisible();
|
|
221
|
+
},
|
|
222
|
+
{ timeout: 2500 }
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
await new Promise( ( resolve ) => setTimeout( resolve, 500 ) );
|
|
226
|
+
await userEvent.clear( canvas.getByRole( 'textbox' ) );
|
|
227
|
+
|
|
228
|
+
// Should show validating state when transitioning from valid to invalid.
|
|
229
|
+
await waitFor(
|
|
230
|
+
() => {
|
|
231
|
+
expect( canvas.getByText( 'Validating...' ) ).toBeVisible();
|
|
232
|
+
},
|
|
233
|
+
{ timeout: 2500 }
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
await waitFor(
|
|
237
|
+
() => {
|
|
238
|
+
expect(
|
|
239
|
+
canvas.getByText( 'Please fill out this field.' )
|
|
240
|
+
).toBeVisible();
|
|
241
|
+
},
|
|
242
|
+
{ timeout: 2500 }
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
// Should not show validating state if there were no changes
|
|
246
|
+
// after a valid/invalid state was already shown.
|
|
247
|
+
await new Promise( ( resolve ) => setTimeout( resolve, 1500 ) );
|
|
248
|
+
await expect(
|
|
249
|
+
canvas.queryByText( 'Validating...' )
|
|
250
|
+
).not.toBeInTheDocument();
|
|
251
|
+
|
|
252
|
+
await userEvent.type( canvas.getByRole( 'textbox' ), 'e', {
|
|
253
|
+
delay: 10,
|
|
254
|
+
} );
|
|
255
|
+
|
|
256
|
+
// Should not show valid state if server has not yet responded.
|
|
257
|
+
await expect(
|
|
258
|
+
canvas.queryByText( 'Validated' )
|
|
259
|
+
).not.toBeInTheDocument();
|
|
260
|
+
|
|
261
|
+
// Should show validating state when transitioning from invalid to valid.
|
|
262
|
+
await waitFor(
|
|
263
|
+
() => {
|
|
264
|
+
expect( canvas.getByText( 'Validating...' ) ).toBeVisible();
|
|
265
|
+
},
|
|
266
|
+
{ timeout: 2500 }
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
await waitFor(
|
|
270
|
+
() => {
|
|
271
|
+
expect( canvas.getByText( 'Validated' ) ).toBeVisible();
|
|
272
|
+
},
|
|
273
|
+
{ timeout: 2500 }
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
await new Promise( ( resolve ) => setTimeout( resolve, 1000 ) );
|
|
277
|
+
await userEvent.type( canvas.getByRole( 'textbox' ), 'rror', {
|
|
278
|
+
delay: 10,
|
|
279
|
+
} );
|
|
280
|
+
|
|
281
|
+
await waitFor(
|
|
282
|
+
() => {
|
|
283
|
+
expect(
|
|
284
|
+
canvas.getByText( 'The word "error" is not allowed.' )
|
|
285
|
+
).toBeVisible();
|
|
286
|
+
},
|
|
287
|
+
{ timeout: 2500 }
|
|
288
|
+
);
|
|
289
|
+
},
|
|
208
290
|
};
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
+
import { usePrevious } from '@wordpress/compose';
|
|
4
5
|
import { __ } from '@wordpress/i18n';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* External dependencies
|
|
8
|
-
*/
|
|
9
6
|
import {
|
|
10
7
|
cloneElement,
|
|
11
8
|
forwardRef,
|
|
@@ -98,6 +95,7 @@ function UnforwardedControlWithError< C extends React.ReactElement >(
|
|
|
98
95
|
| undefined
|
|
99
96
|
>();
|
|
100
97
|
const [ isTouched, setIsTouched ] = useState( false );
|
|
98
|
+
const previousCustomValidityType = usePrevious( customValidity?.type );
|
|
101
99
|
|
|
102
100
|
// Ensure that error messages are visible after user attemps to submit a form
|
|
103
101
|
// with multiple invalid fields.
|
|
@@ -116,7 +114,7 @@ function UnforwardedControlWithError< C extends React.ReactElement >(
|
|
|
116
114
|
};
|
|
117
115
|
} );
|
|
118
116
|
|
|
119
|
-
useEffect( () => {
|
|
117
|
+
useEffect( (): ReturnType< React.EffectCallback > => {
|
|
120
118
|
if ( ! isTouched ) {
|
|
121
119
|
return;
|
|
122
120
|
}
|
|
@@ -134,6 +132,9 @@ function UnforwardedControlWithError< C extends React.ReactElement >(
|
|
|
134
132
|
case 'validating': {
|
|
135
133
|
// Wait before showing a validating state.
|
|
136
134
|
const timer = setTimeout( () => {
|
|
135
|
+
validityTarget?.setCustomValidity( '' );
|
|
136
|
+
setErrorMessage( undefined );
|
|
137
|
+
|
|
137
138
|
setStatusMessage( {
|
|
138
139
|
type: 'validating',
|
|
139
140
|
message: customValidity.message,
|
|
@@ -143,6 +144,12 @@ function UnforwardedControlWithError< C extends React.ReactElement >(
|
|
|
143
144
|
return () => clearTimeout( timer );
|
|
144
145
|
}
|
|
145
146
|
case 'valid': {
|
|
147
|
+
// Ensures that we wait for any async responses before showing
|
|
148
|
+
// a synchronously valid state.
|
|
149
|
+
if ( previousCustomValidityType === 'valid' ) {
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
|
|
146
153
|
validityTarget?.setCustomValidity( '' );
|
|
147
154
|
setErrorMessage( validityTarget?.validationMessage );
|
|
148
155
|
|
|
@@ -150,7 +157,7 @@ function UnforwardedControlWithError< C extends React.ReactElement >(
|
|
|
150
157
|
type: 'valid',
|
|
151
158
|
message: customValidity.message,
|
|
152
159
|
} );
|
|
153
|
-
|
|
160
|
+
break;
|
|
154
161
|
}
|
|
155
162
|
case 'invalid': {
|
|
156
163
|
validityTarget?.setCustomValidity(
|
|
@@ -159,7 +166,7 @@ function UnforwardedControlWithError< C extends React.ReactElement >(
|
|
|
159
166
|
setErrorMessage( validityTarget?.validationMessage );
|
|
160
167
|
|
|
161
168
|
setStatusMessage( undefined );
|
|
162
|
-
|
|
169
|
+
break;
|
|
163
170
|
}
|
|
164
171
|
}
|
|
165
172
|
}, [
|
|
@@ -167,9 +174,14 @@ function UnforwardedControlWithError< C extends React.ReactElement >(
|
|
|
167
174
|
customValidity?.type,
|
|
168
175
|
customValidity?.message,
|
|
169
176
|
getValidityTarget,
|
|
177
|
+
previousCustomValidityType,
|
|
170
178
|
] );
|
|
171
179
|
|
|
172
180
|
const onBlur = ( event: React.FocusEvent< HTMLDivElement > ) => {
|
|
181
|
+
if ( isTouched ) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
173
185
|
// Only consider "blurred from the component" if focus has fully left the wrapping div.
|
|
174
186
|
// This prevents unnecessary blurs from components with multiple focusable elements.
|
|
175
187
|
if (
|
|
@@ -177,17 +189,6 @@ function UnforwardedControlWithError< C extends React.ReactElement >(
|
|
|
177
189
|
! event.currentTarget.contains( event.relatedTarget )
|
|
178
190
|
) {
|
|
179
191
|
setIsTouched( true );
|
|
180
|
-
|
|
181
|
-
const validityTarget = getValidityTarget();
|
|
182
|
-
|
|
183
|
-
// Prevents a double flash of the native error tooltip when the control is already showing one.
|
|
184
|
-
if ( ! validityTarget?.validity.valid ) {
|
|
185
|
-
if ( ! errorMessage ) {
|
|
186
|
-
setErrorMessage( validityTarget?.validationMessage );
|
|
187
|
-
}
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
192
|
onValidate?.();
|
|
192
193
|
}
|
|
193
194
|
};
|