@wordpress/components 30.9.1-next.8b30e05b0.0 → 31.0.1-next.6deb34194.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 +25 -4
- package/build/alignment-matrix-control/cell.js +131 -3
- package/build/alignment-matrix-control/cell.js.map +4 -4
- package/build/alignment-matrix-control/index.js +134 -6
- package/build/alignment-matrix-control/index.js.map +3 -3
- package/build/angle-picker-control/angle-circle.js +119 -15
- package/build/angle-picker-control/angle-circle.js.map +4 -4
- package/build/angle-picker-control/index.js +12 -7
- package/build/angle-picker-control/index.js.map +3 -3
- package/build/dropdown-menu/index.js +1 -1
- package/build/dropdown-menu/index.js.map +2 -2
- package/build/menu/styles.js +17 -17
- package/build/menu/styles.js.map +2 -2
- package/build/menu-item/index.js +1 -1
- package/build/menu-item/index.js.map +2 -2
- package/build/notice/index.js +1 -1
- package/build/notice/index.js.map +2 -2
- package/build/snackbar/index.js +1 -1
- package/build/snackbar/index.js.map +1 -1
- package/build/validated-form-controls/components/checkbox-control.js +0 -10
- package/build/validated-form-controls/components/checkbox-control.js.map +2 -2
- package/build/validated-form-controls/components/combobox-control.js +1 -11
- package/build/validated-form-controls/components/combobox-control.js.map +2 -2
- package/build/validated-form-controls/components/custom-select-control.js +0 -10
- package/build/validated-form-controls/components/custom-select-control.js.map +2 -2
- package/build/validated-form-controls/components/form-token-field.js +2 -12
- package/build/validated-form-controls/components/form-token-field.js.map +2 -2
- package/build/validated-form-controls/components/input-control.js +0 -10
- package/build/validated-form-controls/components/input-control.js.map +2 -2
- package/build/validated-form-controls/components/number-control.js +0 -10
- package/build/validated-form-controls/components/number-control.js.map +2 -2
- package/build/validated-form-controls/components/radio-control.js +0 -10
- package/build/validated-form-controls/components/radio-control.js.map +2 -2
- package/build/validated-form-controls/components/range-control.js +0 -10
- package/build/validated-form-controls/components/range-control.js.map +2 -2
- package/build/validated-form-controls/components/select-control.js +0 -10
- package/build/validated-form-controls/components/select-control.js.map +2 -2
- package/build/validated-form-controls/components/text-control.js +0 -10
- package/build/validated-form-controls/components/text-control.js.map +2 -2
- package/build/validated-form-controls/components/textarea-control.js +0 -10
- package/build/validated-form-controls/components/textarea-control.js.map +2 -2
- package/build/validated-form-controls/components/toggle-control.js +0 -10
- package/build/validated-form-controls/components/toggle-control.js.map +2 -2
- package/build/validated-form-controls/components/toggle-group-control.js +0 -10
- package/build/validated-form-controls/components/toggle-group-control.js.map +2 -2
- package/build/validated-form-controls/control-with-error.js +53 -58
- package/build/validated-form-controls/control-with-error.js.map +2 -2
- package/build-module/alignment-matrix-control/cell.js +131 -3
- package/build-module/alignment-matrix-control/cell.js.map +3 -3
- package/build-module/alignment-matrix-control/index.js +134 -6
- package/build-module/alignment-matrix-control/index.js.map +3 -3
- package/build-module/angle-picker-control/angle-circle.js +109 -15
- package/build-module/angle-picker-control/angle-circle.js.map +3 -3
- package/build-module/angle-picker-control/index.js +12 -7
- package/build-module/angle-picker-control/index.js.map +2 -2
- package/build-module/dropdown-menu/index.js +1 -1
- package/build-module/dropdown-menu/index.js.map +2 -2
- package/build-module/menu/styles.js +17 -17
- package/build-module/menu/styles.js.map +2 -2
- package/build-module/menu-item/index.js +1 -1
- package/build-module/menu-item/index.js.map +2 -2
- package/build-module/notice/index.js +1 -1
- package/build-module/notice/index.js.map +2 -2
- package/build-module/snackbar/index.js +1 -1
- package/build-module/snackbar/index.js.map +1 -1
- package/build-module/validated-form-controls/components/checkbox-control.js +0 -10
- package/build-module/validated-form-controls/components/checkbox-control.js.map +2 -2
- package/build-module/validated-form-controls/components/combobox-control.js +1 -11
- package/build-module/validated-form-controls/components/combobox-control.js.map +2 -2
- package/build-module/validated-form-controls/components/custom-select-control.js +0 -10
- package/build-module/validated-form-controls/components/custom-select-control.js.map +2 -2
- package/build-module/validated-form-controls/components/form-token-field.js +2 -12
- package/build-module/validated-form-controls/components/form-token-field.js.map +2 -2
- package/build-module/validated-form-controls/components/input-control.js +0 -10
- package/build-module/validated-form-controls/components/input-control.js.map +2 -2
- package/build-module/validated-form-controls/components/number-control.js +0 -10
- package/build-module/validated-form-controls/components/number-control.js.map +2 -2
- package/build-module/validated-form-controls/components/radio-control.js +0 -10
- package/build-module/validated-form-controls/components/radio-control.js.map +2 -2
- package/build-module/validated-form-controls/components/range-control.js +0 -10
- package/build-module/validated-form-controls/components/range-control.js.map +2 -2
- package/build-module/validated-form-controls/components/select-control.js +0 -10
- package/build-module/validated-form-controls/components/select-control.js.map +2 -2
- package/build-module/validated-form-controls/components/text-control.js +0 -10
- package/build-module/validated-form-controls/components/text-control.js.map +2 -2
- package/build-module/validated-form-controls/components/textarea-control.js +0 -10
- package/build-module/validated-form-controls/components/textarea-control.js.map +2 -2
- package/build-module/validated-form-controls/components/toggle-control.js +0 -10
- package/build-module/validated-form-controls/components/toggle-control.js.map +2 -2
- package/build-module/validated-form-controls/components/toggle-group-control.js +0 -10
- package/build-module/validated-form-controls/components/toggle-group-control.js.map +2 -2
- package/build-module/validated-form-controls/control-with-error.js +53 -58
- package/build-module/validated-form-controls/control-with-error.js.map +2 -2
- package/build-style/style-rtl.css +21 -33
- package/build-style/style.css +21 -33
- package/build-types/alignment-matrix-control/cell.d.ts.map +1 -1
- package/build-types/alignment-matrix-control/index.d.ts.map +1 -1
- package/build-types/angle-picker-control/angle-circle.d.ts +1 -1
- package/build-types/angle-picker-control/angle-circle.d.ts.map +1 -1
- package/build-types/angle-picker-control/index.d.ts.map +1 -1
- package/build-types/notice/index.d.ts.map +1 -1
- package/build-types/notice/stories/index.story.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/checkbox-control.d.ts +1 -1
- package/build-types/validated-form-controls/components/checkbox-control.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/combobox-control.d.ts +2 -3
- package/build-types/validated-form-controls/components/combobox-control.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/custom-select-control.d.ts +1 -2
- package/build-types/validated-form-controls/components/custom-select-control.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/form-token-field.d.ts +1 -2
- package/build-types/validated-form-controls/components/form-token-field.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/input-control.d.ts +1 -2
- package/build-types/validated-form-controls/components/input-control.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/number-control.d.ts +1 -1
- package/build-types/validated-form-controls/components/number-control.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/radio-control.d.ts +1 -1
- package/build-types/validated-form-controls/components/radio-control.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/range-control.d.ts +1 -1
- package/build-types/validated-form-controls/components/range-control.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/select-control.d.ts +2 -3
- package/build-types/validated-form-controls/components/select-control.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/stories/checkbox-control.story.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/stories/combobox-control.story.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/stories/custom-select-control.story.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/stories/form-token-field.story.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/stories/input-control.story.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/stories/number-control.story.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/stories/overview.story.d.ts +7 -0
- package/build-types/validated-form-controls/components/stories/overview.story.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/stories/radio-control.story.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/stories/range-control.story.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/stories/select-control.story.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/stories/text-control.story.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/stories/textarea-control.story.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/stories/toggle-control.story.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/stories/toggle-group-control.story.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/text-control.d.ts +1 -1
- package/build-types/validated-form-controls/components/text-control.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/textarea-control.d.ts +1 -1
- package/build-types/validated-form-controls/components/textarea-control.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/toggle-control.d.ts +1 -1
- package/build-types/validated-form-controls/components/toggle-control.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/toggle-group-control.d.ts +1 -1
- package/build-types/validated-form-controls/components/toggle-group-control.d.ts.map +1 -1
- package/build-types/validated-form-controls/components/types.d.ts +1 -9
- package/build-types/validated-form-controls/components/types.d.ts.map +1 -1
- package/build-types/validated-form-controls/control-with-error.d.ts +4 -5
- package/build-types/validated-form-controls/control-with-error.d.ts.map +1 -1
- package/package.json +20 -20
- package/src/alignment-matrix-control/cell.tsx +14 -3
- package/src/alignment-matrix-control/index.tsx +15 -6
- package/src/alignment-matrix-control/style.module.scss +84 -0
- package/src/angle-picker-control/angle-circle.tsx +27 -12
- package/src/angle-picker-control/index.tsx +8 -7
- package/src/angle-picker-control/style.module.scss +40 -0
- package/src/button/style.scss +1 -1
- package/src/dropdown-menu/index.tsx +1 -1
- package/src/dropdown-menu/style.scss +1 -1
- package/src/guide/style.scss +3 -3
- package/src/menu/styles.ts +2 -2
- package/src/menu-item/index.tsx +1 -1
- package/src/menu-item/test/__snapshots__/index.js.snap +4 -4
- package/src/modal/style.scss +5 -5
- package/src/notice/index.tsx +53 -46
- package/src/notice/stories/index.story.tsx +17 -1
- package/src/notice/style.scss +3 -20
- package/src/snackbar/index.tsx +1 -1
- package/src/validated-form-controls/components/checkbox-control.tsx +1 -14
- package/src/validated-form-controls/components/combobox-control.tsx +1 -14
- package/src/validated-form-controls/components/custom-select-control.tsx +1 -19
- package/src/validated-form-controls/components/form-token-field.tsx +2 -15
- package/src/validated-form-controls/components/input-control.tsx +1 -14
- package/src/validated-form-controls/components/number-control.tsx +1 -16
- package/src/validated-form-controls/components/radio-control.tsx +2 -18
- package/src/validated-form-controls/components/range-control.tsx +1 -14
- package/src/validated-form-controls/components/select-control.tsx +1 -23
- package/src/validated-form-controls/components/stories/checkbox-control.story.tsx +11 -20
- package/src/validated-form-controls/components/stories/combobox-control.story.tsx +8 -17
- package/src/validated-form-controls/components/stories/custom-select-control.story.tsx +8 -17
- package/src/validated-form-controls/components/stories/form-token-field.story.tsx +14 -26
- package/src/validated-form-controls/components/stories/input-control.story.tsx +25 -50
- package/src/validated-form-controls/components/stories/number-control.story.tsx +10 -19
- package/src/validated-form-controls/components/stories/overview.mdx +3 -3
- package/src/validated-form-controls/components/stories/overview.story.tsx +94 -79
- package/src/validated-form-controls/components/stories/radio-control.story.tsx +11 -20
- package/src/validated-form-controls/components/stories/range-control.story.tsx +8 -17
- package/src/validated-form-controls/components/stories/select-control.story.tsx +9 -18
- package/src/validated-form-controls/components/stories/text-control.story.tsx +11 -17
- package/src/validated-form-controls/components/stories/textarea-control.story.tsx +12 -16
- package/src/validated-form-controls/components/stories/toggle-control.story.tsx +11 -20
- package/src/validated-form-controls/components/stories/toggle-group-control.story.tsx +8 -17
- package/src/validated-form-controls/components/text-control.tsx +1 -14
- package/src/validated-form-controls/components/textarea-control.tsx +1 -14
- package/src/validated-form-controls/components/toggle-control.tsx +1 -14
- package/src/validated-form-controls/components/toggle-group-control.tsx +1 -14
- package/src/validated-form-controls/components/types.ts +1 -9
- package/src/validated-form-controls/control-with-error.tsx +57 -84
- package/src/validated-form-controls/style.scss +7 -7
- package/src/validated-form-controls/test/control-with-error.tsx +66 -5
- package/tsconfig.json +1 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/build/alignment-matrix-control/styles.js +0 -105
- package/build/alignment-matrix-control/styles.js.map +0 -7
- package/build/angle-picker-control/styles/angle-picker-control-styles.js +0 -88
- package/build/angle-picker-control/styles/angle-picker-control-styles.js.map +0 -7
- package/build-module/alignment-matrix-control/styles.js +0 -67
- package/build-module/alignment-matrix-control/styles.js.map +0 -7
- package/build-module/angle-picker-control/styles/angle-picker-control-styles.js +0 -50
- package/build-module/angle-picker-control/styles/angle-picker-control-styles.js.map +0 -7
- package/build-types/alignment-matrix-control/styles.d.ts +0 -21
- package/build-types/alignment-matrix-control/styles.d.ts.map +0 -1
- package/build-types/angle-picker-control/styles/angle-picker-control-styles.d.ts +0 -18
- package/build-types/angle-picker-control/styles/angle-picker-control-styles.d.ts.map +0 -1
- package/src/alignment-matrix-control/styles.ts +0 -113
- package/src/angle-picker-control/styles/angle-picker-control-styles.tsx +0 -58
|
@@ -32,32 +32,23 @@ export default meta;
|
|
|
32
32
|
export const Default: StoryObj< typeof ValidatedCheckboxControl > = {
|
|
33
33
|
render: function Template( { onChange, ...args } ) {
|
|
34
34
|
const [ checked, setChecked ] = useState( false );
|
|
35
|
-
const [ customValidity, setCustomValidity ] =
|
|
36
|
-
useState<
|
|
37
|
-
React.ComponentProps<
|
|
38
|
-
typeof ValidatedCheckboxControl
|
|
39
|
-
>[ 'customValidity' ]
|
|
40
|
-
>( undefined );
|
|
41
35
|
|
|
42
36
|
return (
|
|
43
37
|
<ValidatedCheckboxControl
|
|
44
38
|
{ ...args }
|
|
45
39
|
checked={ checked }
|
|
46
|
-
onChange={ (
|
|
47
|
-
setChecked(
|
|
48
|
-
onChange?.(
|
|
40
|
+
onChange={ ( newValue ) => {
|
|
41
|
+
setChecked( newValue );
|
|
42
|
+
onChange?.( newValue );
|
|
49
43
|
} }
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
} }
|
|
60
|
-
customValidity={ customValidity }
|
|
44
|
+
customValidity={
|
|
45
|
+
checked
|
|
46
|
+
? {
|
|
47
|
+
type: 'invalid',
|
|
48
|
+
message: 'This checkbox may not be checked.',
|
|
49
|
+
}
|
|
50
|
+
: undefined
|
|
51
|
+
}
|
|
61
52
|
/>
|
|
62
53
|
);
|
|
63
54
|
},
|
|
@@ -35,12 +35,6 @@ export const Default: StoryObj< typeof ValidatedComboboxControl > = {
|
|
|
35
35
|
typeof ValidatedComboboxControl
|
|
36
36
|
>[ 'value' ]
|
|
37
37
|
>();
|
|
38
|
-
const [ customValidity, setCustomValidity ] =
|
|
39
|
-
useState<
|
|
40
|
-
React.ComponentProps<
|
|
41
|
-
typeof ValidatedComboboxControl
|
|
42
|
-
>[ 'customValidity' ]
|
|
43
|
-
>( undefined );
|
|
44
38
|
|
|
45
39
|
return (
|
|
46
40
|
<ValidatedComboboxControl
|
|
@@ -50,17 +44,14 @@ export const Default: StoryObj< typeof ValidatedComboboxControl > = {
|
|
|
50
44
|
setValue( newValue );
|
|
51
45
|
onChange?.( newValue );
|
|
52
46
|
} }
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
} }
|
|
63
|
-
customValidity={ customValidity }
|
|
47
|
+
customValidity={
|
|
48
|
+
value === 'a'
|
|
49
|
+
? {
|
|
50
|
+
type: 'invalid',
|
|
51
|
+
message: 'Option A is not allowed.',
|
|
52
|
+
}
|
|
53
|
+
: undefined
|
|
54
|
+
}
|
|
64
55
|
/>
|
|
65
56
|
);
|
|
66
57
|
},
|
|
@@ -35,12 +35,6 @@ export const Default: StoryObj< typeof ValidatedCustomSelectControl > = {
|
|
|
35
35
|
typeof ValidatedCustomSelectControl
|
|
36
36
|
>[ 'value' ]
|
|
37
37
|
>();
|
|
38
|
-
const [ customValidity, setCustomValidity ] =
|
|
39
|
-
useState<
|
|
40
|
-
React.ComponentProps<
|
|
41
|
-
typeof ValidatedCustomSelectControl
|
|
42
|
-
>[ 'customValidity' ]
|
|
43
|
-
>( undefined );
|
|
44
38
|
|
|
45
39
|
return (
|
|
46
40
|
<ValidatedCustomSelectControl
|
|
@@ -50,17 +44,14 @@ export const Default: StoryObj< typeof ValidatedCustomSelectControl > = {
|
|
|
50
44
|
setValue( newValue.selectedItem );
|
|
51
45
|
onChange?.( newValue );
|
|
52
46
|
} }
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
} }
|
|
63
|
-
customValidity={ customValidity }
|
|
47
|
+
customValidity={
|
|
48
|
+
value?.key === 'a'
|
|
49
|
+
? {
|
|
50
|
+
type: 'invalid',
|
|
51
|
+
message: 'Option A is not allowed.',
|
|
52
|
+
}
|
|
53
|
+
: undefined
|
|
54
|
+
}
|
|
64
55
|
/>
|
|
65
56
|
);
|
|
66
57
|
},
|
|
@@ -36,39 +36,27 @@ export default meta;
|
|
|
36
36
|
export const Default: StoryObj< typeof ValidatedFormTokenField > = {
|
|
37
37
|
render: function Template( { onChange, ...args } ) {
|
|
38
38
|
const [ value, setValue ] = useState< ( string | TokenItem )[] >( [] );
|
|
39
|
-
const [ customValidity, setCustomValidity ] =
|
|
40
|
-
useState<
|
|
41
|
-
React.ComponentProps<
|
|
42
|
-
typeof ValidatedFormTokenField
|
|
43
|
-
>[ 'customValidity' ]
|
|
44
|
-
>( undefined );
|
|
45
39
|
|
|
46
40
|
return (
|
|
47
41
|
<ValidatedFormTokenField
|
|
48
42
|
{ ...args }
|
|
49
43
|
value={ value }
|
|
50
|
-
onChange={ ( newValue
|
|
44
|
+
onChange={ ( newValue ) => {
|
|
51
45
|
setValue( newValue );
|
|
52
|
-
onChange?.( newValue
|
|
46
|
+
onChange?.( newValue );
|
|
53
47
|
} }
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
setCustomValidity( undefined );
|
|
70
|
-
} }
|
|
71
|
-
customValidity={ customValidity }
|
|
48
|
+
customValidity={
|
|
49
|
+
value?.some( ( token ) => {
|
|
50
|
+
const tokenValue =
|
|
51
|
+
typeof token === 'string' ? token : token.value;
|
|
52
|
+
return tokenValue.toLowerCase() === 'error';
|
|
53
|
+
} )
|
|
54
|
+
? {
|
|
55
|
+
type: 'invalid',
|
|
56
|
+
message: 'The tag "error" is not allowed.',
|
|
57
|
+
}
|
|
58
|
+
: undefined
|
|
59
|
+
}
|
|
72
60
|
/>
|
|
73
61
|
);
|
|
74
62
|
},
|
|
@@ -42,16 +42,7 @@ export default meta;
|
|
|
42
42
|
|
|
43
43
|
export const Default: StoryObj< typeof ValidatedInputControl > = {
|
|
44
44
|
render: function Template( { onChange, ...args } ) {
|
|
45
|
-
const [ value, setValue ] =
|
|
46
|
-
useState<
|
|
47
|
-
React.ComponentProps< typeof ValidatedInputControl >[ 'value' ]
|
|
48
|
-
>( '' );
|
|
49
|
-
const [ customValidity, setCustomValidity ] =
|
|
50
|
-
useState<
|
|
51
|
-
React.ComponentProps<
|
|
52
|
-
typeof ValidatedInputControl
|
|
53
|
-
>[ 'customValidity' ]
|
|
54
|
-
>( undefined );
|
|
45
|
+
const [ value, setValue ] = useState< string | undefined >( '' );
|
|
55
46
|
|
|
56
47
|
return (
|
|
57
48
|
<ValidatedInputControl
|
|
@@ -61,17 +52,14 @@ export const Default: StoryObj< typeof ValidatedInputControl > = {
|
|
|
61
52
|
setValue( newValue );
|
|
62
53
|
onChange?.( newValue, ...rest );
|
|
63
54
|
} }
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
} }
|
|
74
|
-
customValidity={ customValidity }
|
|
55
|
+
customValidity={
|
|
56
|
+
value?.toLowerCase() === 'error'
|
|
57
|
+
? {
|
|
58
|
+
type: 'invalid',
|
|
59
|
+
message: 'The word "error" is not allowed.',
|
|
60
|
+
}
|
|
61
|
+
: undefined
|
|
62
|
+
}
|
|
75
63
|
/>
|
|
76
64
|
);
|
|
77
65
|
},
|
|
@@ -89,17 +77,8 @@ Default.args = {
|
|
|
89
77
|
*/
|
|
90
78
|
export const Password: StoryObj< typeof ValidatedInputControl > = {
|
|
91
79
|
render: function Template( { onChange, ...args } ) {
|
|
92
|
-
const [ value, setValue ] =
|
|
93
|
-
useState<
|
|
94
|
-
React.ComponentProps< typeof ValidatedInputControl >[ 'value' ]
|
|
95
|
-
>( '' );
|
|
80
|
+
const [ value, setValue ] = useState< string | undefined >( '' );
|
|
96
81
|
const [ visible, setVisible ] = useState( false );
|
|
97
|
-
const [ customValidity, setCustomValidity ] =
|
|
98
|
-
useState<
|
|
99
|
-
React.ComponentProps<
|
|
100
|
-
typeof ValidatedInputControl
|
|
101
|
-
>[ 'customValidity' ]
|
|
102
|
-
>( undefined );
|
|
103
82
|
|
|
104
83
|
return (
|
|
105
84
|
<ValidatedInputControl
|
|
@@ -122,34 +101,30 @@ export const Password: StoryObj< typeof ValidatedInputControl > = {
|
|
|
122
101
|
setValue( newValue );
|
|
123
102
|
onChange?.( newValue, ...rest );
|
|
124
103
|
} }
|
|
125
|
-
|
|
126
|
-
if ( ! /\d/.test(
|
|
127
|
-
|
|
128
|
-
type: 'invalid',
|
|
104
|
+
customValidity={ ( () => {
|
|
105
|
+
if ( ! /\d/.test( value ?? '' ) ) {
|
|
106
|
+
return {
|
|
107
|
+
type: 'invalid' as const,
|
|
129
108
|
message:
|
|
130
109
|
'Password must include at least one number.',
|
|
131
|
-
}
|
|
132
|
-
return;
|
|
110
|
+
};
|
|
133
111
|
}
|
|
134
|
-
if ( ! /[A-Z]/.test(
|
|
135
|
-
|
|
136
|
-
type: 'invalid',
|
|
112
|
+
if ( ! /[A-Z]/.test( value ?? '' ) ) {
|
|
113
|
+
return {
|
|
114
|
+
type: 'invalid' as const,
|
|
137
115
|
message:
|
|
138
116
|
'Password must include at least one capital letter.',
|
|
139
|
-
}
|
|
140
|
-
return;
|
|
117
|
+
};
|
|
141
118
|
}
|
|
142
|
-
if ( ! /[!@£$%^&*#]/.test(
|
|
143
|
-
|
|
144
|
-
type: 'invalid',
|
|
119
|
+
if ( ! /[!@£$%^&*#]/.test( value ?? '' ) ) {
|
|
120
|
+
return {
|
|
121
|
+
type: 'invalid' as const,
|
|
145
122
|
message:
|
|
146
123
|
'Password must include at least one symbol.',
|
|
147
|
-
}
|
|
148
|
-
return;
|
|
124
|
+
};
|
|
149
125
|
}
|
|
150
|
-
|
|
151
|
-
} }
|
|
152
|
-
customValidity={ customValidity }
|
|
126
|
+
return undefined;
|
|
127
|
+
} )() }
|
|
153
128
|
/>
|
|
154
129
|
);
|
|
155
130
|
},
|
|
@@ -37,32 +37,23 @@ export const Default: StoryObj< typeof ValidatedNumberControl > = {
|
|
|
37
37
|
useState<
|
|
38
38
|
React.ComponentProps< typeof ValidatedNumberControl >[ 'value' ]
|
|
39
39
|
>();
|
|
40
|
-
const [ customValidity, setCustomValidity ] =
|
|
41
|
-
useState<
|
|
42
|
-
React.ComponentProps<
|
|
43
|
-
typeof ValidatedNumberControl
|
|
44
|
-
>[ 'customValidity' ]
|
|
45
|
-
>( undefined );
|
|
46
40
|
|
|
47
41
|
return (
|
|
48
42
|
<ValidatedNumberControl
|
|
49
43
|
{ ...args }
|
|
50
44
|
value={ value }
|
|
51
|
-
onChange={ ( newValue,
|
|
45
|
+
onChange={ ( newValue, extra ) => {
|
|
52
46
|
setValue( newValue );
|
|
53
|
-
onChange?.( newValue,
|
|
54
|
-
} }
|
|
55
|
-
onValidate={ ( v ) => {
|
|
56
|
-
if ( v && parseInt( v.toString(), 10 ) % 2 !== 0 ) {
|
|
57
|
-
setCustomValidity( {
|
|
58
|
-
type: 'invalid',
|
|
59
|
-
message: 'Choose an even number.',
|
|
60
|
-
} );
|
|
61
|
-
} else {
|
|
62
|
-
setCustomValidity( undefined );
|
|
63
|
-
}
|
|
47
|
+
onChange?.( newValue, extra );
|
|
64
48
|
} }
|
|
65
|
-
customValidity={
|
|
49
|
+
customValidity={
|
|
50
|
+
value && parseInt( value.toString(), 10 ) % 2 !== 0
|
|
51
|
+
? {
|
|
52
|
+
type: 'invalid',
|
|
53
|
+
message: 'Choose an even number.',
|
|
54
|
+
}
|
|
55
|
+
: undefined
|
|
56
|
+
}
|
|
66
57
|
/>
|
|
67
58
|
);
|
|
68
59
|
},
|
|
@@ -16,7 +16,7 @@ We are still gathering feedback and iterating. Please get in touch with `@WordPr
|
|
|
16
16
|
|
|
17
17
|
Component APIs are the same as the underlying WordPress components, with the addition of some optional props:
|
|
18
18
|
|
|
19
|
-
<ArgTypes of={ ValidatedInputControl } include={ [ 'required', 'markWhenOptional', '
|
|
19
|
+
<ArgTypes of={ ValidatedInputControl } include={ [ 'required', 'markWhenOptional', 'customValidity' ] } />
|
|
20
20
|
|
|
21
21
|
## Implementation
|
|
22
22
|
|
|
@@ -32,14 +32,14 @@ These components are designed to work with the native HTML5 [Constraint Validati
|
|
|
32
32
|
|
|
33
33
|
### No easy access to underlying validation APIs
|
|
34
34
|
|
|
35
|
-
- The consumer does not have a simple way to
|
|
35
|
+
- The consumer does not have a simple way to show validation messages at an arbitrary point in time, unless the fields are wrapped in a `form` element. Currently, when to show validation messages to the user are handled by the component — any messages are first made visible on `blur` after the field is considered "touched", or if the user tries to submit the enclosing `form`. Messages can also be triggered to show at any time by calling the `reportValidity()` method on the wrapping `<form>` element.
|
|
36
36
|
- The consumer does not have direct access to the [`validity` object](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) of the underlying element.
|
|
37
37
|
|
|
38
38
|
We don't foresee these being needed much, but it is technically possible by the consumer accessing the target element's validation APIs via `ref`. Better docs or ergonomics can be added when we have actual use cases.
|
|
39
39
|
|
|
40
40
|
### Delegate elements
|
|
41
41
|
|
|
42
|
-
The implementations for `ToggleGroupControl` and `
|
|
42
|
+
The implementations for `ToggleGroupControl`, `CustomSelectControl`, and `FormTokenField` use a "delegate" element for validation, due to upstream limitations that prevent us from using the actual underlying elements for constraint validation. A delegate element in this context is a visually hidden form element that we "delegate" the Constraint Validation API concerns to.
|
|
43
43
|
|
|
44
44
|
This is not ideal, but lets us maintain a consistent mechanism to scroll to the invalid field when attempting to submit, and block the form from submitting. It is hopefully fine as a stopgap, given the low amount of actual validation that will need happen on these two specific components.
|
|
45
45
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
5
5
|
import { expect, userEvent, waitFor, within } from '@storybook/test';
|
|
6
|
+
import clsx from 'clsx';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* WordPress dependencies
|
|
@@ -32,20 +33,8 @@ type Story = StoryObj< typeof ControlWithError >;
|
|
|
32
33
|
*/
|
|
33
34
|
export const WithMultipleControls: Story = {
|
|
34
35
|
render: function Template() {
|
|
35
|
-
const [ text, setText ] = useState( '' );
|
|
36
|
-
const [ text2, setText2 ] = useState( '' );
|
|
37
|
-
const [ customValidity, setCustomValidity ] =
|
|
38
|
-
useState<
|
|
39
|
-
React.ComponentProps<
|
|
40
|
-
typeof ValidatedInputControl
|
|
41
|
-
>[ 'customValidity' ]
|
|
42
|
-
>( undefined );
|
|
43
|
-
const [ customValidity2, setCustomValidity2 ] =
|
|
44
|
-
useState<
|
|
45
|
-
React.ComponentProps<
|
|
46
|
-
typeof ValidatedInputControl
|
|
47
|
-
>[ 'customValidity' ]
|
|
48
|
-
>( undefined );
|
|
36
|
+
const [ text, setText ] = useState< string | undefined >( '' );
|
|
37
|
+
const [ text2, setText2 ] = useState< string | undefined >( '' );
|
|
49
38
|
|
|
50
39
|
return (
|
|
51
40
|
<>
|
|
@@ -54,36 +43,30 @@ export const WithMultipleControls: Story = {
|
|
|
54
43
|
required
|
|
55
44
|
value={ text }
|
|
56
45
|
help="The word 'error' will trigger an error."
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
} }
|
|
67
|
-
customValidity={ customValidity }
|
|
68
|
-
onChange={ ( value ) => setText( value ?? '' ) }
|
|
46
|
+
onChange={ setText }
|
|
47
|
+
customValidity={
|
|
48
|
+
text?.toLowerCase() === 'error'
|
|
49
|
+
? {
|
|
50
|
+
type: 'invalid',
|
|
51
|
+
message: 'The word "error" is not allowed.',
|
|
52
|
+
}
|
|
53
|
+
: undefined
|
|
54
|
+
}
|
|
69
55
|
/>
|
|
70
56
|
<ValidatedInputControl
|
|
71
57
|
label="Text"
|
|
72
58
|
required
|
|
73
59
|
value={ text2 }
|
|
74
60
|
help="The word 'error' will trigger an error."
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
} }
|
|
85
|
-
onChange={ ( value ) => setText2( value ?? '' ) }
|
|
86
|
-
customValidity={ customValidity2 }
|
|
61
|
+
onChange={ setText2 }
|
|
62
|
+
customValidity={
|
|
63
|
+
text2?.toLowerCase() === 'error'
|
|
64
|
+
? {
|
|
65
|
+
type: 'invalid',
|
|
66
|
+
message: 'The word "error" is not allowed.',
|
|
67
|
+
}
|
|
68
|
+
: undefined
|
|
69
|
+
}
|
|
87
70
|
/>
|
|
88
71
|
</>
|
|
89
72
|
);
|
|
@@ -96,37 +79,44 @@ export const WithMultipleControls: Story = {
|
|
|
96
79
|
*/
|
|
97
80
|
export const WithHelpTextReplacement: Story = {
|
|
98
81
|
render: function Template() {
|
|
99
|
-
const [ text, setText ] = useState( '' );
|
|
100
|
-
const
|
|
101
|
-
useState<
|
|
102
|
-
React.ComponentProps<
|
|
103
|
-
typeof ValidatedInputControl
|
|
104
|
-
>[ 'customValidity' ]
|
|
105
|
-
>( undefined );
|
|
82
|
+
const [ text, setText ] = useState< string | undefined >( '' );
|
|
83
|
+
const isInvalid = text?.toLowerCase() === 'error';
|
|
106
84
|
|
|
107
85
|
return (
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
customValidity
|
|
114
|
-
? undefined
|
|
115
|
-
: 'The word "error" is not allowed.'
|
|
86
|
+
<>
|
|
87
|
+
<style>
|
|
88
|
+
{ `
|
|
89
|
+
.my-control:has(:invalid[data-validity-visible]) .my-control__help:not(.is-visible) {
|
|
90
|
+
display: none;
|
|
116
91
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
92
|
+
` }
|
|
93
|
+
</style>
|
|
94
|
+
<ValidatedInputControl
|
|
95
|
+
className="my-control"
|
|
96
|
+
label="Text"
|
|
97
|
+
required
|
|
98
|
+
value={ text }
|
|
99
|
+
help={
|
|
100
|
+
<span
|
|
101
|
+
className={ clsx(
|
|
102
|
+
'my-control__help',
|
|
103
|
+
! isInvalid && 'is-visible'
|
|
104
|
+
) }
|
|
105
|
+
>
|
|
106
|
+
The word "error" is not allowed.
|
|
107
|
+
</span>
|
|
125
108
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
109
|
+
onChange={ setText }
|
|
110
|
+
customValidity={
|
|
111
|
+
isInvalid
|
|
112
|
+
? {
|
|
113
|
+
type: 'invalid',
|
|
114
|
+
message: 'The word "error" is not allowed.',
|
|
115
|
+
}
|
|
116
|
+
: undefined
|
|
117
|
+
}
|
|
118
|
+
/>
|
|
119
|
+
</>
|
|
130
120
|
);
|
|
131
121
|
},
|
|
132
122
|
};
|
|
@@ -150,23 +140,19 @@ export const AsyncValidation: StoryObj< typeof ValidatedInputControl > = {
|
|
|
150
140
|
>( undefined );
|
|
151
141
|
|
|
152
142
|
const timeoutRef = useRef< ReturnType< typeof setTimeout > >();
|
|
153
|
-
const previousValidationValueRef = useRef< unknown >( '' );
|
|
154
143
|
|
|
155
144
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
156
145
|
const debouncedValidate = useCallback(
|
|
157
146
|
debounce( ( v ) => {
|
|
158
|
-
if ( v ===
|
|
147
|
+
if ( v === '' ) {
|
|
159
148
|
return;
|
|
160
149
|
}
|
|
161
150
|
|
|
162
|
-
previousValidationValueRef.current = v;
|
|
163
|
-
|
|
164
151
|
setCustomValidity( {
|
|
165
152
|
type: 'validating',
|
|
166
153
|
message: 'Validating...',
|
|
167
154
|
} );
|
|
168
155
|
|
|
169
|
-
clearTimeout( timeoutRef.current );
|
|
170
156
|
timeoutRef.current = setTimeout( () => {
|
|
171
157
|
if ( v?.toString().toLowerCase() === 'error' ) {
|
|
172
158
|
setCustomValidity( {
|
|
@@ -190,8 +176,10 @@ export const AsyncValidation: StoryObj< typeof ValidatedInputControl > = {
|
|
|
190
176
|
value={ text }
|
|
191
177
|
onChange={ ( newValue ) => {
|
|
192
178
|
setText( newValue ?? '' );
|
|
179
|
+
setCustomValidity( undefined );
|
|
180
|
+
clearTimeout( timeoutRef.current );
|
|
181
|
+
debouncedValidate( newValue );
|
|
193
182
|
} }
|
|
194
|
-
onValidate={ debouncedValidate }
|
|
195
183
|
customValidity={ customValidity }
|
|
196
184
|
/>
|
|
197
185
|
);
|
|
@@ -225,14 +213,6 @@ const AsyncValidationWithTest: StoryObj< typeof ValidatedInputControl > = {
|
|
|
225
213
|
await new Promise( ( resolve ) => setTimeout( resolve, 500 ) );
|
|
226
214
|
await userEvent.clear( canvas.getByRole( 'textbox' ) );
|
|
227
215
|
|
|
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
216
|
await waitFor(
|
|
237
217
|
() => {
|
|
238
218
|
expect(
|
|
@@ -288,3 +268,38 @@ const AsyncValidationWithTest: StoryObj< typeof ValidatedInputControl > = {
|
|
|
288
268
|
);
|
|
289
269
|
},
|
|
290
270
|
};
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Custom validity errors are effective immediately, even when they are not yet visible
|
|
274
|
+
* to the user. For example, in this form where the initial value is already invalid,
|
|
275
|
+
* the error message will be shown to the user once the submit button is clicked,
|
|
276
|
+
* even if the input has never been interacted with.
|
|
277
|
+
*/
|
|
278
|
+
export const CustomErrorsOnSubmit: StoryObj< typeof ValidatedInputControl > = {
|
|
279
|
+
args: {
|
|
280
|
+
label: 'Text',
|
|
281
|
+
required: true,
|
|
282
|
+
help: 'The word "error" will trigger an error.',
|
|
283
|
+
},
|
|
284
|
+
render: function Template( { ...args } ) {
|
|
285
|
+
const [ text, setText ] = useState< string | undefined >( 'error' );
|
|
286
|
+
|
|
287
|
+
return (
|
|
288
|
+
<>
|
|
289
|
+
<ValidatedInputControl
|
|
290
|
+
{ ...args }
|
|
291
|
+
value={ text }
|
|
292
|
+
onChange={ setText }
|
|
293
|
+
customValidity={
|
|
294
|
+
text === 'error'
|
|
295
|
+
? {
|
|
296
|
+
type: 'invalid',
|
|
297
|
+
message: 'The word "error" is not allowed.',
|
|
298
|
+
}
|
|
299
|
+
: undefined
|
|
300
|
+
}
|
|
301
|
+
/>
|
|
302
|
+
</>
|
|
303
|
+
);
|
|
304
|
+
},
|
|
305
|
+
};
|
|
@@ -35,32 +35,23 @@ export const Default: StoryObj< typeof ValidatedRadioControl > = {
|
|
|
35
35
|
typeof ValidatedRadioControl
|
|
36
36
|
>[ 'selected' ]
|
|
37
37
|
>();
|
|
38
|
-
const [ customValidity, setCustomValidity ] =
|
|
39
|
-
useState<
|
|
40
|
-
React.ComponentProps<
|
|
41
|
-
typeof ValidatedRadioControl
|
|
42
|
-
>[ 'customValidity' ]
|
|
43
|
-
>( undefined );
|
|
44
38
|
|
|
45
39
|
return (
|
|
46
40
|
<ValidatedRadioControl
|
|
47
41
|
{ ...args }
|
|
48
42
|
selected={ selected }
|
|
49
|
-
onChange={ (
|
|
50
|
-
setSelected(
|
|
51
|
-
onChange?.(
|
|
52
|
-
} }
|
|
53
|
-
onValidate={ ( v ) => {
|
|
54
|
-
if ( v === 'b' ) {
|
|
55
|
-
setCustomValidity( {
|
|
56
|
-
type: 'invalid',
|
|
57
|
-
message: 'Option B is not allowed.',
|
|
58
|
-
} );
|
|
59
|
-
} else {
|
|
60
|
-
setCustomValidity( undefined );
|
|
61
|
-
}
|
|
43
|
+
onChange={ ( newValue ) => {
|
|
44
|
+
setSelected( newValue );
|
|
45
|
+
onChange?.( newValue );
|
|
62
46
|
} }
|
|
63
|
-
customValidity={
|
|
47
|
+
customValidity={
|
|
48
|
+
selected === 'b'
|
|
49
|
+
? {
|
|
50
|
+
type: 'invalid',
|
|
51
|
+
message: 'Option B is not allowed.',
|
|
52
|
+
}
|
|
53
|
+
: undefined
|
|
54
|
+
}
|
|
64
55
|
/>
|
|
65
56
|
);
|
|
66
57
|
},
|