@wordpress/components 30.2.1-next.0f6f9d12c.0 → 30.2.1-next.f34ab90e9.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 +10 -1
- package/build/menu-item/index.js +1 -0
- package/build/menu-item/index.js.map +1 -1
- package/build/validated-form-controls/components/checkbox-control.js +5 -3
- package/build/validated-form-controls/components/checkbox-control.js.map +1 -1
- package/build/validated-form-controls/components/combobox-control.js +5 -3
- package/build/validated-form-controls/components/combobox-control.js.map +1 -1
- package/build/validated-form-controls/components/custom-select-control.js +5 -3
- package/build/validated-form-controls/components/custom-select-control.js.map +1 -1
- package/build/validated-form-controls/components/input-control.js +5 -3
- package/build/validated-form-controls/components/input-control.js.map +1 -1
- package/build/validated-form-controls/components/number-control.js +5 -3
- package/build/validated-form-controls/components/number-control.js.map +1 -1
- package/build/validated-form-controls/components/radio-control.js +5 -3
- package/build/validated-form-controls/components/radio-control.js.map +1 -1
- package/build/validated-form-controls/components/range-control.js +5 -3
- package/build/validated-form-controls/components/range-control.js.map +1 -1
- package/build/validated-form-controls/components/select-control.js +5 -3
- package/build/validated-form-controls/components/select-control.js.map +1 -1
- package/build/validated-form-controls/components/text-control.js +5 -3
- package/build/validated-form-controls/components/text-control.js.map +1 -1
- package/build/validated-form-controls/components/textarea-control.js +5 -3
- package/build/validated-form-controls/components/textarea-control.js.map +1 -1
- package/build/validated-form-controls/components/toggle-control.js +5 -3
- package/build/validated-form-controls/components/toggle-control.js.map +1 -1
- package/build/validated-form-controls/components/toggle-group-control.js +5 -3
- package/build/validated-form-controls/components/toggle-group-control.js.map +1 -1
- package/build/validated-form-controls/components/types.js.map +1 -1
- package/build/validated-form-controls/control-with-error.js +57 -22
- package/build/validated-form-controls/control-with-error.js.map +1 -1
- package/build/validated-form-controls/validity-indicator.js +45 -0
- package/build/validated-form-controls/validity-indicator.js.map +1 -0
- package/build-module/menu-item/index.js +1 -0
- package/build-module/menu-item/index.js.map +1 -1
- package/build-module/validated-form-controls/components/checkbox-control.js +5 -3
- package/build-module/validated-form-controls/components/checkbox-control.js.map +1 -1
- package/build-module/validated-form-controls/components/combobox-control.js +5 -3
- package/build-module/validated-form-controls/components/combobox-control.js.map +1 -1
- package/build-module/validated-form-controls/components/custom-select-control.js +5 -3
- package/build-module/validated-form-controls/components/custom-select-control.js.map +1 -1
- package/build-module/validated-form-controls/components/input-control.js +5 -3
- package/build-module/validated-form-controls/components/input-control.js.map +1 -1
- package/build-module/validated-form-controls/components/number-control.js +5 -3
- package/build-module/validated-form-controls/components/number-control.js.map +1 -1
- package/build-module/validated-form-controls/components/radio-control.js +5 -3
- package/build-module/validated-form-controls/components/radio-control.js.map +1 -1
- package/build-module/validated-form-controls/components/range-control.js +5 -3
- package/build-module/validated-form-controls/components/range-control.js.map +1 -1
- package/build-module/validated-form-controls/components/select-control.js +5 -3
- package/build-module/validated-form-controls/components/select-control.js.map +1 -1
- package/build-module/validated-form-controls/components/text-control.js +5 -3
- package/build-module/validated-form-controls/components/text-control.js.map +1 -1
- package/build-module/validated-form-controls/components/textarea-control.js +5 -3
- package/build-module/validated-form-controls/components/textarea-control.js.map +1 -1
- package/build-module/validated-form-controls/components/toggle-control.js +5 -3
- package/build-module/validated-form-controls/components/toggle-control.js.map +1 -1
- package/build-module/validated-form-controls/components/toggle-group-control.js +5 -3
- package/build-module/validated-form-controls/components/toggle-group-control.js.map +1 -1
- package/build-module/validated-form-controls/components/types.js.map +1 -1
- package/build-module/validated-form-controls/control-with-error.js +57 -21
- package/build-module/validated-form-controls/control-with-error.js.map +1 -1
- package/build-module/validated-form-controls/validity-indicator.js +37 -0
- package/build-module/validated-form-controls/validity-indicator.js.map +1 -0
- package/build-style/style-rtl.css +34 -22
- package/build-style/style.css +34 -22
- package/build-types/menu-item/index.d.ts.map +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.map +1 -1
- package/build-types/validated-form-controls/components/custom-select-control.d.ts.map +1 -1
- 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.map +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.map +1 -1
- 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/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 +13 -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.map +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.map +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 +21 -10
- 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/build-types/validated-form-controls/validity-indicator.d.ts +5 -0
- package/build-types/validated-form-controls/validity-indicator.d.ts.map +1 -0
- package/package.json +19 -19
- package/src/calendar/style.scss +22 -22
- package/src/menu-item/index.tsx +1 -0
- package/src/utils/theme-variables.scss +1 -0
- package/src/validated-form-controls/components/checkbox-control.tsx +5 -3
- package/src/validated-form-controls/components/combobox-control.tsx +5 -3
- package/src/validated-form-controls/components/custom-select-control.tsx +5 -3
- package/src/validated-form-controls/components/input-control.tsx +5 -3
- package/src/validated-form-controls/components/number-control.tsx +5 -3
- package/src/validated-form-controls/components/radio-control.tsx +5 -3
- package/src/validated-form-controls/components/range-control.tsx +5 -3
- package/src/validated-form-controls/components/select-control.tsx +5 -3
- package/src/validated-form-controls/components/stories/checkbox-control.story.tsx +17 -6
- package/src/validated-form-controls/components/stories/combobox-control.story.tsx +17 -6
- package/src/validated-form-controls/components/stories/custom-select-control.story.tsx +17 -6
- package/src/validated-form-controls/components/stories/input-control.story.tsx +51 -18
- package/src/validated-form-controls/components/stories/number-control.story.tsx +17 -6
- package/src/validated-form-controls/components/stories/overview.mdx +1 -1
- package/src/validated-form-controls/components/stories/overview.story.tsx +122 -14
- package/src/validated-form-controls/components/stories/radio-control.story.tsx +17 -6
- package/src/validated-form-controls/components/stories/range-control.story.tsx +17 -6
- package/src/validated-form-controls/components/stories/select-control.story.tsx +17 -6
- package/src/validated-form-controls/components/stories/text-control.story.tsx +17 -6
- package/src/validated-form-controls/components/stories/textarea-control.story.tsx +17 -6
- package/src/validated-form-controls/components/stories/toggle-control.story.tsx +17 -6
- package/src/validated-form-controls/components/stories/toggle-group-control.story.tsx +17 -6
- package/src/validated-form-controls/components/text-control.tsx +5 -3
- package/src/validated-form-controls/components/textarea-control.tsx +5 -3
- package/src/validated-form-controls/components/toggle-control.tsx +5 -3
- package/src/validated-form-controls/components/toggle-group-control.tsx +5 -3
- package/src/validated-form-controls/components/types.ts +21 -12
- package/src/validated-form-controls/control-with-error.tsx +77 -26
- package/src/validated-form-controls/style.scss +19 -5
- package/src/validated-form-controls/validity-indicator.tsx +48 -0
- package/tsconfig.tsbuildinfo +1 -1
package/src/calendar/style.scss
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/* Root of the component. */
|
|
2
2
|
// Internal variables
|
|
3
3
|
$wp-components-calendar-outline-focus: var(--wp-admin-border-width-focus) solid $components-color-accent;
|
|
4
|
-
$wp-components-calendar-button-height:
|
|
5
|
-
$wp-components-calendar-button-width:
|
|
6
|
-
$wp-components-calendar-nav-height:
|
|
4
|
+
$wp-components-calendar-button-height: $grid-unit-40;
|
|
5
|
+
$wp-components-calendar-button-width: $grid-unit-40;
|
|
6
|
+
$wp-components-calendar-nav-height: $grid-unit-40;
|
|
7
7
|
$wp-components-calendar-range-middle-background-color: color-mix(in srgb, $components-color-accent 4%, transparent);
|
|
8
8
|
$wp-components-calendar-preview-border-color: color-mix(in srgb, $components-color-accent 16%, transparent);
|
|
9
9
|
|
|
@@ -13,10 +13,10 @@ $wp-components-calendar-preview-border-color: color-mix(in srgb, $components-col
|
|
|
13
13
|
position: relative; /* Required to position the navigation toolbar. */
|
|
14
14
|
box-sizing: border-box;
|
|
15
15
|
display: inline flow-root;
|
|
16
|
-
color: $
|
|
17
|
-
background-color: $
|
|
18
|
-
font-size:
|
|
19
|
-
font-weight:
|
|
16
|
+
color: $components-color-foreground;
|
|
17
|
+
background-color: $components-color-background;
|
|
18
|
+
font-size: $font-size-medium;
|
|
19
|
+
font-weight: $font-weight-regular;
|
|
20
20
|
z-index: 0; // Create a stacking context and render on top of the background.
|
|
21
21
|
|
|
22
22
|
*,
|
|
@@ -35,7 +35,7 @@ $wp-components-calendar-preview-border-color: color-mix(in srgb, $components-col
|
|
|
35
35
|
// date follows the same color as the button's text, since the button
|
|
36
36
|
// inherits its text color.
|
|
37
37
|
&:has(.components-calendar__day-button:disabled) {
|
|
38
|
-
color: $
|
|
38
|
+
color: $components-color-disabled;
|
|
39
39
|
}
|
|
40
40
|
&:has(.components-calendar__day-button:hover:not(:disabled)),
|
|
41
41
|
&:has(.components-calendar__day-button:focus-visible) {
|
|
@@ -57,7 +57,7 @@ $wp-components-calendar-preview-border-color: color-mix(in srgb, $components-col
|
|
|
57
57
|
height: $wp-components-calendar-button-height;
|
|
58
58
|
|
|
59
59
|
border: none;
|
|
60
|
-
border-radius:
|
|
60
|
+
border-radius: $radius-small;
|
|
61
61
|
|
|
62
62
|
font: inherit;
|
|
63
63
|
font-variant-numeric: tabular-nums;
|
|
@@ -73,7 +73,7 @@ $wp-components-calendar-preview-border-color: color-mix(in srgb, $components-col
|
|
|
73
73
|
z-index: -1;
|
|
74
74
|
inset: 0;
|
|
75
75
|
border: none; // No default border to avoid polluting high-contrast mode.
|
|
76
|
-
border-radius:
|
|
76
|
+
border-radius: $radius-small;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
// Use the button's ::after to show the selection preview.
|
|
@@ -117,7 +117,7 @@ $wp-components-calendar-preview-border-color: color-mix(in srgb, $components-col
|
|
|
117
117
|
.components-calendar__button-next,
|
|
118
118
|
.components-calendar__button-previous {
|
|
119
119
|
border: none;
|
|
120
|
-
border-radius:
|
|
120
|
+
border-radius: $radius-small;
|
|
121
121
|
background: none;
|
|
122
122
|
padding: 0;
|
|
123
123
|
margin: 0;
|
|
@@ -139,7 +139,7 @@ $wp-components-calendar-preview-border-color: color-mix(in srgb, $components-col
|
|
|
139
139
|
&[aria-disabled="true"] {
|
|
140
140
|
cursor: revert;
|
|
141
141
|
|
|
142
|
-
color: $
|
|
142
|
+
color: $components-color-disabled;
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
&:focus-visible {
|
|
@@ -150,8 +150,8 @@ $wp-components-calendar-preview-border-color: color-mix(in srgb, $components-col
|
|
|
150
150
|
.components-calendar__chevron {
|
|
151
151
|
display: inline-block;
|
|
152
152
|
fill: currentColor;
|
|
153
|
-
width:
|
|
154
|
-
height:
|
|
153
|
+
width: $grid-unit-20;
|
|
154
|
+
height: $grid-unit-20;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
.components-calendar[dir="rtl"]
|
|
@@ -167,7 +167,7 @@ $wp-components-calendar-preview-border-color: color-mix(in srgb, $components-col
|
|
|
167
167
|
align-content: center;
|
|
168
168
|
|
|
169
169
|
height: $wp-components-calendar-nav-height;
|
|
170
|
-
margin-bottom:
|
|
170
|
+
margin-bottom: $grid-unit-15;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
.components-calendar__months {
|
|
@@ -175,13 +175,13 @@ $wp-components-calendar-preview-border-color: color-mix(in srgb, $components-col
|
|
|
175
175
|
display: flex;
|
|
176
176
|
justify-content: center;
|
|
177
177
|
flex-wrap: wrap;
|
|
178
|
-
gap:
|
|
178
|
+
gap: $grid-unit-20;
|
|
179
179
|
max-width: fit-content;
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
.components-calendar__month-grid {
|
|
183
183
|
border-collapse: separate;
|
|
184
|
-
border-spacing: 0
|
|
184
|
+
border-spacing: 0 $grid-unit-05;
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
.components-calendar__nav {
|
|
@@ -202,7 +202,7 @@ $wp-components-calendar-preview-border-color: color-mix(in srgb, $components-col
|
|
|
202
202
|
height: $wp-components-calendar-button-height;
|
|
203
203
|
padding: 0;
|
|
204
204
|
|
|
205
|
-
color: $gray-700;
|
|
205
|
+
color: $components-color-gray-700;
|
|
206
206
|
text-align: center;
|
|
207
207
|
text-transform: uppercase;
|
|
208
208
|
}
|
|
@@ -227,12 +227,12 @@ $wp-components-calendar-preview-border-color: color-mix(in srgb, $components-col
|
|
|
227
227
|
.components-calendar__day-button,
|
|
228
228
|
.components-calendar__day-button:hover:not(:disabled)
|
|
229
229
|
) {
|
|
230
|
-
color: $
|
|
230
|
+
color: $components-color-foreground-inverted;
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
.components-calendar__day-button {
|
|
234
234
|
&::before {
|
|
235
|
-
background-color: $
|
|
235
|
+
background-color: $components-color-foreground;
|
|
236
236
|
// Render a transparent border to highlight the selected day in
|
|
237
237
|
// forced-colors (high-contrast) mode, since the background is not
|
|
238
238
|
// visible.
|
|
@@ -240,11 +240,11 @@ $wp-components-calendar-preview-border-color: color-mix(in srgb, $components-col
|
|
|
240
240
|
}
|
|
241
241
|
|
|
242
242
|
&:disabled::before {
|
|
243
|
-
background-color: $
|
|
243
|
+
background-color: $components-color-disabled;
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
&:hover:not(:disabled)::before {
|
|
247
|
-
background-color: $gray-800;
|
|
247
|
+
background-color: $components-color-gray-800;
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
250
|
}
|
package/src/menu-item/index.tsx
CHANGED
|
@@ -29,3 +29,4 @@ $components-color-light-gray-placeholder: color-mix(in srgb, $components-color-b
|
|
|
29
29
|
|
|
30
30
|
// Semantic aliases (prefer these over raw gray values when applicable).
|
|
31
31
|
$components-color-border: #{ $components-color-gray-600 };
|
|
32
|
+
$components-color-disabled: #{ $components-color-gray-600 };
|
|
@@ -17,7 +17,8 @@ type Value = CheckboxControlProps[ 'checked' ];
|
|
|
17
17
|
const UnforwardedValidatedCheckboxControl = (
|
|
18
18
|
{
|
|
19
19
|
required,
|
|
20
|
-
|
|
20
|
+
onValidate,
|
|
21
|
+
customValidity,
|
|
21
22
|
onChange,
|
|
22
23
|
markWhenOptional,
|
|
23
24
|
...restProps
|
|
@@ -37,9 +38,10 @@ const UnforwardedValidatedCheckboxControl = (
|
|
|
37
38
|
required={ required }
|
|
38
39
|
markWhenOptional={ markWhenOptional }
|
|
39
40
|
ref={ mergedRefs }
|
|
40
|
-
|
|
41
|
-
return
|
|
41
|
+
onValidate={ () => {
|
|
42
|
+
return onValidate?.( valueRef.current );
|
|
42
43
|
} }
|
|
44
|
+
customValidity={ customValidity }
|
|
43
45
|
getValidityTarget={ () =>
|
|
44
46
|
validityTargetRef.current?.querySelector< HTMLInputElement >(
|
|
45
47
|
'input[type="checkbox"]'
|
|
@@ -17,7 +17,8 @@ type Value = ComboboxControlProps[ 'value' ];
|
|
|
17
17
|
const UnforwardedValidatedComboboxControl = (
|
|
18
18
|
{
|
|
19
19
|
required,
|
|
20
|
-
|
|
20
|
+
onValidate,
|
|
21
|
+
customValidity,
|
|
21
22
|
onChange,
|
|
22
23
|
markWhenOptional,
|
|
23
24
|
...restProps
|
|
@@ -50,9 +51,10 @@ const UnforwardedValidatedComboboxControl = (
|
|
|
50
51
|
required={ required }
|
|
51
52
|
markWhenOptional={ markWhenOptional }
|
|
52
53
|
ref={ mergedRefs }
|
|
53
|
-
|
|
54
|
-
return
|
|
54
|
+
onValidate={ () => {
|
|
55
|
+
return onValidate?.( valueRef.current );
|
|
55
56
|
} }
|
|
57
|
+
customValidity={ customValidity }
|
|
56
58
|
getValidityTarget={ () =>
|
|
57
59
|
validityTargetRef.current?.querySelector< HTMLInputElement >(
|
|
58
60
|
'input[role="combobox"]'
|
|
@@ -21,7 +21,8 @@ type Value = CustomSelectControlProps[ 'value' ];
|
|
|
21
21
|
const UnforwardedValidatedCustomSelectControl = (
|
|
22
22
|
{
|
|
23
23
|
required,
|
|
24
|
-
|
|
24
|
+
onValidate,
|
|
25
|
+
customValidity,
|
|
25
26
|
onChange,
|
|
26
27
|
markWhenOptional,
|
|
27
28
|
...restProps
|
|
@@ -43,9 +44,10 @@ const UnforwardedValidatedCustomSelectControl = (
|
|
|
43
44
|
<ControlWithError
|
|
44
45
|
required={ required }
|
|
45
46
|
markWhenOptional={ markWhenOptional }
|
|
46
|
-
|
|
47
|
-
return
|
|
47
|
+
onValidate={ () => {
|
|
48
|
+
return onValidate?.( valueRef.current );
|
|
48
49
|
} }
|
|
50
|
+
customValidity={ customValidity }
|
|
49
51
|
getValidityTarget={ () => validityTargetRef.current }
|
|
50
52
|
>
|
|
51
53
|
<CustomSelectControl
|
|
@@ -17,7 +17,8 @@ type Value = InputControlProps[ 'value' ];
|
|
|
17
17
|
const UnforwardedValidatedInputControl = (
|
|
18
18
|
{
|
|
19
19
|
required,
|
|
20
|
-
|
|
20
|
+
onValidate,
|
|
21
|
+
customValidity,
|
|
21
22
|
onChange,
|
|
22
23
|
markWhenOptional,
|
|
23
24
|
...restProps
|
|
@@ -36,9 +37,10 @@ const UnforwardedValidatedInputControl = (
|
|
|
36
37
|
<ControlWithError
|
|
37
38
|
required={ required }
|
|
38
39
|
markWhenOptional={ markWhenOptional }
|
|
39
|
-
|
|
40
|
-
return
|
|
40
|
+
onValidate={ () => {
|
|
41
|
+
return onValidate?.( valueRef.current );
|
|
41
42
|
} }
|
|
43
|
+
customValidity={ customValidity }
|
|
42
44
|
getValidityTarget={ () => validityTargetRef.current }
|
|
43
45
|
>
|
|
44
46
|
<InputControl
|
|
@@ -17,7 +17,8 @@ type Value = NumberControlProps[ 'value' ];
|
|
|
17
17
|
const UnforwardedValidatedNumberControl = (
|
|
18
18
|
{
|
|
19
19
|
required,
|
|
20
|
-
|
|
20
|
+
onValidate,
|
|
21
|
+
customValidity,
|
|
21
22
|
onChange,
|
|
22
23
|
markWhenOptional,
|
|
23
24
|
...restProps
|
|
@@ -36,9 +37,10 @@ const UnforwardedValidatedNumberControl = (
|
|
|
36
37
|
<ControlWithError
|
|
37
38
|
required={ required }
|
|
38
39
|
markWhenOptional={ markWhenOptional }
|
|
39
|
-
|
|
40
|
-
return
|
|
40
|
+
onValidate={ () => {
|
|
41
|
+
return onValidate?.( valueRef.current );
|
|
41
42
|
} }
|
|
43
|
+
customValidity={ customValidity }
|
|
42
44
|
getValidityTarget={ () => validityTargetRef.current }
|
|
43
45
|
>
|
|
44
46
|
<NumberControl
|
|
@@ -17,7 +17,8 @@ type Value = RadioControlProps[ 'selected' ];
|
|
|
17
17
|
const UnforwardedValidatedRadioControl = (
|
|
18
18
|
{
|
|
19
19
|
required,
|
|
20
|
-
|
|
20
|
+
onValidate,
|
|
21
|
+
customValidity,
|
|
21
22
|
onChange,
|
|
22
23
|
markWhenOptional,
|
|
23
24
|
...restProps
|
|
@@ -35,9 +36,10 @@ const UnforwardedValidatedRadioControl = (
|
|
|
35
36
|
markWhenOptional={ markWhenOptional }
|
|
36
37
|
// TODO: Upstream limitation - RadioControl does not accept a ref.
|
|
37
38
|
ref={ mergedRefs }
|
|
38
|
-
|
|
39
|
-
return
|
|
39
|
+
onValidate={ () => {
|
|
40
|
+
return onValidate?.( valueRef.current );
|
|
40
41
|
} }
|
|
42
|
+
customValidity={ customValidity }
|
|
41
43
|
getValidityTarget={ () =>
|
|
42
44
|
validityTargetRef.current?.querySelector< HTMLInputElement >(
|
|
43
45
|
'input[type="radio"]'
|
|
@@ -17,7 +17,8 @@ type Value = RangeControlProps[ 'value' ];
|
|
|
17
17
|
const UnforwardedValidatedRangeControl = (
|
|
18
18
|
{
|
|
19
19
|
required,
|
|
20
|
-
|
|
20
|
+
onValidate,
|
|
21
|
+
customValidity,
|
|
21
22
|
onChange,
|
|
22
23
|
markWhenOptional,
|
|
23
24
|
...restProps
|
|
@@ -36,9 +37,10 @@ const UnforwardedValidatedRangeControl = (
|
|
|
36
37
|
<ControlWithError
|
|
37
38
|
required={ required }
|
|
38
39
|
markWhenOptional={ markWhenOptional }
|
|
39
|
-
|
|
40
|
-
return
|
|
40
|
+
onValidate={ () => {
|
|
41
|
+
return onValidate?.( valueRef.current );
|
|
41
42
|
} }
|
|
43
|
+
customValidity={ customValidity }
|
|
42
44
|
getValidityTarget={ () => validityTargetRef.current }
|
|
43
45
|
>
|
|
44
46
|
<RangeControl
|
|
@@ -26,7 +26,8 @@ type Value = SelectControlProps[ 'value' ];
|
|
|
26
26
|
const UnforwardedValidatedSelectControl = (
|
|
27
27
|
{
|
|
28
28
|
required,
|
|
29
|
-
|
|
29
|
+
onValidate,
|
|
30
|
+
customValidity,
|
|
30
31
|
onChange,
|
|
31
32
|
markWhenOptional,
|
|
32
33
|
...restProps
|
|
@@ -51,9 +52,10 @@ const UnforwardedValidatedSelectControl = (
|
|
|
51
52
|
<ControlWithError
|
|
52
53
|
required={ required }
|
|
53
54
|
markWhenOptional={ markWhenOptional }
|
|
54
|
-
|
|
55
|
-
return
|
|
55
|
+
onValidate={ () => {
|
|
56
|
+
return onValidate?.( valueRef.current );
|
|
56
57
|
} }
|
|
58
|
+
customValidity={ customValidity }
|
|
57
59
|
getValidityTarget={ () => validityTargetRef.current }
|
|
58
60
|
>
|
|
59
61
|
<SelectControl
|
|
@@ -32,6 +32,12 @@ 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 );
|
|
35
41
|
|
|
36
42
|
return (
|
|
37
43
|
<ValidatedCheckboxControl
|
|
@@ -41,6 +47,17 @@ export const Default: StoryObj< typeof ValidatedCheckboxControl > = {
|
|
|
41
47
|
setChecked( value );
|
|
42
48
|
onChange?.( value );
|
|
43
49
|
} }
|
|
50
|
+
onValidate={ ( value ) => {
|
|
51
|
+
if ( value ) {
|
|
52
|
+
setCustomValidity( {
|
|
53
|
+
type: 'invalid',
|
|
54
|
+
message: 'This checkbox may not be checked.',
|
|
55
|
+
} );
|
|
56
|
+
} else {
|
|
57
|
+
setCustomValidity( undefined );
|
|
58
|
+
}
|
|
59
|
+
} }
|
|
60
|
+
customValidity={ customValidity }
|
|
44
61
|
/>
|
|
45
62
|
);
|
|
46
63
|
},
|
|
@@ -49,10 +66,4 @@ Default.args = {
|
|
|
49
66
|
required: true,
|
|
50
67
|
label: 'Checkbox',
|
|
51
68
|
help: 'This checkbox may neither be checked nor unchecked.',
|
|
52
|
-
customValidator: ( value ) => {
|
|
53
|
-
if ( value ) {
|
|
54
|
-
return 'This checkbox may not be checked.';
|
|
55
|
-
}
|
|
56
|
-
return undefined;
|
|
57
|
-
},
|
|
58
69
|
};
|
|
@@ -35,6 +35,12 @@ 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 );
|
|
38
44
|
|
|
39
45
|
return (
|
|
40
46
|
<ValidatedComboboxControl
|
|
@@ -44,6 +50,17 @@ export const Default: StoryObj< typeof ValidatedComboboxControl > = {
|
|
|
44
50
|
setValue( newValue );
|
|
45
51
|
onChange?.( newValue );
|
|
46
52
|
} }
|
|
53
|
+
onValidate={ ( v ) => {
|
|
54
|
+
if ( v === 'a' ) {
|
|
55
|
+
setCustomValidity( {
|
|
56
|
+
type: 'invalid',
|
|
57
|
+
message: 'Option A is not allowed.',
|
|
58
|
+
} );
|
|
59
|
+
} else {
|
|
60
|
+
setCustomValidity( undefined );
|
|
61
|
+
}
|
|
62
|
+
} }
|
|
63
|
+
customValidity={ customValidity }
|
|
47
64
|
/>
|
|
48
65
|
);
|
|
49
66
|
},
|
|
@@ -56,10 +73,4 @@ Default.args = {
|
|
|
56
73
|
{ value: 'a', label: 'Option A (not allowed)' },
|
|
57
74
|
{ value: 'b', label: 'Option B' },
|
|
58
75
|
],
|
|
59
|
-
customValidator: ( value ) => {
|
|
60
|
-
if ( value === 'a' ) {
|
|
61
|
-
return 'Option A is not allowed.';
|
|
62
|
-
}
|
|
63
|
-
return undefined;
|
|
64
|
-
},
|
|
65
76
|
};
|
|
@@ -35,6 +35,12 @@ 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 );
|
|
38
44
|
|
|
39
45
|
return (
|
|
40
46
|
<ValidatedCustomSelectControl
|
|
@@ -44,6 +50,17 @@ export const Default: StoryObj< typeof ValidatedCustomSelectControl > = {
|
|
|
44
50
|
setValue( newValue.selectedItem );
|
|
45
51
|
onChange?.( newValue );
|
|
46
52
|
} }
|
|
53
|
+
onValidate={ ( v ) => {
|
|
54
|
+
if ( v?.key === 'a' ) {
|
|
55
|
+
setCustomValidity( {
|
|
56
|
+
type: 'invalid',
|
|
57
|
+
message: 'Option A is not allowed.',
|
|
58
|
+
} );
|
|
59
|
+
} else {
|
|
60
|
+
setCustomValidity( undefined );
|
|
61
|
+
}
|
|
62
|
+
} }
|
|
63
|
+
customValidity={ customValidity }
|
|
47
64
|
/>
|
|
48
65
|
);
|
|
49
66
|
},
|
|
@@ -56,10 +73,4 @@ Default.args = {
|
|
|
56
73
|
{ key: 'a', name: 'Option A (not allowed)' },
|
|
57
74
|
{ key: 'b', name: 'Option B' },
|
|
58
75
|
],
|
|
59
|
-
customValidator: ( value ) => {
|
|
60
|
-
if ( value?.key === 'a' ) {
|
|
61
|
-
return 'Option A is not allowed.';
|
|
62
|
-
}
|
|
63
|
-
return undefined;
|
|
64
|
-
},
|
|
65
76
|
};
|
|
@@ -46,6 +46,12 @@ export const Default: StoryObj< typeof ValidatedInputControl > = {
|
|
|
46
46
|
useState<
|
|
47
47
|
React.ComponentProps< typeof ValidatedInputControl >[ 'value' ]
|
|
48
48
|
>( '' );
|
|
49
|
+
const [ customValidity, setCustomValidity ] =
|
|
50
|
+
useState<
|
|
51
|
+
React.ComponentProps<
|
|
52
|
+
typeof ValidatedInputControl
|
|
53
|
+
>[ 'customValidity' ]
|
|
54
|
+
>( undefined );
|
|
49
55
|
|
|
50
56
|
return (
|
|
51
57
|
<ValidatedInputControl
|
|
@@ -55,6 +61,17 @@ export const Default: StoryObj< typeof ValidatedInputControl > = {
|
|
|
55
61
|
setValue( newValue );
|
|
56
62
|
onChange?.( newValue, ...rest );
|
|
57
63
|
} }
|
|
64
|
+
onValidate={ ( v ) => {
|
|
65
|
+
if ( v?.toLowerCase() === 'error' ) {
|
|
66
|
+
setCustomValidity( {
|
|
67
|
+
type: 'invalid',
|
|
68
|
+
message: 'The word "error" is not allowed.',
|
|
69
|
+
} );
|
|
70
|
+
} else {
|
|
71
|
+
setCustomValidity( undefined );
|
|
72
|
+
}
|
|
73
|
+
} }
|
|
74
|
+
customValidity={ customValidity }
|
|
58
75
|
/>
|
|
59
76
|
);
|
|
60
77
|
},
|
|
@@ -63,12 +80,6 @@ Default.args = {
|
|
|
63
80
|
required: true,
|
|
64
81
|
label: 'Input',
|
|
65
82
|
help: 'The word "error" will trigger an error.',
|
|
66
|
-
customValidator: ( value ) => {
|
|
67
|
-
if ( value?.toLowerCase() === 'error' ) {
|
|
68
|
-
return 'The word "error" is not allowed.';
|
|
69
|
-
}
|
|
70
|
-
return undefined;
|
|
71
|
-
},
|
|
72
83
|
};
|
|
73
84
|
|
|
74
85
|
/**
|
|
@@ -83,6 +94,12 @@ export const Password: StoryObj< typeof ValidatedInputControl > = {
|
|
|
83
94
|
React.ComponentProps< typeof ValidatedInputControl >[ 'value' ]
|
|
84
95
|
>( '' );
|
|
85
96
|
const [ visible, setVisible ] = useState( false );
|
|
97
|
+
const [ customValidity, setCustomValidity ] =
|
|
98
|
+
useState<
|
|
99
|
+
React.ComponentProps<
|
|
100
|
+
typeof ValidatedInputControl
|
|
101
|
+
>[ 'customValidity' ]
|
|
102
|
+
>( undefined );
|
|
86
103
|
|
|
87
104
|
return (
|
|
88
105
|
<ValidatedInputControl
|
|
@@ -105,6 +122,34 @@ export const Password: StoryObj< typeof ValidatedInputControl > = {
|
|
|
105
122
|
setValue( newValue );
|
|
106
123
|
onChange?.( newValue, ...rest );
|
|
107
124
|
} }
|
|
125
|
+
onValidate={ ( v ) => {
|
|
126
|
+
if ( ! /\d/.test( v ?? '' ) ) {
|
|
127
|
+
setCustomValidity( {
|
|
128
|
+
type: 'invalid',
|
|
129
|
+
message:
|
|
130
|
+
'Password must include at least one number.',
|
|
131
|
+
} );
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if ( ! /[A-Z]/.test( v ?? '' ) ) {
|
|
135
|
+
setCustomValidity( {
|
|
136
|
+
type: 'invalid',
|
|
137
|
+
message:
|
|
138
|
+
'Password must include at least one capital letter.',
|
|
139
|
+
} );
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if ( ! /[!@£$%^&*#]/.test( v ?? '' ) ) {
|
|
143
|
+
setCustomValidity( {
|
|
144
|
+
type: 'invalid',
|
|
145
|
+
message:
|
|
146
|
+
'Password must include at least one symbol.',
|
|
147
|
+
} );
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
setCustomValidity( undefined );
|
|
151
|
+
} }
|
|
152
|
+
customValidity={ customValidity }
|
|
108
153
|
/>
|
|
109
154
|
);
|
|
110
155
|
},
|
|
@@ -114,18 +159,6 @@ Password.args = {
|
|
|
114
159
|
label: 'Password',
|
|
115
160
|
help: 'Minimum 8 characters, include a number, capital letter, and symbol (!@£$%^&*#).',
|
|
116
161
|
minLength: 8,
|
|
117
|
-
customValidator: ( value ) => {
|
|
118
|
-
if ( ! /\d/.test( value ?? '' ) ) {
|
|
119
|
-
return 'Password must include at least one number.';
|
|
120
|
-
}
|
|
121
|
-
if ( ! /[A-Z]/.test( value ?? '' ) ) {
|
|
122
|
-
return 'Password must include at least one capital letter.';
|
|
123
|
-
}
|
|
124
|
-
if ( ! /[!@£$%^&*#]/.test( value ?? '' ) ) {
|
|
125
|
-
return 'Password must include at least one symbol.';
|
|
126
|
-
}
|
|
127
|
-
return undefined;
|
|
128
|
-
},
|
|
129
162
|
};
|
|
130
163
|
Password.argTypes = {
|
|
131
164
|
suffix: { control: false },
|
|
@@ -37,6 +37,12 @@ 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 );
|
|
40
46
|
|
|
41
47
|
return (
|
|
42
48
|
<ValidatedNumberControl
|
|
@@ -46,6 +52,17 @@ export const Default: StoryObj< typeof ValidatedNumberControl > = {
|
|
|
46
52
|
setValue( newValue );
|
|
47
53
|
onChange?.( newValue, ...rest );
|
|
48
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
|
+
}
|
|
64
|
+
} }
|
|
65
|
+
customValidity={ customValidity }
|
|
49
66
|
/>
|
|
50
67
|
);
|
|
51
68
|
},
|
|
@@ -54,10 +71,4 @@ Default.args = {
|
|
|
54
71
|
required: true,
|
|
55
72
|
label: 'Number',
|
|
56
73
|
help: 'Odd numbers are not allowed.',
|
|
57
|
-
customValidator: ( value ) => {
|
|
58
|
-
if ( value && parseInt( value.toString(), 10 ) % 2 !== 0 ) {
|
|
59
|
-
return 'Choose an even number.';
|
|
60
|
-
}
|
|
61
|
-
return undefined;
|
|
62
|
-
},
|
|
63
74
|
};
|
|
@@ -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', 'onValidate', 'customValidity' ] } />
|
|
20
20
|
|
|
21
21
|
## Implementation
|
|
22
22
|
|