@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
@@ -117,4 +117,196 @@ describe( 'validation', () => {
117
117
  const result = isItemValid( item, fields, form );
118
118
  expect( result ).toBe( true );
119
119
  } );
120
+
121
+ it( 'array field is invalid when required but empty', () => {
122
+ const item = { id: 1, tags: [] };
123
+ const fields: Field< {} >[] = [
124
+ {
125
+ id: 'tags',
126
+ type: 'array',
127
+ isValid: {
128
+ required: true,
129
+ },
130
+ },
131
+ ];
132
+ const form = { fields: [ 'tags' ] };
133
+ const result = isItemValid( item, fields, form );
134
+ expect( result ).toBe( false );
135
+ } );
136
+
137
+ it( 'array field is invalid when required but not an array', () => {
138
+ const item = { id: 1, tags: null };
139
+ const fields: Field< {} >[] = [
140
+ {
141
+ id: 'tags',
142
+ type: 'array',
143
+ isValid: {
144
+ required: true,
145
+ },
146
+ },
147
+ ];
148
+ const form = { fields: [ 'tags' ] };
149
+ const result = isItemValid( item, fields, form );
150
+ expect( result ).toBe( false );
151
+ } );
152
+
153
+ it( 'array field is valid when required and has values', () => {
154
+ const item = { id: 1, tags: [ 'tag1', 'tag2' ] };
155
+ const fields: Field< {} >[] = [
156
+ {
157
+ id: 'tags',
158
+ type: 'array',
159
+ isValid: {
160
+ required: true,
161
+ },
162
+ },
163
+ ];
164
+ const form = { fields: [ 'tags' ] };
165
+ const result = isItemValid( item, fields, form );
166
+ expect( result ).toBe( true );
167
+ } );
168
+
169
+ it( 'text field with isValid.elements validates against elements', () => {
170
+ const item = { id: 1, status: 'published' };
171
+ const fields: Field< {} >[] = [
172
+ {
173
+ id: 'status',
174
+ type: 'text',
175
+ elements: [
176
+ { value: 'draft', label: 'Draft' },
177
+ { value: 'published', label: 'Published' },
178
+ ],
179
+ isValid: {
180
+ elements: true,
181
+ },
182
+ },
183
+ ];
184
+ const form = { fields: [ 'status' ] };
185
+ const result = isItemValid( item, fields, form );
186
+ expect( result ).toBe( true );
187
+ } );
188
+
189
+ it( 'text field with isValid.elements rejects invalid values', () => {
190
+ const item = { id: 1, status: 'invalid-status' };
191
+ const fields: Field< {} >[] = [
192
+ {
193
+ id: 'status',
194
+ type: 'text',
195
+ elements: [
196
+ { value: 'draft', label: 'Draft' },
197
+ { value: 'published', label: 'Published' },
198
+ ],
199
+ isValid: {
200
+ elements: true,
201
+ },
202
+ },
203
+ ];
204
+ const form = { fields: [ 'status' ] };
205
+ const result = isItemValid( item, fields, form );
206
+ expect( result ).toBe( false );
207
+ } );
208
+
209
+ it( 'integer field with isValid.elements validates against elements', () => {
210
+ const item = { id: 1, priority: 2 };
211
+ const fields: Field< {} >[] = [
212
+ {
213
+ id: 'priority',
214
+ type: 'integer',
215
+ elements: [
216
+ { value: 1, label: 'Low' },
217
+ { value: 2, label: 'Medium' },
218
+ { value: 3, label: 'High' },
219
+ ],
220
+ isValid: {
221
+ elements: true,
222
+ },
223
+ },
224
+ ];
225
+ const form = { fields: [ 'priority' ] };
226
+ const result = isItemValid( item, fields, form );
227
+ expect( result ).toBe( true );
228
+ } );
229
+
230
+ it( 'integer field with isValid.elements rejects invalid values', () => {
231
+ const item = { id: 1, priority: 5 };
232
+ const fields: Field< {} >[] = [
233
+ {
234
+ id: 'priority',
235
+ type: 'integer',
236
+ elements: [
237
+ { value: 1, label: 'Low' },
238
+ { value: 2, label: 'Medium' },
239
+ { value: 3, label: 'High' },
240
+ ],
241
+ isValid: {
242
+ elements: true,
243
+ },
244
+ },
245
+ ];
246
+ const form = { fields: [ 'priority' ] };
247
+ const result = isItemValid( item, fields, form );
248
+ expect( result ).toBe( false );
249
+ } );
250
+
251
+ it( 'array field with isValid.elements validates all items against elements', () => {
252
+ const item = { id: 1, tags: [ 'red', 'blue' ] };
253
+ const fields: Field< {} >[] = [
254
+ {
255
+ id: 'tags',
256
+ type: 'array',
257
+ elements: [
258
+ { value: 'red', label: 'Red' },
259
+ { value: 'blue', label: 'Blue' },
260
+ { value: 'green', label: 'Green' },
261
+ ],
262
+ isValid: {
263
+ elements: true,
264
+ },
265
+ },
266
+ ];
267
+ const form = { fields: [ 'tags' ] };
268
+ const result = isItemValid( item, fields, form );
269
+ expect( result ).toBe( true );
270
+ } );
271
+
272
+ it( 'array field with isValid.elements rejects arrays with invalid items', () => {
273
+ const item = { id: 1, tags: [ 'red', 'yellow' ] };
274
+ const fields: Field< {} >[] = [
275
+ {
276
+ id: 'tags',
277
+ type: 'array',
278
+ elements: [
279
+ { value: 'red', label: 'Red' },
280
+ { value: 'blue', label: 'Blue' },
281
+ { value: 'green', label: 'Green' },
282
+ ],
283
+ isValid: {
284
+ elements: true,
285
+ },
286
+ },
287
+ ];
288
+ const form = { fields: [ 'tags' ] };
289
+ const result = isItemValid( item, fields, form );
290
+ expect( result ).toBe( false );
291
+ } );
292
+
293
+ it( 'array field with isValid.elements handles non-array values', () => {
294
+ const item = { id: 1, tags: 'not-an-array' };
295
+ const fields: Field< {} >[] = [
296
+ {
297
+ id: 'tags',
298
+ type: 'array',
299
+ elements: [
300
+ { value: 'red', label: 'Red' },
301
+ { value: 'blue', label: 'Blue' },
302
+ ],
303
+ isValid: {
304
+ elements: true,
305
+ },
306
+ },
307
+ ];
308
+ const form = { fields: [ 'tags' ] };
309
+ const result = isItemValid( item, fields, form );
310
+ expect( result ).toBe( false );
311
+ } );
120
312
  } );
package/src/types.ts CHANGED
@@ -18,6 +18,14 @@ import type { SetSelection } from './private-types';
18
18
  */
19
19
  import type { useFocusOnMount } from '@wordpress/compose';
20
20
 
21
+ /**
22
+ * Utility type that makes all properties of T optional recursively.
23
+ * Used by field setValue functions to allow partial item updates.
24
+ */
25
+ export type DeepPartial< T > = {
26
+ [ P in keyof T ]?: T[ P ] extends object ? DeepPartial< T[ P ] > : T[ P ];
27
+ };
28
+
21
29
  export type SortDirection = 'asc' | 'desc';
22
30
 
23
31
  /**
@@ -126,7 +134,11 @@ export type FieldTypeDefinition< Item > = {
126
134
  /**
127
135
  * Callback used to render an edit control for the field or control name.
128
136
  */
129
- Edit: ComponentType< DataFormControlProps< Item > > | string | null;
137
+ Edit:
138
+ | ComponentType< DataFormControlProps< Item > >
139
+ | string
140
+ | EditConfig
141
+ | null;
130
142
 
131
143
  /**
132
144
  * Callback used to render the field.
@@ -152,9 +164,52 @@ export type FieldTypeDefinition< Item > = {
152
164
 
153
165
  export type Rules< Item > = {
154
166
  required?: boolean;
167
+ elements?: boolean;
155
168
  custom?: ( item: Item, field: NormalizedField< Item > ) => null | string;
156
169
  };
157
170
 
171
+ /**
172
+ * Edit configuration for textarea controls.
173
+ */
174
+ export type EditConfigTextarea = {
175
+ control: 'textarea';
176
+ /**
177
+ * Number of rows for the textarea.
178
+ */
179
+ rows?: number;
180
+ };
181
+
182
+ /**
183
+ * Edit configuration for text controls.
184
+ */
185
+ export type EditConfigText = {
186
+ control: 'text';
187
+ /**
188
+ * Prefix component to display before the input.
189
+ */
190
+ prefix?: React.ComponentType;
191
+ /**
192
+ * Suffix component to display after the input.
193
+ */
194
+ suffix?: React.ComponentType;
195
+ };
196
+
197
+ /**
198
+ * Edit configuration for other control types (excluding 'text' and 'textarea').
199
+ */
200
+ export type EditConfigGeneric = {
201
+ control: Exclude< FieldType, 'text' | 'textarea' >;
202
+ };
203
+
204
+ /**
205
+ * Edit configuration object with type-safe control options.
206
+ * Each control type has its own specific configuration properties.
207
+ */
208
+ export type EditConfig =
209
+ | EditConfigTextarea
210
+ | EditConfigText
211
+ | EditConfigGeneric;
212
+
158
213
  /**
159
214
  * A dataview field for a specific property of a data type.
160
215
  */
@@ -198,7 +253,7 @@ export type Field< Item > = {
198
253
  /**
199
254
  * Callback used to render an edit control for the field.
200
255
  */
201
- Edit?: ComponentType< DataFormControlProps< Item > > | string;
256
+ Edit?: ComponentType< DataFormControlProps< Item > > | string | EditConfig;
202
257
 
203
258
  /**
204
259
  * Callback used to sort the field.
@@ -226,7 +281,7 @@ export type Field< Item > = {
226
281
  enableGlobalSearch?: boolean;
227
282
 
228
283
  /**
229
- * Whether the field is filterable.
284
+ * Whether the field can be hidden in the UI.
230
285
  */
231
286
  enableHiding?: boolean;
232
287
 
@@ -251,12 +306,19 @@ export type Field< Item > = {
251
306
  * Defaults to `item[ field.id ]`.
252
307
  */
253
308
  getValue?: ( args: { item: Item } ) => any;
309
+
310
+ /**
311
+ * Callback used to set the value of the field on the item.
312
+ * Used for editing operations to update field values.
313
+ */
314
+ setValue?: ( args: { item: Item; value: any } ) => DeepPartial< Item >;
254
315
  };
255
316
 
256
317
  export type NormalizedField< Item > = Omit< Field< Item >, 'Edit' > & {
257
318
  label: string;
258
319
  header: string | ReactElement;
259
320
  getValue: ( args: { item: Item } ) => any;
321
+ setValue: ( args: { item: Item; value: any } ) => DeepPartial< Item >;
260
322
  render: ComponentType< DataViewRenderFieldProps< Item > >;
261
323
  Edit: ComponentType< DataFormControlProps< Item > > | null;
262
324
  sort: ( a: Item, b: Item, direction: SortDirection ) => number;
@@ -277,7 +339,7 @@ export type Data< Item > = Item[];
277
339
  export type DataFormControlProps< Item > = {
278
340
  data: Item;
279
341
  field: NormalizedField< Item >;
280
- onChange: ( value: Record< string, any > ) => void;
342
+ onChange: ( value: DeepPartial< Item > ) => void;
281
343
  hideLabelFromVision?: boolean;
282
344
  /**
283
345
  * The currently selected filter operator for this field.
@@ -285,6 +347,14 @@ export type DataFormControlProps< Item > = {
285
347
  * Used by DataViews filters to determine which control to render based on the operator type.
286
348
  */
287
349
  operator?: Operator;
350
+ /**
351
+ * Configuration object for the control.
352
+ */
353
+ config?: {
354
+ prefix?: React.ComponentType;
355
+ suffix?: React.ComponentType;
356
+ rows?: number;
357
+ };
288
358
  };
289
359
 
290
360
  export type DataViewRenderFieldProps< Item > = {
@@ -793,6 +863,7 @@ export type CombinedFormField = {
793
863
  description?: string;
794
864
  layout?: Layout;
795
865
  children: Array< FormField | string >;
866
+ summary?: string | string[];
796
867
  };
797
868
 
798
869
  export type FormField = SimpleFormField | CombinedFormField;
package/src/validation.ts CHANGED
@@ -25,6 +25,14 @@ export function isItemValid< Item >(
25
25
  const isEmptyNullOrUndefined = ( value: any ) =>
26
26
  [ undefined, '', null ].includes( value );
27
27
 
28
+ const isArrayOrElementsEmptyNullOrUndefined = ( value: any ) => {
29
+ return (
30
+ ! Array.isArray( value ) ||
31
+ value.length === 0 ||
32
+ value.every( ( element: any ) => isEmptyNullOrUndefined( element ) )
33
+ );
34
+ };
35
+
28
36
  return _fields.every( ( field ) => {
29
37
  const value = field.getValue( { item } );
30
38
 
@@ -39,6 +47,8 @@ export function isItemValid< Item >(
39
47
  isEmptyNullOrUndefined( value ) ) ||
40
48
  ( field.type === 'integer' &&
41
49
  isEmptyNullOrUndefined( value ) ) ||
50
+ ( field.type === 'array' &&
51
+ isArrayOrElementsEmptyNullOrUndefined( value ) ) ||
42
52
  ( field.type === undefined && isEmptyNullOrUndefined( value ) )
43
53
  ) {
44
54
  return false;
@@ -49,6 +59,26 @@ export function isItemValid< Item >(
49
59
  }
50
60
  }
51
61
 
62
+ if ( field.isValid.elements ) {
63
+ if ( field.elements ) {
64
+ const validValues = field.elements.map(
65
+ ( element ) => element.value
66
+ );
67
+
68
+ if ( field.type === 'array' ) {
69
+ // For arrays, check if all values are valid elements
70
+ if ( Array.isArray( value ) ) {
71
+ return value.every( ( arrayItem ) =>
72
+ validValues.includes( arrayItem )
73
+ );
74
+ }
75
+ return false;
76
+ }
77
+ // For single-value fields, check if the value is a valid element
78
+ return validValues.includes( value );
79
+ }
80
+ }
81
+
52
82
  if (
53
83
  typeof field.isValid.custom === 'function' &&
54
84
  field.isValid.custom( item, field ) !== null