@wordpress/dataviews 11.3.1-next.v.0 → 12.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 (444) hide show
  1. package/CHANGELOG.md +46 -1
  2. package/README.md +44 -2
  3. package/build/components/dataform-controls/adaptive-select.cjs +52 -0
  4. package/build/components/dataform-controls/adaptive-select.cjs.map +7 -0
  5. package/build/components/dataform-controls/array.cjs +2 -0
  6. package/build/components/dataform-controls/array.cjs.map +2 -2
  7. package/build/components/dataform-controls/checkbox.cjs +2 -0
  8. package/build/components/dataform-controls/checkbox.cjs.map +2 -2
  9. package/build/components/dataform-controls/color.cjs +21 -30
  10. package/build/components/dataform-controls/color.cjs.map +3 -3
  11. package/build/components/dataform-controls/combobox.cjs +80 -0
  12. package/build/components/dataform-controls/combobox.cjs.map +7 -0
  13. package/build/components/dataform-controls/date.cjs +58 -19
  14. package/build/components/dataform-controls/date.cjs.map +2 -2
  15. package/build/components/dataform-controls/datetime.cjs +11 -3
  16. package/build/components/dataform-controls/datetime.cjs.map +2 -2
  17. package/build/components/dataform-controls/email.cjs +2 -0
  18. package/build/components/dataform-controls/email.cjs.map +2 -2
  19. package/build/components/dataform-controls/index.cjs +5 -1
  20. package/build/components/dataform-controls/index.cjs.map +3 -3
  21. package/build/components/dataform-controls/password.cjs +2 -0
  22. package/build/components/dataform-controls/password.cjs.map +2 -2
  23. package/build/components/dataform-controls/radio.cjs +2 -0
  24. package/build/components/dataform-controls/radio.cjs.map +2 -2
  25. package/build/components/dataform-controls/select.cjs +2 -0
  26. package/build/components/dataform-controls/select.cjs.map +2 -2
  27. package/build/components/dataform-controls/telephone.cjs +2 -0
  28. package/build/components/dataform-controls/telephone.cjs.map +2 -2
  29. package/build/components/dataform-controls/text.cjs +2 -0
  30. package/build/components/dataform-controls/text.cjs.map +2 -2
  31. package/build/components/dataform-controls/textarea.cjs +2 -0
  32. package/build/components/dataform-controls/textarea.cjs.map +2 -2
  33. package/build/components/dataform-controls/toggle-group.cjs +2 -0
  34. package/build/components/dataform-controls/toggle-group.cjs.map +2 -2
  35. package/build/components/dataform-controls/toggle.cjs +2 -0
  36. package/build/components/dataform-controls/toggle.cjs.map +2 -2
  37. package/build/components/dataform-controls/url.cjs +2 -0
  38. package/build/components/dataform-controls/url.cjs.map +2 -2
  39. package/build/components/dataform-controls/utils/relative-date-control.cjs +1 -1
  40. package/build/components/dataform-controls/utils/relative-date-control.cjs.map +1 -1
  41. package/build/components/dataform-controls/utils/validated-input.cjs +2 -0
  42. package/build/components/dataform-controls/utils/validated-input.cjs.map +2 -2
  43. package/build/components/dataform-controls/utils/validated-number.cjs +2 -0
  44. package/build/components/dataform-controls/utils/validated-number.cjs.map +2 -2
  45. package/build/components/dataform-layouts/card/index.cjs +28 -3
  46. package/build/components/dataform-layouts/card/index.cjs.map +3 -3
  47. package/build/components/dataform-layouts/data-form-layout.cjs +11 -2
  48. package/build/components/dataform-layouts/data-form-layout.cjs.map +2 -2
  49. package/build/components/dataform-layouts/details/index.cjs +69 -12
  50. package/build/components/dataform-layouts/details/index.cjs.map +3 -3
  51. package/build/components/dataform-layouts/index.cjs +5 -5
  52. package/build/components/dataform-layouts/index.cjs.map +1 -1
  53. package/build/components/dataform-layouts/normalize-form.cjs +2 -1
  54. package/build/components/dataform-layouts/normalize-form.cjs.map +2 -2
  55. package/build/components/dataform-layouts/panel/dropdown.cjs +88 -63
  56. package/build/components/dataform-layouts/panel/dropdown.cjs.map +3 -3
  57. package/build/components/dataform-layouts/panel/index.cjs +13 -175
  58. package/build/components/dataform-layouts/panel/index.cjs.map +3 -3
  59. package/build/components/dataform-layouts/panel/modal.cjs +28 -18
  60. package/build/components/dataform-layouts/panel/modal.cjs.map +3 -3
  61. package/build/components/dataform-layouts/panel/summary-button.cjs +125 -56
  62. package/build/components/dataform-layouts/panel/summary-button.cjs.map +3 -3
  63. package/build/components/dataform-layouts/panel/utils/get-first-validation-error.cjs +59 -0
  64. package/build/components/dataform-layouts/panel/utils/get-first-validation-error.cjs.map +7 -0
  65. package/build/components/dataform-layouts/panel/utils/get-label-classname.cjs +45 -0
  66. package/build/components/dataform-layouts/panel/utils/get-label-classname.cjs.map +7 -0
  67. package/build/components/dataform-layouts/panel/utils/get-label-content.cjs +36 -0
  68. package/build/components/dataform-layouts/panel/utils/get-label-content.cjs.map +7 -0
  69. package/build/components/dataform-layouts/panel/utils/use-field-from-form-field.cjs +77 -0
  70. package/build/components/dataform-layouts/panel/utils/use-field-from-form-field.cjs.map +7 -0
  71. package/build/components/dataform-layouts/regular/index.cjs +6 -3
  72. package/build/components/dataform-layouts/regular/index.cjs.map +2 -2
  73. package/build/components/dataform-layouts/row/index.cjs +5 -2
  74. package/build/components/dataform-layouts/row/index.cjs.map +2 -2
  75. package/build/components/dataform-layouts/validation-badge.cjs +67 -0
  76. package/build/components/dataform-layouts/validation-badge.cjs.map +7 -0
  77. package/build/components/dataviews-bulk-actions/index.cjs +4 -4
  78. package/build/components/dataviews-bulk-actions/index.cjs.map +2 -2
  79. package/build/components/dataviews-context/index.cjs.map +2 -2
  80. package/build/components/dataviews-filters/filter.cjs +1 -1
  81. package/build/components/dataviews-filters/filter.cjs.map +1 -1
  82. package/build/components/dataviews-filters/filters.cjs +1 -1
  83. package/build/components/dataviews-filters/filters.cjs.map +1 -1
  84. package/build/components/dataviews-filters/search-widget.cjs +25 -11
  85. package/build/components/dataviews-filters/search-widget.cjs.map +2 -2
  86. package/build/components/dataviews-filters/toggle.cjs.map +1 -1
  87. package/build/components/dataviews-footer/index.cjs +1 -1
  88. package/build/components/dataviews-footer/index.cjs.map +1 -1
  89. package/build/components/dataviews-layouts/activity/activity-item.cjs +4 -4
  90. package/build/components/dataviews-layouts/activity/activity-item.cjs.map +1 -1
  91. package/build/components/dataviews-layouts/activity/index.cjs +1 -1
  92. package/build/components/dataviews-layouts/activity/index.cjs.map +1 -1
  93. package/build/components/dataviews-layouts/grid/composite-grid.cjs +27 -38
  94. package/build/components/dataviews-layouts/grid/composite-grid.cjs.map +2 -2
  95. package/build/components/dataviews-layouts/grid/index.cjs +2 -2
  96. package/build/components/dataviews-layouts/grid/index.cjs.map +1 -1
  97. package/build/components/dataviews-layouts/list/index.cjs +7 -8
  98. package/build/components/dataviews-layouts/list/index.cjs.map +2 -2
  99. package/build/components/dataviews-layouts/picker-grid/index.cjs +5 -5
  100. package/build/components/dataviews-layouts/picker-grid/index.cjs.map +2 -2
  101. package/build/components/dataviews-layouts/picker-table/index.cjs +1 -1
  102. package/build/components/dataviews-layouts/picker-table/index.cjs.map +2 -2
  103. package/build/components/dataviews-layouts/table/column-primary.cjs +1 -1
  104. package/build/components/dataviews-layouts/table/column-primary.cjs.map +1 -1
  105. package/build/components/dataviews-layouts/table/index.cjs +1 -1
  106. package/build/components/dataviews-layouts/table/index.cjs.map +2 -2
  107. package/build/components/dataviews-layouts/utils/item-click-wrapper.cjs.map +2 -2
  108. package/build/components/dataviews-pagination/index.cjs +3 -3
  109. package/build/components/dataviews-pagination/index.cjs.map +2 -2
  110. package/build/components/dataviews-picker-footer/index.cjs +3 -3
  111. package/build/components/dataviews-picker-footer/index.cjs.map +2 -2
  112. package/build/components/dataviews-view-config/index.cjs +74 -57
  113. package/build/components/dataviews-view-config/index.cjs.map +3 -3
  114. package/build/components/dataviews-view-config/properties-section.cjs +1 -1
  115. package/build/components/dataviews-view-config/properties-section.cjs.map +1 -1
  116. package/build/dataviews/index.cjs +7 -5
  117. package/build/dataviews/index.cjs.map +2 -2
  118. package/build/dataviews-picker/index.cjs +3 -3
  119. package/build/dataviews-picker/index.cjs.map +2 -2
  120. package/build/hooks/use-form-validity.cjs +61 -28
  121. package/build/hooks/use-form-validity.cjs.map +2 -2
  122. package/build/hooks/use-report-validity.cjs +39 -0
  123. package/build/hooks/use-report-validity.cjs.map +7 -0
  124. package/build/types/dataform.cjs.map +1 -1
  125. package/build/types/field-api.cjs.map +1 -1
  126. package/build-module/components/dataform-controls/adaptive-select.mjs +21 -0
  127. package/build-module/components/dataform-controls/adaptive-select.mjs.map +7 -0
  128. package/build-module/components/dataform-controls/array.mjs +2 -0
  129. package/build-module/components/dataform-controls/array.mjs.map +2 -2
  130. package/build-module/components/dataform-controls/checkbox.mjs +2 -0
  131. package/build-module/components/dataform-controls/checkbox.mjs.map +2 -2
  132. package/build-module/components/dataform-controls/color.mjs +26 -31
  133. package/build-module/components/dataform-controls/color.mjs.map +2 -2
  134. package/build-module/components/dataform-controls/combobox.mjs +49 -0
  135. package/build-module/components/dataform-controls/combobox.mjs.map +7 -0
  136. package/build-module/components/dataform-controls/date.mjs +58 -19
  137. package/build-module/components/dataform-controls/date.mjs.map +2 -2
  138. package/build-module/components/dataform-controls/datetime.mjs +11 -3
  139. package/build-module/components/dataform-controls/datetime.mjs.map +2 -2
  140. package/build-module/components/dataform-controls/email.mjs +2 -0
  141. package/build-module/components/dataform-controls/email.mjs.map +2 -2
  142. package/build-module/components/dataform-controls/index.mjs +5 -1
  143. package/build-module/components/dataform-controls/index.mjs.map +2 -2
  144. package/build-module/components/dataform-controls/password.mjs +2 -0
  145. package/build-module/components/dataform-controls/password.mjs.map +2 -2
  146. package/build-module/components/dataform-controls/radio.mjs +2 -0
  147. package/build-module/components/dataform-controls/radio.mjs.map +2 -2
  148. package/build-module/components/dataform-controls/select.mjs +2 -0
  149. package/build-module/components/dataform-controls/select.mjs.map +2 -2
  150. package/build-module/components/dataform-controls/telephone.mjs +2 -0
  151. package/build-module/components/dataform-controls/telephone.mjs.map +2 -2
  152. package/build-module/components/dataform-controls/text.mjs +2 -0
  153. package/build-module/components/dataform-controls/text.mjs.map +2 -2
  154. package/build-module/components/dataform-controls/textarea.mjs +2 -0
  155. package/build-module/components/dataform-controls/textarea.mjs.map +2 -2
  156. package/build-module/components/dataform-controls/toggle-group.mjs +2 -0
  157. package/build-module/components/dataform-controls/toggle-group.mjs.map +2 -2
  158. package/build-module/components/dataform-controls/toggle.mjs +2 -0
  159. package/build-module/components/dataform-controls/toggle.mjs.map +2 -2
  160. package/build-module/components/dataform-controls/url.mjs +2 -0
  161. package/build-module/components/dataform-controls/url.mjs.map +2 -2
  162. package/build-module/components/dataform-controls/utils/relative-date-control.mjs +1 -1
  163. package/build-module/components/dataform-controls/utils/relative-date-control.mjs.map +1 -1
  164. package/build-module/components/dataform-controls/utils/validated-input.mjs +2 -0
  165. package/build-module/components/dataform-controls/utils/validated-input.mjs.map +2 -2
  166. package/build-module/components/dataform-controls/utils/validated-number.mjs +2 -0
  167. package/build-module/components/dataform-controls/utils/validated-number.mjs.map +2 -2
  168. package/build-module/components/dataform-layouts/card/index.mjs +29 -3
  169. package/build-module/components/dataform-layouts/card/index.mjs.map +2 -2
  170. package/build-module/components/dataform-layouts/data-form-layout.mjs +12 -3
  171. package/build-module/components/dataform-layouts/data-form-layout.mjs.map +2 -2
  172. package/build-module/components/dataform-layouts/details/index.mjs +77 -13
  173. package/build-module/components/dataform-layouts/details/index.mjs.map +2 -2
  174. package/build-module/components/dataform-layouts/index.mjs +5 -5
  175. package/build-module/components/dataform-layouts/index.mjs.map +1 -1
  176. package/build-module/components/dataform-layouts/normalize-form.mjs +2 -1
  177. package/build-module/components/dataform-layouts/normalize-form.mjs.map +2 -2
  178. package/build-module/components/dataform-layouts/panel/dropdown.mjs +91 -66
  179. package/build-module/components/dataform-layouts/panel/dropdown.mjs.map +2 -2
  180. package/build-module/components/dataform-layouts/panel/index.mjs +14 -176
  181. package/build-module/components/dataform-layouts/panel/index.mjs.map +2 -2
  182. package/build-module/components/dataform-layouts/panel/modal.mjs +30 -20
  183. package/build-module/components/dataform-layouts/panel/modal.mjs.map +2 -2
  184. package/build-module/components/dataform-layouts/panel/summary-button.mjs +117 -58
  185. package/build-module/components/dataform-layouts/panel/summary-button.mjs.map +2 -2
  186. package/build-module/components/dataform-layouts/panel/utils/get-first-validation-error.mjs +38 -0
  187. package/build-module/components/dataform-layouts/panel/utils/get-first-validation-error.mjs.map +7 -0
  188. package/build-module/components/dataform-layouts/panel/utils/get-label-classname.mjs +14 -0
  189. package/build-module/components/dataform-layouts/panel/utils/get-label-classname.mjs.map +7 -0
  190. package/build-module/components/dataform-layouts/panel/utils/get-label-content.mjs +15 -0
  191. package/build-module/components/dataform-layouts/panel/utils/get-label-content.mjs.map +7 -0
  192. package/build-module/components/dataform-layouts/panel/utils/use-field-from-form-field.mjs +46 -0
  193. package/build-module/components/dataform-layouts/panel/utils/use-field-from-form-field.mjs.map +7 -0
  194. package/build-module/components/dataform-layouts/regular/index.mjs +6 -3
  195. package/build-module/components/dataform-layouts/regular/index.mjs.map +2 -2
  196. package/build-module/components/dataform-layouts/row/index.mjs +5 -2
  197. package/build-module/components/dataform-layouts/row/index.mjs.map +2 -2
  198. package/build-module/components/dataform-layouts/validation-badge.mjs +46 -0
  199. package/build-module/components/dataform-layouts/validation-badge.mjs.map +7 -0
  200. package/build-module/components/dataviews-bulk-actions/index.mjs +4 -4
  201. package/build-module/components/dataviews-bulk-actions/index.mjs.map +2 -2
  202. package/build-module/components/dataviews-context/index.mjs.map +2 -2
  203. package/build-module/components/dataviews-filters/filter.mjs +1 -1
  204. package/build-module/components/dataviews-filters/filter.mjs.map +1 -1
  205. package/build-module/components/dataviews-filters/filters.mjs +1 -1
  206. package/build-module/components/dataviews-filters/filters.mjs.map +1 -1
  207. package/build-module/components/dataviews-filters/search-widget.mjs +25 -11
  208. package/build-module/components/dataviews-filters/search-widget.mjs.map +2 -2
  209. package/build-module/components/dataviews-filters/toggle.mjs.map +1 -1
  210. package/build-module/components/dataviews-footer/index.mjs +1 -1
  211. package/build-module/components/dataviews-footer/index.mjs.map +1 -1
  212. package/build-module/components/dataviews-layouts/activity/activity-item.mjs +4 -4
  213. package/build-module/components/dataviews-layouts/activity/activity-item.mjs.map +1 -1
  214. package/build-module/components/dataviews-layouts/activity/index.mjs +1 -1
  215. package/build-module/components/dataviews-layouts/activity/index.mjs.map +1 -1
  216. package/build-module/components/dataviews-layouts/grid/composite-grid.mjs +27 -38
  217. package/build-module/components/dataviews-layouts/grid/composite-grid.mjs.map +2 -2
  218. package/build-module/components/dataviews-layouts/grid/index.mjs +2 -2
  219. package/build-module/components/dataviews-layouts/grid/index.mjs.map +1 -1
  220. package/build-module/components/dataviews-layouts/list/index.mjs +7 -8
  221. package/build-module/components/dataviews-layouts/list/index.mjs.map +2 -2
  222. package/build-module/components/dataviews-layouts/picker-grid/index.mjs +5 -5
  223. package/build-module/components/dataviews-layouts/picker-grid/index.mjs.map +2 -2
  224. package/build-module/components/dataviews-layouts/picker-table/index.mjs +1 -1
  225. package/build-module/components/dataviews-layouts/picker-table/index.mjs.map +2 -2
  226. package/build-module/components/dataviews-layouts/table/column-primary.mjs +1 -1
  227. package/build-module/components/dataviews-layouts/table/column-primary.mjs.map +1 -1
  228. package/build-module/components/dataviews-layouts/table/index.mjs +1 -1
  229. package/build-module/components/dataviews-layouts/table/index.mjs.map +2 -2
  230. package/build-module/components/dataviews-layouts/utils/item-click-wrapper.mjs.map +2 -2
  231. package/build-module/components/dataviews-pagination/index.mjs +3 -3
  232. package/build-module/components/dataviews-pagination/index.mjs.map +2 -2
  233. package/build-module/components/dataviews-picker-footer/index.mjs +3 -3
  234. package/build-module/components/dataviews-picker-footer/index.mjs.map +2 -2
  235. package/build-module/components/dataviews-view-config/index.mjs +74 -59
  236. package/build-module/components/dataviews-view-config/index.mjs.map +2 -2
  237. package/build-module/components/dataviews-view-config/properties-section.mjs +1 -1
  238. package/build-module/components/dataviews-view-config/properties-section.mjs.map +1 -1
  239. package/build-module/dataviews/index.mjs +7 -5
  240. package/build-module/dataviews/index.mjs.map +2 -2
  241. package/build-module/dataviews-picker/index.mjs +3 -3
  242. package/build-module/dataviews-picker/index.mjs.map +2 -2
  243. package/build-module/hooks/use-form-validity.mjs +61 -28
  244. package/build-module/hooks/use-form-validity.mjs.map +2 -2
  245. package/build-module/hooks/use-report-validity.mjs +18 -0
  246. package/build-module/hooks/use-report-validity.mjs.map +7 -0
  247. package/build-style/style-rtl.css +149 -217
  248. package/build-style/style.css +149 -217
  249. package/build-types/components/dataform-controls/adaptive-select.d.ts +6 -0
  250. package/build-types/components/dataform-controls/adaptive-select.d.ts.map +1 -0
  251. package/build-types/components/dataform-controls/array.d.ts +1 -1
  252. package/build-types/components/dataform-controls/array.d.ts.map +1 -1
  253. package/build-types/components/dataform-controls/checkbox.d.ts +1 -1
  254. package/build-types/components/dataform-controls/checkbox.d.ts.map +1 -1
  255. package/build-types/components/dataform-controls/color.d.ts +1 -1
  256. package/build-types/components/dataform-controls/color.d.ts.map +1 -1
  257. package/build-types/components/dataform-controls/combobox.d.ts +6 -0
  258. package/build-types/components/dataform-controls/combobox.d.ts.map +1 -0
  259. package/build-types/components/dataform-controls/date.d.ts +1 -1
  260. package/build-types/components/dataform-controls/date.d.ts.map +1 -1
  261. package/build-types/components/dataform-controls/datetime.d.ts +1 -1
  262. package/build-types/components/dataform-controls/datetime.d.ts.map +1 -1
  263. package/build-types/components/dataform-controls/email.d.ts +1 -1
  264. package/build-types/components/dataform-controls/email.d.ts.map +1 -1
  265. package/build-types/components/dataform-controls/index.d.ts.map +1 -1
  266. package/build-types/components/dataform-controls/password.d.ts +1 -1
  267. package/build-types/components/dataform-controls/password.d.ts.map +1 -1
  268. package/build-types/components/dataform-controls/radio.d.ts +1 -1
  269. package/build-types/components/dataform-controls/radio.d.ts.map +1 -1
  270. package/build-types/components/dataform-controls/select.d.ts +1 -1
  271. package/build-types/components/dataform-controls/select.d.ts.map +1 -1
  272. package/build-types/components/dataform-controls/telephone.d.ts +1 -1
  273. package/build-types/components/dataform-controls/telephone.d.ts.map +1 -1
  274. package/build-types/components/dataform-controls/text.d.ts +1 -1
  275. package/build-types/components/dataform-controls/text.d.ts.map +1 -1
  276. package/build-types/components/dataform-controls/textarea.d.ts +1 -1
  277. package/build-types/components/dataform-controls/textarea.d.ts.map +1 -1
  278. package/build-types/components/dataform-controls/toggle-group.d.ts +1 -1
  279. package/build-types/components/dataform-controls/toggle-group.d.ts.map +1 -1
  280. package/build-types/components/dataform-controls/toggle.d.ts +1 -1
  281. package/build-types/components/dataform-controls/toggle.d.ts.map +1 -1
  282. package/build-types/components/dataform-controls/url.d.ts +1 -1
  283. package/build-types/components/dataform-controls/url.d.ts.map +1 -1
  284. package/build-types/components/dataform-controls/utils/validated-input.d.ts +1 -1
  285. package/build-types/components/dataform-controls/utils/validated-input.d.ts.map +1 -1
  286. package/build-types/components/dataform-controls/utils/validated-number.d.ts +1 -1
  287. package/build-types/components/dataform-controls/utils/validated-number.d.ts.map +1 -1
  288. package/build-types/components/dataform-layouts/card/index.d.ts +3 -1
  289. package/build-types/components/dataform-layouts/card/index.d.ts.map +1 -1
  290. package/build-types/components/dataform-layouts/data-form-layout.d.ts +2 -1
  291. package/build-types/components/dataform-layouts/data-form-layout.d.ts.map +1 -1
  292. package/build-types/components/dataform-layouts/details/index.d.ts +1 -1
  293. package/build-types/components/dataform-layouts/details/index.d.ts.map +1 -1
  294. package/build-types/components/dataform-layouts/normalize-form.d.ts.map +1 -1
  295. package/build-types/components/dataform-layouts/panel/dropdown.d.ts +2 -12
  296. package/build-types/components/dataform-layouts/panel/dropdown.d.ts.map +1 -1
  297. package/build-types/components/dataform-layouts/panel/index.d.ts +1 -1
  298. package/build-types/components/dataform-layouts/panel/index.d.ts.map +1 -1
  299. package/build-types/components/dataform-layouts/panel/modal.d.ts +2 -10
  300. package/build-types/components/dataform-layouts/panel/modal.d.ts.map +1 -1
  301. package/build-types/components/dataform-layouts/panel/summary-button.d.ts +6 -5
  302. package/build-types/components/dataform-layouts/panel/summary-button.d.ts.map +1 -1
  303. package/build-types/components/dataform-layouts/panel/utils/get-first-validation-error.d.ts +4 -0
  304. package/build-types/components/dataform-layouts/panel/utils/get-first-validation-error.d.ts.map +1 -0
  305. package/build-types/components/dataform-layouts/panel/utils/get-label-classname.d.ts +4 -0
  306. package/build-types/components/dataform-layouts/panel/utils/get-label-classname.d.ts.map +1 -0
  307. package/build-types/components/dataform-layouts/panel/utils/get-label-content.d.ts +3 -0
  308. package/build-types/components/dataform-layouts/panel/utils/get-label-content.d.ts.map +1 -0
  309. package/build-types/components/dataform-layouts/panel/utils/use-field-from-form-field.d.ts +23 -0
  310. package/build-types/components/dataform-layouts/panel/utils/use-field-from-form-field.d.ts.map +1 -0
  311. package/build-types/components/dataform-layouts/regular/index.d.ts +1 -1
  312. package/build-types/components/dataform-layouts/regular/index.d.ts.map +1 -1
  313. package/build-types/components/dataform-layouts/row/index.d.ts +1 -1
  314. package/build-types/components/dataform-layouts/row/index.d.ts.map +1 -1
  315. package/build-types/components/dataform-layouts/validation-badge.d.ts +8 -0
  316. package/build-types/components/dataform-layouts/validation-badge.d.ts.map +1 -0
  317. package/build-types/components/dataviews-context/index.d.ts +1 -0
  318. package/build-types/components/dataviews-context/index.d.ts.map +1 -1
  319. package/build-types/components/dataviews-filters/filter.d.ts +1 -1
  320. package/build-types/components/dataviews-filters/filter.d.ts.map +1 -1
  321. package/build-types/components/dataviews-filters/search-widget.d.ts.map +1 -1
  322. package/build-types/components/dataviews-layouts/list/index.d.ts.map +1 -1
  323. package/build-types/components/dataviews-layouts/utils/item-click-wrapper.d.ts +1 -0
  324. package/build-types/components/dataviews-layouts/utils/item-click-wrapper.d.ts.map +1 -1
  325. package/build-types/components/dataviews-view-config/index.d.ts.map +1 -1
  326. package/build-types/dataform/stories/content.story.d.ts +14 -0
  327. package/build-types/dataform/stories/content.story.d.ts.map +1 -0
  328. package/build-types/dataform/stories/index.story.d.ts +10 -2
  329. package/build-types/dataform/stories/index.story.d.ts.map +1 -1
  330. package/build-types/dataform/stories/layout-panel.d.ts +3 -1
  331. package/build-types/dataform/stories/layout-panel.d.ts.map +1 -1
  332. package/build-types/dataform/stories/validation.d.ts +1 -1
  333. package/build-types/dataform/stories/validation.d.ts.map +1 -1
  334. package/build-types/dataviews/index.d.ts +2 -1
  335. package/build-types/dataviews/index.d.ts.map +1 -1
  336. package/build-types/dataviews/stories/fixtures.d.ts +1 -0
  337. package/build-types/dataviews/stories/fixtures.d.ts.map +1 -1
  338. package/build-types/dataviews/stories/index.story.d.ts +14 -2
  339. package/build-types/dataviews/stories/index.story.d.ts.map +1 -1
  340. package/build-types/dataviews/stories/layout-activity.d.ts +2 -1
  341. package/build-types/dataviews/stories/layout-activity.d.ts.map +1 -1
  342. package/build-types/dataviews/stories/layout-list.d.ts +2 -1
  343. package/build-types/dataviews/stories/layout-list.d.ts.map +1 -1
  344. package/build-types/field-types/stories/index.story.d.ts +42 -16
  345. package/build-types/field-types/stories/index.story.d.ts.map +1 -1
  346. package/build-types/hooks/use-form-validity.d.ts.map +1 -1
  347. package/build-types/hooks/use-report-validity.d.ts +14 -0
  348. package/build-types/hooks/use-report-validity.d.ts.map +1 -0
  349. package/build-types/types/dataform.d.ts +4 -0
  350. package/build-types/types/dataform.d.ts.map +1 -1
  351. package/build-types/types/field-api.d.ts +4 -0
  352. package/build-types/types/field-api.d.ts.map +1 -1
  353. package/build-wp/index.js +3749 -2632
  354. package/package.json +22 -21
  355. package/src/components/dataform-controls/adaptive-select.tsx +23 -0
  356. package/src/components/dataform-controls/array.tsx +2 -0
  357. package/src/components/dataform-controls/checkbox.tsx +2 -0
  358. package/src/components/dataform-controls/color.tsx +31 -36
  359. package/src/components/dataform-controls/combobox.tsx +58 -0
  360. package/src/components/dataform-controls/date.tsx +69 -26
  361. package/src/components/dataform-controls/datetime.tsx +16 -6
  362. package/src/components/dataform-controls/email.tsx +2 -0
  363. package/src/components/dataform-controls/index.tsx +5 -1
  364. package/src/components/dataform-controls/password.tsx +2 -0
  365. package/src/components/dataform-controls/radio.tsx +2 -0
  366. package/src/components/dataform-controls/select.tsx +2 -0
  367. package/src/components/dataform-controls/style.scss +4 -0
  368. package/src/components/dataform-controls/telephone.tsx +2 -0
  369. package/src/components/dataform-controls/text.tsx +2 -0
  370. package/src/components/dataform-controls/textarea.tsx +2 -0
  371. package/src/components/dataform-controls/toggle-group.tsx +2 -0
  372. package/src/components/dataform-controls/toggle.tsx +2 -0
  373. package/src/components/dataform-controls/url.tsx +2 -0
  374. package/src/components/dataform-controls/utils/relative-date-control.tsx +1 -1
  375. package/src/components/dataform-controls/utils/validated-input.tsx +2 -0
  376. package/src/components/dataform-controls/utils/validated-number.tsx +2 -0
  377. package/src/components/dataform-layouts/card/index.tsx +40 -3
  378. package/src/components/dataform-layouts/data-form-layout.tsx +18 -4
  379. package/src/components/dataform-layouts/details/index.tsx +66 -4
  380. package/src/components/dataform-layouts/details/style.scss +5 -0
  381. package/src/components/dataform-layouts/index.tsx +5 -5
  382. package/src/components/dataform-layouts/normalize-form.ts +1 -0
  383. package/src/components/dataform-layouts/panel/dropdown.tsx +110 -94
  384. package/src/components/dataform-layouts/panel/index.tsx +10 -243
  385. package/src/components/dataform-layouts/panel/modal.tsx +43 -29
  386. package/src/components/dataform-layouts/panel/style.scss +109 -27
  387. package/src/components/dataform-layouts/panel/summary-button.tsx +140 -62
  388. package/src/components/dataform-layouts/panel/utils/get-first-validation-error.ts +47 -0
  389. package/src/components/dataform-layouts/panel/utils/get-label-classname.ts +18 -0
  390. package/src/components/dataform-layouts/panel/utils/get-label-content.tsx +26 -0
  391. package/src/components/dataform-layouts/panel/utils/use-field-from-form-field.ts +78 -0
  392. package/src/components/dataform-layouts/regular/index.tsx +8 -3
  393. package/src/components/dataform-layouts/regular/style.scss +10 -0
  394. package/src/components/dataform-layouts/row/index.tsx +5 -2
  395. package/src/components/dataform-layouts/test/normalize-form.ts +5 -0
  396. package/src/components/dataform-layouts/validation-badge.tsx +63 -0
  397. package/src/components/dataviews-bulk-actions/index.tsx +4 -4
  398. package/src/components/dataviews-context/index.ts +1 -0
  399. package/src/components/dataviews-filters/filter.tsx +2 -2
  400. package/src/components/dataviews-filters/filters.tsx +1 -1
  401. package/src/components/dataviews-filters/search-widget.tsx +10 -2
  402. package/src/components/dataviews-filters/style.scss +8 -0
  403. package/src/components/dataviews-filters/toggle.tsx +1 -1
  404. package/src/components/dataviews-footer/index.tsx +1 -1
  405. package/src/components/dataviews-layouts/activity/activity-item.tsx +4 -4
  406. package/src/components/dataviews-layouts/activity/index.tsx +1 -1
  407. package/src/components/dataviews-layouts/grid/composite-grid.tsx +35 -35
  408. package/src/components/dataviews-layouts/grid/index.tsx +2 -2
  409. package/src/components/dataviews-layouts/grid/style.scss +15 -1
  410. package/src/components/dataviews-layouts/list/index.tsx +7 -8
  411. package/src/components/dataviews-layouts/list/style.scss +1 -0
  412. package/src/components/dataviews-layouts/picker-grid/index.tsx +5 -5
  413. package/src/components/dataviews-layouts/picker-table/index.tsx +1 -1
  414. package/src/components/dataviews-layouts/table/column-primary.tsx +1 -1
  415. package/src/components/dataviews-layouts/table/index.tsx +1 -1
  416. package/src/components/dataviews-layouts/utils/item-click-wrapper.tsx +1 -0
  417. package/src/components/dataviews-pagination/index.tsx +3 -3
  418. package/src/components/dataviews-picker-footer/index.tsx +3 -3
  419. package/src/components/dataviews-view-config/index.tsx +61 -50
  420. package/src/components/dataviews-view-config/properties-section.tsx +1 -1
  421. package/src/components/dataviews-view-config/style.scss +21 -0
  422. package/src/dataform/stories/content.story.mdx +159 -0
  423. package/src/dataform/stories/content.story.tsx +390 -0
  424. package/src/dataform/stories/index.story.tsx +14 -2
  425. package/src/dataform/stories/layout-panel.tsx +19 -2
  426. package/src/dataform/stories/validation.tsx +100 -7
  427. package/src/dataform/test/dataform.tsx +2 -2
  428. package/src/dataviews/index.tsx +7 -4
  429. package/src/dataviews/stories/empty.tsx +1 -1
  430. package/src/dataviews/stories/fixtures.tsx +93 -4
  431. package/src/dataviews/stories/free-composition.tsx +6 -6
  432. package/src/dataviews/stories/index.story.tsx +12 -0
  433. package/src/dataviews/stories/layout-activity.tsx +6 -3
  434. package/src/dataviews/stories/layout-list.tsx +3 -0
  435. package/src/dataviews-picker/index.tsx +4 -4
  436. package/src/dataviews-picker/stories/fixtures.tsx +2 -2
  437. package/src/dataviews-picker/stories/index.story.tsx +1 -1
  438. package/src/field-types/stories/index.story.tsx +101 -5
  439. package/src/hooks/test/use-form-validity.ts +303 -178
  440. package/src/hooks/use-form-validity.ts +85 -36
  441. package/src/hooks/use-report-validity.ts +32 -0
  442. package/src/style.scss +0 -2
  443. package/src/types/dataform.ts +5 -0
  444. package/src/types/field-api.ts +4 -0
@@ -8,24 +8,24 @@ import {
8
8
  Button,
9
9
  } from '@wordpress/components';
10
10
  import { __ } from '@wordpress/i18n';
11
- import { useMemo } from '@wordpress/element';
11
+ import { useMemo, useRef, useState } from '@wordpress/element';
12
12
  import { closeSmall } from '@wordpress/icons';
13
- import { useFocusOnMount } from '@wordpress/compose';
13
+ import { __experimentalUseDialog as useDialog } from '@wordpress/compose';
14
14
  import { Stack } from '@wordpress/ui';
15
15
 
16
16
  /**
17
17
  * Internal dependencies
18
18
  */
19
19
  import type {
20
- FieldValidity,
20
+ FieldLayoutProps,
21
21
  NormalizedForm,
22
- NormalizedFormField,
23
22
  FormValidity,
24
- NormalizedField,
25
23
  } from '../../../types';
26
24
  import { DataFormLayout } from '../data-form-layout';
27
25
  import { DEFAULT_LAYOUT } from '../normalize-form';
28
26
  import SummaryButton from './summary-button';
27
+ import useReportValidity from '../../../hooks/use-report-validity';
28
+ import useFieldFromFormField from './utils/use-field-from-form-field';
29
29
 
30
30
  function DropdownHeader( {
31
31
  title,
@@ -38,9 +38,9 @@ function DropdownHeader( {
38
38
  <Stack
39
39
  direction="column"
40
40
  className="dataforms-layouts-panel__dropdown-header"
41
- gap="md"
41
+ gap="lg"
42
42
  >
43
- <Stack direction="row" gap="xs" align="center">
43
+ <Stack direction="row" gap="sm" align="center">
44
44
  { title && (
45
45
  <Heading level={ 2 } size={ 13 }>
46
46
  { title }
@@ -60,28 +60,46 @@ function DropdownHeader( {
60
60
  );
61
61
  }
62
62
 
63
+ function DropdownContentWithValidation( {
64
+ touched,
65
+ children,
66
+ }: {
67
+ touched: boolean;
68
+ children: React.ReactNode;
69
+ } ) {
70
+ const ref = useRef< HTMLDivElement >( null );
71
+ useReportValidity( ref, touched );
72
+ return <div ref={ ref }>{ children }</div>;
73
+ }
74
+
63
75
  function PanelDropdown< Item >( {
64
76
  data,
65
77
  field,
66
78
  onChange,
67
79
  validity,
68
- labelPosition = 'side',
69
- summaryFields,
70
- fieldDefinition,
71
- popoverAnchor,
72
- onOpen,
73
- }: {
74
- data: Item;
75
- field: NormalizedFormField;
76
- onChange: ( value: any ) => void;
77
- validity?: FieldValidity;
78
- labelPosition: 'side' | 'top' | 'none';
79
- summaryFields: NormalizedField< Item >[];
80
- fieldDefinition: NormalizedField< Item >;
81
- popoverAnchor: HTMLElement | null;
82
- onOpen?: () => void;
83
- } ) {
84
- const fieldLabel = !! field.children ? field.label : fieldDefinition?.label;
80
+ }: FieldLayoutProps< Item > ) {
81
+ const [ touched, setTouched ] = useState( false );
82
+
83
+ // Use internal state instead of a ref to make sure that the component
84
+ // re-renders when the popover's anchor updates.
85
+ const [ popoverAnchor, setPopoverAnchor ] = useState< HTMLElement | null >(
86
+ null
87
+ );
88
+ // Memoize popoverProps to avoid returning a new object every time.
89
+ const popoverProps = useMemo(
90
+ () => ( {
91
+ // Anchor the popover to the middle of the entire row so that it doesn't
92
+ // move around when the label changes.
93
+ anchor: popoverAnchor,
94
+ placement: 'left-start',
95
+ offset: 36,
96
+ shift: true,
97
+ } ),
98
+ [ popoverAnchor ]
99
+ );
100
+ const [ dialogRef, dialogProps ] = useDialog( {
101
+ focusOnMount: 'firstInputElement',
102
+ } );
85
103
 
86
104
  const form: NormalizedForm = useMemo(
87
105
  () => ( {
@@ -105,78 +123,76 @@ function PanelDropdown< Item >( {
105
123
  return { [ field.id ]: validity };
106
124
  }, [ validity, field ] );
107
125
 
108
- // Memoize popoverProps to avoid returning a new object every time.
109
- const popoverProps = useMemo(
110
- () => ( {
111
- // Anchor the popover to the middle of the entire row so that it doesn't
112
- // move around when the label changes.
113
- anchor: popoverAnchor,
114
- placement: 'left-start',
115
- offset: 36,
116
- shift: true,
117
- } ),
118
- [ popoverAnchor ]
119
- );
120
-
121
- const focusOnMountRef = useFocusOnMount( 'firstInputElement' );
126
+ const { fieldDefinition, fieldLabel, summaryFields } =
127
+ useFieldFromFormField( field );
128
+ if ( ! fieldDefinition ) {
129
+ return null;
130
+ }
122
131
 
123
132
  return (
124
- <Dropdown
125
- contentClassName="dataforms-layouts-panel__field-dropdown"
126
- popoverProps={ popoverProps }
127
- focusOnMount={ false }
128
- toggleProps={ {
129
- size: 'compact',
130
- variant: 'tertiary',
131
- tooltipPosition: 'middle left',
132
- } }
133
- renderToggle={ ( { isOpen, onToggle } ) => (
134
- <SummaryButton
135
- summaryFields={ summaryFields }
136
- data={ data }
137
- labelPosition={ labelPosition }
138
- fieldLabel={ fieldLabel }
139
- disabled={ fieldDefinition.readOnly === true }
140
- onClick={ () => {
141
- if ( ! isOpen && onOpen ) {
142
- onOpen();
143
- }
144
- onToggle();
145
- } }
146
- aria-expanded={ isOpen }
147
- />
148
- ) }
149
- renderContent={ ( { onClose } ) => (
150
- <>
151
- <DropdownHeader title={ fieldLabel } onClose={ onClose } />
152
- <div ref={ focusOnMountRef }>
153
- <DataFormLayout
154
- data={ data }
155
- form={ form }
156
- onChange={ onChange }
157
- validity={ formValidity }
158
- >
159
- { (
160
- FieldLayout,
161
- childField,
162
- childFieldValidity
163
- ) => (
164
- <FieldLayout
165
- key={ childField.id }
166
- data={ data }
167
- field={ childField }
168
- onChange={ onChange }
169
- hideLabelFromVision={
170
- ( form?.fields ?? [] ).length < 2
171
- }
172
- validity={ childFieldValidity }
173
- />
174
- ) }
175
- </DataFormLayout>
176
- </div>
177
- </>
178
- ) }
179
- />
133
+ <div
134
+ ref={ setPopoverAnchor }
135
+ className="dataforms-layouts-panel__field-dropdown-anchor"
136
+ >
137
+ <Dropdown
138
+ contentClassName="dataforms-layouts-panel__field-dropdown"
139
+ popoverProps={ popoverProps }
140
+ focusOnMount={ false }
141
+ onToggle={ ( willOpen ) => {
142
+ if ( ! willOpen ) {
143
+ setTouched( true );
144
+ }
145
+ } }
146
+ renderToggle={ ( { isOpen, onToggle } ) => (
147
+ <SummaryButton
148
+ data={ data }
149
+ field={ field }
150
+ fieldLabel={ fieldLabel }
151
+ summaryFields={ summaryFields }
152
+ validity={ validity }
153
+ touched={ touched }
154
+ disabled={ fieldDefinition.readOnly === true }
155
+ onClick={ onToggle }
156
+ aria-expanded={ isOpen }
157
+ />
158
+ ) }
159
+ renderContent={ ( { onClose } ) => (
160
+ <DropdownContentWithValidation touched={ touched }>
161
+ <div ref={ dialogRef } { ...dialogProps }>
162
+ <DropdownHeader
163
+ title={ fieldLabel }
164
+ onClose={ onClose }
165
+ />
166
+ <DataFormLayout
167
+ data={ data }
168
+ form={ form }
169
+ onChange={ onChange }
170
+ validity={ formValidity }
171
+ >
172
+ { (
173
+ FieldLayout,
174
+ childField,
175
+ childFieldValidity,
176
+ markWhenOptional
177
+ ) => (
178
+ <FieldLayout
179
+ key={ childField.id }
180
+ data={ data }
181
+ field={ childField }
182
+ onChange={ onChange }
183
+ hideLabelFromVision={
184
+ ( form?.fields ?? [] ).length < 2
185
+ }
186
+ markWhenOptional={ markWhenOptional }
187
+ validity={ childFieldValidity }
188
+ />
189
+ ) }
190
+ </DataFormLayout>
191
+ </div>
192
+ </DropdownContentWithValidation>
193
+ ) }
194
+ />
195
+ </div>
180
196
  );
181
197
  }
182
198
 
@@ -1,136 +1,9 @@
1
- /**
2
- * External dependencies
3
- */
4
- import clsx from 'clsx';
5
-
6
- /**
7
- * WordPress dependencies
8
- */
9
- import { Icon, Tooltip } from '@wordpress/components';
10
- import { useState, useContext } from '@wordpress/element';
11
- import { error as errorIcon } from '@wordpress/icons';
12
- import { Stack } from '@wordpress/ui';
13
-
14
1
  /**
15
2
  * Internal dependencies
16
3
  */
17
- import type {
18
- FieldLayoutProps,
19
- FieldValidity,
20
- NormalizedField,
21
- NormalizedFormField,
22
- NormalizedPanelLayout,
23
- } from '../../../types';
24
- import DataFormContext from '../../dataform-context';
25
- import PanelDropdown from './dropdown';
4
+ import type { FieldLayoutProps, NormalizedPanelLayout } from '../../../types';
26
5
  import PanelModal from './modal';
27
- import { getSummaryFields } from '../get-summary-fields';
28
-
29
- function getFirstValidationError(
30
- validity: FieldValidity | undefined
31
- ): string | undefined {
32
- if ( ! validity ) {
33
- return undefined;
34
- }
35
-
36
- const validityRules = Object.keys( validity ).filter(
37
- ( key ) => key !== 'children'
38
- );
39
-
40
- for ( const key of validityRules ) {
41
- const rule = validity[ key as keyof Omit< FieldValidity, 'children' > ];
42
- if ( rule === undefined ) {
43
- continue;
44
- }
45
-
46
- if ( rule.type === 'invalid' ) {
47
- if ( rule.message ) {
48
- return rule.message;
49
- }
50
-
51
- // Provide default message for required validation (message is optional)
52
- if ( key === 'required' ) {
53
- return 'A required field is empty';
54
- }
55
-
56
- return 'Unidentified validation error';
57
- }
58
- }
59
-
60
- // Check children recursively
61
- if ( validity.children ) {
62
- for ( const childValidity of Object.values( validity.children ) ) {
63
- const childError = getFirstValidationError( childValidity );
64
- if ( childError ) {
65
- return childError;
66
- }
67
- }
68
- }
69
-
70
- return undefined;
71
- }
72
-
73
- const getFieldDefinition = < Item, >(
74
- field: NormalizedFormField,
75
- fields: NormalizedField< Item >[]
76
- ) => {
77
- const fieldDefinition = fields.find( ( _field ) => _field.id === field.id );
78
-
79
- if ( ! fieldDefinition ) {
80
- return fields.find( ( _field ) => {
81
- if ( !! field.children ) {
82
- const simpleChildren = field.children.filter(
83
- ( child ) => ! child.children
84
- );
85
-
86
- if ( simpleChildren.length === 0 ) {
87
- return false;
88
- }
89
-
90
- return _field.id === simpleChildren[ 0 ].id;
91
- }
92
-
93
- return _field.id === field.id;
94
- } );
95
- }
96
-
97
- return fieldDefinition;
98
- };
99
-
100
- /**
101
- * Determines the field definition and summary fields for a panel layout.
102
- *
103
- * Summary fields are determined with the following priority:
104
- * 1. Use layout.summary fields if they exist
105
- * 2. Fall back to the field definition that matches the form field's id
106
- * 3. If the form field id doesn't exist, pick the first child field
107
- * 4. If no field definition is found, return empty summary fields
108
- *
109
- * @param layout - The normalized panel layout configuration
110
- * @param field - The form field to get definition for
111
- * @param fields - Array of normalized field definitions
112
- * @return Object containing fieldDefinition and summaryFields
113
- */
114
- const getFieldDefinitionAndSummaryFields = < Item, >(
115
- layout: NormalizedPanelLayout,
116
- field: NormalizedFormField,
117
- fields: NormalizedField< Item >[]
118
- ) => {
119
- const summaryFields = getSummaryFields( layout.summary, fields );
120
- const fieldDefinition = getFieldDefinition( field, fields );
121
-
122
- if ( summaryFields.length === 0 ) {
123
- return {
124
- summaryFields: fieldDefinition ? [ fieldDefinition ] : [],
125
- fieldDefinition,
126
- };
127
- }
128
-
129
- return {
130
- summaryFields,
131
- fieldDefinition,
132
- };
133
- };
6
+ import PanelDropdown from './dropdown';
134
7
 
135
8
  export default function FormPanelField< Item >( {
136
9
  data,
@@ -138,131 +11,25 @@ export default function FormPanelField< Item >( {
138
11
  onChange,
139
12
  validity,
140
13
  }: FieldLayoutProps< Item > ) {
141
- const { fields } = useContext( DataFormContext );
142
14
  const layout = field.layout as NormalizedPanelLayout;
143
15
 
144
- // Use internal state instead of a ref to make sure that the component
145
- // re-renders when the popover's anchor updates.
146
- const [ popoverAnchor, setPopoverAnchor ] = useState< HTMLElement | null >(
147
- null
148
- );
149
-
150
- // Track if the panel has been opened (touched) to only show errors after interaction.
151
- const [ touched, setTouched ] = useState( false );
152
- const handleOpen = () => setTouched( true );
153
-
154
- const { fieldDefinition, summaryFields } =
155
- getFieldDefinitionAndSummaryFields( layout, field, fields );
156
-
157
- if ( ! fieldDefinition ) {
158
- return null;
159
- }
160
-
161
- const labelPosition = layout.labelPosition;
162
- const errorMessage = getFirstValidationError( validity );
163
- const showError = touched && !! errorMessage;
164
- const labelClassName = clsx(
165
- 'dataforms-layouts-panel__field-label',
166
- `dataforms-layouts-panel__field-label--label-position-${ labelPosition }`,
167
- { 'has-error': showError }
168
- );
169
- const fieldLabel = !! field.children ? field.label : fieldDefinition?.label;
170
-
171
- const labelContent = showError ? (
172
- <Tooltip text={ errorMessage } placement="top">
173
- <Stack
174
- direction="row"
175
- gap="xs"
176
- className="dataforms-layouts-panel__field-label-error-content"
177
- justify="flex-start"
178
- >
179
- <Icon icon={ errorIcon } size={ 16 } />
180
- <>{ fieldLabel }</>
181
- </Stack>
182
- </Tooltip>
183
- ) : (
184
- fieldLabel
185
- );
186
-
187
- const renderedControl =
188
- layout.openAs === 'modal' ? (
16
+ if ( layout.openAs === 'modal' ) {
17
+ return (
189
18
  <PanelModal
190
- data={ data }
191
- field={ field }
192
- onChange={ onChange }
193
- labelPosition={ labelPosition }
194
- summaryFields={ summaryFields }
195
- fieldDefinition={ fieldDefinition }
196
- onOpen={ handleOpen }
197
- />
198
- ) : (
199
- <PanelDropdown
200
19
  data={ data }
201
20
  field={ field }
202
21
  onChange={ onChange }
203
22
  validity={ validity }
204
- labelPosition={ labelPosition }
205
- summaryFields={ summaryFields }
206
- fieldDefinition={ fieldDefinition }
207
- popoverAnchor={ popoverAnchor }
208
- onOpen={ handleOpen }
209
23
  />
210
24
  );
211
-
212
- if ( labelPosition === 'top' ) {
213
- return (
214
- <Stack
215
- direction="column"
216
- className="dataforms-layouts-panel__field"
217
- >
218
- <div
219
- className={ labelClassName }
220
- style={ { paddingBottom: 0 } }
221
- >
222
- { labelContent }
223
- </div>
224
- <div className="dataforms-layouts-panel__field-control">
225
- { renderedControl }
226
- </div>
227
- </Stack>
228
- );
229
- }
230
-
231
- if ( labelPosition === 'none' ) {
232
- return (
233
- <Stack
234
- direction="row"
235
- gap="xs"
236
- className="dataforms-layouts-panel__field dataforms-layouts-panel__field--label-position-none"
237
- >
238
- { showError && (
239
- <Tooltip text={ errorMessage } placement="top">
240
- <Icon
241
- className="dataforms-layouts-panel__field-label-error-content"
242
- icon={ errorIcon }
243
- size={ 16 }
244
- />
245
- </Tooltip>
246
- ) }
247
- <div className="dataforms-layouts-panel__field-control">
248
- { renderedControl }
249
- </div>
250
- </Stack>
251
- );
252
25
  }
253
26
 
254
- // Defaults to label position side.
255
27
  return (
256
- <Stack
257
- direction="row"
258
- gap="xs"
259
- ref={ setPopoverAnchor }
260
- className="dataforms-layouts-panel__field"
261
- >
262
- <div className={ labelClassName }>{ labelContent }</div>
263
- <div className="dataforms-layouts-panel__field-control">
264
- { renderedControl }
265
- </div>
266
- </Stack>
28
+ <PanelDropdown
29
+ data={ data }
30
+ field={ field }
31
+ onChange={ onChange }
32
+ validity={ validity }
33
+ />
267
34
  );
268
35
  }
@@ -12,8 +12,8 @@ import {
12
12
  Modal,
13
13
  } from '@wordpress/components';
14
14
  import { __ } from '@wordpress/i18n';
15
- import { useContext, useState, useMemo } from '@wordpress/element';
16
- import { useFocusOnMount } from '@wordpress/compose';
15
+ import { useContext, useMemo, useRef, useState } from '@wordpress/element';
16
+ import { useFocusOnMount, useMergeRefs } from '@wordpress/compose';
17
17
  import { Stack } from '@wordpress/ui';
18
18
 
19
19
  /**
@@ -23,13 +23,15 @@ import type {
23
23
  Field,
24
24
  NormalizedForm,
25
25
  NormalizedFormField,
26
- NormalizedField,
26
+ FieldLayoutProps,
27
27
  } from '../../../types';
28
28
  import { DataFormLayout } from '../data-form-layout';
29
29
  import { DEFAULT_LAYOUT } from '../normalize-form';
30
30
  import SummaryButton from './summary-button';
31
31
  import useFormValidity from '../../../hooks/use-form-validity';
32
+ import useReportValidity from '../../../hooks/use-report-validity';
32
33
  import DataFormContext from '../../dataform-context';
34
+ import useFieldFromFormField from './utils/use-field-from-form-field';
33
35
 
34
36
  function ModalContent< Item >( {
35
37
  data,
@@ -37,12 +39,14 @@ function ModalContent< Item >( {
37
39
  onChange,
38
40
  fieldLabel,
39
41
  onClose,
42
+ touched,
40
43
  }: {
41
44
  data: Item;
42
45
  field: NormalizedFormField;
43
46
  onChange: ( data: Partial< Item > ) => void;
44
47
  onClose: () => void;
45
48
  fieldLabel: string;
49
+ touched: boolean;
46
50
  } ) {
47
51
  const { fields } = useContext( DataFormContext );
48
52
  const [ changes, setChanges ] = useState< Partial< Item > >( {} );
@@ -92,6 +96,12 @@ function ModalContent< Item >( {
92
96
  };
93
97
 
94
98
  const focusOnMountRef = useFocusOnMount( 'firstInputElement' );
99
+ const contentRef = useRef< HTMLDivElement >( null );
100
+ const mergedRef = useMergeRefs( [ focusOnMountRef, contentRef ] );
101
+
102
+ // When the modal is opened after being previously closed (touched),
103
+ // trigger reportValidity to show field-level errors.
104
+ useReportValidity( contentRef, touched );
95
105
 
96
106
  return (
97
107
  <Modal
@@ -101,20 +111,26 @@ function ModalContent< Item >( {
101
111
  title={ fieldLabel }
102
112
  size="medium"
103
113
  >
104
- <div ref={ focusOnMountRef }>
114
+ <div ref={ mergedRef }>
105
115
  <DataFormLayout
106
116
  data={ modalData }
107
117
  form={ form }
108
118
  onChange={ handleOnChange }
109
119
  validity={ validity }
110
120
  >
111
- { ( FieldLayout, childField, childFieldValidity ) => (
121
+ { (
122
+ FieldLayout,
123
+ childField,
124
+ childFieldValidity,
125
+ markWhenOptional
126
+ ) => (
112
127
  <FieldLayout
113
128
  key={ childField.id }
114
129
  data={ modalData }
115
130
  field={ childField }
116
131
  onChange={ handleOnChange }
117
132
  hideLabelFromVision={ form.fields.length < 2 }
133
+ markWhenOptional={ markWhenOptional }
118
134
  validity={ childFieldValidity }
119
135
  />
120
136
  ) }
@@ -123,7 +139,7 @@ function ModalContent< Item >( {
123
139
  <Stack
124
140
  direction="row"
125
141
  className="dataforms-layouts-panel__modal-footer"
126
- gap="sm"
142
+ gap="md"
127
143
  >
128
144
  <Spacer style={ { flex: 1 } } />
129
145
  <Button
@@ -149,37 +165,34 @@ function PanelModal< Item >( {
149
165
  data,
150
166
  field,
151
167
  onChange,
152
- labelPosition,
153
- summaryFields,
154
- fieldDefinition,
155
- onOpen,
156
- }: {
157
- data: Item;
158
- field: NormalizedFormField;
159
- onChange: ( value: any ) => void;
160
- labelPosition: 'side' | 'top' | 'none';
161
- summaryFields: NormalizedField< Item >[];
162
- fieldDefinition: NormalizedField< Item >;
163
- onOpen?: () => void;
164
- } ) {
168
+ validity,
169
+ }: FieldLayoutProps< Item > ) {
170
+ const [ touched, setTouched ] = useState( false );
171
+
165
172
  const [ isOpen, setIsOpen ] = useState( false );
166
173
 
167
- const fieldLabel = !! field.children ? field.label : fieldDefinition?.label;
174
+ const { fieldDefinition, fieldLabel, summaryFields } =
175
+ useFieldFromFormField( field );
176
+ if ( ! fieldDefinition ) {
177
+ return null;
178
+ }
179
+
180
+ const handleClose = () => {
181
+ setIsOpen( false );
182
+ setTouched( true );
183
+ };
168
184
 
169
185
  return (
170
186
  <>
171
187
  <SummaryButton
172
- summaryFields={ summaryFields }
173
188
  data={ data }
174
- labelPosition={ labelPosition }
189
+ field={ field }
175
190
  fieldLabel={ fieldLabel }
191
+ summaryFields={ summaryFields }
192
+ validity={ validity }
193
+ touched={ touched }
176
194
  disabled={ fieldDefinition.readOnly === true }
177
- onClick={ () => {
178
- if ( onOpen ) {
179
- onOpen();
180
- }
181
- setIsOpen( true );
182
- } }
195
+ onClick={ () => setIsOpen( true ) }
183
196
  aria-expanded={ isOpen }
184
197
  />
185
198
  { isOpen && (
@@ -188,7 +201,8 @@ function PanelModal< Item >( {
188
201
  field={ field }
189
202
  onChange={ onChange }
190
203
  fieldLabel={ fieldLabel ?? '' }
191
- onClose={ () => setIsOpen( false ) }
204
+ onClose={ handleClose }
205
+ touched={ touched }
192
206
  />
193
207
  ) }
194
208
  </>