@wordpress/dataviews 4.0.0 → 4.2.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 (285) hide show
  1. package/CHANGELOG.md +33 -5
  2. package/README.md +31 -23
  3. package/build/components/dataform/index.js +10 -61
  4. package/build/components/dataform/index.js.map +1 -1
  5. package/build/components/dataviews/index.js +23 -14
  6. package/build/components/dataviews/index.js.map +1 -1
  7. package/build/components/dataviews-bulk-actions/index.js +3 -0
  8. package/build/components/dataviews-bulk-actions/index.js.map +1 -1
  9. package/build/components/dataviews-filters/add-filter.js +34 -17
  10. package/build/components/dataviews-filters/add-filter.js.map +1 -1
  11. package/build/components/dataviews-filters/index.js +109 -43
  12. package/build/components/dataviews-filters/index.js.map +1 -1
  13. package/build/components/dataviews-filters/search-widget.js +2 -5
  14. package/build/components/dataviews-filters/search-widget.js.map +1 -1
  15. package/build/components/dataviews-layout/index.js +2 -2
  16. package/build/components/dataviews-layout/index.js.map +1 -1
  17. package/build/components/dataviews-pagination/index.js +23 -15
  18. package/build/components/dataviews-pagination/index.js.map +1 -1
  19. package/build/components/dataviews-search/index.js +8 -5
  20. package/build/components/dataviews-search/index.js.map +1 -1
  21. package/build/components/dataviews-view-config/index.js +240 -188
  22. package/build/components/dataviews-view-config/index.js.map +1 -1
  23. package/build/constants.js +6 -1
  24. package/build/constants.js.map +1 -1
  25. package/build/dataform-controls/datetime.js +49 -0
  26. package/build/dataform-controls/datetime.js.map +1 -0
  27. package/build/dataform-controls/index.js +50 -0
  28. package/build/dataform-controls/index.js.map +1 -0
  29. package/build/dataform-controls/integer.js +45 -0
  30. package/build/dataform-controls/integer.js.map +1 -0
  31. package/build/dataform-controls/radio.js +45 -0
  32. package/build/dataform-controls/radio.js.map +1 -0
  33. package/build/dataform-controls/select.js +58 -0
  34. package/build/dataform-controls/select.js.map +1 -0
  35. package/build/dataform-controls/text.js +45 -0
  36. package/build/dataform-controls/text.js.map +1 -0
  37. package/build/dataforms-layouts/index.js +24 -0
  38. package/build/dataforms-layouts/index.js.map +1 -0
  39. package/build/dataforms-layouts/panel/index.js +132 -0
  40. package/build/dataforms-layouts/panel/index.js.map +1 -0
  41. package/build/dataforms-layouts/regular/index.js +42 -0
  42. package/build/dataforms-layouts/regular/index.js.map +1 -0
  43. package/build/dataviews-layouts/grid/density-picker.js +114 -0
  44. package/build/dataviews-layouts/grid/density-picker.js.map +1 -0
  45. package/build/{layouts → dataviews-layouts}/grid/index.js +9 -9
  46. package/build/dataviews-layouts/grid/index.js.map +1 -0
  47. package/build/dataviews-layouts/index.js.map +1 -0
  48. package/build/{layouts → dataviews-layouts}/list/index.js +6 -2
  49. package/build/dataviews-layouts/list/index.js.map +1 -0
  50. package/build/{layouts → dataviews-layouts}/table/column-header-menu.js +3 -6
  51. package/build/dataviews-layouts/table/column-header-menu.js.map +1 -0
  52. package/build/dataviews-layouts/table/index.js.map +1 -0
  53. package/build/field-types/datetime.js +30 -0
  54. package/build/field-types/datetime.js.map +1 -0
  55. package/build/field-types/index.js +50 -0
  56. package/build/field-types/index.js.map +1 -0
  57. package/build/field-types/integer.js +35 -0
  58. package/build/field-types/integer.js.map +1 -0
  59. package/build/field-types/text.js +28 -0
  60. package/build/field-types/text.js.map +1 -0
  61. package/build/filter-and-sort-data-view.js +2 -11
  62. package/build/filter-and-sort-data-view.js.map +1 -1
  63. package/build/index.js +9 -2
  64. package/build/index.js.map +1 -1
  65. package/build/normalize-fields.js +34 -1
  66. package/build/normalize-fields.js.map +1 -1
  67. package/build/types.js.map +1 -1
  68. package/build/validation.js +22 -0
  69. package/build/validation.js.map +1 -0
  70. package/build-module/components/dataform/index.js +10 -61
  71. package/build-module/components/dataform/index.js.map +1 -1
  72. package/build-module/components/dataviews/index.js +21 -14
  73. package/build-module/components/dataviews/index.js.map +1 -1
  74. package/build-module/components/dataviews-bulk-actions/index.js +3 -0
  75. package/build-module/components/dataviews-bulk-actions/index.js.map +1 -1
  76. package/build-module/components/dataviews-filters/add-filter.js +33 -17
  77. package/build-module/components/dataviews-filters/add-filter.js.map +1 -1
  78. package/build-module/components/dataviews-filters/index.js +108 -45
  79. package/build-module/components/dataviews-filters/index.js.map +1 -1
  80. package/build-module/components/dataviews-filters/search-widget.js +2 -5
  81. package/build-module/components/dataviews-filters/search-widget.js.map +1 -1
  82. package/build-module/components/dataviews-layout/index.js +1 -1
  83. package/build-module/components/dataviews-layout/index.js.map +1 -1
  84. package/build-module/components/dataviews-pagination/index.js +23 -15
  85. package/build-module/components/dataviews-pagination/index.js.map +1 -1
  86. package/build-module/components/dataviews-search/index.js +8 -5
  87. package/build-module/components/dataviews-search/index.js.map +1 -1
  88. package/build-module/components/dataviews-view-config/index.js +243 -191
  89. package/build-module/components/dataviews-view-config/index.js.map +1 -1
  90. package/build-module/constants.js +5 -0
  91. package/build-module/constants.js.map +1 -1
  92. package/build-module/dataform-controls/datetime.js +43 -0
  93. package/build-module/dataform-controls/datetime.js.map +1 -0
  94. package/build-module/dataform-controls/index.js +42 -0
  95. package/build-module/dataform-controls/index.js.map +1 -0
  96. package/build-module/dataform-controls/integer.js +38 -0
  97. package/build-module/dataform-controls/integer.js.map +1 -0
  98. package/build-module/dataform-controls/radio.js +38 -0
  99. package/build-module/dataform-controls/radio.js.map +1 -0
  100. package/build-module/dataform-controls/select.js +51 -0
  101. package/build-module/dataform-controls/select.js.map +1 -0
  102. package/build-module/dataform-controls/text.js +38 -0
  103. package/build-module/dataform-controls/text.js.map +1 -0
  104. package/build-module/dataforms-layouts/index.js +16 -0
  105. package/build-module/dataforms-layouts/index.js.map +1 -0
  106. package/build-module/dataforms-layouts/panel/index.js +127 -0
  107. package/build-module/dataforms-layouts/panel/index.js.map +1 -0
  108. package/build-module/dataforms-layouts/regular/index.js +35 -0
  109. package/build-module/dataforms-layouts/regular/index.js.map +1 -0
  110. package/build-module/dataviews-layouts/grid/density-picker.js +107 -0
  111. package/build-module/dataviews-layouts/grid/density-picker.js.map +1 -0
  112. package/build-module/{layouts → dataviews-layouts}/grid/index.js +9 -9
  113. package/build-module/dataviews-layouts/grid/index.js.map +1 -0
  114. package/build-module/dataviews-layouts/index.js.map +1 -0
  115. package/build-module/{layouts → dataviews-layouts}/list/index.js +5 -2
  116. package/build-module/dataviews-layouts/list/index.js.map +1 -0
  117. package/build-module/{layouts → dataviews-layouts}/table/column-header-menu.js +3 -6
  118. package/build-module/dataviews-layouts/table/column-header-menu.js.map +1 -0
  119. package/build-module/dataviews-layouts/table/index.js.map +1 -0
  120. package/build-module/field-types/datetime.js +24 -0
  121. package/build-module/field-types/datetime.js.map +1 -0
  122. package/build-module/field-types/index.js +44 -0
  123. package/build-module/field-types/index.js.map +1 -0
  124. package/build-module/field-types/integer.js +29 -0
  125. package/build-module/field-types/integer.js.map +1 -0
  126. package/build-module/field-types/text.js +22 -0
  127. package/build-module/field-types/text.js.map +1 -0
  128. package/build-module/filter-and-sort-data-view.js +2 -11
  129. package/build-module/filter-and-sort-data-view.js.map +1 -1
  130. package/build-module/index.js +2 -1
  131. package/build-module/index.js.map +1 -1
  132. package/build-module/normalize-fields.js +33 -1
  133. package/build-module/normalize-fields.js.map +1 -1
  134. package/build-module/types.js.map +1 -1
  135. package/build-module/validation.js +15 -0
  136. package/build-module/validation.js.map +1 -0
  137. package/build-style/style-rtl.css +186 -20
  138. package/build-style/style.css +186 -20
  139. package/build-types/components/dataform/index.d.ts +2 -13
  140. package/build-types/components/dataform/index.d.ts.map +1 -1
  141. package/build-types/components/dataform/stories/index.story.d.ts +12 -1
  142. package/build-types/components/dataform/stories/index.story.d.ts.map +1 -1
  143. package/build-types/components/dataviews/index.d.ts.map +1 -1
  144. package/build-types/components/dataviews/stories/fixtures.d.ts +25 -0
  145. package/build-types/components/dataviews/stories/fixtures.d.ts.map +1 -1
  146. package/build-types/components/dataviews/stories/index.story.d.ts +9 -0
  147. package/build-types/components/dataviews/stories/index.story.d.ts.map +1 -1
  148. package/build-types/components/dataviews-bulk-actions/index.d.ts.map +1 -1
  149. package/build-types/components/dataviews-filters/add-filter.d.ts +3 -0
  150. package/build-types/components/dataviews-filters/add-filter.d.ts.map +1 -1
  151. package/build-types/components/dataviews-filters/index.d.ts +11 -1
  152. package/build-types/components/dataviews-filters/index.d.ts.map +1 -1
  153. package/build-types/components/dataviews-filters/search-widget.d.ts.map +1 -1
  154. package/build-types/components/dataviews-pagination/index.d.ts.map +1 -1
  155. package/build-types/components/dataviews-search/index.d.ts.map +1 -1
  156. package/build-types/components/dataviews-view-config/index.d.ts +4 -3
  157. package/build-types/components/dataviews-view-config/index.d.ts.map +1 -1
  158. package/build-types/constants.d.ts +4 -0
  159. package/build-types/constants.d.ts.map +1 -1
  160. package/build-types/dataform-controls/datetime.d.ts +6 -0
  161. package/build-types/dataform-controls/datetime.d.ts.map +1 -0
  162. package/build-types/dataform-controls/index.d.ts +11 -0
  163. package/build-types/dataform-controls/index.d.ts.map +1 -0
  164. package/build-types/dataform-controls/integer.d.ts +6 -0
  165. package/build-types/dataform-controls/integer.d.ts.map +1 -0
  166. package/build-types/dataform-controls/radio.d.ts +6 -0
  167. package/build-types/dataform-controls/radio.d.ts.map +1 -0
  168. package/build-types/dataform-controls/select.d.ts +6 -0
  169. package/build-types/dataform-controls/select.d.ts.map +1 -0
  170. package/build-types/dataform-controls/text.d.ts +6 -0
  171. package/build-types/dataform-controls/text.d.ts.map +1 -0
  172. package/build-types/dataforms-layouts/index.d.ts +9 -0
  173. package/build-types/dataforms-layouts/index.d.ts.map +1 -0
  174. package/build-types/dataforms-layouts/panel/index.d.ts +3 -0
  175. package/build-types/dataforms-layouts/panel/index.d.ts.map +1 -0
  176. package/build-types/dataforms-layouts/regular/index.d.ts +3 -0
  177. package/build-types/dataforms-layouts/regular/index.d.ts.map +1 -0
  178. package/build-types/dataviews-layouts/grid/density-picker.d.ts.map +1 -0
  179. package/build-types/dataviews-layouts/grid/index.d.ts.map +1 -0
  180. package/build-types/dataviews-layouts/index.d.ts.map +1 -0
  181. package/build-types/dataviews-layouts/list/index.d.ts.map +1 -0
  182. package/build-types/dataviews-layouts/table/column-header-menu.d.ts.map +1 -0
  183. package/build-types/dataviews-layouts/table/index.d.ts.map +1 -0
  184. package/build-types/field-types/datetime.d.ts +13 -0
  185. package/build-types/field-types/datetime.d.ts.map +1 -0
  186. package/build-types/field-types/index.d.ts +20 -0
  187. package/build-types/field-types/index.d.ts.map +1 -0
  188. package/build-types/field-types/integer.d.ts +13 -0
  189. package/build-types/field-types/integer.d.ts.map +1 -0
  190. package/build-types/field-types/text.d.ts +13 -0
  191. package/build-types/field-types/text.d.ts.map +1 -0
  192. package/build-types/filter-and-sort-data-view.d.ts.map +1 -1
  193. package/build-types/index.d.ts +2 -1
  194. package/build-types/index.d.ts.map +1 -1
  195. package/build-types/normalize-fields.d.ts +0 -3
  196. package/build-types/normalize-fields.d.ts.map +1 -1
  197. package/build-types/types.d.ts +73 -18
  198. package/build-types/types.d.ts.map +1 -1
  199. package/build-types/validation.d.ts +3 -0
  200. package/build-types/validation.d.ts.map +1 -0
  201. package/package.json +12 -11
  202. package/src/components/dataform/index.tsx +8 -97
  203. package/src/components/dataform/stories/index.story.tsx +82 -4
  204. package/src/components/dataviews/index.tsx +26 -14
  205. package/src/components/dataviews/stories/fixtures.js +30 -1
  206. package/src/components/dataviews/stories/index.story.js +7 -1
  207. package/src/components/dataviews/style.scss +5 -14
  208. package/src/components/dataviews-bulk-actions/index.tsx +5 -0
  209. package/src/components/dataviews-bulk-actions-toolbar/style.scss +1 -1
  210. package/src/components/dataviews-filters/add-filter.tsx +37 -21
  211. package/src/components/dataviews-filters/index.tsx +152 -61
  212. package/src/components/dataviews-filters/search-widget.tsx +1 -8
  213. package/src/components/dataviews-filters/style.scss +31 -1
  214. package/src/components/dataviews-layout/index.tsx +1 -1
  215. package/src/components/dataviews-pagination/index.tsx +35 -16
  216. package/src/components/dataviews-pagination/style.scss +9 -4
  217. package/src/components/dataviews-search/index.tsx +8 -5
  218. package/src/components/dataviews-view-config/index.tsx +300 -257
  219. package/src/components/dataviews-view-config/style.scss +44 -0
  220. package/src/constants.ts +5 -0
  221. package/src/dataform-controls/datetime.tsx +43 -0
  222. package/src/dataform-controls/index.tsx +61 -0
  223. package/src/dataform-controls/integer.tsx +38 -0
  224. package/src/dataform-controls/radio.tsx +42 -0
  225. package/src/dataform-controls/select.tsx +52 -0
  226. package/src/dataform-controls/style.scss +4 -0
  227. package/src/dataform-controls/text.tsx +40 -0
  228. package/src/dataforms-layouts/index.tsx +20 -0
  229. package/src/dataforms-layouts/panel/index.tsx +168 -0
  230. package/src/dataforms-layouts/panel/style.scss +59 -0
  231. package/src/dataforms-layouts/regular/index.tsx +45 -0
  232. package/src/dataviews-layouts/grid/density-picker.tsx +102 -0
  233. package/src/{layouts → dataviews-layouts}/grid/index.tsx +9 -9
  234. package/src/{layouts → dataviews-layouts}/grid/style.scss +29 -4
  235. package/src/{layouts → dataviews-layouts}/list/index.tsx +6 -2
  236. package/src/{layouts → dataviews-layouts}/list/style.scss +4 -1
  237. package/src/{layouts → dataviews-layouts}/table/column-header-menu.tsx +4 -6
  238. package/src/field-types/datetime.tsx +28 -0
  239. package/src/field-types/index.tsx +50 -0
  240. package/src/field-types/integer.tsx +34 -0
  241. package/src/field-types/text.tsx +27 -0
  242. package/src/filter-and-sort-data-view.ts +1 -15
  243. package/src/index.ts +2 -1
  244. package/src/normalize-fields.ts +43 -4
  245. package/src/style.scss +7 -3
  246. package/src/test/filter-and-sort-data-view.js +74 -3
  247. package/src/test/validation.ts +131 -0
  248. package/src/types.ts +92 -23
  249. package/src/validation.ts +18 -0
  250. package/tsconfig.json +2 -1
  251. package/tsconfig.tsbuildinfo +1 -1
  252. package/build/layouts/grid/density-picker.js +0 -143
  253. package/build/layouts/grid/density-picker.js.map +0 -1
  254. package/build/layouts/grid/index.js.map +0 -1
  255. package/build/layouts/index.js.map +0 -1
  256. package/build/layouts/list/index.js.map +0 -1
  257. package/build/layouts/table/column-header-menu.js.map +0 -1
  258. package/build/layouts/table/index.js.map +0 -1
  259. package/build-module/layouts/grid/density-picker.js +0 -138
  260. package/build-module/layouts/grid/density-picker.js.map +0 -1
  261. package/build-module/layouts/grid/index.js.map +0 -1
  262. package/build-module/layouts/index.js.map +0 -1
  263. package/build-module/layouts/list/index.js.map +0 -1
  264. package/build-module/layouts/table/column-header-menu.js.map +0 -1
  265. package/build-module/layouts/table/index.js.map +0 -1
  266. package/build-types/layouts/grid/density-picker.d.ts.map +0 -1
  267. package/build-types/layouts/grid/index.d.ts.map +0 -1
  268. package/build-types/layouts/index.d.ts.map +0 -1
  269. package/build-types/layouts/list/index.d.ts.map +0 -1
  270. package/build-types/layouts/table/column-header-menu.d.ts.map +0 -1
  271. package/build-types/layouts/table/index.d.ts.map +0 -1
  272. package/src/layouts/grid/density-picker.tsx +0 -136
  273. /package/build/{layouts → dataviews-layouts}/index.js +0 -0
  274. /package/build/{layouts → dataviews-layouts}/table/index.js +0 -0
  275. /package/build-module/{layouts → dataviews-layouts}/index.js +0 -0
  276. /package/build-module/{layouts → dataviews-layouts}/table/index.js +0 -0
  277. /package/build-types/{layouts → dataviews-layouts}/grid/density-picker.d.ts +0 -0
  278. /package/build-types/{layouts → dataviews-layouts}/grid/index.d.ts +0 -0
  279. /package/build-types/{layouts → dataviews-layouts}/index.d.ts +0 -0
  280. /package/build-types/{layouts → dataviews-layouts}/list/index.d.ts +0 -0
  281. /package/build-types/{layouts → dataviews-layouts}/table/column-header-menu.d.ts +0 -0
  282. /package/build-types/{layouts → dataviews-layouts}/table/index.d.ts +0 -0
  283. /package/src/{layouts → dataviews-layouts}/index.ts +0 -0
  284. /package/src/{layouts → dataviews-layouts}/table/index.tsx +0 -0
  285. /package/src/{layouts → dataviews-layouts}/table/style.scss +0 -0
@@ -0,0 +1,43 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { BaseControl, TimePicker, VisuallyHidden } from '@wordpress/components';
5
+ import { useCallback } from '@wordpress/element';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import type { DataFormControlProps } from '../types';
11
+
12
+ export default function DateTime< Item >( {
13
+ data,
14
+ field,
15
+ onChange,
16
+ hideLabelFromVision,
17
+ }: DataFormControlProps< Item > ) {
18
+ const { id, label } = field;
19
+ const value = field.getValue( { item: data } );
20
+
21
+ const onChangeControl = useCallback(
22
+ ( newValue: string | null ) => onChange( { [ id ]: newValue } ),
23
+ [ id, onChange ]
24
+ );
25
+
26
+ return (
27
+ <fieldset className="dataviews-controls__datetime">
28
+ { ! hideLabelFromVision && (
29
+ <BaseControl.VisualLabel as="legend">
30
+ { label }
31
+ </BaseControl.VisualLabel>
32
+ ) }
33
+ { hideLabelFromVision && (
34
+ <VisuallyHidden as="legend">{ label }</VisuallyHidden>
35
+ ) }
36
+ <TimePicker
37
+ currentTime={ value }
38
+ onChange={ onChangeControl }
39
+ hideLabelFromVision
40
+ />
41
+ </fieldset>
42
+ );
43
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ComponentType } from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import type {
10
+ DataFormControlProps,
11
+ Field,
12
+ FieldTypeDefinition,
13
+ } from '../types';
14
+ import datetime from './datetime';
15
+ import integer from './integer';
16
+ import radio from './radio';
17
+ import select from './select';
18
+ import text from './text';
19
+
20
+ interface FormControls {
21
+ [ key: string ]: ComponentType< DataFormControlProps< any > >;
22
+ }
23
+
24
+ const FORM_CONTROLS: FormControls = {
25
+ datetime,
26
+ integer,
27
+ radio,
28
+ select,
29
+ text,
30
+ };
31
+
32
+ export function getControl< Item >(
33
+ field: Field< Item >,
34
+ fieldTypeDefinition: FieldTypeDefinition< Item >
35
+ ) {
36
+ if ( typeof field.Edit === 'function' ) {
37
+ return field.Edit;
38
+ }
39
+
40
+ if ( typeof field.Edit === 'string' ) {
41
+ return getControlByType( field.Edit );
42
+ }
43
+
44
+ if ( field.elements ) {
45
+ return getControlByType( 'select' );
46
+ }
47
+
48
+ if ( typeof fieldTypeDefinition.Edit === 'string' ) {
49
+ return getControlByType( fieldTypeDefinition.Edit );
50
+ }
51
+
52
+ return fieldTypeDefinition.Edit;
53
+ }
54
+
55
+ export function getControlByType( type: string ) {
56
+ if ( Object.keys( FORM_CONTROLS ).includes( type ) ) {
57
+ return FORM_CONTROLS[ type ];
58
+ }
59
+
60
+ throw 'Control ' + type + ' not found';
61
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __experimentalNumberControl as NumberControl } from '@wordpress/components';
5
+ import { useCallback } from '@wordpress/element';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import type { DataFormControlProps } from '../types';
11
+
12
+ export default function Integer< Item >( {
13
+ data,
14
+ field,
15
+ onChange,
16
+ hideLabelFromVision,
17
+ }: DataFormControlProps< Item > ) {
18
+ const { id, label, description } = field;
19
+ const value = field.getValue( { item: data } ) ?? '';
20
+ const onChangeControl = useCallback(
21
+ ( newValue: string | undefined ) =>
22
+ onChange( {
23
+ [ id ]: Number( newValue ),
24
+ } ),
25
+ [ id, onChange ]
26
+ );
27
+
28
+ return (
29
+ <NumberControl
30
+ label={ label }
31
+ help={ description }
32
+ value={ value }
33
+ onChange={ onChangeControl }
34
+ __next40pxDefaultSize
35
+ hideLabelFromVision={ hideLabelFromVision }
36
+ />
37
+ );
38
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { RadioControl } from '@wordpress/components';
5
+ import { useCallback } from '@wordpress/element';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import type { DataFormControlProps } from '../types';
11
+
12
+ export default function Radio< Item >( {
13
+ data,
14
+ field,
15
+ onChange,
16
+ hideLabelFromVision,
17
+ }: DataFormControlProps< Item > ) {
18
+ const { id, label } = field;
19
+ const value = field.getValue( { item: data } );
20
+
21
+ const onChangeControl = useCallback(
22
+ ( newValue: string ) =>
23
+ onChange( {
24
+ [ id ]: newValue,
25
+ } ),
26
+ [ id, onChange ]
27
+ );
28
+
29
+ if ( field.elements ) {
30
+ return (
31
+ <RadioControl
32
+ label={ label }
33
+ onChange={ onChangeControl }
34
+ options={ field.elements }
35
+ selected={ value }
36
+ hideLabelFromVision={ hideLabelFromVision }
37
+ />
38
+ );
39
+ }
40
+
41
+ return null;
42
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { SelectControl } from '@wordpress/components';
5
+ import { useCallback } from '@wordpress/element';
6
+ import { __ } from '@wordpress/i18n';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import type { DataFormControlProps } from '../types';
12
+
13
+ export default function Select< Item >( {
14
+ data,
15
+ field,
16
+ onChange,
17
+ hideLabelFromVision,
18
+ }: DataFormControlProps< Item > ) {
19
+ const { id, label } = field;
20
+ const value = field.getValue( { item: data } ) ?? '';
21
+ const onChangeControl = useCallback(
22
+ ( newValue: any ) =>
23
+ onChange( {
24
+ [ id ]: newValue,
25
+ } ),
26
+ [ id, onChange ]
27
+ );
28
+
29
+ const elements = [
30
+ /*
31
+ * Value can be undefined when:
32
+ *
33
+ * - the field is not required
34
+ * - in bulk editing
35
+ *
36
+ */
37
+ { label: __( 'Select item' ), value: '' },
38
+ ...( field?.elements ?? [] ),
39
+ ];
40
+
41
+ return (
42
+ <SelectControl
43
+ label={ label }
44
+ value={ value }
45
+ options={ elements }
46
+ onChange={ onChangeControl }
47
+ __next40pxDefaultSize
48
+ __nextHasNoMarginBottom
49
+ hideLabelFromVision={ hideLabelFromVision }
50
+ />
51
+ );
52
+ }
@@ -0,0 +1,4 @@
1
+ .dataviews-controls__datetime {
2
+ border: none;
3
+ padding: 0;
4
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { TextControl } from '@wordpress/components';
5
+ import { useCallback } from '@wordpress/element';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import type { DataFormControlProps } from '../types';
11
+
12
+ export default function Text< Item >( {
13
+ data,
14
+ field,
15
+ onChange,
16
+ hideLabelFromVision,
17
+ }: DataFormControlProps< Item > ) {
18
+ const { id, label, placeholder } = field;
19
+ const value = field.getValue( { item: data } );
20
+
21
+ const onChangeControl = useCallback(
22
+ ( newValue: string ) =>
23
+ onChange( {
24
+ [ id ]: newValue,
25
+ } ),
26
+ [ id, onChange ]
27
+ );
28
+
29
+ return (
30
+ <TextControl
31
+ label={ label }
32
+ placeholder={ placeholder }
33
+ value={ value ?? '' }
34
+ onChange={ onChangeControl }
35
+ __next40pxDefaultSize
36
+ __nextHasNoMarginBottom
37
+ hideLabelFromVision={ hideLabelFromVision }
38
+ />
39
+ );
40
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import FormRegular from './regular';
5
+ import FormPanel from './panel';
6
+
7
+ const FORM_LAYOUTS = [
8
+ {
9
+ type: 'regular',
10
+ component: FormRegular,
11
+ },
12
+ {
13
+ type: 'panel',
14
+ component: FormPanel,
15
+ },
16
+ ];
17
+
18
+ export function getFormLayout( type: string ) {
19
+ return FORM_LAYOUTS.find( ( layout ) => layout.type === type );
20
+ }
@@ -0,0 +1,168 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ __experimentalVStack as VStack,
6
+ __experimentalHStack as HStack,
7
+ __experimentalHeading as Heading,
8
+ __experimentalSpacer as Spacer,
9
+ Dropdown,
10
+ Button,
11
+ } from '@wordpress/components';
12
+ import { useState, useMemo } from '@wordpress/element';
13
+ import { sprintf, __ } from '@wordpress/i18n';
14
+ import { closeSmall } from '@wordpress/icons';
15
+
16
+ /**
17
+ * Internal dependencies
18
+ */
19
+ import { normalizeFields } from '../../normalize-fields';
20
+ import type { DataFormProps, NormalizedField, Field } from '../../types';
21
+
22
+ interface FormFieldProps< Item > {
23
+ data: Item;
24
+ field: NormalizedField< Item >;
25
+ onChange: ( value: any ) => void;
26
+ }
27
+
28
+ function DropdownHeader( {
29
+ title,
30
+ onClose,
31
+ }: {
32
+ title: string;
33
+ onClose: () => void;
34
+ } ) {
35
+ return (
36
+ <VStack
37
+ className="dataforms-layouts-panel__dropdown-header"
38
+ spacing={ 4 }
39
+ >
40
+ <HStack alignment="center">
41
+ <Heading level={ 2 } size={ 13 }>
42
+ { title }
43
+ </Heading>
44
+ <Spacer />
45
+ { onClose && (
46
+ <Button
47
+ className="dataforms-layouts-panel__dropdown-header-action"
48
+ label={ __( 'Close' ) }
49
+ icon={ closeSmall }
50
+ onClick={ onClose }
51
+ />
52
+ ) }
53
+ </HStack>
54
+ </VStack>
55
+ );
56
+ }
57
+
58
+ function FormField< Item >( {
59
+ data,
60
+ field,
61
+ onChange,
62
+ }: FormFieldProps< Item > ) {
63
+ // Use internal state instead of a ref to make sure that the component
64
+ // re-renders when the popover's anchor updates.
65
+ const [ popoverAnchor, setPopoverAnchor ] = useState< HTMLElement | null >(
66
+ null
67
+ );
68
+ // Memoize popoverProps to avoid returning a new object every time.
69
+ const popoverProps = useMemo(
70
+ () => ( {
71
+ // Anchor the popover to the middle of the entire row so that it doesn't
72
+ // move around when the label changes.
73
+ anchor: popoverAnchor,
74
+ placement: 'left-start',
75
+ offset: 36,
76
+ shift: true,
77
+ } ),
78
+ [ popoverAnchor ]
79
+ );
80
+
81
+ return (
82
+ <HStack
83
+ ref={ setPopoverAnchor }
84
+ className="dataforms-layouts-panel__field"
85
+ >
86
+ <div className="dataforms-layouts-panel__field-label">
87
+ { field.label }
88
+ </div>
89
+ <div>
90
+ <Dropdown
91
+ contentClassName="dataforms-layouts-panel__field-dropdown"
92
+ popoverProps={ popoverProps }
93
+ focusOnMount
94
+ toggleProps={ {
95
+ size: 'compact',
96
+ variant: 'tertiary',
97
+ tooltipPosition: 'middle left',
98
+ } }
99
+ renderToggle={ ( { isOpen, onToggle } ) => (
100
+ <Button
101
+ className="dataforms-layouts-panel__field-control"
102
+ size="compact"
103
+ variant="tertiary"
104
+ aria-expanded={ isOpen }
105
+ aria-label={ sprintf(
106
+ // translators: %s: Field name.
107
+ __( 'Edit %s' ),
108
+ field.label
109
+ ) }
110
+ onClick={ onToggle }
111
+ >
112
+ <field.render item={ data } />
113
+ </Button>
114
+ ) }
115
+ renderContent={ ( { onClose } ) => (
116
+ <>
117
+ <DropdownHeader
118
+ title={ field.label }
119
+ onClose={ onClose }
120
+ />
121
+ <field.Edit
122
+ key={ field.id }
123
+ data={ data }
124
+ field={ field }
125
+ onChange={ onChange }
126
+ hideLabelFromVision
127
+ />
128
+ </>
129
+ ) }
130
+ />
131
+ </div>
132
+ </HStack>
133
+ );
134
+ }
135
+
136
+ export default function FormPanel< Item >( {
137
+ data,
138
+ fields,
139
+ form,
140
+ onChange,
141
+ }: DataFormProps< Item > ) {
142
+ const visibleFields = useMemo(
143
+ () =>
144
+ normalizeFields(
145
+ ( form.fields ?? [] )
146
+ .map( ( fieldId ) =>
147
+ fields.find( ( { id } ) => id === fieldId )
148
+ )
149
+ .filter( ( field ): field is Field< Item > => !! field )
150
+ ),
151
+ [ fields, form.fields ]
152
+ );
153
+
154
+ return (
155
+ <VStack spacing={ 2 }>
156
+ { visibleFields.map( ( field ) => {
157
+ return (
158
+ <FormField
159
+ key={ field.id }
160
+ data={ data }
161
+ field={ field }
162
+ onChange={ onChange }
163
+ />
164
+ );
165
+ } ) }
166
+ </VStack>
167
+ );
168
+ }
@@ -0,0 +1,59 @@
1
+ .dataforms-layouts-panel__field {
2
+ width: 100%;
3
+ min-height: $grid-unit-40;
4
+ justify-content: flex-start !important;
5
+ align-items: flex-start !important;
6
+ }
7
+
8
+ .dataforms-layouts-panel__field-label {
9
+ width: 38%;
10
+ flex-shrink: 0;
11
+ min-height: $grid-unit-40;
12
+ display: flex;
13
+ align-items: center;
14
+ padding: 6px 0; // Matches button to ensure alignment
15
+ line-height: $grid-unit-05 * 5;
16
+ hyphens: auto;
17
+ }
18
+
19
+ .dataforms-layouts-panel__field-control {
20
+ flex-grow: 1;
21
+ min-height: $grid-unit-40;
22
+ display: flex;
23
+ align-items: center;
24
+
25
+ .components-button {
26
+ max-width: 100%;
27
+ text-align: left;
28
+ white-space: normal;
29
+ text-wrap: balance; // Fallback for Safari.
30
+ text-wrap: pretty;
31
+ min-height: $button-size-compact;
32
+ }
33
+
34
+ .components-dropdown {
35
+ max-width: 100%;
36
+ }
37
+ }
38
+
39
+ .dataforms-layouts-panel__field-dropdown .components-popover__content {
40
+ min-width: 320px;
41
+ padding: $grid-unit-20;
42
+ }
43
+
44
+ .dataforms-layouts-panel__dropdown-header {
45
+ margin-bottom: $grid-unit-20;
46
+ }
47
+
48
+ [class].dataforms-layouts-panel__dropdown-header-action {
49
+ height: $icon-size;
50
+
51
+ &.has-icon {
52
+ min-width: $icon-size;
53
+ padding: 0;
54
+ }
55
+
56
+ &:not(.has-icon) {
57
+ text-decoration: underline;
58
+ }
59
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __experimentalVStack as VStack } from '@wordpress/components';
5
+ import { useMemo } from '@wordpress/element';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { normalizeFields } from '../../normalize-fields';
11
+ import type { DataFormProps, Field } from '../../types';
12
+
13
+ export default function FormRegular< Item >( {
14
+ data,
15
+ fields,
16
+ form,
17
+ onChange,
18
+ }: DataFormProps< Item > ) {
19
+ const visibleFields = useMemo(
20
+ () =>
21
+ normalizeFields(
22
+ ( form.fields ?? [] )
23
+ .map( ( fieldId ) =>
24
+ fields.find( ( { id } ) => id === fieldId )
25
+ )
26
+ .filter( ( field ): field is Field< Item > => !! field )
27
+ ),
28
+ [ fields, form.fields ]
29
+ );
30
+
31
+ return (
32
+ <VStack spacing={ 4 }>
33
+ { visibleFields.map( ( field ) => {
34
+ return (
35
+ <field.Edit
36
+ key={ field.id }
37
+ data={ data }
38
+ field={ field }
39
+ onChange={ onChange }
40
+ />
41
+ );
42
+ } ) }
43
+ </VStack>
44
+ );
45
+ }
@@ -0,0 +1,102 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { RangeControl } from '@wordpress/components';
5
+ import { __ } from '@wordpress/i18n';
6
+ import { useViewportMatch } from '@wordpress/compose';
7
+ import { useEffect, useMemo } from '@wordpress/element';
8
+
9
+ const viewportBreaks = {
10
+ xhuge: { min: 3, max: 6, default: 5 },
11
+ huge: { min: 2, max: 4, default: 4 },
12
+ xlarge: { min: 2, max: 3, default: 3 },
13
+ large: { min: 1, max: 2, default: 2 },
14
+ mobile: { min: 1, max: 2, default: 2 },
15
+ };
16
+
17
+ function useViewPortBreakpoint() {
18
+ const isXHuge = useViewportMatch( 'xhuge', '>=' );
19
+ const isHuge = useViewportMatch( 'huge', '>=' );
20
+ const isXlarge = useViewportMatch( 'xlarge', '>=' );
21
+ const isLarge = useViewportMatch( 'large', '>=' );
22
+ const isMobile = useViewportMatch( 'mobile', '>=' );
23
+
24
+ if ( isXHuge ) {
25
+ return 'xhuge';
26
+ }
27
+ if ( isHuge ) {
28
+ return 'huge';
29
+ }
30
+ if ( isXlarge ) {
31
+ return 'xlarge';
32
+ }
33
+ if ( isLarge ) {
34
+ return 'large';
35
+ }
36
+ if ( isMobile ) {
37
+ return 'mobile';
38
+ }
39
+ return null;
40
+ }
41
+
42
+ export default function DensityPicker( {
43
+ density,
44
+ setDensity,
45
+ }: {
46
+ density: number;
47
+ setDensity: React.Dispatch< React.SetStateAction< number > >;
48
+ } ) {
49
+ const viewport = useViewPortBreakpoint();
50
+ useEffect( () => {
51
+ setDensity( ( _density ) => {
52
+ if ( ! viewport || ! _density ) {
53
+ return 0;
54
+ }
55
+ const breakValues = viewportBreaks[ viewport ];
56
+ if ( _density < breakValues.min ) {
57
+ return breakValues.min;
58
+ }
59
+ if ( _density > breakValues.max ) {
60
+ return breakValues.max;
61
+ }
62
+ return _density;
63
+ } );
64
+ }, [ setDensity, viewport ] );
65
+ const breakValues = viewportBreaks[ viewport || 'mobile' ];
66
+ const densityToUse = density || breakValues.default;
67
+
68
+ const marks = useMemo(
69
+ () =>
70
+ Array.from(
71
+ { length: breakValues.max - breakValues.min + 1 },
72
+ ( _, i ) => {
73
+ return {
74
+ value: breakValues.min + i,
75
+ };
76
+ }
77
+ ),
78
+ [ breakValues ]
79
+ );
80
+
81
+ if ( ! viewport ) {
82
+ return null;
83
+ }
84
+
85
+ return (
86
+ <RangeControl
87
+ __nextHasNoMarginBottom
88
+ __next40pxDefaultSize
89
+ showTooltip={ false }
90
+ label={ __( 'Preview size' ) }
91
+ value={ breakValues.max + breakValues.min - densityToUse }
92
+ marks={ marks }
93
+ min={ breakValues.min }
94
+ max={ breakValues.max }
95
+ withInputField={ false }
96
+ onChange={ ( value = 0 ) => {
97
+ setDensity( breakValues.max + breakValues.min - value );
98
+ } }
99
+ step={ 1 }
100
+ />
101
+ );
102
+ }