@wordpress/dataviews 6.0.0 → 7.0.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 (194) hide show
  1. package/CHANGELOG.md +25 -1
  2. package/README.md +42 -14
  3. package/build/components/dataviews/index.js +38 -6
  4. package/build/components/dataviews/index.js.map +1 -1
  5. package/build/components/dataviews-context/index.js +4 -1
  6. package/build/components/dataviews-context/index.js.map +1 -1
  7. package/build/components/dataviews-item-actions/index.js +1 -10
  8. package/build/components/dataviews-item-actions/index.js.map +1 -1
  9. package/build/components/dataviews-pagination/index.js +1 -1
  10. package/build/components/dataviews-pagination/index.js.map +1 -1
  11. package/build/components/dataviews-view-config/index.js +8 -5
  12. package/build/components/dataviews-view-config/index.js.map +1 -1
  13. package/build/components/dataviews-view-config/infinite-scroll-toggle.js +47 -0
  14. package/build/components/dataviews-view-config/infinite-scroll-toggle.js.map +1 -0
  15. package/build/dataform-controls/array.js +70 -0
  16. package/build/dataform-controls/array.js.map +1 -0
  17. package/build/dataform-controls/boolean.js +15 -7
  18. package/build/dataform-controls/boolean.js.map +1 -1
  19. package/build/dataform-controls/email.js +14 -7
  20. package/build/dataform-controls/email.js.map +1 -1
  21. package/build/dataform-controls/index.js +3 -1
  22. package/build/dataform-controls/index.js.map +1 -1
  23. package/build/dataform-controls/integer.js +14 -7
  24. package/build/dataform-controls/integer.js.map +1 -1
  25. package/build/dataform-controls/text.js +14 -7
  26. package/build/dataform-controls/text.js.map +1 -1
  27. package/build/dataforms-layouts/card/index.js +137 -0
  28. package/build/dataforms-layouts/card/index.js.map +1 -0
  29. package/build/dataforms-layouts/data-form-layout.js +2 -2
  30. package/build/dataforms-layouts/data-form-layout.js.map +1 -1
  31. package/build/dataforms-layouts/index.js +4 -0
  32. package/build/dataforms-layouts/index.js.map +1 -1
  33. package/build/dataforms-layouts/panel/dropdown.js +124 -0
  34. package/build/dataforms-layouts/panel/dropdown.js.map +1 -0
  35. package/build/dataforms-layouts/panel/index.js +34 -149
  36. package/build/dataforms-layouts/panel/index.js.map +1 -1
  37. package/build/dataforms-layouts/panel/modal.js +125 -0
  38. package/build/dataforms-layouts/panel/modal.js.map +1 -0
  39. package/build/dataforms-layouts/regular/index.js +10 -21
  40. package/build/dataforms-layouts/regular/index.js.map +1 -1
  41. package/build/dataviews-layouts/grid/index.js +24 -7
  42. package/build/dataviews-layouts/grid/index.js.map +1 -1
  43. package/build/dataviews-layouts/grid/preview-size-picker.js +11 -11
  44. package/build/dataviews-layouts/grid/preview-size-picker.js.map +1 -1
  45. package/build/dataviews-layouts/list/index.js +45 -27
  46. package/build/dataviews-layouts/list/index.js.map +1 -1
  47. package/build/dataviews-layouts/table/column-header-menu.js +3 -0
  48. package/build/dataviews-layouts/table/column-header-menu.js.map +1 -1
  49. package/build/dataviews-layouts/table/index.js +23 -8
  50. package/build/dataviews-layouts/table/index.js.map +1 -1
  51. package/build/field-types/array.js +2 -2
  52. package/build/field-types/array.js.map +1 -1
  53. package/build/normalize-form-fields.js +52 -13
  54. package/build/normalize-form-fields.js.map +1 -1
  55. package/build/types.js.map +1 -1
  56. package/build-module/components/dataviews/index.js +40 -8
  57. package/build-module/components/dataviews/index.js.map +1 -1
  58. package/build-module/components/dataviews-context/index.js +4 -1
  59. package/build-module/components/dataviews-context/index.js.map +1 -1
  60. package/build-module/components/dataviews-item-actions/index.js +1 -10
  61. package/build-module/components/dataviews-item-actions/index.js.map +1 -1
  62. package/build-module/components/dataviews-pagination/index.js +1 -1
  63. package/build-module/components/dataviews-pagination/index.js.map +1 -1
  64. package/build-module/components/dataviews-view-config/index.js +8 -5
  65. package/build-module/components/dataviews-view-config/index.js.map +1 -1
  66. package/build-module/components/dataviews-view-config/infinite-scroll-toggle.js +39 -0
  67. package/build-module/components/dataviews-view-config/infinite-scroll-toggle.js.map +1 -0
  68. package/build-module/dataform-controls/array.js +63 -0
  69. package/build-module/dataform-controls/array.js.map +1 -0
  70. package/build-module/dataform-controls/boolean.js +15 -7
  71. package/build-module/dataform-controls/boolean.js.map +1 -1
  72. package/build-module/dataform-controls/email.js +15 -8
  73. package/build-module/dataform-controls/email.js.map +1 -1
  74. package/build-module/dataform-controls/index.js +3 -1
  75. package/build-module/dataform-controls/index.js.map +1 -1
  76. package/build-module/dataform-controls/integer.js +15 -8
  77. package/build-module/dataform-controls/integer.js.map +1 -1
  78. package/build-module/dataform-controls/text.js +15 -8
  79. package/build-module/dataform-controls/text.js.map +1 -1
  80. package/build-module/dataforms-layouts/card/index.js +128 -0
  81. package/build-module/dataforms-layouts/card/index.js.map +1 -0
  82. package/build-module/dataforms-layouts/data-form-layout.js +2 -2
  83. package/build-module/dataforms-layouts/data-form-layout.js.map +1 -1
  84. package/build-module/dataforms-layouts/index.js +4 -0
  85. package/build-module/dataforms-layouts/index.js.map +1 -1
  86. package/build-module/dataforms-layouts/panel/dropdown.js +118 -0
  87. package/build-module/dataforms-layouts/panel/dropdown.js.map +1 -0
  88. package/build-module/dataforms-layouts/panel/index.js +37 -152
  89. package/build-module/dataforms-layouts/panel/index.js.map +1 -1
  90. package/build-module/dataforms-layouts/panel/modal.js +119 -0
  91. package/build-module/dataforms-layouts/panel/modal.js.map +1 -0
  92. package/build-module/dataforms-layouts/regular/index.js +10 -21
  93. package/build-module/dataforms-layouts/regular/index.js.map +1 -1
  94. package/build-module/dataviews-layouts/grid/index.js +25 -8
  95. package/build-module/dataviews-layouts/grid/index.js.map +1 -1
  96. package/build-module/dataviews-layouts/grid/preview-size-picker.js +11 -11
  97. package/build-module/dataviews-layouts/grid/preview-size-picker.js.map +1 -1
  98. package/build-module/dataviews-layouts/list/index.js +47 -29
  99. package/build-module/dataviews-layouts/list/index.js.map +1 -1
  100. package/build-module/dataviews-layouts/table/column-header-menu.js +3 -0
  101. package/build-module/dataviews-layouts/table/column-header-menu.js.map +1 -1
  102. package/build-module/dataviews-layouts/table/index.js +23 -8
  103. package/build-module/dataviews-layouts/table/index.js.map +1 -1
  104. package/build-module/field-types/array.js +2 -2
  105. package/build-module/field-types/array.js.map +1 -1
  106. package/build-module/normalize-form-fields.js +50 -13
  107. package/build-module/normalize-form-fields.js.map +1 -1
  108. package/build-module/types.js.map +1 -1
  109. package/build-style/style-rtl.css +53 -16
  110. package/build-style/style.css +53 -16
  111. package/build-types/components/dataform/stories/index.story.d.ts +41 -17
  112. package/build-types/components/dataform/stories/index.story.d.ts.map +1 -1
  113. package/build-types/components/dataviews/index.d.ts +5 -2
  114. package/build-types/components/dataviews/index.d.ts.map +1 -1
  115. package/build-types/components/dataviews/stories/fixtures.d.ts.map +1 -1
  116. package/build-types/components/dataviews/stories/index.story.d.ts +2 -1
  117. package/build-types/components/dataviews/stories/index.story.d.ts.map +1 -1
  118. package/build-types/components/dataviews-context/index.d.ts +4 -1
  119. package/build-types/components/dataviews-context/index.d.ts.map +1 -1
  120. package/build-types/components/dataviews-item-actions/index.d.ts.map +1 -1
  121. package/build-types/components/dataviews-view-config/index.d.ts.map +1 -1
  122. package/build-types/components/dataviews-view-config/infinite-scroll-toggle.d.ts +2 -0
  123. package/build-types/components/dataviews-view-config/infinite-scroll-toggle.d.ts.map +1 -0
  124. package/build-types/dataform-controls/array.d.ts +6 -0
  125. package/build-types/dataform-controls/array.d.ts.map +1 -0
  126. package/build-types/dataform-controls/boolean.d.ts.map +1 -1
  127. package/build-types/dataform-controls/email.d.ts.map +1 -1
  128. package/build-types/dataform-controls/index.d.ts.map +1 -1
  129. package/build-types/dataform-controls/integer.d.ts.map +1 -1
  130. package/build-types/dataform-controls/text.d.ts.map +1 -1
  131. package/build-types/dataforms-layouts/card/index.d.ts +13 -0
  132. package/build-types/dataforms-layouts/card/index.d.ts.map +1 -0
  133. package/build-types/dataforms-layouts/index.d.ts.map +1 -1
  134. package/build-types/dataforms-layouts/panel/dropdown.d.ts +14 -0
  135. package/build-types/dataforms-layouts/panel/dropdown.d.ts.map +1 -0
  136. package/build-types/dataforms-layouts/panel/index.d.ts.map +1 -1
  137. package/build-types/dataforms-layouts/panel/modal.d.ts +13 -0
  138. package/build-types/dataforms-layouts/panel/modal.d.ts.map +1 -0
  139. package/build-types/dataforms-layouts/regular/index.d.ts.map +1 -1
  140. package/build-types/dataviews-layouts/grid/index.d.ts.map +1 -1
  141. package/build-types/dataviews-layouts/grid/preview-size-picker.d.ts +1 -1
  142. package/build-types/dataviews-layouts/grid/preview-size-picker.d.ts.map +1 -1
  143. package/build-types/dataviews-layouts/list/index.d.ts.map +1 -1
  144. package/build-types/dataviews-layouts/table/column-header-menu.d.ts.map +1 -1
  145. package/build-types/dataviews-layouts/table/index.d.ts.map +1 -1
  146. package/build-types/field-types/boolean.d.ts +1 -1
  147. package/build-types/normalize-form-fields.d.ts +10 -3
  148. package/build-types/normalize-form-fields.d.ts.map +1 -1
  149. package/build-types/test/normalize-form-fields.d.ts +2 -0
  150. package/build-types/test/normalize-form-fields.d.ts.map +1 -0
  151. package/build-types/types.d.ts +54 -6
  152. package/build-types/types.d.ts.map +1 -1
  153. package/build-wp/index.js +3062 -1147
  154. package/package.json +15 -15
  155. package/src/components/dataform/stories/index.story.tsx +478 -91
  156. package/src/components/dataviews/index.tsx +50 -14
  157. package/src/components/dataviews/stories/fixtures.tsx +98 -7
  158. package/src/components/dataviews/stories/index.story.tsx +137 -4
  159. package/src/components/dataviews/style.scss +4 -0
  160. package/src/components/dataviews-context/index.ts +6 -2
  161. package/src/components/dataviews-item-actions/index.tsx +7 -16
  162. package/src/components/dataviews-pagination/index.tsx +1 -1
  163. package/src/components/dataviews-view-config/index.tsx +13 -5
  164. package/src/components/dataviews-view-config/infinite-scroll-toggle.tsx +39 -0
  165. package/src/dataform-controls/array.tsx +85 -0
  166. package/src/dataform-controls/boolean.tsx +24 -10
  167. package/src/dataform-controls/email.tsx +24 -11
  168. package/src/dataform-controls/index.tsx +3 -1
  169. package/src/dataform-controls/integer.tsx +27 -13
  170. package/src/dataform-controls/text.tsx +24 -11
  171. package/src/dataforms-layouts/card/index.tsx +154 -0
  172. package/src/dataforms-layouts/card/style.scss +3 -0
  173. package/src/dataforms-layouts/data-form-layout.tsx +2 -2
  174. package/src/dataforms-layouts/index.tsx +5 -0
  175. package/src/dataforms-layouts/panel/dropdown.tsx +160 -0
  176. package/src/dataforms-layouts/panel/index.tsx +49 -189
  177. package/src/dataforms-layouts/panel/modal.tsx +165 -0
  178. package/src/dataforms-layouts/panel/style.scss +4 -0
  179. package/src/dataforms-layouts/regular/index.tsx +20 -23
  180. package/src/dataviews-layouts/grid/index.tsx +32 -5
  181. package/src/dataviews-layouts/grid/preview-size-picker.tsx +15 -13
  182. package/src/dataviews-layouts/grid/style.scss +3 -1
  183. package/src/dataviews-layouts/list/index.tsx +65 -31
  184. package/src/dataviews-layouts/list/style.scss +7 -3
  185. package/src/dataviews-layouts/table/column-header-menu.tsx +4 -0
  186. package/src/dataviews-layouts/table/index.tsx +27 -1
  187. package/src/field-types/array.tsx +1 -1
  188. package/src/normalize-form-fields.ts +63 -17
  189. package/src/test/dataform.tsx +181 -3
  190. package/src/test/dataviews.tsx +38 -0
  191. package/src/test/filter-and-sort-data-view.js +123 -64
  192. package/src/test/normalize-form-fields.ts +247 -0
  193. package/src/types.ts +72 -6
  194. 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 );
@@ -29,47 +37,32 @@ type SamplePost = {
29
37
  password?: string;
30
38
  filesize?: number;
31
39
  dimensions?: string;
40
+ tags?: string[];
41
+ address1?: string;
42
+ address2?: string;
43
+ city?: string;
32
44
  };
33
45
 
34
- const meta = {
35
- title: 'DataViews/DataForm',
36
- component: DataForm,
37
- argTypes: {
38
- type: {
39
- control: { type: 'select' },
40
- description:
41
- 'Chooses the default layout of each field. "regular" is the default layout.',
42
- options: [ 'default', 'regular', 'panel' ],
43
- },
44
- labelPosition: {
45
- control: { type: 'select' },
46
- description: 'Chooses the label position of the layout.',
47
- options: [ 'default', 'top', 'side', 'none' ],
48
- },
49
- },
50
- };
51
- export default meta;
52
-
53
- const fields = [
46
+ const fields: Field< SamplePost >[] = [
54
47
  {
55
48
  id: 'title',
56
49
  label: 'Title',
57
- type: 'text' as const,
50
+ type: 'text',
58
51
  },
59
52
  {
60
53
  id: 'order',
61
54
  label: 'Order',
62
- type: 'integer' as const,
55
+ type: 'integer',
63
56
  },
64
57
  {
65
58
  id: 'date',
66
59
  label: 'Date',
67
- type: 'datetime' as const,
60
+ type: 'datetime',
68
61
  },
69
62
  {
70
63
  id: 'birthdate',
71
64
  label: 'Date as options',
72
- type: 'datetime' as const,
65
+ type: 'datetime',
73
66
  elements: [
74
67
  { value: '', label: 'Select a date' },
75
68
  { value: '1970-02-23T12:00:00', label: "Jane's birth date" },
@@ -79,28 +72,31 @@ const fields = [
79
72
  {
80
73
  id: 'author',
81
74
  label: 'Author',
82
- type: 'integer' as const,
75
+ type: 'integer',
83
76
  elements: [
84
77
  { value: 1, label: 'Jane' },
85
78
  { value: 2, label: 'John' },
79
+ { value: 3, label: 'Alice' },
80
+ { value: 4, label: 'Bob' },
86
81
  ],
87
82
  },
88
83
  {
89
84
  id: 'reviewer',
90
85
  label: 'Reviewer',
91
- type: 'text' as const,
92
- Edit: 'radio' as const,
86
+ type: 'text',
87
+ Edit: 'radio',
93
88
  elements: [
94
- { value: 'fulano', label: 'Fulano' },
95
- { value: 'mengano', label: 'Mengano' },
96
- { value: 'zutano', label: 'Zutano' },
89
+ { value: 'jane', label: 'Jane' },
90
+ { value: 'john', label: 'John' },
91
+ { value: 'alice', label: 'Alice' },
92
+ { value: 'bob', label: 'Bob' },
97
93
  ],
98
94
  },
99
95
  {
100
96
  id: 'status',
101
97
  label: 'Status',
102
- type: 'text' as const,
103
- Edit: 'toggleGroup' as const,
98
+ type: 'text',
99
+ Edit: 'toggleGroup',
104
100
  elements: [
105
101
  { value: 'draft', label: 'Draft' },
106
102
  { value: 'published', label: 'Published' },
@@ -110,12 +106,12 @@ const fields = [
110
106
  {
111
107
  id: 'email',
112
108
  label: 'Email',
113
- type: 'email' as const,
109
+ type: 'email',
114
110
  },
115
111
  {
116
112
  id: 'password',
117
113
  label: 'Password',
118
- type: 'text' as const,
114
+ type: 'text',
119
115
  isVisible: ( item: SamplePost ) => {
120
116
  return item.status !== 'private';
121
117
  },
@@ -128,28 +124,57 @@ const fields = [
128
124
  {
129
125
  id: 'can_comment',
130
126
  label: 'Allow people to leave a comment',
131
- type: 'boolean' as const,
127
+ type: 'boolean',
132
128
  Edit: 'checkbox',
133
129
  },
134
130
  {
135
131
  id: 'filesize',
136
132
  label: 'File Size',
137
- type: 'integer' as const,
133
+ type: 'integer',
138
134
  readOnly: true,
139
135
  },
140
136
  {
141
137
  id: 'dimensions',
142
138
  label: 'Dimensions',
143
- type: 'text' as const,
139
+ type: 'text',
144
140
  readOnly: true,
145
141
  },
146
- ] as Field< SamplePost >[];
142
+ {
143
+ id: 'tags',
144
+ label: 'Tags',
145
+ type: 'array',
146
+ placeholder: 'Enter comma-separated tags',
147
+ description: 'Add tags separated by commas (e.g., "tag1, tag2, tag3")',
148
+ elements: [
149
+ { value: 'astronomy', label: 'Astronomy' },
150
+ { value: 'book-review', label: 'Book review' },
151
+ { value: 'event', label: 'Event' },
152
+ { value: 'photography', label: 'Photography' },
153
+ { value: 'travel', label: 'Travel' },
154
+ ],
155
+ },
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
+ ];
147
172
 
148
- export const Default = ( {
149
- type,
173
+ const LayoutRegularComponent = ( {
174
+ type = 'default',
150
175
  labelPosition,
151
176
  }: {
152
- type: 'default' | 'regular' | 'panel';
177
+ type?: 'default' | 'regular' | 'panel' | 'card';
153
178
  labelPosition: 'default' | 'top' | 'side' | 'none';
154
179
  } ) => {
155
180
  const [ post, setPost ] = useState( {
@@ -165,12 +190,15 @@ export const Default = ( {
165
190
  can_comment: false,
166
191
  filesize: 1024,
167
192
  dimensions: '1920x1080',
193
+ tags: [ 'photography' ],
168
194
  } );
169
195
 
170
- const form = useMemo(
196
+ const form: Form = useMemo(
171
197
  () => ( {
172
- type,
173
- labelPosition,
198
+ layout: getLayoutFromStoryArgs( {
199
+ type,
200
+ labelPosition,
201
+ } ),
174
202
  fields: [
175
203
  'title',
176
204
  'order',
@@ -185,10 +213,11 @@ export const Default = ( {
185
213
  'can_comment',
186
214
  'filesize',
187
215
  'dimensions',
216
+ 'tags',
188
217
  ],
189
218
  } ),
190
219
  [ type, labelPosition ]
191
- ) as Form;
220
+ );
192
221
 
193
222
  return (
194
223
  <DataForm< SamplePost >
@@ -205,12 +234,59 @@ export const Default = ( {
205
234
  );
206
235
  };
207
236
 
208
- const CombinedFieldsComponent = ( {
237
+ const getLayoutFromStoryArgs = ( {
209
238
  type,
210
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,
211
286
  }: {
212
- type: 'default' | 'regular' | 'panel';
287
+ type: 'default' | 'regular' | 'panel' | 'card';
213
288
  labelPosition: 'default' | 'top' | 'side' | 'none';
289
+ openAs: 'default' | 'dropdown' | 'modal';
214
290
  } ) => {
215
291
  const [ post, setPost ] = useState< SamplePost >( {
216
292
  title: 'Hello, World!',
@@ -222,12 +298,19 @@ const CombinedFieldsComponent = ( {
222
298
  birthdate: '1950-02-23T12:00:00',
223
299
  filesize: 1024,
224
300
  dimensions: '1920x1080',
301
+ tags: [ 'photography' ],
302
+ address1: '123 Main St',
303
+ address2: 'Apt 4B',
304
+ city: 'New York',
225
305
  } );
226
306
 
227
- const form = useMemo(
228
- () => ( {
229
- type,
230
- labelPosition,
307
+ const form: Form = useMemo( () => {
308
+ return {
309
+ layout: getLayoutFromStoryArgs( {
310
+ type: 'panel',
311
+ labelPosition,
312
+ openAs,
313
+ } ),
231
314
  fields: [
232
315
  'title',
233
316
  {
@@ -239,10 +322,15 @@ const CombinedFieldsComponent = ( {
239
322
  'author',
240
323
  'filesize',
241
324
  'dimensions',
325
+ 'tags',
326
+ {
327
+ id: 'address1',
328
+ label: 'Combined Address',
329
+ children: [ 'address1', 'address2', 'city' ],
330
+ },
242
331
  ],
243
- } ),
244
- [ type, labelPosition ]
245
- ) as Form;
332
+ };
333
+ }, [ labelPosition, openAs ] );
246
334
 
247
335
  return (
248
336
  <DataForm< SamplePost >
@@ -259,17 +347,6 @@ const CombinedFieldsComponent = ( {
259
347
  );
260
348
  };
261
349
 
262
- export const CombinedFields = {
263
- title: 'DataViews/CombinedFields',
264
- render: CombinedFieldsComponent,
265
- argTypes: {
266
- ...meta.argTypes,
267
- },
268
- args: {
269
- type: 'panel',
270
- },
271
- };
272
-
273
350
  function CustomEditControl< Item >( {
274
351
  data,
275
352
  field,
@@ -302,7 +379,7 @@ function CustomEditControl< Item >( {
302
379
  );
303
380
  }
304
381
 
305
- const DataFormValidationComponent = ( { required }: { required: boolean } ) => {
382
+ const ValidationComponent = ( { required }: { required: boolean } ) => {
306
383
  type ValidatedItem = {
307
384
  text: string;
308
385
  email: string;
@@ -324,7 +401,7 @@ const DataFormValidationComponent = ( { required }: { required: boolean } ) => {
324
401
  const _fields: Field< ValidatedItem >[] = [
325
402
  {
326
403
  id: 'text',
327
- type: 'text' as const,
404
+ type: 'text',
328
405
  label: 'Text',
329
406
  isValid: {
330
407
  required,
@@ -332,7 +409,7 @@ const DataFormValidationComponent = ( { required }: { required: boolean } ) => {
332
409
  },
333
410
  {
334
411
  id: 'email',
335
- type: 'email' as const,
412
+ type: 'email',
336
413
  label: 'e-mail',
337
414
  isValid: {
338
415
  required,
@@ -340,7 +417,7 @@ const DataFormValidationComponent = ( { required }: { required: boolean } ) => {
340
417
  },
341
418
  {
342
419
  id: 'integer',
343
- type: 'integer' as const,
420
+ type: 'integer',
344
421
  label: 'Integer',
345
422
  isValid: {
346
423
  required,
@@ -348,7 +425,7 @@ const DataFormValidationComponent = ( { required }: { required: boolean } ) => {
348
425
  },
349
426
  {
350
427
  id: 'boolean',
351
- type: 'boolean' as const,
428
+ type: 'boolean',
352
429
  label: 'Boolean',
353
430
  isValid: {
354
431
  required,
@@ -423,21 +500,7 @@ const DataFormValidationComponent = ( { required }: { required: boolean } ) => {
423
500
  );
424
501
  };
425
502
 
426
- export const Validation = {
427
- title: 'DataForm/Validation',
428
- render: DataFormValidationComponent,
429
- argTypes: {
430
- required: {
431
- control: { type: 'boolean' },
432
- description: 'Whether or not the fields are required.',
433
- },
434
- },
435
- args: {
436
- required: true,
437
- },
438
- };
439
-
440
- const DataFormVisibilityComponent = () => {
503
+ const VisibilityComponent = () => {
441
504
  type Post = {
442
505
  name: string;
443
506
  email: string;
@@ -449,7 +512,7 @@ const DataFormVisibilityComponent = () => {
449
512
  isActive: true,
450
513
  } );
451
514
 
452
- const _fields = [
515
+ const _fields: Field< Post >[] = [
453
516
  { id: 'isActive', label: 'Is module active?', type: 'boolean' },
454
517
  {
455
518
  id: 'name',
@@ -463,8 +526,8 @@ const DataFormVisibilityComponent = () => {
463
526
  type: 'email',
464
527
  isVisible: ( post ) => post.isActive === true,
465
528
  },
466
- ] satisfies Field< Post >[];
467
- const form = {
529
+ ];
530
+ const form: Form = {
468
531
  fields: [ 'isActive', 'name', 'email' ],
469
532
  };
470
533
  return (
@@ -482,7 +545,331 @@ const DataFormVisibilityComponent = () => {
482
545
  );
483
546
  };
484
547
 
548
+ const LayoutCardComponent = ( { withHeader }: { withHeader: boolean } ) => {
549
+ type Customer = {
550
+ name: string;
551
+ email: string;
552
+ phone: string;
553
+ plan: string;
554
+ shippingAddress: string;
555
+ billingAddress: string;
556
+ displayPayments: boolean;
557
+ totalOrders: number;
558
+ totalRevenue: number;
559
+ averageOrderValue: number;
560
+ hasVat: boolean;
561
+ vat: number;
562
+ commission: number;
563
+ };
564
+
565
+ const customerFields: Field< Customer >[] = [
566
+ {
567
+ id: 'name',
568
+ label: 'Customer Name',
569
+ type: 'text',
570
+ },
571
+ {
572
+ id: 'phone',
573
+ label: 'Phone',
574
+ type: 'text',
575
+ },
576
+ {
577
+ id: 'email',
578
+ label: 'Email',
579
+ type: 'email',
580
+ },
581
+ {
582
+ id: 'plan',
583
+ label: 'Plan',
584
+ type: 'text',
585
+ Edit: 'toggleGroup',
586
+ elements: [
587
+ { value: 'basic', label: 'Basic' },
588
+ { value: 'business', label: 'Business' },
589
+ { value: 'vip', label: 'VIP' },
590
+ ],
591
+ },
592
+ {
593
+ id: 'shippingAddress',
594
+ label: 'Shipping Address',
595
+ type: 'text',
596
+ },
597
+ {
598
+ id: 'billingAddress',
599
+ label: 'Billing Address',
600
+ type: 'text',
601
+ },
602
+ {
603
+ id: 'displayPayments',
604
+ label: 'Display Payments?',
605
+ type: 'boolean',
606
+ },
607
+ {
608
+ id: 'payments',
609
+ label: 'Payments',
610
+ type: 'text',
611
+ readOnly: true, // Triggers using the render method instead of Edit.
612
+ isVisible: ( item ) => item.displayPayments,
613
+ render: ( { item } ) => {
614
+ return (
615
+ <p>
616
+ The customer has made a total of { item.totalOrders }{ ' ' }
617
+ orders, amounting to { item.totalRevenue } dollars. The
618
+ average order value is { item.averageOrderValue }{ ' ' }
619
+ dollars.
620
+ </p>
621
+ );
622
+ },
623
+ },
624
+ {
625
+ id: 'vat',
626
+ label: 'VAT',
627
+ type: 'integer',
628
+ },
629
+ {
630
+ id: 'commission',
631
+ label: 'Commission',
632
+ type: 'integer',
633
+ },
634
+ ];
635
+
636
+ const [ customer, setCustomer ] = useState< Customer >( {
637
+ name: 'Danyka Romaguera',
638
+ email: 'aromaguera@example.org',
639
+ phone: '1-828-352-1250',
640
+ plan: 'Business',
641
+ shippingAddress: 'N/A',
642
+ billingAddress: 'Danyka Romaguera, West Myrtiehaven, 80240-4282, BI',
643
+ displayPayments: true,
644
+ totalOrders: 2,
645
+ totalRevenue: 1430,
646
+ averageOrderValue: 715,
647
+ hasVat: true,
648
+ vat: 10,
649
+ commission: 5,
650
+ } );
651
+
652
+ const form: Form = useMemo(
653
+ () => ( {
654
+ layout: getLayoutFromStoryArgs( {
655
+ type: 'card',
656
+ withHeader,
657
+ } ),
658
+ fields: [
659
+ {
660
+ id: 'customerCard',
661
+ label: 'Customer',
662
+ children: [
663
+ {
664
+ id: 'customerContact',
665
+ label: 'Contact',
666
+ layout: { type: 'panel', labelPosition: 'top' },
667
+ children: [
668
+ {
669
+ id: 'name',
670
+ layout: {
671
+ type: 'regular',
672
+ labelPosition: 'top',
673
+ },
674
+ },
675
+ {
676
+ id: 'phone',
677
+ layout: {
678
+ type: 'regular',
679
+ labelPosition: 'top',
680
+ },
681
+ },
682
+ {
683
+ id: 'email',
684
+ layout: {
685
+ type: 'regular',
686
+ labelPosition: 'top',
687
+ },
688
+ },
689
+ ],
690
+ },
691
+ {
692
+ id: 'plan',
693
+ layout: { type: 'panel', labelPosition: 'top' },
694
+ },
695
+ {
696
+ id: 'shippingAddress',
697
+ layout: { type: 'panel', labelPosition: 'top' },
698
+ },
699
+ {
700
+ id: 'billingAddress',
701
+ layout: { type: 'panel', labelPosition: 'top' },
702
+ },
703
+ 'displayPayments',
704
+ ],
705
+ },
706
+ {
707
+ id: 'payments',
708
+ layout: {
709
+ type: 'card',
710
+ withHeader: false,
711
+ },
712
+ },
713
+ {
714
+ id: 'taxConfiguration',
715
+ label: 'Taxes',
716
+ layout: {
717
+ type: 'card',
718
+ isOpened: false,
719
+ },
720
+ children: [ 'vat', 'commission' ],
721
+ },
722
+ ],
723
+ } ),
724
+ [ withHeader ]
725
+ );
726
+
727
+ return (
728
+ <DataForm
729
+ data={ customer }
730
+ fields={ customerFields }
731
+ form={ form }
732
+ onChange={ ( edits ) =>
733
+ setCustomer( ( prev ) => ( {
734
+ ...prev,
735
+ ...edits,
736
+ } ) )
737
+ }
738
+ />
739
+ );
740
+ };
741
+
742
+ const LayoutMixedComponent = () => {
743
+ const [ post, setPost ] = useState< SamplePost >( {
744
+ title: 'Hello, World!',
745
+ order: 2,
746
+ author: 1,
747
+ status: 'draft',
748
+ reviewer: 'fulano',
749
+ date: '2021-01-01T12:00:00',
750
+ birthdate: '1950-02-23T12:00:00',
751
+ filesize: 1024,
752
+ dimensions: '1920x1080',
753
+ } );
754
+
755
+ const form: Form = {
756
+ fields: [
757
+ {
758
+ id: 'title',
759
+ layout: {
760
+ type: 'panel',
761
+ labelPosition: 'top',
762
+ openAs: 'dropdown',
763
+ },
764
+ },
765
+ 'status',
766
+ {
767
+ id: 'order',
768
+ layout: {
769
+ type: 'card',
770
+ },
771
+ children: [ { id: 'order', layout: { type: 'panel' } } ],
772
+ },
773
+ {
774
+ id: 'authorDateCard',
775
+ label: 'Author & Date',
776
+ layout: {
777
+ type: 'card',
778
+ },
779
+ children: [ 'author', 'date' ],
780
+ },
781
+ ],
782
+ };
783
+
784
+ return (
785
+ <DataForm< SamplePost >
786
+ data={ post }
787
+ fields={ fields }
788
+ form={ form }
789
+ onChange={ ( edits ) =>
790
+ setPost( ( prev ) => ( {
791
+ ...prev,
792
+ ...edits,
793
+ } ) )
794
+ }
795
+ />
796
+ );
797
+ };
798
+
799
+ const meta = {
800
+ title: 'DataViews/DataForm',
801
+ component: DataForm,
802
+ };
803
+ export default meta;
804
+
805
+ export const Default = {
806
+ render: LayoutRegularComponent,
807
+ argTypes: {
808
+ type: {
809
+ control: { type: 'select' },
810
+ description: 'Chooses the layout type.',
811
+ options: [ 'default', 'card', 'panel', 'regular' ],
812
+ },
813
+ },
814
+ };
815
+
816
+ export const LayoutCard = {
817
+ render: LayoutCardComponent,
818
+ argTypes: {
819
+ withHeader: {
820
+ control: { type: 'boolean' },
821
+ description: 'Whether the card has a header.',
822
+ },
823
+ },
824
+ args: {
825
+ withHeader: true,
826
+ },
827
+ };
828
+
829
+ export const LayoutPanel = {
830
+ render: LayoutPanelComponent,
831
+ argTypes: {
832
+ labelPosition: {
833
+ control: { type: 'select' },
834
+ description: 'Chooses the label position.',
835
+ options: [ 'default', 'top', 'side', 'none' ],
836
+ },
837
+ openAs: {
838
+ control: { type: 'select' },
839
+ description: 'Chooses how to open the panel.',
840
+ options: [ 'default', 'dropdown', 'modal' ],
841
+ },
842
+ },
843
+ };
844
+
845
+ export const LayoutRegular = {
846
+ render: LayoutRegularComponent,
847
+ argTypes: {
848
+ labelPosition: {
849
+ control: { type: 'select' },
850
+ description: 'Chooses the label position.',
851
+ options: [ 'default', 'top', 'side', 'none' ],
852
+ },
853
+ },
854
+ };
855
+
856
+ export const LayoutMixed = {
857
+ render: LayoutMixedComponent,
858
+ };
859
+
860
+ export const Validation = {
861
+ render: ValidationComponent,
862
+ argTypes: {
863
+ required: {
864
+ control: { type: 'boolean' },
865
+ description: 'Whether or not the fields are required.',
866
+ },
867
+ },
868
+ args: {
869
+ required: true,
870
+ },
871
+ };
872
+
485
873
  export const Visibility = {
486
- title: 'DataForm/Visibility',
487
- render: DataFormVisibilityComponent,
874
+ render: VisibilityComponent,
488
875
  };