@wordpress/dataviews 7.0.1-next.0f6f9d12c.0 → 7.0.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.
Files changed (73) hide show
  1. package/CHANGELOG.md +4 -1
  2. package/build/components/dataviews-item-actions/index.js +1 -10
  3. package/build/components/dataviews-item-actions/index.js.map +1 -1
  4. package/build/dataform-controls/boolean.js +15 -7
  5. package/build/dataform-controls/boolean.js.map +1 -1
  6. package/build/dataform-controls/email.js +14 -7
  7. package/build/dataform-controls/email.js.map +1 -1
  8. package/build/dataform-controls/integer.js +14 -7
  9. package/build/dataform-controls/integer.js.map +1 -1
  10. package/build/dataform-controls/text.js +14 -7
  11. package/build/dataform-controls/text.js.map +1 -1
  12. package/build/dataforms-layouts/panel/dropdown.js +124 -0
  13. package/build/dataforms-layouts/panel/dropdown.js.map +1 -0
  14. package/build/dataforms-layouts/panel/index.js +19 -127
  15. package/build/dataforms-layouts/panel/index.js.map +1 -1
  16. package/build/dataforms-layouts/panel/modal.js +125 -0
  17. package/build/dataforms-layouts/panel/modal.js.map +1 -0
  18. package/build/normalize-form-fields.js +3 -2
  19. package/build/normalize-form-fields.js.map +1 -1
  20. package/build/types.js.map +1 -1
  21. package/build-module/components/dataviews-item-actions/index.js +1 -10
  22. package/build-module/components/dataviews-item-actions/index.js.map +1 -1
  23. package/build-module/dataform-controls/boolean.js +15 -7
  24. package/build-module/dataform-controls/boolean.js.map +1 -1
  25. package/build-module/dataform-controls/email.js +15 -8
  26. package/build-module/dataform-controls/email.js.map +1 -1
  27. package/build-module/dataform-controls/integer.js +15 -8
  28. package/build-module/dataform-controls/integer.js.map +1 -1
  29. package/build-module/dataform-controls/text.js +15 -8
  30. package/build-module/dataform-controls/text.js.map +1 -1
  31. package/build-module/dataforms-layouts/panel/dropdown.js +118 -0
  32. package/build-module/dataforms-layouts/panel/dropdown.js.map +1 -0
  33. package/build-module/dataforms-layouts/panel/index.js +23 -131
  34. package/build-module/dataforms-layouts/panel/index.js.map +1 -1
  35. package/build-module/dataforms-layouts/panel/modal.js +119 -0
  36. package/build-module/dataforms-layouts/panel/modal.js.map +1 -0
  37. package/build-module/normalize-form-fields.js +3 -2
  38. package/build-module/normalize-form-fields.js.map +1 -1
  39. package/build-module/types.js.map +1 -1
  40. package/build-style/style-rtl.css +4 -0
  41. package/build-style/style.css +4 -0
  42. package/build-types/components/dataform/stories/index.story.d.ts +58 -25
  43. package/build-types/components/dataform/stories/index.story.d.ts.map +1 -1
  44. package/build-types/components/dataviews-item-actions/index.d.ts.map +1 -1
  45. package/build-types/dataform-controls/boolean.d.ts.map +1 -1
  46. package/build-types/dataform-controls/email.d.ts.map +1 -1
  47. package/build-types/dataform-controls/integer.d.ts.map +1 -1
  48. package/build-types/dataform-controls/text.d.ts.map +1 -1
  49. package/build-types/dataforms-layouts/panel/dropdown.d.ts +14 -0
  50. package/build-types/dataforms-layouts/panel/dropdown.d.ts.map +1 -0
  51. package/build-types/dataforms-layouts/panel/index.d.ts.map +1 -1
  52. package/build-types/dataforms-layouts/panel/modal.d.ts +13 -0
  53. package/build-types/dataforms-layouts/panel/modal.d.ts.map +1 -0
  54. package/build-types/normalize-form-fields.d.ts.map +1 -1
  55. package/build-types/types.d.ts +2 -0
  56. package/build-types/types.d.ts.map +1 -1
  57. package/build-wp/index.js +394 -178
  58. package/package.json +15 -15
  59. package/src/components/dataform/stories/index.story.tsx +354 -219
  60. package/src/components/dataviews-item-actions/index.tsx +7 -16
  61. package/src/dataform-controls/boolean.tsx +24 -10
  62. package/src/dataform-controls/email.tsx +24 -11
  63. package/src/dataform-controls/integer.tsx +27 -13
  64. package/src/dataform-controls/text.tsx +24 -11
  65. package/src/dataforms-layouts/panel/dropdown.tsx +160 -0
  66. package/src/dataforms-layouts/panel/index.tsx +28 -172
  67. package/src/dataforms-layouts/panel/modal.tsx +165 -0
  68. package/src/dataforms-layouts/panel/style.scss +4 -0
  69. package/src/normalize-form-fields.ts +1 -0
  70. package/src/test/dataform.tsx +169 -0
  71. package/src/test/normalize-form-fields.ts +15 -3
  72. package/src/types.ts +2 -0
  73. package/tsconfig.tsbuildinfo +1 -1
@@ -13,7 +13,15 @@ import {
13
13
  */
14
14
  import DataForm from '../index';
15
15
  import { isItemValid } from '../../../validation';
16
- import type { Field, Form, DataFormControlProps } from '../../../types';
16
+ import type {
17
+ Field,
18
+ Form,
19
+ DataFormControlProps,
20
+ Layout,
21
+ RegularLayout,
22
+ PanelLayout,
23
+ CardLayout,
24
+ } from '../../../types';
17
25
  import { unlock } from '../../../lock-unlock';
18
26
 
19
27
  const { ValidatedTextControl } = unlock( privateApis );
@@ -30,47 +38,31 @@ type SamplePost = {
30
38
  filesize?: number;
31
39
  dimensions?: string;
32
40
  tags?: string[];
41
+ address1?: string;
42
+ address2?: string;
43
+ city?: string;
33
44
  };
34
45
 
35
- const meta = {
36
- title: 'DataViews/DataForm',
37
- component: DataForm,
38
- argTypes: {
39
- type: {
40
- control: { type: 'select' },
41
- description:
42
- 'Chooses the default layout of each field. "regular" is the default layout.',
43
- options: [ 'default', 'regular', 'panel', 'card' ],
44
- },
45
- labelPosition: {
46
- control: { type: 'select' },
47
- description: 'Chooses the label position of the layout.',
48
- options: [ 'default', 'top', 'side', 'none' ],
49
- },
50
- },
51
- };
52
- export default meta;
53
-
54
- const fields = [
46
+ const fields: Field< SamplePost >[] = [
55
47
  {
56
48
  id: 'title',
57
49
  label: 'Title',
58
- type: 'text' as const,
50
+ type: 'text',
59
51
  },
60
52
  {
61
53
  id: 'order',
62
54
  label: 'Order',
63
- type: 'integer' as const,
55
+ type: 'integer',
64
56
  },
65
57
  {
66
58
  id: 'date',
67
59
  label: 'Date',
68
- type: 'datetime' as const,
60
+ type: 'datetime',
69
61
  },
70
62
  {
71
63
  id: 'birthdate',
72
64
  label: 'Date as options',
73
- type: 'datetime' as const,
65
+ type: 'datetime',
74
66
  elements: [
75
67
  { value: '', label: 'Select a date' },
76
68
  { value: '1970-02-23T12:00:00', label: "Jane's birth date" },
@@ -80,28 +72,31 @@ const fields = [
80
72
  {
81
73
  id: 'author',
82
74
  label: 'Author',
83
- type: 'integer' as const,
75
+ type: 'integer',
84
76
  elements: [
85
77
  { value: 1, label: 'Jane' },
86
78
  { value: 2, label: 'John' },
79
+ { value: 3, label: 'Alice' },
80
+ { value: 4, label: 'Bob' },
87
81
  ],
88
82
  },
89
83
  {
90
84
  id: 'reviewer',
91
85
  label: 'Reviewer',
92
- type: 'text' as const,
93
- Edit: 'radio' as const,
86
+ type: 'text',
87
+ Edit: 'radio',
94
88
  elements: [
95
- { value: 'fulano', label: 'Fulano' },
96
- { value: 'mengano', label: 'Mengano' },
97
- { value: 'zutano', label: 'Zutano' },
89
+ { value: 'jane', label: 'Jane' },
90
+ { value: 'john', label: 'John' },
91
+ { value: 'alice', label: 'Alice' },
92
+ { value: 'bob', label: 'Bob' },
98
93
  ],
99
94
  },
100
95
  {
101
96
  id: 'status',
102
97
  label: 'Status',
103
- type: 'text' as const,
104
- Edit: 'toggleGroup' as const,
98
+ type: 'text',
99
+ Edit: 'toggleGroup',
105
100
  elements: [
106
101
  { value: 'draft', label: 'Draft' },
107
102
  { value: 'published', label: 'Published' },
@@ -111,12 +106,12 @@ const fields = [
111
106
  {
112
107
  id: 'email',
113
108
  label: 'Email',
114
- type: 'email' as const,
109
+ type: 'email',
115
110
  },
116
111
  {
117
112
  id: 'password',
118
113
  label: 'Password',
119
- type: 'text' as const,
114
+ type: 'text',
120
115
  isVisible: ( item: SamplePost ) => {
121
116
  return item.status !== 'private';
122
117
  },
@@ -129,25 +124,25 @@ const fields = [
129
124
  {
130
125
  id: 'can_comment',
131
126
  label: 'Allow people to leave a comment',
132
- type: 'boolean' as const,
127
+ type: 'boolean',
133
128
  Edit: 'checkbox',
134
129
  },
135
130
  {
136
131
  id: 'filesize',
137
132
  label: 'File Size',
138
- type: 'integer' as const,
133
+ type: 'integer',
139
134
  readOnly: true,
140
135
  },
141
136
  {
142
137
  id: 'dimensions',
143
138
  label: 'Dimensions',
144
- type: 'text' as const,
139
+ type: 'text',
145
140
  readOnly: true,
146
141
  },
147
142
  {
148
143
  id: 'tags',
149
144
  label: 'Tags',
150
- type: 'array' as const,
145
+ type: 'array',
151
146
  placeholder: 'Enter comma-separated tags',
152
147
  description: 'Add tags separated by commas (e.g., "tag1, tag2, tag3")',
153
148
  elements: [
@@ -158,13 +153,28 @@ const fields = [
158
153
  { value: 'travel', label: 'Travel' },
159
154
  ],
160
155
  },
161
- ] as Field< SamplePost >[];
156
+ {
157
+ id: 'address1',
158
+ label: 'Address 1',
159
+ type: 'text',
160
+ },
161
+ {
162
+ id: 'address2',
163
+ label: 'Address 2',
164
+ type: 'text',
165
+ },
166
+ {
167
+ id: 'city',
168
+ label: 'City',
169
+ type: 'text',
170
+ },
171
+ ];
162
172
 
163
- export const Default = ( {
164
- type,
173
+ const LayoutRegularComponent = ( {
174
+ type = 'default',
165
175
  labelPosition,
166
176
  }: {
167
- type: 'default' | 'regular' | 'panel' | 'card';
177
+ type?: 'default' | 'regular' | 'panel' | 'card';
168
178
  labelPosition: 'default' | 'top' | 'side' | 'none';
169
179
  } ) => {
170
180
  const [ post, setPost ] = useState( {
@@ -183,12 +193,12 @@ export const Default = ( {
183
193
  tags: [ 'photography' ],
184
194
  } );
185
195
 
186
- const form = useMemo(
196
+ const form: Form = useMemo(
187
197
  () => ( {
188
- layout: {
198
+ layout: getLayoutFromStoryArgs( {
189
199
  type,
190
200
  labelPosition,
191
- },
201
+ } ),
192
202
  fields: [
193
203
  'title',
194
204
  'order',
@@ -207,7 +217,7 @@ export const Default = ( {
207
217
  ],
208
218
  } ),
209
219
  [ type, labelPosition ]
210
- ) as Form;
220
+ );
211
221
 
212
222
  return (
213
223
  <DataForm< SamplePost >
@@ -224,12 +234,59 @@ export const Default = ( {
224
234
  );
225
235
  };
226
236
 
227
- const CombinedFieldsComponent = ( {
237
+ const getLayoutFromStoryArgs = ( {
228
238
  type,
229
239
  labelPosition,
240
+ openAs,
241
+ withHeader,
242
+ }: {
243
+ type: 'default' | 'regular' | 'panel' | 'card';
244
+ labelPosition?: 'default' | 'top' | 'side' | 'none';
245
+ openAs?: 'default' | 'dropdown' | 'modal';
246
+ withHeader?: boolean;
247
+ } ): Layout | undefined => {
248
+ let layout: Layout | undefined;
249
+
250
+ if ( type === 'default' || type === 'regular' ) {
251
+ const regularLayout: RegularLayout = {
252
+ type: 'regular',
253
+ };
254
+ if ( labelPosition !== 'default' ) {
255
+ regularLayout.labelPosition = labelPosition;
256
+ }
257
+ layout = regularLayout;
258
+ } else if ( type === 'panel' ) {
259
+ const panelLayout: PanelLayout = {
260
+ type: 'panel',
261
+ };
262
+ if ( labelPosition !== 'default' ) {
263
+ panelLayout.labelPosition = labelPosition;
264
+ }
265
+ if ( openAs !== 'default' ) {
266
+ panelLayout.openAs = openAs;
267
+ }
268
+ layout = panelLayout;
269
+ } else if ( type === 'card' ) {
270
+ const cardLayout: CardLayout = {
271
+ type: 'card',
272
+ };
273
+ if ( withHeader !== undefined ) {
274
+ // @ts-ignore We want to demo the effects of configuring withHeader.
275
+ cardLayout.withHeader = withHeader;
276
+ }
277
+ layout = cardLayout;
278
+ }
279
+
280
+ return layout;
281
+ };
282
+
283
+ const LayoutPanelComponent = ( {
284
+ labelPosition,
285
+ openAs,
230
286
  }: {
231
287
  type: 'default' | 'regular' | 'panel' | 'card';
232
288
  labelPosition: 'default' | 'top' | 'side' | 'none';
289
+ openAs: 'default' | 'dropdown' | 'modal';
233
290
  } ) => {
234
291
  const [ post, setPost ] = useState< SamplePost >( {
235
292
  title: 'Hello, World!',
@@ -242,14 +299,18 @@ const CombinedFieldsComponent = ( {
242
299
  filesize: 1024,
243
300
  dimensions: '1920x1080',
244
301
  tags: [ 'photography' ],
302
+ address1: '123 Main St',
303
+ address2: 'Apt 4B',
304
+ city: 'New York',
245
305
  } );
246
306
 
247
- const form = useMemo(
248
- () => ( {
249
- layout: {
250
- type,
307
+ const form: Form = useMemo( () => {
308
+ return {
309
+ layout: getLayoutFromStoryArgs( {
310
+ type: 'panel',
251
311
  labelPosition,
252
- },
312
+ openAs,
313
+ } ),
253
314
  fields: [
254
315
  'title',
255
316
  {
@@ -262,10 +323,14 @@ const CombinedFieldsComponent = ( {
262
323
  'filesize',
263
324
  'dimensions',
264
325
  'tags',
326
+ {
327
+ id: 'address1',
328
+ label: 'Combined Address',
329
+ children: [ 'address1', 'address2', 'city' ],
330
+ },
265
331
  ],
266
- } ),
267
- [ type, labelPosition ]
268
- ) as Form;
332
+ };
333
+ }, [ labelPosition, openAs ] );
269
334
 
270
335
  return (
271
336
  <DataForm< SamplePost >
@@ -282,17 +347,6 @@ const CombinedFieldsComponent = ( {
282
347
  );
283
348
  };
284
349
 
285
- export const CombinedFields = {
286
- title: 'DataViews/CombinedFields',
287
- render: CombinedFieldsComponent,
288
- argTypes: {
289
- ...meta.argTypes,
290
- },
291
- args: {
292
- type: 'panel',
293
- },
294
- };
295
-
296
350
  function CustomEditControl< Item >( {
297
351
  data,
298
352
  field,
@@ -325,53 +379,90 @@ function CustomEditControl< Item >( {
325
379
  );
326
380
  }
327
381
 
328
- const DataFormValidationComponent = ( { required }: { required: boolean } ) => {
382
+ const ValidationComponent = ( {
383
+ required,
384
+ type,
385
+ custom,
386
+ }: {
387
+ required: boolean;
388
+ custom: boolean;
389
+ type: 'regular' | 'panel';
390
+ } ) => {
329
391
  type ValidatedItem = {
330
392
  text: string;
331
393
  email: string;
332
394
  integer: number;
333
395
  boolean: boolean;
334
396
  customEdit: string;
335
- customValidation: string;
336
397
  };
337
398
 
338
399
  const [ post, setPost ] = useState< ValidatedItem >( {
339
- text: 'Hello, World!',
400
+ text: 'Can have letters and spaces',
340
401
  email: 'hi@example.com',
341
402
  integer: 2,
342
403
  boolean: true,
343
404
  customEdit: 'custom control',
344
- customValidation: 'potato',
345
405
  } );
346
406
 
407
+ const customTextRule = ( value: ValidatedItem ) => {
408
+ if ( ! /^[a-zA-Z ]+$/.test( value.text ) ) {
409
+ return 'Value must only contain letters and spaces.';
410
+ }
411
+
412
+ return null;
413
+ };
414
+ const customEmailRule = ( value: ValidatedItem ) => {
415
+ if ( ! /^[a-zA-Z0-9._%+-]+@example\.com$/.test( value.email ) ) {
416
+ return 'Email address must be from @example.com domain.';
417
+ }
418
+
419
+ return null;
420
+ };
421
+ const customIntegerRule = ( value: ValidatedItem ) => {
422
+ if ( value.integer % 2 !== 0 ) {
423
+ return 'Integer must be an even number.';
424
+ }
425
+
426
+ return null;
427
+ };
428
+
429
+ const maybeCustomRule = (
430
+ rule: ( item: ValidatedItem ) => null | string
431
+ ) => {
432
+ return custom ? rule : undefined;
433
+ };
434
+
347
435
  const _fields: Field< ValidatedItem >[] = [
348
436
  {
349
437
  id: 'text',
350
- type: 'text' as const,
438
+ type: 'text',
351
439
  label: 'Text',
352
440
  isValid: {
353
441
  required,
442
+ custom: maybeCustomRule( customTextRule ),
354
443
  },
355
444
  },
356
445
  {
357
446
  id: 'email',
358
- type: 'email' as const,
447
+ type: 'email',
359
448
  label: 'e-mail',
360
449
  isValid: {
361
450
  required,
451
+ custom: maybeCustomRule( customEmailRule ),
362
452
  },
363
453
  },
364
454
  {
365
455
  id: 'integer',
366
- type: 'integer' as const,
456
+ type: 'integer',
367
457
  label: 'Integer',
368
458
  isValid: {
369
459
  required,
460
+ custom: maybeCustomRule( customIntegerRule ),
370
461
  },
371
462
  },
372
463
  {
373
464
  id: 'boolean',
374
- type: 'boolean' as const,
465
+ type: 'boolean',
375
466
  label: 'Boolean',
376
467
  isValid: {
377
468
  required,
@@ -385,36 +476,11 @@ const DataFormValidationComponent = ( { required }: { required: boolean } ) => {
385
476
  required,
386
477
  },
387
478
  },
388
- {
389
- id: 'customValidation',
390
- type: 'text',
391
- label: 'Custom validation',
392
- isValid: {
393
- required,
394
- custom: ( value: ValidatedItem ) => {
395
- if (
396
- ! [ 'tomato', 'potato' ].includes(
397
- value.customValidation
398
- )
399
- ) {
400
- return 'Value must be one of "tomato", "potato"';
401
- }
402
-
403
- return null;
404
- },
405
- },
406
- },
407
479
  ];
408
480
 
409
481
  const form = {
410
- fields: [
411
- 'text',
412
- 'email',
413
- 'integer',
414
- 'boolean',
415
- 'customEdit',
416
- 'customValidation',
417
- ],
482
+ layout: { type },
483
+ fields: [ 'text', 'email', 'integer', 'boolean', 'customEdit' ],
418
484
  };
419
485
 
420
486
  const canSave = isItemValid( post, _fields, form );
@@ -446,21 +512,7 @@ const DataFormValidationComponent = ( { required }: { required: boolean } ) => {
446
512
  );
447
513
  };
448
514
 
449
- export const Validation = {
450
- title: 'DataForm/Validation',
451
- render: DataFormValidationComponent,
452
- argTypes: {
453
- required: {
454
- control: { type: 'boolean' },
455
- description: 'Whether or not the fields are required.',
456
- },
457
- },
458
- args: {
459
- required: true,
460
- },
461
- };
462
-
463
- const DataFormVisibilityComponent = () => {
515
+ const VisibilityComponent = () => {
464
516
  type Post = {
465
517
  name: string;
466
518
  email: string;
@@ -472,7 +524,7 @@ const DataFormVisibilityComponent = () => {
472
524
  isActive: true,
473
525
  } );
474
526
 
475
- const _fields = [
527
+ const _fields: Field< Post >[] = [
476
528
  { id: 'isActive', label: 'Is module active?', type: 'boolean' },
477
529
  {
478
530
  id: 'name',
@@ -486,8 +538,8 @@ const DataFormVisibilityComponent = () => {
486
538
  type: 'email',
487
539
  isVisible: ( post ) => post.isActive === true,
488
540
  },
489
- ] satisfies Field< Post >[];
490
- const form = {
541
+ ];
542
+ const form: Form = {
491
543
  fields: [ 'isActive', 'name', 'email' ],
492
544
  };
493
545
  return (
@@ -505,12 +557,7 @@ const DataFormVisibilityComponent = () => {
505
557
  );
506
558
  };
507
559
 
508
- export const Visibility = {
509
- title: 'DataForm/Visibility',
510
- render: DataFormVisibilityComponent,
511
- };
512
-
513
- const LayoutCardComponent = () => {
560
+ const LayoutCardComponent = ( { withHeader }: { withHeader: boolean } ) => {
514
561
  type Customer = {
515
562
  name: string;
516
563
  email: string;
@@ -614,76 +661,79 @@ const LayoutCardComponent = () => {
614
661
  commission: 5,
615
662
  } );
616
663
 
617
- const form = useMemo(
618
- () =>
619
- ( {
620
- layout: {
621
- type: 'card',
622
- },
623
- fields: [
624
- {
625
- id: 'customerCard',
626
- label: 'Customer',
627
- children: [
628
- {
629
- id: 'customerContact',
630
- label: 'Contact',
631
- layout: { type: 'panel', labelPosition: 'top' },
632
- children: [
633
- {
634
- id: 'name',
635
- layout: {
636
- type: 'regular',
637
- labelPosition: 'top',
638
- },
664
+ const form: Form = useMemo(
665
+ () => ( {
666
+ layout: getLayoutFromStoryArgs( {
667
+ type: 'card',
668
+ withHeader,
669
+ } ),
670
+ fields: [
671
+ {
672
+ id: 'customerCard',
673
+ label: 'Customer',
674
+ children: [
675
+ {
676
+ id: 'customerContact',
677
+ label: 'Contact',
678
+ layout: { type: 'panel', labelPosition: 'top' },
679
+ children: [
680
+ {
681
+ id: 'name',
682
+ layout: {
683
+ type: 'regular',
684
+ labelPosition: 'top',
639
685
  },
640
- {
641
- id: 'phone',
642
- layout: {
643
- type: 'regular',
644
- labelPosition: 'top',
645
- },
686
+ },
687
+ {
688
+ id: 'phone',
689
+ layout: {
690
+ type: 'regular',
691
+ labelPosition: 'top',
646
692
  },
647
- {
648
- id: 'email',
649
- layout: {
650
- type: 'regular',
651
- labelPosition: 'top',
652
- },
693
+ },
694
+ {
695
+ id: 'email',
696
+ layout: {
697
+ type: 'regular',
698
+ labelPosition: 'top',
653
699
  },
654
- ],
655
- },
656
- {
657
- id: 'plan',
658
- layout: { type: 'panel', labelPosition: 'top' },
659
- },
660
- {
661
- id: 'shippingAddress',
662
- layout: { type: 'panel', labelPosition: 'top' },
663
- },
664
- {
665
- id: 'billingAddress',
666
- layout: { type: 'panel', labelPosition: 'top' },
667
- },
668
- 'displayPayments',
669
- ],
670
- },
671
- {
672
- id: 'payments',
673
- layout: { type: 'card', withHeader: false },
674
- },
675
- {
676
- id: 'taxConfiguration',
677
- label: 'Taxes',
678
- layout: {
679
- type: 'card',
680
- isOpened: false,
700
+ },
701
+ ],
702
+ },
703
+ {
704
+ id: 'plan',
705
+ layout: { type: 'panel', labelPosition: 'top' },
681
706
  },
682
- children: [ 'vat', 'commission' ],
707
+ {
708
+ id: 'shippingAddress',
709
+ layout: { type: 'panel', labelPosition: 'top' },
710
+ },
711
+ {
712
+ id: 'billingAddress',
713
+ layout: { type: 'panel', labelPosition: 'top' },
714
+ },
715
+ 'displayPayments',
716
+ ],
717
+ },
718
+ {
719
+ id: 'payments',
720
+ layout: {
721
+ type: 'card',
722
+ withHeader: false,
723
+ },
724
+ },
725
+ {
726
+ id: 'taxConfiguration',
727
+ label: 'Taxes',
728
+ layout: {
729
+ type: 'card',
730
+ isOpened: false,
683
731
  },
684
- ],
685
- } ) satisfies Form,
686
- []
732
+ children: [ 'vat', 'commission' ],
733
+ },
734
+ ],
735
+ } ),
736
+ [ withHeader ]
687
737
  );
688
738
 
689
739
  return (
@@ -701,11 +751,6 @@ const LayoutCardComponent = () => {
701
751
  );
702
752
  };
703
753
 
704
- export const LayoutCard = {
705
- title: 'DataForm/LayoutCard',
706
- render: LayoutCardComponent,
707
- };
708
-
709
754
  const LayoutMixedComponent = () => {
710
755
  const [ post, setPost ] = useState< SamplePost >( {
711
756
  title: 'Hello, World!',
@@ -719,28 +764,34 @@ const LayoutMixedComponent = () => {
719
764
  dimensions: '1920x1080',
720
765
  } );
721
766
 
722
- const form = useMemo(
723
- () =>
724
- ( {
725
- fields: [
726
- {
727
- id: 'title',
728
- layout: { type: 'panel', labelPosition: 'top' },
729
- },
730
- 'status',
731
- { id: 'order', layout: { type: 'card' } },
732
- {
733
- id: 'authorDateCard',
734
- label: 'Author & Date',
735
- layout: {
736
- type: 'card',
737
- },
738
- children: [ 'author', 'date' ],
739
- },
740
- ],
741
- } ) satisfies Form,
742
- []
743
- );
767
+ const form: Form = {
768
+ fields: [
769
+ {
770
+ id: 'title',
771
+ layout: {
772
+ type: 'panel',
773
+ labelPosition: 'top',
774
+ openAs: 'dropdown',
775
+ },
776
+ },
777
+ 'status',
778
+ {
779
+ id: 'order',
780
+ layout: {
781
+ type: 'card',
782
+ },
783
+ children: [ { id: 'order', layout: { type: 'panel' } } ],
784
+ },
785
+ {
786
+ id: 'authorDateCard',
787
+ label: 'Author & Date',
788
+ layout: {
789
+ type: 'card',
790
+ },
791
+ children: [ 'author', 'date' ],
792
+ },
793
+ ],
794
+ };
744
795
 
745
796
  return (
746
797
  <DataForm< SamplePost >
@@ -757,7 +808,91 @@ const LayoutMixedComponent = () => {
757
808
  );
758
809
  };
759
810
 
811
+ const meta = {
812
+ title: 'DataViews/DataForm',
813
+ component: DataForm,
814
+ };
815
+ export default meta;
816
+
817
+ export const Default = {
818
+ render: LayoutRegularComponent,
819
+ argTypes: {
820
+ type: {
821
+ control: { type: 'select' },
822
+ description: 'Chooses the layout type.',
823
+ options: [ 'default', 'card', 'panel', 'regular' ],
824
+ },
825
+ },
826
+ };
827
+
828
+ export const LayoutCard = {
829
+ render: LayoutCardComponent,
830
+ argTypes: {
831
+ withHeader: {
832
+ control: { type: 'boolean' },
833
+ description: 'Whether the card has a header.',
834
+ },
835
+ },
836
+ args: {
837
+ withHeader: true,
838
+ },
839
+ };
840
+
841
+ export const LayoutPanel = {
842
+ render: LayoutPanelComponent,
843
+ argTypes: {
844
+ labelPosition: {
845
+ control: { type: 'select' },
846
+ description: 'Chooses the label position.',
847
+ options: [ 'default', 'top', 'side', 'none' ],
848
+ },
849
+ openAs: {
850
+ control: { type: 'select' },
851
+ description: 'Chooses how to open the panel.',
852
+ options: [ 'default', 'dropdown', 'modal' ],
853
+ },
854
+ },
855
+ };
856
+
857
+ export const LayoutRegular = {
858
+ render: LayoutRegularComponent,
859
+ argTypes: {
860
+ labelPosition: {
861
+ control: { type: 'select' },
862
+ description: 'Chooses the label position.',
863
+ options: [ 'default', 'top', 'side', 'none' ],
864
+ },
865
+ },
866
+ };
867
+
760
868
  export const LayoutMixed = {
761
- title: 'DataForm/LayoutMixed',
762
869
  render: LayoutMixedComponent,
763
870
  };
871
+
872
+ export const Validation = {
873
+ render: ValidationComponent,
874
+ argTypes: {
875
+ required: {
876
+ control: { type: 'boolean' },
877
+ description: 'Whether or not the fields are required.',
878
+ },
879
+ type: {
880
+ control: { type: 'select' },
881
+ description: 'Chooses the validation type.',
882
+ options: [ 'regular', 'panel' ],
883
+ },
884
+ custom: {
885
+ control: { type: 'boolean' },
886
+ description: 'Whether or not the fields have custom validation.',
887
+ },
888
+ },
889
+ args: {
890
+ required: true,
891
+ type: 'regular',
892
+ custom: true,
893
+ },
894
+ };
895
+
896
+ export const Visibility = {
897
+ render: VisibilityComponent,
898
+ };