@wordpress/dataviews 9.0.1-next.6f42e1382.0 → 9.1.1-next.f56bd8138.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.
Files changed (201) hide show
  1. package/CHANGELOG.md +22 -2
  2. package/README.md +107 -11
  3. package/build/components/dataviews-filters/input-widget.js +48 -4
  4. package/build/components/dataviews-filters/input-widget.js.map +1 -1
  5. package/build/components/dataviews-view-config/index.js +22 -3
  6. package/build/components/dataviews-view-config/index.js.map +1 -1
  7. package/build/dataform-controls/array.js +117 -29
  8. package/build/dataform-controls/array.js.map +1 -1
  9. package/build/dataform-controls/checkbox.js +31 -20
  10. package/build/dataform-controls/checkbox.js.map +1 -1
  11. package/build/dataform-controls/color.js +29 -24
  12. package/build/dataform-controls/color.js.map +1 -1
  13. package/build/dataform-controls/date.js +32 -24
  14. package/build/dataform-controls/date.js.map +1 -1
  15. package/build/dataform-controls/datetime.js +133 -19
  16. package/build/dataform-controls/datetime.js.map +1 -1
  17. package/build/dataform-controls/email.js +7 -1
  18. package/build/dataform-controls/email.js.map +1 -1
  19. package/build/dataform-controls/index.js +23 -0
  20. package/build/dataform-controls/index.js.map +1 -1
  21. package/build/dataform-controls/integer.js +47 -34
  22. package/build/dataform-controls/integer.js.map +1 -1
  23. package/build/dataform-controls/radio.js +42 -9
  24. package/build/dataform-controls/radio.js.map +1 -1
  25. package/build/dataform-controls/relative-date-control.js +6 -10
  26. package/build/dataform-controls/relative-date-control.js.map +1 -1
  27. package/build/dataform-controls/select.js +41 -10
  28. package/build/dataform-controls/select.js.map +1 -1
  29. package/build/dataform-controls/telephone.js +7 -1
  30. package/build/dataform-controls/telephone.js.map +1 -1
  31. package/build/dataform-controls/text.js +14 -2
  32. package/build/dataform-controls/text.js.map +1 -1
  33. package/build/dataform-controls/textarea.js +33 -20
  34. package/build/dataform-controls/textarea.js.map +1 -1
  35. package/build/dataform-controls/toggle-group.js +36 -6
  36. package/build/dataform-controls/toggle-group.js.map +1 -1
  37. package/build/dataform-controls/toggle.js +33 -22
  38. package/build/dataform-controls/toggle.js.map +1 -1
  39. package/build/dataform-controls/url.js +7 -1
  40. package/build/dataform-controls/url.js.map +1 -1
  41. package/build/dataform-controls/utils/validated-input.js +34 -32
  42. package/build/dataform-controls/utils/validated-input.js.map +1 -1
  43. package/build/dataforms-layouts/panel/dropdown.js +10 -14
  44. package/build/dataforms-layouts/panel/dropdown.js.map +1 -1
  45. package/build/dataforms-layouts/panel/index.js +24 -11
  46. package/build/dataforms-layouts/panel/index.js.map +1 -1
  47. package/build/dataforms-layouts/panel/modal.js +22 -27
  48. package/build/dataforms-layouts/panel/modal.js.map +1 -1
  49. package/build/dataforms-layouts/panel/summary-button.js +67 -0
  50. package/build/dataforms-layouts/panel/summary-button.js.map +1 -0
  51. package/build/field-types/array.js +0 -6
  52. package/build/field-types/array.js.map +1 -1
  53. package/build/index.js +7 -0
  54. package/build/index.js.map +1 -1
  55. package/build/normalize-fields.js +17 -0
  56. package/build/normalize-fields.js.map +1 -1
  57. package/build/types.js.map +1 -1
  58. package/build/validation.js +18 -1
  59. package/build/validation.js.map +1 -1
  60. package/build-module/components/dataviews-filters/input-widget.js +48 -4
  61. package/build-module/components/dataviews-filters/input-widget.js.map +1 -1
  62. package/build-module/components/dataviews-view-config/index.js +22 -3
  63. package/build-module/components/dataviews-view-config/index.js.map +1 -1
  64. package/build-module/dataform-controls/array.js +120 -32
  65. package/build-module/dataform-controls/array.js.map +1 -1
  66. package/build-module/dataform-controls/checkbox.js +31 -21
  67. package/build-module/dataform-controls/checkbox.js.map +1 -1
  68. package/build-module/dataform-controls/color.js +28 -24
  69. package/build-module/dataform-controls/color.js.map +1 -1
  70. package/build-module/dataform-controls/date.js +32 -24
  71. package/build-module/dataform-controls/date.js.map +1 -1
  72. package/build-module/dataform-controls/datetime.js +135 -21
  73. package/build-module/dataform-controls/datetime.js.map +1 -1
  74. package/build-module/dataform-controls/email.js +7 -1
  75. package/build-module/dataform-controls/email.js.map +1 -1
  76. package/build-module/dataform-controls/index.js +23 -0
  77. package/build-module/dataform-controls/index.js.map +1 -1
  78. package/build-module/dataform-controls/integer.js +46 -34
  79. package/build-module/dataform-controls/integer.js.map +1 -1
  80. package/build-module/dataform-controls/radio.js +44 -11
  81. package/build-module/dataform-controls/radio.js.map +1 -1
  82. package/build-module/dataform-controls/relative-date-control.js +6 -10
  83. package/build-module/dataform-controls/relative-date-control.js.map +1 -1
  84. package/build-module/dataform-controls/select.js +43 -12
  85. package/build-module/dataform-controls/select.js.map +1 -1
  86. package/build-module/dataform-controls/telephone.js +7 -1
  87. package/build-module/dataform-controls/telephone.js.map +1 -1
  88. package/build-module/dataform-controls/text.js +14 -2
  89. package/build-module/dataform-controls/text.js.map +1 -1
  90. package/build-module/dataform-controls/textarea.js +32 -20
  91. package/build-module/dataform-controls/textarea.js.map +1 -1
  92. package/build-module/dataform-controls/toggle-group.js +38 -8
  93. package/build-module/dataform-controls/toggle-group.js.map +1 -1
  94. package/build-module/dataform-controls/toggle.js +33 -23
  95. package/build-module/dataform-controls/toggle.js.map +1 -1
  96. package/build-module/dataform-controls/url.js +7 -1
  97. package/build-module/dataform-controls/url.js.map +1 -1
  98. package/build-module/dataform-controls/utils/validated-input.js +34 -33
  99. package/build-module/dataform-controls/utils/validated-input.js.map +1 -1
  100. package/build-module/dataforms-layouts/panel/dropdown.js +10 -15
  101. package/build-module/dataforms-layouts/panel/dropdown.js.map +1 -1
  102. package/build-module/dataforms-layouts/panel/index.js +24 -11
  103. package/build-module/dataforms-layouts/panel/index.js.map +1 -1
  104. package/build-module/dataforms-layouts/panel/modal.js +22 -28
  105. package/build-module/dataforms-layouts/panel/modal.js.map +1 -1
  106. package/build-module/dataforms-layouts/panel/summary-button.js +60 -0
  107. package/build-module/dataforms-layouts/panel/summary-button.js.map +1 -0
  108. package/build-module/field-types/array.js +0 -6
  109. package/build-module/field-types/array.js.map +1 -1
  110. package/build-module/index.js +1 -0
  111. package/build-module/index.js.map +1 -1
  112. package/build-module/normalize-fields.js +15 -0
  113. package/build-module/normalize-fields.js.map +1 -1
  114. package/build-module/types.js.map +1 -1
  115. package/build-module/validation.js +18 -1
  116. package/build-module/validation.js.map +1 -1
  117. package/build-types/components/dataform/stories/index.story.d.ts +3 -0
  118. package/build-types/components/dataform/stories/index.story.d.ts.map +1 -1
  119. package/build-types/components/dataviews/stories/fixtures.d.ts +4 -2
  120. package/build-types/components/dataviews/stories/fixtures.d.ts.map +1 -1
  121. package/build-types/components/dataviews-filters/input-widget.d.ts.map +1 -1
  122. package/build-types/components/dataviews-view-config/index.d.ts.map +1 -1
  123. package/build-types/dataform-controls/array.d.ts.map +1 -1
  124. package/build-types/dataform-controls/checkbox.d.ts.map +1 -1
  125. package/build-types/dataform-controls/color.d.ts.map +1 -1
  126. package/build-types/dataform-controls/date.d.ts.map +1 -1
  127. package/build-types/dataform-controls/datetime.d.ts.map +1 -1
  128. package/build-types/dataform-controls/email.d.ts.map +1 -1
  129. package/build-types/dataform-controls/index.d.ts +1 -1
  130. package/build-types/dataform-controls/index.d.ts.map +1 -1
  131. package/build-types/dataform-controls/integer.d.ts.map +1 -1
  132. package/build-types/dataform-controls/radio.d.ts.map +1 -1
  133. package/build-types/dataform-controls/relative-date-control.d.ts +6 -5
  134. package/build-types/dataform-controls/relative-date-control.d.ts.map +1 -1
  135. package/build-types/dataform-controls/select.d.ts.map +1 -1
  136. package/build-types/dataform-controls/telephone.d.ts.map +1 -1
  137. package/build-types/dataform-controls/text.d.ts +1 -1
  138. package/build-types/dataform-controls/text.d.ts.map +1 -1
  139. package/build-types/dataform-controls/textarea.d.ts +1 -1
  140. package/build-types/dataform-controls/textarea.d.ts.map +1 -1
  141. package/build-types/dataform-controls/toggle-group.d.ts.map +1 -1
  142. package/build-types/dataform-controls/toggle.d.ts.map +1 -1
  143. package/build-types/dataform-controls/url.d.ts.map +1 -1
  144. package/build-types/dataform-controls/utils/validated-input.d.ts +4 -4
  145. package/build-types/dataform-controls/utils/validated-input.d.ts.map +1 -1
  146. package/build-types/dataforms-layouts/panel/dropdown.d.ts +2 -1
  147. package/build-types/dataforms-layouts/panel/dropdown.d.ts.map +1 -1
  148. package/build-types/dataforms-layouts/panel/index.d.ts.map +1 -1
  149. package/build-types/dataforms-layouts/panel/modal.d.ts +2 -1
  150. package/build-types/dataforms-layouts/panel/modal.d.ts.map +1 -1
  151. package/build-types/dataforms-layouts/panel/summary-button.d.ts +15 -0
  152. package/build-types/dataforms-layouts/panel/summary-button.d.ts.map +1 -0
  153. package/build-types/field-types/array.d.ts.map +1 -1
  154. package/build-types/field-types/stories/index.story.d.ts.map +1 -1
  155. package/build-types/index.d.ts +1 -0
  156. package/build-types/index.d.ts.map +1 -1
  157. package/build-types/normalize-fields.d.ts +3 -0
  158. package/build-types/normalize-fields.d.ts.map +1 -1
  159. package/build-types/types.d.ts +68 -4
  160. package/build-types/types.d.ts.map +1 -1
  161. package/build-types/validation.d.ts.map +1 -1
  162. package/build-wp/index.js +2009 -1489
  163. package/package.json +16 -15
  164. package/src/components/dataform/stories/index.story.tsx +509 -8
  165. package/src/components/dataviews/stories/fixtures.tsx +99 -41
  166. package/src/components/dataviews/stories/index.story.tsx +1 -1
  167. package/src/components/dataviews-filters/input-widget.tsx +44 -5
  168. package/src/components/dataviews-picker/stories/index.story.tsx +1 -1
  169. package/src/components/dataviews-view-config/index.tsx +18 -3
  170. package/src/dataform-controls/array.tsx +139 -44
  171. package/src/dataform-controls/checkbox.tsx +41 -24
  172. package/src/dataform-controls/color.tsx +33 -24
  173. package/src/dataform-controls/date.tsx +47 -21
  174. package/src/dataform-controls/datetime.tsx +171 -23
  175. package/src/dataform-controls/email.tsx +9 -1
  176. package/src/dataform-controls/index.tsx +26 -0
  177. package/src/dataform-controls/integer.tsx +82 -49
  178. package/src/dataform-controls/radio.tsx +53 -11
  179. package/src/dataform-controls/relative-date-control.tsx +11 -10
  180. package/src/dataform-controls/select.tsx +53 -10
  181. package/src/dataform-controls/telephone.tsx +9 -1
  182. package/src/dataform-controls/text.tsx +18 -1
  183. package/src/dataform-controls/textarea.tsx +38 -24
  184. package/src/dataform-controls/toggle-group.tsx +50 -10
  185. package/src/dataform-controls/toggle.tsx +41 -24
  186. package/src/dataform-controls/url.tsx +9 -1
  187. package/src/dataform-controls/utils/validated-input.tsx +50 -50
  188. package/src/dataforms-layouts/panel/dropdown.tsx +12 -23
  189. package/src/dataforms-layouts/panel/index.tsx +39 -16
  190. package/src/dataforms-layouts/panel/modal.tsx +24 -30
  191. package/src/dataforms-layouts/panel/summary-button.tsx +92 -0
  192. package/src/field-types/array.tsx +0 -8
  193. package/src/field-types/stories/index.story.tsx +89 -1
  194. package/src/index.ts +1 -0
  195. package/src/normalize-fields.ts +18 -0
  196. package/src/test/filter-and-sort-data-view.js +148 -138
  197. package/src/test/normalize-fields.ts +114 -0
  198. package/src/test/validation.ts +192 -0
  199. package/src/types.ts +75 -4
  200. package/src/validation.ts +30 -0
  201. package/tsconfig.tsbuildinfo +1 -1
@@ -1,3 +1,8 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import deepMerge from 'deepmerge';
5
+
1
6
  /**
2
7
  * WordPress dependencies
3
8
  */
@@ -19,33 +24,29 @@ import { unlock } from '../lock-unlock';
19
24
 
20
25
  const { ValidatedNumberControl } = unlock( privateApis );
21
26
 
22
- function BetweenControls< Item >( {
23
- id,
27
+ type IntegerBetween = [ number | string, number | string ];
28
+
29
+ function BetweenControls( {
24
30
  value,
25
31
  onChange,
26
32
  hideLabelFromVision,
27
33
  }: {
28
- id: string;
29
- value: any;
30
- onChange: DataFormControlProps< Item >[ 'onChange' ];
34
+ value: IntegerBetween;
35
+ onChange: ( [ min, max ]: IntegerBetween ) => void;
31
36
  hideLabelFromVision?: boolean;
32
37
  } ) {
33
- const [ min = '', max = '' ] = Array.isArray( value ) ? value : [];
38
+ const [ min = '', max = '' ] = value;
34
39
 
35
40
  const onChangeMin = useCallback(
36
41
  ( newValue: string | undefined ) =>
37
- onChange( {
38
- [ id ]: [ Number( newValue ), max ],
39
- } ),
40
- [ id, onChange, max ]
42
+ onChange( [ Number( newValue ), max ] ),
43
+ [ onChange, max ]
41
44
  );
42
45
 
43
46
  const onChangeMax = useCallback(
44
47
  ( newValue: string | undefined ) =>
45
- onChange( {
46
- [ id ]: [ min, Number( newValue ) ],
47
- } ),
48
- [ id, onChange, min ]
48
+ onChange( [ min, Number( newValue ) ] ),
49
+ [ onChange, min ]
49
50
  );
50
51
 
51
52
  return (
@@ -82,8 +83,8 @@ export default function Integer< Item >( {
82
83
  hideLabelFromVision,
83
84
  operator,
84
85
  }: DataFormControlProps< Item > ) {
85
- const { id, label, description } = field;
86
- const value = field.getValue( { item: data } ) ?? '';
86
+ const { label, description, getValue, setValue } = field;
87
+ const value = getValue( { item: data } ) ?? '';
87
88
  const [ customValidity, setCustomValidity ] =
88
89
  useState<
89
90
  React.ComponentProps<
@@ -93,24 +94,76 @@ export default function Integer< Item >( {
93
94
 
94
95
  const onChangeControl = useCallback(
95
96
  ( newValue: string | undefined ) => {
96
- onChange( {
97
- // Do not convert an empty string or undefined to a number,
98
- // otherwise there's a mismatch between the UI control (empty)
99
- // and the data relied by onChange (0).
100
- [ id ]: [ '', undefined ].includes( newValue )
101
- ? undefined
102
- : Number( newValue ),
103
- } );
97
+ onChange(
98
+ setValue( {
99
+ item: data,
100
+ // Do not convert an empty string or undefined to a number,
101
+ // otherwise there's a mismatch between the UI control (empty)
102
+ // and the data relied by onChange (0).
103
+ value: [ '', undefined ].includes( newValue )
104
+ ? undefined
105
+ : Number( newValue ),
106
+ } )
107
+ );
108
+ },
109
+ [ data, onChange, setValue ]
110
+ );
111
+
112
+ const onChangeBetweenControls = useCallback(
113
+ ( newValue: IntegerBetween ) => {
114
+ onChange(
115
+ setValue( {
116
+ item: data,
117
+ value: newValue,
118
+ } )
119
+ );
120
+ },
121
+ [ data, onChange, setValue ]
122
+ );
123
+
124
+ const onValidateControl = useCallback(
125
+ ( newValue: any ) => {
126
+ const message = field.isValid?.custom?.(
127
+ deepMerge(
128
+ data,
129
+ setValue( {
130
+ item: data,
131
+ value: [ undefined, '', null ].includes( newValue )
132
+ ? undefined
133
+ : Number( newValue ),
134
+ } ) as Partial< Item >
135
+ ),
136
+ field
137
+ );
138
+
139
+ if ( message ) {
140
+ setCustomValidity( {
141
+ type: 'invalid',
142
+ message,
143
+ } );
144
+ return;
145
+ }
146
+
147
+ setCustomValidity( undefined );
104
148
  },
105
- [ id, onChange ]
149
+ [ data, field, setValue ]
106
150
  );
107
151
 
108
152
  if ( operator === OPERATOR_BETWEEN ) {
153
+ let valueBetween: IntegerBetween = [ '', '' ];
154
+ if (
155
+ Array.isArray( value ) &&
156
+ value.length === 2 &&
157
+ value.every(
158
+ ( element ) => typeof element === 'number' || element === ''
159
+ )
160
+ ) {
161
+ valueBetween = value as IntegerBetween;
162
+ }
109
163
  return (
110
164
  <BetweenControls
111
- id={ id }
112
- value={ value }
113
- onChange={ onChange }
165
+ value={ valueBetween }
166
+ onChange={ onChangeBetweenControls }
114
167
  hideLabelFromVision={ hideLabelFromVision }
115
168
  />
116
169
  );
@@ -119,27 +172,7 @@ export default function Integer< Item >( {
119
172
  return (
120
173
  <ValidatedNumberControl
121
174
  required={ !! field.isValid?.required }
122
- onValidate={ ( newValue: any ) => {
123
- const message = field.isValid?.custom?.(
124
- {
125
- ...data,
126
- [ id ]: [ undefined, '', null ].includes( newValue )
127
- ? undefined
128
- : Number( newValue ),
129
- },
130
- field
131
- );
132
-
133
- if ( message ) {
134
- setCustomValidity( {
135
- type: 'invalid',
136
- message,
137
- } );
138
- return;
139
- }
140
-
141
- setCustomValidity( undefined );
142
- } }
175
+ onValidate={ onValidateControl }
143
176
  customValidity={ customValidity }
144
177
  label={ label }
145
178
  help={ description }
@@ -1,13 +1,21 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import deepMerge from 'deepmerge';
5
+
1
6
  /**
2
7
  * WordPress dependencies
3
8
  */
4
- import { RadioControl } from '@wordpress/components';
5
- import { useCallback } from '@wordpress/element';
9
+ import { privateApis } from '@wordpress/components';
10
+ import { useCallback, useState } from '@wordpress/element';
6
11
 
7
12
  /**
8
13
  * Internal dependencies
9
14
  */
10
15
  import type { DataFormControlProps } from '../types';
16
+ import { unlock } from '../lock-unlock';
17
+
18
+ const { ValidatedRadioControl } = unlock( privateApis );
11
19
 
12
20
  export default function Radio< Item >( {
13
21
  data,
@@ -15,23 +23,57 @@ export default function Radio< Item >( {
15
23
  onChange,
16
24
  hideLabelFromVision,
17
25
  }: DataFormControlProps< Item > ) {
18
- const { id, label } = field;
19
- const value = field.getValue( { item: data } );
26
+ const { label, description, elements, getValue, setValue } = field;
27
+ const value = getValue( { item: data } );
28
+ const [ customValidity, setCustomValidity ] =
29
+ useState<
30
+ React.ComponentProps<
31
+ typeof ValidatedRadioControl
32
+ >[ 'customValidity' ]
33
+ >( undefined );
20
34
 
21
35
  const onChangeControl = useCallback(
22
36
  ( newValue: string ) =>
23
- onChange( {
24
- [ id ]: newValue,
25
- } ),
26
- [ id, onChange ]
37
+ onChange( setValue( { item: data, value: newValue } ) ),
38
+ [ data, onChange, setValue ]
39
+ );
40
+
41
+ const onValidateControl = useCallback(
42
+ ( newValue: any ) => {
43
+ const message = field.isValid?.custom?.(
44
+ deepMerge(
45
+ data,
46
+ setValue( {
47
+ item: data,
48
+ value: newValue,
49
+ } ) as Partial< Item >
50
+ ),
51
+ field
52
+ );
53
+
54
+ if ( message ) {
55
+ setCustomValidity( {
56
+ type: 'invalid',
57
+ message,
58
+ } );
59
+ return;
60
+ }
61
+
62
+ setCustomValidity( undefined );
63
+ },
64
+ [ data, field, setValue ]
27
65
  );
28
66
 
29
- if ( field.elements ) {
67
+ if ( elements ) {
30
68
  return (
31
- <RadioControl
69
+ <ValidatedRadioControl
70
+ required={ !! field.isValid?.required }
71
+ onValidate={ onValidateControl }
72
+ customValidity={ customValidity }
32
73
  label={ label }
74
+ help={ description }
33
75
  onChange={ onChangeControl }
34
- options={ field.elements }
76
+ options={ elements }
35
77
  selected={ value }
36
78
  hideLabelFromVision={ hideLabelFromVision }
37
79
  />
@@ -20,10 +20,15 @@ import { __ } from '@wordpress/i18n';
20
20
  */
21
21
  import { OPERATOR_IN_THE_PAST, OPERATOR_OVER } from '../constants';
22
22
 
23
+ export type DateRelative = {
24
+ value?: string | number;
25
+ unit?: string;
26
+ };
27
+
23
28
  interface RelativeDateControlProps {
24
29
  id: string;
25
- value: { value?: string | number; unit?: string };
26
- onChange: ( value: any ) => void;
30
+ value: DateRelative;
31
+ onChange: ( args: DateRelative ) => void;
27
32
  label: string;
28
33
  hideLabelFromVision?: boolean;
29
34
  options: { value: string; label: string }[];
@@ -58,18 +63,14 @@ export default function RelativeDateControl( {
58
63
 
59
64
  const onChangeValue = useCallback(
60
65
  ( newValue: string | undefined ) =>
61
- onChange( {
62
- [ id ]: { value: Number( newValue ), unit },
63
- } ),
64
- [ id, onChange, unit ]
66
+ onChange( { value: Number( newValue ), unit } ),
67
+ [ onChange, unit ]
65
68
  );
66
69
 
67
70
  const onChangeUnit = useCallback(
68
71
  ( newUnit: string | undefined ) =>
69
- onChange( {
70
- [ id ]: { value: relValue, unit: newUnit },
71
- } ),
72
- [ id, onChange, relValue ]
72
+ onChange( { value: relValue, unit: newUnit } ),
73
+ [ onChange, relValue ]
73
74
  );
74
75
 
75
76
  return (
@@ -1,14 +1,22 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import deepMerge from 'deepmerge';
5
+
1
6
  /**
2
7
  * WordPress dependencies
3
8
  */
4
- import { SelectControl } from '@wordpress/components';
5
- import { useCallback } from '@wordpress/element';
9
+ import { privateApis } from '@wordpress/components';
10
+ import { useCallback, useState } from '@wordpress/element';
6
11
  import { __ } from '@wordpress/i18n';
7
12
 
8
13
  /**
9
14
  * Internal dependencies
10
15
  */
11
16
  import type { DataFormControlProps } from '../types';
17
+ import { unlock } from '../lock-unlock';
18
+
19
+ const { ValidatedSelectControl } = unlock( privateApis );
12
20
 
13
21
  export default function Select< Item >( {
14
22
  data,
@@ -16,15 +24,47 @@ export default function Select< Item >( {
16
24
  onChange,
17
25
  hideLabelFromVision,
18
26
  }: DataFormControlProps< Item > ) {
19
- const { id, label, type } = field;
27
+ const { type, label, description, getValue, setValue } = field;
28
+ const [ customValidity, setCustomValidity ] =
29
+ useState<
30
+ React.ComponentProps<
31
+ typeof ValidatedSelectControl
32
+ >[ 'customValidity' ]
33
+ >( undefined );
34
+
20
35
  const isMultiple = type === 'array';
21
- const value = field.getValue( { item: data } ) ?? ( isMultiple ? [] : '' );
36
+ const value = getValue( { item: data } ) ?? ( isMultiple ? [] : '' );
37
+
22
38
  const onChangeControl = useCallback(
23
39
  ( newValue: any ) =>
24
- onChange( {
25
- [ id ]: newValue,
26
- } ),
27
- [ id, onChange ]
40
+ onChange( setValue( { item: data, value: newValue } ) ),
41
+ [ data, onChange, setValue ]
42
+ );
43
+
44
+ const onValidateControl = useCallback(
45
+ ( newValue: any ) => {
46
+ const message = field.isValid?.custom?.(
47
+ deepMerge(
48
+ data,
49
+ setValue( {
50
+ item: data,
51
+ value: newValue,
52
+ } ) as Partial< Item >
53
+ ),
54
+ field
55
+ );
56
+
57
+ if ( message ) {
58
+ setCustomValidity( {
59
+ type: 'invalid',
60
+ message,
61
+ } );
62
+ return;
63
+ }
64
+
65
+ setCustomValidity( undefined );
66
+ },
67
+ [ data, field, setValue ]
28
68
  );
29
69
 
30
70
  const fieldElements = field?.elements ?? [];
@@ -48,10 +88,13 @@ export default function Select< Item >( {
48
88
  ];
49
89
 
50
90
  return (
51
- <SelectControl
91
+ <ValidatedSelectControl
92
+ required={ !! field.isValid?.required }
93
+ onValidate={ onValidateControl }
94
+ customValidity={ customValidity }
52
95
  label={ label }
53
96
  value={ value }
54
- help={ field.description }
97
+ help={ description }
55
98
  options={ elements }
56
99
  onChange={ onChangeControl }
57
100
  __next40pxDefaultSize
@@ -1,6 +1,10 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
+ import {
5
+ Icon,
6
+ __experimentalInputControlPrefixWrapper as InputControlPrefixWrapper,
7
+ } from '@wordpress/components';
4
8
  import { mobile } from '@wordpress/icons';
5
9
 
6
10
  /**
@@ -23,7 +27,11 @@ export default function Telephone< Item >( {
23
27
  onChange,
24
28
  hideLabelFromVision,
25
29
  type: 'tel',
26
- icon: mobile,
30
+ prefix: (
31
+ <InputControlPrefixWrapper variant="icon">
32
+ <Icon icon={ mobile } />
33
+ </InputControlPrefixWrapper>
34
+ ),
27
35
  } }
28
36
  />
29
37
  );
@@ -1,3 +1,8 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { createElement } from '@wordpress/element';
5
+
1
6
  /**
2
7
  * Internal dependencies
3
8
  */
@@ -9,8 +14,20 @@ export default function Text< Item >( {
9
14
  field,
10
15
  onChange,
11
16
  hideLabelFromVision,
17
+ config,
12
18
  }: DataFormControlProps< Item > ) {
19
+ const { prefix, suffix } = config || {};
20
+
13
21
  return (
14
- <ValidatedText { ...{ data, field, onChange, hideLabelFromVision } } />
22
+ <ValidatedText
23
+ { ...{
24
+ data,
25
+ field,
26
+ onChange,
27
+ hideLabelFromVision,
28
+ prefix: prefix ? createElement( prefix ) : undefined,
29
+ suffix: suffix ? createElement( suffix ) : undefined,
30
+ } }
31
+ />
15
32
  );
16
33
  }
@@ -1,3 +1,8 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import deepMerge from 'deepmerge';
5
+
1
6
  /**
2
7
  * WordPress dependencies
3
8
  */
@@ -17,8 +22,10 @@ export default function Textarea< Item >( {
17
22
  field,
18
23
  onChange,
19
24
  hideLabelFromVision,
25
+ config,
20
26
  }: DataFormControlProps< Item > ) {
21
- const { id, label, placeholder, description } = field;
27
+ const { rows = 4 } = config || {};
28
+ const { label, placeholder, description, setValue } = field;
22
29
  const value = field.getValue( { item: data } );
23
30
  const [ customValidity, setCustomValidity ] =
24
31
  useState<
@@ -29,40 +36,47 @@ export default function Textarea< Item >( {
29
36
 
30
37
  const onChangeControl = useCallback(
31
38
  ( newValue: string ) =>
32
- onChange( {
33
- [ id ]: newValue,
34
- } ),
35
- [ id, onChange ]
39
+ onChange( setValue( { item: data, value: newValue } ) ),
40
+ [ data, onChange, setValue ]
41
+ );
42
+
43
+ const onValidateControl = useCallback(
44
+ ( newValue: any ) => {
45
+ const message = field.isValid?.custom?.(
46
+ deepMerge(
47
+ data,
48
+ setValue( {
49
+ item: data,
50
+ value: newValue,
51
+ } ) as Partial< Item >
52
+ ),
53
+ field
54
+ );
55
+
56
+ if ( message ) {
57
+ setCustomValidity( {
58
+ type: 'invalid',
59
+ message,
60
+ } );
61
+ return;
62
+ }
63
+
64
+ setCustomValidity( undefined );
65
+ },
66
+ [ data, field, setValue ]
36
67
  );
37
68
 
38
69
  return (
39
70
  <ValidatedTextareaControl
40
71
  required={ !! field.isValid?.required }
41
- onValidate={ ( newValue: any ) => {
42
- const message = field.isValid?.custom?.(
43
- {
44
- ...data,
45
- [ id ]: newValue,
46
- },
47
- field
48
- );
49
-
50
- if ( message ) {
51
- setCustomValidity( {
52
- type: 'invalid',
53
- message,
54
- } );
55
- return;
56
- }
57
-
58
- setCustomValidity( undefined );
59
- } }
72
+ onValidate={ onValidateControl }
60
73
  customValidity={ customValidity }
61
74
  label={ label }
62
75
  placeholder={ placeholder }
63
76
  value={ value ?? '' }
64
77
  help={ description }
65
78
  onChange={ onChangeControl }
79
+ rows={ rows }
66
80
  __next40pxDefaultSize
67
81
  __nextHasNoMarginBottom
68
82
  hideLabelFromVision={ hideLabelFromVision }
@@ -1,16 +1,24 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import deepMerge from 'deepmerge';
5
+
1
6
  /**
2
7
  * WordPress dependencies
3
8
  */
4
9
  import {
5
- __experimentalToggleGroupControl as ToggleGroupControl,
10
+ privateApis,
6
11
  __experimentalToggleGroupControlOption as ToggleGroupControlOption,
7
12
  } from '@wordpress/components';
8
- import { useCallback } from '@wordpress/element';
13
+ import { useCallback, useState } from '@wordpress/element';
9
14
 
10
15
  /**
11
16
  * Internal dependencies
12
17
  */
13
18
  import type { DataFormControlProps } from '../types';
19
+ import { unlock } from '../lock-unlock';
20
+
21
+ const { ValidatedToggleGroupControl } = unlock( privateApis );
14
22
 
15
23
  export default function ToggleGroup< Item >( {
16
24
  data,
@@ -18,15 +26,44 @@ export default function ToggleGroup< Item >( {
18
26
  onChange,
19
27
  hideLabelFromVision,
20
28
  }: DataFormControlProps< Item > ) {
21
- const { id } = field;
22
- const value = field.getValue( { item: data } );
29
+ const { getValue, setValue } = field;
30
+ const [ customValidity, setCustomValidity ] =
31
+ useState<
32
+ React.ComponentProps<
33
+ typeof ValidatedToggleGroupControl
34
+ >[ 'customValidity' ]
35
+ >( undefined );
36
+ const value = getValue( { item: data } );
23
37
 
24
38
  const onChangeControl = useCallback(
25
39
  ( newValue: string | number | undefined ) =>
26
- onChange( {
27
- [ id ]: newValue,
28
- } ),
29
- [ id, onChange ]
40
+ onChange( setValue( { item: data, value: newValue } ) ),
41
+ [ data, onChange, setValue ]
42
+ );
43
+ const onValidateControl = useCallback(
44
+ ( newValue: any ) => {
45
+ const message = field.isValid?.custom?.(
46
+ deepMerge(
47
+ data,
48
+ setValue( {
49
+ item: data,
50
+ value: newValue,
51
+ } ) as Partial< Item >
52
+ ),
53
+ field
54
+ );
55
+
56
+ if ( message ) {
57
+ setCustomValidity( {
58
+ type: 'invalid',
59
+ message,
60
+ } );
61
+ return;
62
+ }
63
+
64
+ setCustomValidity( undefined );
65
+ },
66
+ [ data, field, setValue ]
30
67
  );
31
68
 
32
69
  if ( field.elements ) {
@@ -34,7 +71,10 @@ export default function ToggleGroup< Item >( {
34
71
  ( el ) => el.value === value
35
72
  );
36
73
  return (
37
- <ToggleGroupControl
74
+ <ValidatedToggleGroupControl
75
+ required={ !! field.isValid?.required }
76
+ onValidate={ onValidateControl }
77
+ customValidity={ customValidity }
38
78
  __next40pxDefaultSize
39
79
  __nextHasNoMarginBottom
40
80
  isBlock
@@ -51,7 +91,7 @@ export default function ToggleGroup< Item >( {
51
91
  value={ el.value }
52
92
  />
53
93
  ) ) }
54
- </ToggleGroupControl>
94
+ </ValidatedToggleGroupControl>
55
95
  );
56
96
  }
57
97