@wordpress/dataviews 12.0.1-next.v.202602091733.0 → 12.0.1

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 (260) hide show
  1. package/CHANGELOG.md +39 -1
  2. package/README.md +3 -1
  3. package/build/components/dataform-controls/color.cjs +19 -30
  4. package/build/components/dataform-controls/color.cjs.map +3 -3
  5. package/build/components/dataform-controls/date.cjs.map +1 -1
  6. package/build/components/dataform-controls/datetime.cjs +12 -21
  7. package/build/components/dataform-controls/datetime.cjs.map +2 -2
  8. package/build/components/dataform-layouts/card/index.cjs +112 -164
  9. package/build/components/dataform-layouts/card/index.cjs.map +3 -3
  10. package/build/components/dataform-layouts/index.cjs +1 -1
  11. package/build/components/dataform-layouts/index.cjs.map +1 -1
  12. package/build/components/dataform-layouts/normalize-form.cjs +2 -1
  13. package/build/components/dataform-layouts/normalize-form.cjs.map +2 -2
  14. package/build/components/dataform-layouts/panel/dropdown.cjs +79 -65
  15. package/build/components/dataform-layouts/panel/dropdown.cjs.map +3 -3
  16. package/build/components/dataform-layouts/panel/index.cjs +13 -177
  17. package/build/components/dataform-layouts/panel/index.cjs.map +3 -3
  18. package/build/components/dataform-layouts/panel/modal.cjs +12 -9
  19. package/build/components/dataform-layouts/panel/modal.cjs.map +3 -3
  20. package/build/components/dataform-layouts/panel/summary-button.cjs +125 -56
  21. package/build/components/dataform-layouts/panel/summary-button.cjs.map +3 -3
  22. package/build/components/dataform-layouts/panel/utils/get-first-validation-error.cjs +59 -0
  23. package/build/components/dataform-layouts/panel/utils/get-first-validation-error.cjs.map +7 -0
  24. package/build/components/dataform-layouts/panel/utils/get-label-classname.cjs +45 -0
  25. package/build/components/dataform-layouts/panel/utils/get-label-classname.cjs.map +7 -0
  26. package/build/components/dataform-layouts/panel/utils/get-label-content.cjs +36 -0
  27. package/build/components/dataform-layouts/panel/utils/get-label-content.cjs.map +7 -0
  28. package/build/components/dataform-layouts/panel/utils/use-field-from-form-field.cjs +77 -0
  29. package/build/components/dataform-layouts/panel/utils/use-field-from-form-field.cjs.map +7 -0
  30. package/build/components/dataviews-bulk-actions/index.cjs +2 -2
  31. package/build/components/dataviews-bulk-actions/index.cjs.map +2 -2
  32. package/build/components/dataviews-context/index.cjs +1 -0
  33. package/build/components/dataviews-context/index.cjs.map +2 -2
  34. package/build/components/dataviews-filters/filter.cjs.map +1 -1
  35. package/build/components/dataviews-filters/search-widget.cjs +25 -11
  36. package/build/components/dataviews-filters/search-widget.cjs.map +2 -2
  37. package/build/components/dataviews-filters/toggle.cjs +6 -2
  38. package/build/components/dataviews-filters/toggle.cjs.map +2 -2
  39. package/build/components/dataviews-footer/index.cjs +28 -12
  40. package/build/components/dataviews-footer/index.cjs.map +3 -3
  41. package/build/components/dataviews-item-actions/index.cjs +0 -1
  42. package/build/components/dataviews-item-actions/index.cjs.map +2 -2
  43. package/build/components/dataviews-layout/index.cjs +12 -0
  44. package/build/components/dataviews-layout/index.cjs.map +2 -2
  45. package/build/components/dataviews-layouts/activity/index.cjs +41 -26
  46. package/build/components/dataviews-layouts/activity/index.cjs.map +3 -3
  47. package/build/components/dataviews-layouts/grid/composite-grid.cjs +2 -0
  48. package/build/components/dataviews-layouts/grid/composite-grid.cjs.map +2 -2
  49. package/build/components/dataviews-layouts/grid/index.cjs +19 -14
  50. package/build/components/dataviews-layouts/grid/index.cjs.map +3 -3
  51. package/build/components/dataviews-layouts/list/index.cjs +13 -9
  52. package/build/components/dataviews-layouts/list/index.cjs.map +2 -2
  53. package/build/components/dataviews-layouts/picker-table/index.cjs +1 -1
  54. package/build/components/dataviews-layouts/picker-table/index.cjs.map +2 -2
  55. package/build/components/dataviews-layouts/table/index.cjs +40 -19
  56. package/build/components/dataviews-layouts/table/index.cjs.map +2 -2
  57. package/build/dataviews/index.cjs +9 -2
  58. package/build/dataviews/index.cjs.map +3 -3
  59. package/build/dataviews-picker/index.cjs +1 -0
  60. package/build/dataviews-picker/index.cjs.map +2 -2
  61. package/build/hooks/use-data.cjs +46 -0
  62. package/build/hooks/use-data.cjs.map +7 -0
  63. package/build/hooks/use-delayed-loading.cjs +47 -0
  64. package/build/hooks/use-delayed-loading.cjs.map +7 -0
  65. package/build/types/dataform.cjs.map +1 -1
  66. package/build-module/components/dataform-controls/color.mjs +24 -31
  67. package/build-module/components/dataform-controls/color.mjs.map +2 -2
  68. package/build-module/components/dataform-controls/date.mjs.map +1 -1
  69. package/build-module/components/dataform-controls/datetime.mjs +13 -22
  70. package/build-module/components/dataform-controls/datetime.mjs.map +2 -2
  71. package/build-module/components/dataform-layouts/card/index.mjs +113 -161
  72. package/build-module/components/dataform-layouts/card/index.mjs.map +3 -3
  73. package/build-module/components/dataform-layouts/index.mjs +1 -1
  74. package/build-module/components/dataform-layouts/index.mjs.map +1 -1
  75. package/build-module/components/dataform-layouts/normalize-form.mjs +2 -1
  76. package/build-module/components/dataform-layouts/normalize-form.mjs.map +2 -2
  77. package/build-module/components/dataform-layouts/panel/dropdown.mjs +81 -67
  78. package/build-module/components/dataform-layouts/panel/dropdown.mjs.map +2 -2
  79. package/build-module/components/dataform-layouts/panel/index.mjs +14 -178
  80. package/build-module/components/dataform-layouts/panel/index.mjs.map +2 -2
  81. package/build-module/components/dataform-layouts/panel/modal.mjs +12 -9
  82. package/build-module/components/dataform-layouts/panel/modal.mjs.map +2 -2
  83. package/build-module/components/dataform-layouts/panel/summary-button.mjs +117 -58
  84. package/build-module/components/dataform-layouts/panel/summary-button.mjs.map +2 -2
  85. package/build-module/components/dataform-layouts/panel/utils/get-first-validation-error.mjs +38 -0
  86. package/build-module/components/dataform-layouts/panel/utils/get-first-validation-error.mjs.map +7 -0
  87. package/build-module/components/dataform-layouts/panel/utils/get-label-classname.mjs +14 -0
  88. package/build-module/components/dataform-layouts/panel/utils/get-label-classname.mjs.map +7 -0
  89. package/build-module/components/dataform-layouts/panel/utils/get-label-content.mjs +15 -0
  90. package/build-module/components/dataform-layouts/panel/utils/get-label-content.mjs.map +7 -0
  91. package/build-module/components/dataform-layouts/panel/utils/use-field-from-form-field.mjs +46 -0
  92. package/build-module/components/dataform-layouts/panel/utils/use-field-from-form-field.mjs.map +7 -0
  93. package/build-module/components/dataviews-bulk-actions/index.mjs +2 -2
  94. package/build-module/components/dataviews-bulk-actions/index.mjs.map +2 -2
  95. package/build-module/components/dataviews-context/index.mjs +1 -0
  96. package/build-module/components/dataviews-context/index.mjs.map +2 -2
  97. package/build-module/components/dataviews-filters/filter.mjs.map +1 -1
  98. package/build-module/components/dataviews-filters/search-widget.mjs +25 -11
  99. package/build-module/components/dataviews-filters/search-widget.mjs.map +2 -2
  100. package/build-module/components/dataviews-filters/toggle.mjs +6 -2
  101. package/build-module/components/dataviews-filters/toggle.mjs.map +2 -2
  102. package/build-module/components/dataviews-footer/index.mjs +28 -12
  103. package/build-module/components/dataviews-footer/index.mjs.map +2 -2
  104. package/build-module/components/dataviews-item-actions/index.mjs +0 -1
  105. package/build-module/components/dataviews-item-actions/index.mjs.map +2 -2
  106. package/build-module/components/dataviews-layout/index.mjs +12 -0
  107. package/build-module/components/dataviews-layout/index.mjs.map +2 -2
  108. package/build-module/components/dataviews-layouts/activity/index.mjs +41 -26
  109. package/build-module/components/dataviews-layouts/activity/index.mjs.map +2 -2
  110. package/build-module/components/dataviews-layouts/grid/composite-grid.mjs +2 -0
  111. package/build-module/components/dataviews-layouts/grid/composite-grid.mjs.map +2 -2
  112. package/build-module/components/dataviews-layouts/grid/index.mjs +19 -14
  113. package/build-module/components/dataviews-layouts/grid/index.mjs.map +2 -2
  114. package/build-module/components/dataviews-layouts/list/index.mjs +13 -9
  115. package/build-module/components/dataviews-layouts/list/index.mjs.map +2 -2
  116. package/build-module/components/dataviews-layouts/picker-table/index.mjs +1 -1
  117. package/build-module/components/dataviews-layouts/picker-table/index.mjs.map +2 -2
  118. package/build-module/components/dataviews-layouts/table/index.mjs +40 -19
  119. package/build-module/components/dataviews-layouts/table/index.mjs.map +2 -2
  120. package/build-module/dataviews/index.mjs +9 -2
  121. package/build-module/dataviews/index.mjs.map +2 -2
  122. package/build-module/dataviews-picker/index.mjs +1 -0
  123. package/build-module/dataviews-picker/index.mjs.map +2 -2
  124. package/build-module/hooks/use-data.mjs +25 -0
  125. package/build-module/hooks/use-data.mjs.map +7 -0
  126. package/build-module/hooks/use-delayed-loading.mjs +22 -0
  127. package/build-module/hooks/use-delayed-loading.mjs.map +7 -0
  128. package/build-style/style-rtl.css +190 -31
  129. package/build-style/style.css +190 -31
  130. package/build-types/components/dataform-controls/color.d.ts.map +1 -1
  131. package/build-types/components/dataform-controls/datetime.d.ts.map +1 -1
  132. package/build-types/components/dataform-controls/utils/use-disabled-date-matchers.d.ts +16 -0
  133. package/build-types/components/dataform-controls/utils/use-disabled-date-matchers.d.ts.map +1 -0
  134. package/build-types/components/dataform-layouts/card/index.d.ts +1 -10
  135. package/build-types/components/dataform-layouts/card/index.d.ts.map +1 -1
  136. package/build-types/components/dataform-layouts/normalize-form.d.ts.map +1 -1
  137. package/build-types/components/dataform-layouts/panel/dropdown.d.ts +2 -13
  138. package/build-types/components/dataform-layouts/panel/dropdown.d.ts.map +1 -1
  139. package/build-types/components/dataform-layouts/panel/index.d.ts +1 -1
  140. package/build-types/components/dataform-layouts/panel/index.d.ts.map +1 -1
  141. package/build-types/components/dataform-layouts/panel/modal.d.ts +2 -11
  142. package/build-types/components/dataform-layouts/panel/modal.d.ts.map +1 -1
  143. package/build-types/components/dataform-layouts/panel/summary-button.d.ts +6 -5
  144. package/build-types/components/dataform-layouts/panel/summary-button.d.ts.map +1 -1
  145. package/build-types/components/dataform-layouts/panel/utils/get-first-validation-error.d.ts +4 -0
  146. package/build-types/components/dataform-layouts/panel/utils/get-first-validation-error.d.ts.map +1 -0
  147. package/build-types/components/dataform-layouts/panel/utils/get-label-classname.d.ts +4 -0
  148. package/build-types/components/dataform-layouts/panel/utils/get-label-classname.d.ts.map +1 -0
  149. package/build-types/components/dataform-layouts/panel/utils/get-label-content.d.ts +3 -0
  150. package/build-types/components/dataform-layouts/panel/utils/get-label-content.d.ts.map +1 -0
  151. package/build-types/components/dataform-layouts/panel/utils/use-field-from-form-field.d.ts +23 -0
  152. package/build-types/components/dataform-layouts/panel/utils/use-field-from-form-field.d.ts.map +1 -0
  153. package/build-types/components/dataviews-context/index.d.ts +1 -0
  154. package/build-types/components/dataviews-context/index.d.ts.map +1 -1
  155. package/build-types/components/dataviews-filters/filter.d.ts +1 -1
  156. package/build-types/components/dataviews-filters/filter.d.ts.map +1 -1
  157. package/build-types/components/dataviews-filters/search-widget.d.ts.map +1 -1
  158. package/build-types/components/dataviews-filters/toggle.d.ts.map +1 -1
  159. package/build-types/components/dataviews-footer/index.d.ts +1 -1
  160. package/build-types/components/dataviews-footer/index.d.ts.map +1 -1
  161. package/build-types/components/dataviews-item-actions/index.d.ts.map +1 -1
  162. package/build-types/components/dataviews-layout/index.d.ts +1 -1
  163. package/build-types/components/dataviews-layout/index.d.ts.map +1 -1
  164. package/build-types/components/dataviews-layouts/activity/index.d.ts.map +1 -1
  165. package/build-types/components/dataviews-layouts/grid/composite-grid.d.ts +2 -1
  166. package/build-types/components/dataviews-layouts/grid/composite-grid.d.ts.map +1 -1
  167. package/build-types/components/dataviews-layouts/grid/index.d.ts.map +1 -1
  168. package/build-types/components/dataviews-layouts/list/index.d.ts.map +1 -1
  169. package/build-types/components/dataviews-layouts/picker-activity/index.d.ts +3 -0
  170. package/build-types/components/dataviews-layouts/picker-activity/index.d.ts.map +1 -0
  171. package/build-types/components/dataviews-layouts/table/index.d.ts.map +1 -1
  172. package/build-types/components/dataviews-layouts/table/use-scroll-state.d.ts +25 -0
  173. package/build-types/components/dataviews-layouts/table/use-scroll-state.d.ts.map +1 -0
  174. package/build-types/components/dataviews-layouts/utils/grid-config-options.d.ts +2 -0
  175. package/build-types/components/dataviews-layouts/utils/grid-config-options.d.ts.map +1 -0
  176. package/build-types/components/dataviews-layouts/utils/use-infinite-scroll.d.ts +22 -0
  177. package/build-types/components/dataviews-layouts/utils/use-infinite-scroll.d.ts.map +1 -0
  178. package/build-types/dataform/stories/index.story.d.ts +9 -1
  179. package/build-types/dataform/stories/index.story.d.ts.map +1 -1
  180. package/build-types/dataform/stories/layout-panel.d.ts +3 -1
  181. package/build-types/dataform/stories/layout-panel.d.ts.map +1 -1
  182. package/build-types/dataviews/index.d.ts.map +1 -1
  183. package/build-types/dataviews/stories/empty.d.ts.map +1 -1
  184. package/build-types/dataviews/stories/fixtures.d.ts +1 -0
  185. package/build-types/dataviews/stories/fixtures.d.ts.map +1 -1
  186. package/build-types/dataviews/stories/free-composition.d.ts.map +1 -1
  187. package/build-types/dataviews/stories/layout-table.d.ts.map +1 -1
  188. package/build-types/dataviews/stories/minimal-ui.d.ts.map +1 -1
  189. package/build-types/dataviews/stories/with-card.d.ts.map +1 -1
  190. package/build-types/dataviews-picker/index.d.ts.map +1 -1
  191. package/build-types/field-types/utils/is-valid-date-boundary.d.ts +7 -0
  192. package/build-types/field-types/utils/is-valid-date-boundary.d.ts.map +1 -0
  193. package/build-types/hooks/test/use-data.d.ts +2 -0
  194. package/build-types/hooks/test/use-data.d.ts.map +1 -0
  195. package/build-types/hooks/use-data.d.ts +12 -0
  196. package/build-types/hooks/use-data.d.ts.map +1 -0
  197. package/build-types/hooks/use-delayed-loading.d.ts +4 -0
  198. package/build-types/hooks/use-delayed-loading.d.ts.map +1 -0
  199. package/build-types/hooks/use-infinite-scroll.d.ts +21 -0
  200. package/build-types/hooks/use-infinite-scroll.d.ts.map +1 -0
  201. package/build-types/hooks/use-selected-items.d.ts +19 -0
  202. package/build-types/hooks/use-selected-items.d.ts.map +1 -0
  203. package/build-types/types/dataform.d.ts +3 -0
  204. package/build-types/types/dataform.d.ts.map +1 -1
  205. package/build-wp/index.js +2898 -2198
  206. package/package.json +21 -21
  207. package/src/components/dataform-controls/color.tsx +29 -36
  208. package/src/components/dataform-controls/date.tsx +2 -2
  209. package/src/components/dataform-controls/datetime.tsx +19 -34
  210. package/src/components/dataform-controls/style.scss +4 -0
  211. package/src/components/dataform-layouts/card/index.tsx +118 -185
  212. package/src/components/dataform-layouts/index.tsx +1 -1
  213. package/src/components/dataform-layouts/normalize-form.ts +1 -0
  214. package/src/components/dataform-layouts/panel/dropdown.tsx +95 -96
  215. package/src/components/dataform-layouts/panel/index.tsx +10 -245
  216. package/src/components/dataform-layouts/panel/modal.tsx +16 -20
  217. package/src/components/dataform-layouts/panel/style.scss +110 -27
  218. package/src/components/dataform-layouts/panel/summary-button.tsx +140 -62
  219. package/src/components/dataform-layouts/panel/utils/get-first-validation-error.ts +47 -0
  220. package/src/components/dataform-layouts/panel/utils/get-label-classname.ts +18 -0
  221. package/src/components/dataform-layouts/panel/utils/get-label-content.tsx +24 -0
  222. package/src/components/dataform-layouts/panel/utils/use-field-from-form-field.ts +78 -0
  223. package/src/components/dataform-layouts/regular/style.scss +7 -0
  224. package/src/components/dataform-layouts/test/normalize-form.ts +5 -0
  225. package/src/components/dataviews-bulk-actions/index.tsx +2 -2
  226. package/src/components/dataviews-context/index.ts +2 -0
  227. package/src/components/dataviews-filters/filter.tsx +1 -1
  228. package/src/components/dataviews-filters/search-widget.tsx +10 -2
  229. package/src/components/dataviews-filters/style.scss +8 -0
  230. package/src/components/dataviews-filters/toggle.tsx +10 -3
  231. package/src/components/dataviews-footer/index.tsx +39 -12
  232. package/src/components/dataviews-footer/style.scss +6 -1
  233. package/src/components/dataviews-item-actions/index.tsx +0 -3
  234. package/src/components/dataviews-item-actions/style.scss +7 -0
  235. package/src/components/dataviews-layout/index.tsx +24 -0
  236. package/src/components/dataviews-layouts/activity/index.tsx +29 -22
  237. package/src/components/dataviews-layouts/activity/style.scss +5 -0
  238. package/src/components/dataviews-layouts/grid/composite-grid.tsx +5 -1
  239. package/src/components/dataviews-layouts/grid/index.tsx +19 -22
  240. package/src/components/dataviews-layouts/grid/style.scss +5 -0
  241. package/src/components/dataviews-layouts/list/index.tsx +18 -18
  242. package/src/components/dataviews-layouts/list/style.scss +5 -0
  243. package/src/components/dataviews-layouts/picker-table/index.tsx +1 -1
  244. package/src/components/dataviews-layouts/table/index.tsx +48 -22
  245. package/src/components/dataviews-layouts/table/style.scss +8 -2
  246. package/src/dataform/stories/index.story.tsx +5 -0
  247. package/src/dataform/stories/layout-panel.tsx +19 -2
  248. package/src/dataform/test/dataform.tsx +2 -2
  249. package/src/dataviews/index.tsx +11 -3
  250. package/src/dataviews/stories/empty.tsx +1 -7
  251. package/src/dataviews/stories/fixtures.tsx +89 -0
  252. package/src/dataviews/stories/free-composition.tsx +0 -5
  253. package/src/dataviews/stories/layout-table.tsx +1 -7
  254. package/src/dataviews/stories/minimal-ui.tsx +0 -5
  255. package/src/dataviews/stories/with-card.tsx +1 -7
  256. package/src/dataviews/style.scss +25 -0
  257. package/src/dataviews-picker/index.tsx +2 -1
  258. package/src/hooks/use-data.ts +45 -0
  259. package/src/hooks/use-delayed-loading.ts +21 -0
  260. package/src/types/dataform.ts +4 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/dataviews",
3
- "version": "12.0.1-next.v.202602091733.0+daa0b19c4",
3
+ "version": "12.0.1",
4
4
  "description": "DataViews is a component that provides an API to render datasets using different types of layouts (table, grid, list, etc.).",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -52,24 +52,24 @@
52
52
  "types": "build-types",
53
53
  "sideEffects": false,
54
54
  "dependencies": {
55
- "@ariakit/react": "^0.4.15",
56
- "@wordpress/base-styles": "^6.15.1-next.v.202602091733.0+daa0b19c4",
57
- "@wordpress/components": "^32.2.1-next.v.202602091733.0+daa0b19c4",
58
- "@wordpress/compose": "^7.39.1-next.v.202602091733.0+daa0b19c4",
59
- "@wordpress/data": "^10.39.1-next.v.202602091733.0+daa0b19c4",
60
- "@wordpress/date": "^5.39.1-next.v.202602091733.0+daa0b19c4",
61
- "@wordpress/deprecated": "^4.39.1-next.v.202602091733.0+daa0b19c4",
62
- "@wordpress/dom": "^4.39.1-next.v.202602091733.0+daa0b19c4",
63
- "@wordpress/element": "^6.39.1-next.v.202602091733.0+daa0b19c4",
64
- "@wordpress/i18n": "^6.12.1-next.v.202602091733.0+daa0b19c4",
65
- "@wordpress/icons": "^11.6.1-next.v.202602091733.0+daa0b19c4",
66
- "@wordpress/keycodes": "^4.39.1-next.v.202602091733.0+daa0b19c4",
67
- "@wordpress/primitives": "^4.39.1-next.v.202602091733.0+daa0b19c4",
68
- "@wordpress/private-apis": "^1.39.1-next.v.202602091733.0+daa0b19c4",
69
- "@wordpress/theme": "^0.7.1-next.v.202602091733.0+daa0b19c4",
70
- "@wordpress/ui": "^0.7.1-next.v.202602091733.0+daa0b19c4",
71
- "@wordpress/url": "^4.39.1-next.v.202602091733.0+daa0b19c4",
72
- "@wordpress/warning": "^3.39.1-next.v.202602091733.0+daa0b19c4",
55
+ "@ariakit/react": "^0.4.21",
56
+ "@wordpress/base-styles": "^6.16.1",
57
+ "@wordpress/components": "^32.2.1",
58
+ "@wordpress/compose": "^7.40.1",
59
+ "@wordpress/data": "^10.40.1",
60
+ "@wordpress/date": "^5.40.1",
61
+ "@wordpress/deprecated": "^4.40.1",
62
+ "@wordpress/dom": "^4.40.1",
63
+ "@wordpress/element": "^6.40.1",
64
+ "@wordpress/i18n": "^6.13.1",
65
+ "@wordpress/icons": "^11.7.1",
66
+ "@wordpress/keycodes": "^4.40.1",
67
+ "@wordpress/primitives": "^4.40.1",
68
+ "@wordpress/private-apis": "^1.40.1",
69
+ "@wordpress/theme": "^0.7.1",
70
+ "@wordpress/ui": "^0.7.1",
71
+ "@wordpress/url": "^4.40.1",
72
+ "@wordpress/warning": "^3.40.1",
73
73
  "clsx": "^2.1.1",
74
74
  "colord": "^2.7.0",
75
75
  "date-fns": "^4.1.0",
@@ -80,7 +80,7 @@
80
80
  "devDependencies": {
81
81
  "@storybook/addon-docs": "^10.1.11",
82
82
  "@storybook/react-vite": "^10.1.11",
83
- "@testing-library/jest-dom": "^6.6.3",
83
+ "@testing-library/jest-dom": "^6.9.1",
84
84
  "@types/jest": "^29.5.14",
85
85
  "esbuild": "^0.27.2",
86
86
  "storybook": "^10.1.11"
@@ -95,5 +95,5 @@
95
95
  "scripts": {
96
96
  "build:wp": "node build.cjs"
97
97
  },
98
- "gitHead": "74f59922b25e30904319373dda91bf8e81f3544e"
98
+ "gitHead": "adb6623c9f32490cfc73c7ac7f122578c1f10c65"
99
99
  }
@@ -7,11 +7,16 @@ import { colord } from 'colord';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import {
10
+ Button,
11
+ ColorIndicator,
12
+ ColorPicker,
10
13
  Dropdown,
11
14
  privateApis,
12
15
  __experimentalInputControlPrefixWrapper as InputControlPrefixWrapper,
16
+ __experimentalDropdownContentWrapper as DropdownContentWrapper,
13
17
  } from '@wordpress/components';
14
18
  import { useCallback } from '@wordpress/element';
19
+ import { __ } from '@wordpress/i18n';
15
20
 
16
21
  /**
17
22
  * Internal dependencies
@@ -20,51 +25,37 @@ import type { DataFormControlProps } from '../../types';
20
25
  import { unlock } from '../../lock-unlock';
21
26
  import getCustomValidity from './utils/get-custom-validity';
22
27
 
23
- const { ValidatedInputControl, Picker } = unlock( privateApis );
28
+ const { ValidatedInputControl } = unlock( privateApis );
24
29
 
25
- const ColorPicker = ( {
30
+ const ColorPickerDropdown = ( {
26
31
  color,
27
32
  onColorChange,
28
33
  }: {
29
34
  color: string;
30
- onColorChange: ( colorObject: any ) => void;
35
+ onColorChange: ( newColor: string ) => void;
31
36
  } ) => {
32
37
  const validColor = color && colord( color ).isValid() ? color : '#ffffff';
33
38
 
34
39
  return (
35
40
  <Dropdown
36
- renderToggle={ ( { onToggle, isOpen } ) => (
37
- <InputControlPrefixWrapper variant="icon">
38
- <button
39
- type="button"
40
- onClick={ onToggle }
41
- style={ {
42
- width: '24px',
43
- height: '24px',
44
- borderRadius: '50%',
45
- backgroundColor: validColor,
46
- border: '1px solid #ddd',
47
- cursor: 'pointer',
48
- outline: isOpen ? '2px solid #007cba' : 'none',
49
- outlineOffset: '2px',
50
- display: 'flex',
51
- alignItems: 'center',
52
- justifyContent: 'center',
53
- padding: 0,
54
- margin: 0,
55
- } }
56
- aria-label="Open color picker"
57
- />
58
- </InputControlPrefixWrapper>
41
+ className="dataviews-controls__color-picker-dropdown"
42
+ popoverProps={ { resize: false } }
43
+ renderToggle={ ( { onToggle } ) => (
44
+ <Button
45
+ onClick={ onToggle }
46
+ aria-label={ __( 'Open color picker' ) }
47
+ size="small"
48
+ icon={ () => <ColorIndicator colorValue={ validColor } /> }
49
+ />
59
50
  ) }
60
51
  renderContent={ () => (
61
- <div style={ { padding: '16px' } }>
62
- <Picker
63
- color={ colord( validColor ) }
52
+ <DropdownContentWrapper paddingSize="none">
53
+ <ColorPicker
54
+ color={ validColor }
64
55
  onChange={ onColorChange }
65
56
  enableAlpha
66
57
  />
67
- </div>
58
+ </DropdownContentWrapper>
68
59
  ) }
69
60
  />
70
61
  );
@@ -82,8 +73,8 @@ export default function Color< Item >( {
82
73
  const value = field.getValue( { item: data } ) || '';
83
74
 
84
75
  const handleColorChange = useCallback(
85
- ( colorObject: any ) => {
86
- onChange( setValue( { item: data, value: colorObject.toHex() } ) );
76
+ ( newColor: string ) => {
77
+ onChange( setValue( { item: data, value: newColor } ) );
87
78
  },
88
79
  [ data, onChange, setValue ]
89
80
  );
@@ -108,10 +99,12 @@ export default function Color< Item >( {
108
99
  hideLabelFromVision={ hideLabelFromVision }
109
100
  type="text"
110
101
  prefix={
111
- <ColorPicker
112
- color={ value }
113
- onColorChange={ handleColorChange }
114
- />
102
+ <InputControlPrefixWrapper variant="control">
103
+ <ColorPickerDropdown
104
+ color={ value }
105
+ onColorChange={ handleColorChange }
106
+ />
107
+ </InputControlPrefixWrapper>
115
108
  }
116
109
  />
117
110
  );
@@ -161,8 +161,8 @@ function ValidatedDateControl< Item >( {
161
161
  field: NormalizedField< Item >;
162
162
  validity?: FieldValidity;
163
163
  inputRefs:
164
- | React.RefObject< HTMLInputElement >
165
- | React.RefObject< HTMLInputElement >[];
164
+ | React.RefObject< HTMLInputElement | null >
165
+ | React.RefObject< HTMLInputElement | null >[];
166
166
  isTouched: boolean;
167
167
  setIsTouched: ( touched: boolean ) => void;
168
168
  children: React.ReactNode;
@@ -1,8 +1,3 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { format } from 'date-fns';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
@@ -12,7 +7,7 @@ import {
12
7
  } from '@wordpress/components';
13
8
  import { useCallback, useEffect, useRef, useState } from '@wordpress/element';
14
9
  import { __ } from '@wordpress/i18n';
15
- import { getSettings } from '@wordpress/date';
10
+ import { dateI18n, getDate, getSettings } from '@wordpress/date';
16
11
  import { Stack } from '@wordpress/ui';
17
12
 
18
13
  /**
@@ -27,15 +22,12 @@ import { unlock } from '../../lock-unlock';
27
22
 
28
23
  const { DateCalendar, ValidatedInputControl } = unlock( componentsPrivateApis );
29
24
 
30
- const formatDateTime = ( date?: Date | string ): string => {
31
- if ( ! date ) {
25
+ const formatDateTime = ( value?: string ): string => {
26
+ if ( ! value ) {
32
27
  return '';
33
28
  }
34
- if ( typeof date === 'string' ) {
35
- return date;
36
- }
37
- // Format as datetime-local input expects: YYYY-MM-DDTHH:mm
38
- return format( date, "yyyy-MM-dd'T'HH:mm" );
29
+ // Format in WordPress timezone for datetime-local input: YYYY-MM-DDTHH:mm
30
+ return dateI18n( 'Y-m-d\\TH:i', getDate( value ) );
39
31
  };
40
32
 
41
33
  function CalendarDateTimeControl< Item >( {
@@ -56,7 +48,8 @@ function CalendarDateTimeControl< Item >( {
56
48
  } );
57
49
 
58
50
  const inputControlRef = useRef< HTMLInputElement >( null );
59
- const validationTimeoutRef = useRef< ReturnType< typeof setTimeout > >();
51
+ const validationTimeoutRef =
52
+ useRef< ReturnType< typeof setTimeout > >( undefined );
60
53
  const previousFocusRef = useRef< Element | null >( null );
61
54
 
62
55
  const onChangeCallback = useCallback(
@@ -78,21 +71,19 @@ function CalendarDateTimeControl< Item >( {
78
71
  ( newDate: Date | undefined | null ) => {
79
72
  let dateTimeValue: string | undefined;
80
73
  if ( newDate ) {
81
- // Preserve time if it exists in current value, otherwise use current time
82
- let finalDateTime = newDate;
74
+ // Extract the date part in WP timezone from the calendar selection
75
+ const wpDate = dateI18n( 'Y-m-d', newDate );
83
76
 
77
+ // Preserve time if it exists in current value, otherwise use current time
78
+ let wpTime: string;
84
79
  if ( value ) {
85
- const currentDateTime = parseDateTime( value );
86
- if ( currentDateTime ) {
87
- // Preserve the time part
88
- finalDateTime = new Date( newDate );
89
- finalDateTime.setHours( currentDateTime.getHours() );
90
- finalDateTime.setMinutes(
91
- currentDateTime.getMinutes()
92
- );
93
- }
80
+ wpTime = dateI18n( 'H:i', getDate( value ) );
81
+ } else {
82
+ wpTime = dateI18n( 'H:i', newDate );
94
83
  }
95
84
 
85
+ // Combine date and time in WP timezone and convert to ISO
86
+ const finalDateTime = getDate( `${ wpDate }T${ wpTime }` );
96
87
  dateTimeValue = finalDateTime.toISOString();
97
88
  onChangeCallback( dateTimeValue );
98
89
 
@@ -132,8 +123,8 @@ function CalendarDateTimeControl< Item >( {
132
123
  const handleManualDateTimeChange = useCallback(
133
124
  ( newValue?: string ) => {
134
125
  if ( newValue ) {
135
- // Convert from datetime-local format to ISO string
136
- const dateTime = new Date( newValue );
126
+ // Interpret the datetime-local value in WordPress timezone
127
+ const dateTime = getDate( newValue );
137
128
  onChangeCallback( dateTime.toISOString() );
138
129
 
139
130
  // Update calendar month to match
@@ -196,13 +187,7 @@ function CalendarDateTimeControl< Item >( {
196
187
  type="datetime-local"
197
188
  label={ __( 'Date time' ) }
198
189
  hideLabelFromVision
199
- value={
200
- value
201
- ? formatDateTime(
202
- parseDateTime( value ) || undefined
203
- )
204
- : ''
205
- }
190
+ value={ formatDateTime( value ) }
206
191
  onChange={ handleManualDateTimeChange }
207
192
  />
208
193
  </Stack>
@@ -23,6 +23,10 @@
23
23
  min-width: 0;
24
24
  }
25
25
 
26
+ .dataviews-controls__color-picker-dropdown {
27
+ display: flex;
28
+ }
29
+
26
30
  .dataviews-controls__date-preset {
27
31
  border: 1px solid #ddd;
28
32
 
@@ -7,6 +7,7 @@ import {
7
7
  CardBody,
8
8
  CardHeader as OriginalCardHeader,
9
9
  } from '@wordpress/components';
10
+ import { useInstanceId } from '@wordpress/compose';
10
11
  import {
11
12
  useCallback,
12
13
  useContext,
@@ -15,6 +16,7 @@ import {
15
16
  useRef,
16
17
  useState,
17
18
  } from '@wordpress/element';
19
+ import { __ } from '@wordpress/i18n';
18
20
  import { chevronDown, chevronUp } from '@wordpress/icons';
19
21
 
20
22
  /**
@@ -35,98 +37,6 @@ import { getSummaryFields } from '../get-summary-fields';
35
37
  import useReportValidity from '../../../hooks/use-report-validity';
36
38
  import ValidationBadge from '../validation-badge';
37
39
 
38
- const NonCollapsibleCardHeader = ( {
39
- children,
40
- ...props
41
- }: {
42
- children: React.ReactNode;
43
- } ) => (
44
- <OriginalCardHeader isBorderless { ...props }>
45
- <div
46
- style={ {
47
- height: '40px', // This is to match the chevron's __next40pxDefaultSize
48
- width: '100%',
49
- display: 'flex',
50
- justifyContent: 'space-between',
51
- alignItems: 'center',
52
- } }
53
- >
54
- { children }
55
- </div>
56
- </OriginalCardHeader>
57
- );
58
-
59
- export function useCardHeader( layout: NormalizedCardLayout ) {
60
- const { isOpened, isCollapsible } = layout;
61
- const [ isOpen, setIsOpen ] = useState( isOpened );
62
- const [ touched, setTouched ] = useState( false );
63
-
64
- // Sync internal state when the isOpened prop changes.
65
- // This is unlikely to happen in production, but it helps with storybook controls.
66
- useEffect( () => {
67
- setIsOpen( isOpened );
68
- }, [ isOpened ] );
69
-
70
- const toggle = useCallback( () => {
71
- // Mark as touched when collapsing (going from open to closed)
72
- if ( isOpen ) {
73
- setTouched( true );
74
- }
75
- setIsOpen( ( prev ) => ! prev );
76
- }, [ isOpen ] );
77
-
78
- const CollapsibleCardHeader = useCallback(
79
- ( {
80
- children,
81
- ...props
82
- }: {
83
- children: React.ReactNode;
84
- [ key: string ]: any;
85
- } ) => (
86
- <OriginalCardHeader
87
- { ...props }
88
- onClick={ toggle }
89
- style={ {
90
- cursor: 'pointer',
91
- ...props.style,
92
- } }
93
- isBorderless
94
- >
95
- <div
96
- style={ {
97
- width: '100%',
98
- display: 'flex',
99
- justifyContent: 'space-between',
100
- alignItems: 'center',
101
- } }
102
- >
103
- { children }
104
- </div>
105
- <Button
106
- __next40pxDefaultSize
107
- variant="tertiary"
108
- icon={ isOpen ? chevronUp : chevronDown }
109
- aria-expanded={ isOpen }
110
- aria-label={ isOpen ? 'Collapse' : 'Expand' }
111
- />
112
- </OriginalCardHeader>
113
- ),
114
- [ toggle, isOpen ]
115
- );
116
-
117
- const effectiveIsOpen = isCollapsible ? isOpen : true;
118
- const CardHeaderComponent = isCollapsible
119
- ? CollapsibleCardHeader
120
- : NonCollapsibleCardHeader;
121
-
122
- return {
123
- isOpen: effectiveIsOpen,
124
- CardHeader: CardHeaderComponent,
125
- touched,
126
- setTouched,
127
- };
128
- }
129
-
130
40
  function isSummaryFieldVisible< Item >(
131
41
  summaryField: NormalizedField< Item >,
132
42
  summaryConfig: NormalizedCardLayout[ 'summary' ],
@@ -189,6 +99,10 @@ export default function FormCardField< Item >( {
189
99
  const { fields } = useContext( DataFormContext );
190
100
  const layout = field.layout as NormalizedCardLayout;
191
101
  const cardBodyRef = useRef< HTMLDivElement >( null );
102
+ const bodyId = useInstanceId(
103
+ FormCardField,
104
+ 'dataforms-layouts-card-card-body'
105
+ );
192
106
 
193
107
  const form: NormalizedForm = useMemo(
194
108
  () => ( {
@@ -198,7 +112,27 @@ export default function FormCardField< Item >( {
198
112
  [ field ]
199
113
  );
200
114
 
201
- const { isOpen, CardHeader, touched, setTouched } = useCardHeader( layout );
115
+ const { isOpened, isCollapsible } = layout;
116
+ const [ internalIsOpen, setIsOpen ] = useState( isOpened );
117
+ const [ touched, setTouched ] = useState( false );
118
+
119
+ // Sync internal state when the isOpened prop changes.
120
+ // This is unlikely to happen in production, but it helps with storybook controls.
121
+ useEffect( () => {
122
+ setIsOpen( isOpened );
123
+ }, [ isOpened ] );
124
+
125
+ const toggle = useCallback( () => {
126
+ setIsOpen( ( prev ) => {
127
+ // Mark as touched when collapsing (going from open to closed)
128
+ if ( prev ) {
129
+ setTouched( true );
130
+ }
131
+ return ! prev;
132
+ } );
133
+ }, [] );
134
+
135
+ const isOpen = isCollapsible ? internalIsOpen : true;
202
136
 
203
137
  // Mark the card as touched when any field inside it is blurred.
204
138
  // This aligns with how validated controls show errors on blur.
@@ -228,24 +162,86 @@ export default function FormCardField< Item >( {
228
162
  inlineEnd: 'medium' as const,
229
163
  };
230
164
 
231
- if ( !! field.children ) {
232
- const withHeader = !! field.label && layout.withHeader;
165
+ let label = field.label;
166
+ let withHeader: boolean;
167
+ let bodyContent: React.ReactNode;
168
+
169
+ if ( field.children ) {
170
+ withHeader = !! label && layout.withHeader;
171
+ bodyContent = (
172
+ <>
173
+ { field.description && (
174
+ <div className="dataforms-layouts-card__field-description">
175
+ { field.description }
176
+ </div>
177
+ ) }
178
+ <DataFormLayout
179
+ data={ data }
180
+ form={ form }
181
+ onChange={ onChange }
182
+ validity={ validity?.children }
183
+ />
184
+ </>
185
+ );
186
+ } else {
187
+ const fieldDefinition = fields.find(
188
+ ( fieldDef ) => fieldDef.id === field.id
189
+ );
233
190
 
234
- const sizeCardBody = {
235
- blockStart: withHeader
236
- ? ( 'none' as const )
237
- : ( 'medium' as const ),
238
- blockEnd: 'medium' as const,
239
- inlineStart: 'medium' as const,
240
- inlineEnd: 'medium' as const,
241
- };
191
+ if ( ! fieldDefinition || ! fieldDefinition.Edit ) {
192
+ return null;
193
+ }
242
194
 
243
- return (
244
- <Card className="dataforms-layouts-card__field" size={ sizeCard }>
245
- { withHeader && (
246
- <CardHeader className="dataforms-layouts-card__field-header">
195
+ const SingleFieldLayout = getFormFieldLayout( 'regular' )?.component;
196
+ if ( ! SingleFieldLayout ) {
197
+ return null;
198
+ }
199
+
200
+ label = fieldDefinition.label;
201
+ withHeader = !! label && layout.withHeader;
202
+ bodyContent = (
203
+ <SingleFieldLayout
204
+ data={ data }
205
+ field={ field }
206
+ onChange={ onChange }
207
+ hideLabelFromVision={ hideLabelFromVision || withHeader }
208
+ markWhenOptional={ markWhenOptional }
209
+ validity={ validity }
210
+ />
211
+ );
212
+ }
213
+
214
+ const sizeCardBody = {
215
+ blockStart: withHeader ? ( 'none' as const ) : ( 'medium' as const ),
216
+ blockEnd: 'medium' as const,
217
+ inlineStart: 'medium' as const,
218
+ inlineEnd: 'medium' as const,
219
+ };
220
+
221
+ return (
222
+ <Card className="dataforms-layouts-card__field" size={ sizeCard }>
223
+ { withHeader && (
224
+ <OriginalCardHeader
225
+ className="dataforms-layouts-card__field-header"
226
+ onClick={ isCollapsible ? toggle : undefined }
227
+ style={ {
228
+ cursor: isCollapsible ? 'pointer' : undefined,
229
+ } }
230
+ isBorderless
231
+ >
232
+ <div
233
+ style={ {
234
+ // Match the expand/collapse button's height to avoid layout
235
+ // differences when that button is not displayed.
236
+ height: isCollapsible ? undefined : '40px',
237
+ width: '100%',
238
+ display: 'flex',
239
+ justifyContent: 'space-between',
240
+ alignItems: 'center',
241
+ } }
242
+ >
247
243
  <span className="dataforms-layouts-card__field-header-label">
248
- { field.label }
244
+ { label }
249
245
  </span>
250
246
  { validationBadge }
251
247
  { visibleSummaryFields.length > 0 &&
@@ -262,95 +258,32 @@ export default function FormCardField< Item >( {
262
258
  ) }
263
259
  </div>
264
260
  ) }
265
- </CardHeader>
266
- ) }
267
- { ( isOpen || ! withHeader ) && (
268
- // If it doesn't have a header, keep it open.
269
- // Otherwise, the card will not be visible.
270
- <CardBody
271
- size={ sizeCardBody }
272
- className="dataforms-layouts-card__field-control"
273
- ref={ cardBodyRef }
274
- onBlur={ handleBlur }
275
- >
276
- { field.description && (
277
- <div className="dataforms-layouts-card__field-description">
278
- { field.description }
279
- </div>
280
- ) }
281
- <DataFormLayout
282
- data={ data }
283
- form={ form }
284
- onChange={ onChange }
285
- validity={ validity?.children }
261
+ </div>
262
+ { isCollapsible && (
263
+ <Button
264
+ __next40pxDefaultSize
265
+ variant="tertiary"
266
+ icon={ isOpen ? chevronUp : chevronDown }
267
+ aria-expanded={ isOpen }
268
+ aria-controls={ bodyId }
269
+ aria-label={
270
+ isOpen ? __( 'Collapse' ) : __( 'Expand' )
271
+ }
286
272
  />
287
- </CardBody>
288
- ) }
289
- </Card>
290
- );
291
- }
292
-
293
- const fieldDefinition = fields.find(
294
- ( fieldDef ) => fieldDef.id === field.id
295
- );
296
-
297
- if ( ! fieldDefinition || ! fieldDefinition.Edit ) {
298
- return null;
299
- }
300
-
301
- const RegularLayout = getFormFieldLayout( 'regular' )?.component;
302
- if ( ! RegularLayout ) {
303
- return null;
304
- }
305
- const withHeader = !! fieldDefinition.label && layout.withHeader;
306
-
307
- const sizeCardBody = {
308
- blockStart: withHeader ? ( 'none' as const ) : ( 'medium' as const ),
309
- blockEnd: 'medium' as const,
310
- inlineStart: 'medium' as const,
311
- inlineEnd: 'medium' as const,
312
- };
313
-
314
- return (
315
- <Card className="dataforms-layouts-card__field" size={ sizeCard }>
316
- { withHeader && (
317
- <CardHeader className="dataforms-layouts-card__field-header">
318
- <span className="dataforms-layouts-card__field-header-label">
319
- { fieldDefinition.label }
320
- </span>
321
- { validationBadge }
322
- { visibleSummaryFields.length > 0 && layout.withHeader && (
323
- <div className="dataforms-layouts-card__field-summary">
324
- { visibleSummaryFields.map( ( summaryField ) => (
325
- <summaryField.render
326
- key={ summaryField.id }
327
- item={ data }
328
- field={ summaryField }
329
- />
330
- ) ) }
331
- </div>
332
273
  ) }
333
- </CardHeader>
274
+ </OriginalCardHeader>
334
275
  ) }
335
276
  { ( isOpen || ! withHeader ) && (
336
277
  // If it doesn't have a header, keep it open.
337
278
  // Otherwise, the card will not be visible.
338
279
  <CardBody
280
+ id={ bodyId }
339
281
  size={ sizeCardBody }
340
282
  className="dataforms-layouts-card__field-control"
341
283
  ref={ cardBodyRef }
342
284
  onBlur={ handleBlur }
343
285
  >
344
- <RegularLayout
345
- data={ data }
346
- field={ field }
347
- onChange={ onChange }
348
- hideLabelFromVision={
349
- hideLabelFromVision || withHeader
350
- }
351
- markWhenOptional={ markWhenOptional }
352
- validity={ validity }
353
- />
286
+ { bodyContent }
354
287
  </CardBody>
355
288
  ) }
356
289
  </Card>
@@ -34,7 +34,7 @@ const FORM_FIELD_LAYOUTS = [
34
34
  <Stack
35
35
  direction="column"
36
36
  className="dataforms-layouts__wrapper"
37
- gap="sm"
37
+ gap="md"
38
38
  >
39
39
  { children }
40
40
  </Stack>
@@ -60,6 +60,7 @@ function normalizeLayout( layout?: Layout ): NormalizedLayout {
60
60
  labelPosition: layout?.labelPosition ?? 'side',
61
61
  openAs: layout?.openAs ?? 'dropdown',
62
62
  summary: normalizedSummary,
63
+ editVisibility: layout?.editVisibility ?? 'on-hover',
63
64
  } satisfies NormalizedPanelLayout;
64
65
  } else if ( layout?.type === 'card' ) {
65
66
  if ( layout.withHeader === false ) {