@wordpress/dataviews 10.0.1-next.ff1cebbba.0 → 10.1.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 (399) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/README.md +97 -8
  3. package/build/components/dataform/index.js +11 -2
  4. package/build/components/dataform/index.js.map +2 -2
  5. package/build/components/dataform-context/index.js.map +2 -2
  6. package/build/components/dataviews-bulk-actions/index.js +2 -4
  7. package/build/components/dataviews-bulk-actions/index.js.map +2 -2
  8. package/build/components/dataviews-filters/filter.js +9 -4
  9. package/build/components/dataviews-filters/filter.js.map +3 -3
  10. package/build/components/dataviews-filters/search-widget.js +13 -2
  11. package/build/components/dataviews-filters/search-widget.js.map +3 -3
  12. package/build/components/dataviews-filters/use-filters.js +4 -2
  13. package/build/components/dataviews-filters/use-filters.js.map +2 -2
  14. package/build/components/dataviews-item-actions/index.js +6 -6
  15. package/build/components/dataviews-item-actions/index.js.map +2 -2
  16. package/build/dataform-controls/array.js +14 -61
  17. package/build/dataform-controls/array.js.map +3 -3
  18. package/build/dataform-controls/checkbox.js +5 -29
  19. package/build/dataform-controls/checkbox.js.map +3 -3
  20. package/build/dataform-controls/color.js +5 -29
  21. package/build/dataform-controls/color.js.map +3 -3
  22. package/build/dataform-controls/date.js +40 -57
  23. package/build/dataform-controls/date.js.map +3 -3
  24. package/build/dataform-controls/datetime.js +12 -37
  25. package/build/dataform-controls/datetime.js.map +3 -3
  26. package/build/dataform-controls/email.js +3 -1
  27. package/build/dataform-controls/email.js.map +2 -2
  28. package/build/dataform-controls/index.js +2 -1
  29. package/build/dataform-controls/index.js.map +3 -3
  30. package/build/dataform-controls/password.js +3 -1
  31. package/build/dataform-controls/password.js.map +2 -2
  32. package/build/dataform-controls/radio.js +24 -43
  33. package/build/dataform-controls/radio.js.map +3 -3
  34. package/build/dataform-controls/select.js +13 -30
  35. package/build/dataform-controls/select.js.map +3 -3
  36. package/build/dataform-controls/telephone.js +3 -1
  37. package/build/dataform-controls/telephone.js.map +2 -2
  38. package/build/dataform-controls/text.js +3 -1
  39. package/build/dataform-controls/text.js.map +2 -2
  40. package/build/dataform-controls/textarea.js +6 -30
  41. package/build/dataform-controls/textarea.js.map +3 -3
  42. package/build/dataform-controls/toggle-group.js +38 -56
  43. package/build/dataform-controls/toggle-group.js.map +3 -3
  44. package/build/dataform-controls/toggle.js +6 -30
  45. package/build/dataform-controls/toggle.js.map +3 -3
  46. package/build/dataform-controls/url.js +3 -1
  47. package/build/dataform-controls/url.js.map +2 -2
  48. package/build/dataform-controls/utils/get-custom-validity.js +35 -0
  49. package/build/dataform-controls/utils/get-custom-validity.js.map +7 -0
  50. package/build/dataform-controls/utils/validated-input.js +4 -28
  51. package/build/dataform-controls/utils/validated-input.js.map +3 -3
  52. package/build/dataform-controls/utils/validated-number.js +6 -30
  53. package/build/dataform-controls/utils/validated-number.js.map +3 -3
  54. package/build/dataform-layouts/card/index.js +6 -3
  55. package/build/dataform-layouts/card/index.js.map +2 -2
  56. package/build/dataform-layouts/data-form-layout.js +8 -2
  57. package/build/dataform-layouts/data-form-layout.js.map +2 -2
  58. package/build/dataform-layouts/panel/dropdown.js +21 -9
  59. package/build/dataform-layouts/panel/dropdown.js.map +2 -2
  60. package/build/dataform-layouts/panel/index.js +12 -10
  61. package/build/dataform-layouts/panel/index.js.map +2 -2
  62. package/build/dataform-layouts/panel/modal.js +32 -22
  63. package/build/dataform-layouts/panel/modal.js.map +3 -3
  64. package/build/dataform-layouts/regular/index.js +8 -4
  65. package/build/dataform-layouts/regular/index.js.map +2 -2
  66. package/build/dataform-layouts/row/index.js +11 -7
  67. package/build/dataform-layouts/row/index.js.map +2 -2
  68. package/build/dataviews-layouts/list/index.js +7 -7
  69. package/build/dataviews-layouts/list/index.js.map +2 -2
  70. package/build/dataviews-layouts/table/column-header-menu.js +1 -1
  71. package/build/dataviews-layouts/table/column-header-menu.js.map +2 -2
  72. package/build/field-types/boolean.js +3 -2
  73. package/build/field-types/boolean.js.map +3 -3
  74. package/build/field-types/color.js +2 -2
  75. package/build/field-types/color.js.map +3 -3
  76. package/build/field-types/date.js +3 -2
  77. package/build/field-types/date.js.map +3 -3
  78. package/build/field-types/datetime.js +2 -1
  79. package/build/field-types/datetime.js.map +3 -3
  80. package/build/field-types/email.js +2 -1
  81. package/build/field-types/email.js.map +3 -3
  82. package/build/field-types/index.js +2 -1
  83. package/build/field-types/index.js.map +3 -3
  84. package/build/field-types/integer.js +2 -1
  85. package/build/field-types/integer.js.map +3 -3
  86. package/build/field-types/number.js +18 -9
  87. package/build/field-types/number.js.map +3 -3
  88. package/build/field-types/password.js +2 -1
  89. package/build/field-types/password.js.map +3 -3
  90. package/build/field-types/telephone.js +2 -1
  91. package/build/field-types/telephone.js.map +3 -3
  92. package/build/field-types/text.js +2 -1
  93. package/build/field-types/text.js.map +3 -3
  94. package/build/field-types/url.js +2 -1
  95. package/build/field-types/url.js.map +3 -3
  96. package/build/field-types/utils/render-from-elements.js +24 -3
  97. package/build/field-types/utils/render-from-elements.js.map +4 -4
  98. package/build/hooks/index.js +39 -0
  99. package/build/hooks/index.js.map +7 -0
  100. package/build/hooks/use-elements.js +63 -0
  101. package/build/hooks/use-elements.js.map +7 -0
  102. package/build/hooks/use-form-validity.js +426 -0
  103. package/build/hooks/use-form-validity.js.map +7 -0
  104. package/build/index.js +3 -3
  105. package/build/index.js.map +2 -2
  106. package/build/types/dataform.js.map +1 -1
  107. package/build/types/dataviews.js.map +1 -1
  108. package/build/types/field-api.js.map +1 -1
  109. package/build/utils/has-elements.js +27 -0
  110. package/build/utils/has-elements.js.map +7 -0
  111. package/build/utils/normalize-fields.js +4 -2
  112. package/build/utils/normalize-fields.js.map +3 -3
  113. package/build-module/components/dataform/index.js +11 -2
  114. package/build-module/components/dataform/index.js.map +2 -2
  115. package/build-module/components/dataform-context/index.js.map +2 -2
  116. package/build-module/components/dataviews-bulk-actions/index.js +2 -4
  117. package/build-module/components/dataviews-bulk-actions/index.js.map +2 -2
  118. package/build-module/components/dataviews-filters/filter.js +9 -4
  119. package/build-module/components/dataviews-filters/filter.js.map +2 -2
  120. package/build-module/components/dataviews-filters/search-widget.js +19 -3
  121. package/build-module/components/dataviews-filters/search-widget.js.map +2 -2
  122. package/build-module/components/dataviews-filters/use-filters.js +4 -2
  123. package/build-module/components/dataviews-filters/use-filters.js.map +2 -2
  124. package/build-module/components/dataviews-item-actions/index.js +6 -6
  125. package/build-module/components/dataviews-item-actions/index.js.map +2 -2
  126. package/build-module/dataform-controls/array.js +16 -63
  127. package/build-module/dataform-controls/array.js.map +2 -2
  128. package/build-module/dataform-controls/checkbox.js +6 -30
  129. package/build-module/dataform-controls/checkbox.js.map +2 -2
  130. package/build-module/dataform-controls/color.js +6 -30
  131. package/build-module/dataform-controls/color.js.map +2 -2
  132. package/build-module/dataform-controls/date.js +49 -66
  133. package/build-module/dataform-controls/date.js.map +2 -2
  134. package/build-module/dataform-controls/datetime.js +14 -39
  135. package/build-module/dataform-controls/datetime.js.map +2 -2
  136. package/build-module/dataform-controls/email.js +3 -1
  137. package/build-module/dataform-controls/email.js.map +2 -2
  138. package/build-module/dataform-controls/index.js +2 -1
  139. package/build-module/dataform-controls/index.js.map +2 -2
  140. package/build-module/dataform-controls/password.js +3 -1
  141. package/build-module/dataform-controls/password.js.map +2 -2
  142. package/build-module/dataform-controls/radio.js +26 -45
  143. package/build-module/dataform-controls/radio.js.map +2 -2
  144. package/build-module/dataform-controls/select.js +15 -32
  145. package/build-module/dataform-controls/select.js.map +2 -2
  146. package/build-module/dataform-controls/telephone.js +3 -1
  147. package/build-module/dataform-controls/telephone.js.map +2 -2
  148. package/build-module/dataform-controls/text.js +3 -1
  149. package/build-module/dataform-controls/text.js.map +2 -2
  150. package/build-module/dataform-controls/textarea.js +7 -31
  151. package/build-module/dataform-controls/textarea.js.map +2 -2
  152. package/build-module/dataform-controls/toggle-group.js +41 -58
  153. package/build-module/dataform-controls/toggle-group.js.map +2 -2
  154. package/build-module/dataform-controls/toggle.js +7 -31
  155. package/build-module/dataform-controls/toggle.js.map +2 -2
  156. package/build-module/dataform-controls/url.js +3 -1
  157. package/build-module/dataform-controls/url.js.map +2 -2
  158. package/build-module/dataform-controls/utils/get-custom-validity.js +15 -0
  159. package/build-module/dataform-controls/utils/get-custom-validity.js.map +7 -0
  160. package/build-module/dataform-controls/utils/validated-input.js +5 -29
  161. package/build-module/dataform-controls/utils/validated-input.js.map +2 -2
  162. package/build-module/dataform-controls/utils/validated-number.js +7 -31
  163. package/build-module/dataform-controls/utils/validated-number.js.map +2 -2
  164. package/build-module/dataform-layouts/card/index.js +6 -3
  165. package/build-module/dataform-layouts/card/index.js.map +2 -2
  166. package/build-module/dataform-layouts/data-form-layout.js +8 -2
  167. package/build-module/dataform-layouts/data-form-layout.js.map +2 -2
  168. package/build-module/dataform-layouts/panel/dropdown.js +21 -9
  169. package/build-module/dataform-layouts/panel/dropdown.js.map +2 -2
  170. package/build-module/dataform-layouts/panel/index.js +12 -10
  171. package/build-module/dataform-layouts/panel/index.js.map +2 -2
  172. package/build-module/dataform-layouts/panel/modal.js +33 -23
  173. package/build-module/dataform-layouts/panel/modal.js.map +2 -2
  174. package/build-module/dataform-layouts/regular/index.js +8 -4
  175. package/build-module/dataform-layouts/regular/index.js.map +2 -2
  176. package/build-module/dataform-layouts/row/index.js +11 -7
  177. package/build-module/dataform-layouts/row/index.js.map +2 -2
  178. package/build-module/dataviews-layouts/list/index.js +7 -7
  179. package/build-module/dataviews-layouts/list/index.js.map +2 -2
  180. package/build-module/dataviews-layouts/table/column-header-menu.js +1 -1
  181. package/build-module/dataviews-layouts/table/column-header-menu.js.map +2 -2
  182. package/build-module/field-types/boolean.js +4 -3
  183. package/build-module/field-types/boolean.js.map +2 -2
  184. package/build-module/field-types/color.js +3 -3
  185. package/build-module/field-types/color.js.map +2 -2
  186. package/build-module/field-types/date.js +4 -3
  187. package/build-module/field-types/date.js.map +2 -2
  188. package/build-module/field-types/datetime.js +3 -2
  189. package/build-module/field-types/datetime.js.map +2 -2
  190. package/build-module/field-types/email.js +3 -2
  191. package/build-module/field-types/email.js.map +2 -2
  192. package/build-module/field-types/index.js +3 -2
  193. package/build-module/field-types/index.js.map +2 -2
  194. package/build-module/field-types/integer.js +3 -2
  195. package/build-module/field-types/integer.js.map +2 -2
  196. package/build-module/field-types/number.js +8 -9
  197. package/build-module/field-types/number.js.map +2 -2
  198. package/build-module/field-types/password.js +3 -2
  199. package/build-module/field-types/password.js.map +2 -2
  200. package/build-module/field-types/telephone.js +3 -2
  201. package/build-module/field-types/telephone.js.map +2 -2
  202. package/build-module/field-types/text.js +3 -2
  203. package/build-module/field-types/text.js.map +2 -2
  204. package/build-module/field-types/url.js +3 -2
  205. package/build-module/field-types/url.js.map +2 -2
  206. package/build-module/field-types/utils/render-from-elements.js +14 -3
  207. package/build-module/field-types/utils/render-from-elements.js.map +3 -3
  208. package/build-module/hooks/index.js +5 -0
  209. package/build-module/hooks/index.js.map +7 -0
  210. package/build-module/hooks/use-elements.js +43 -0
  211. package/build-module/hooks/use-elements.js.map +7 -0
  212. package/build-module/hooks/use-form-validity.js +392 -0
  213. package/build-module/hooks/use-form-validity.js.map +7 -0
  214. package/build-module/index.js +2 -2
  215. package/build-module/index.js.map +2 -2
  216. package/build-module/utils/has-elements.js +7 -0
  217. package/build-module/utils/has-elements.js.map +7 -0
  218. package/build-module/utils/normalize-fields.js +4 -2
  219. package/build-module/utils/normalize-fields.js.map +2 -2
  220. package/build-style/style-rtl.css +10 -4
  221. package/build-style/style.css +10 -4
  222. package/build-types/components/dataform/index.d.ts +1 -1
  223. package/build-types/components/dataform/index.d.ts.map +1 -1
  224. package/build-types/components/dataform-context/index.d.ts.map +1 -1
  225. package/build-types/components/dataviews-bulk-actions/index.d.ts.map +1 -1
  226. package/build-types/components/dataviews-filters/filter.d.ts +1 -1
  227. package/build-types/components/dataviews-filters/filter.d.ts.map +1 -1
  228. package/build-types/components/dataviews-filters/search-widget.d.ts.map +1 -1
  229. package/build-types/components/dataviews-filters/use-filters.d.ts.map +1 -1
  230. package/build-types/components/dataviews-item-actions/index.d.ts.map +1 -1
  231. package/build-types/dataform-controls/array.d.ts +1 -1
  232. package/build-types/dataform-controls/array.d.ts.map +1 -1
  233. package/build-types/dataform-controls/checkbox.d.ts +1 -1
  234. package/build-types/dataform-controls/checkbox.d.ts.map +1 -1
  235. package/build-types/dataform-controls/color.d.ts +1 -1
  236. package/build-types/dataform-controls/color.d.ts.map +1 -1
  237. package/build-types/dataform-controls/date.d.ts +1 -1
  238. package/build-types/dataform-controls/date.d.ts.map +1 -1
  239. package/build-types/dataform-controls/datetime.d.ts +1 -1
  240. package/build-types/dataform-controls/datetime.d.ts.map +1 -1
  241. package/build-types/dataform-controls/email.d.ts +1 -1
  242. package/build-types/dataform-controls/email.d.ts.map +1 -1
  243. package/build-types/dataform-controls/index.d.ts.map +1 -1
  244. package/build-types/dataform-controls/password.d.ts +1 -1
  245. package/build-types/dataform-controls/password.d.ts.map +1 -1
  246. package/build-types/dataform-controls/radio.d.ts +1 -1
  247. package/build-types/dataform-controls/radio.d.ts.map +1 -1
  248. package/build-types/dataform-controls/select.d.ts +1 -1
  249. package/build-types/dataform-controls/select.d.ts.map +1 -1
  250. package/build-types/dataform-controls/telephone.d.ts +1 -1
  251. package/build-types/dataform-controls/telephone.d.ts.map +1 -1
  252. package/build-types/dataform-controls/text.d.ts +1 -1
  253. package/build-types/dataform-controls/text.d.ts.map +1 -1
  254. package/build-types/dataform-controls/textarea.d.ts +1 -1
  255. package/build-types/dataform-controls/textarea.d.ts.map +1 -1
  256. package/build-types/dataform-controls/toggle-group.d.ts +1 -1
  257. package/build-types/dataform-controls/toggle-group.d.ts.map +1 -1
  258. package/build-types/dataform-controls/toggle.d.ts +1 -1
  259. package/build-types/dataform-controls/toggle.d.ts.map +1 -1
  260. package/build-types/dataform-controls/url.d.ts +1 -1
  261. package/build-types/dataform-controls/url.d.ts.map +1 -1
  262. package/build-types/dataform-controls/utils/get-custom-validity.d.ts +9 -0
  263. package/build-types/dataform-controls/utils/get-custom-validity.d.ts.map +1 -0
  264. package/build-types/dataform-controls/utils/validated-input.d.ts +1 -1
  265. package/build-types/dataform-controls/utils/validated-input.d.ts.map +1 -1
  266. package/build-types/dataform-controls/utils/validated-number.d.ts +1 -1
  267. package/build-types/dataform-controls/utils/validated-number.d.ts.map +1 -1
  268. package/build-types/dataform-layouts/card/index.d.ts +1 -1
  269. package/build-types/dataform-layouts/card/index.d.ts.map +1 -1
  270. package/build-types/dataform-layouts/data-form-layout.d.ts +5 -3
  271. package/build-types/dataform-layouts/data-form-layout.d.ts.map +1 -1
  272. package/build-types/dataform-layouts/panel/dropdown.d.ts +8 -7
  273. package/build-types/dataform-layouts/panel/dropdown.d.ts.map +1 -1
  274. package/build-types/dataform-layouts/panel/index.d.ts +1 -1
  275. package/build-types/dataform-layouts/panel/index.d.ts.map +1 -1
  276. package/build-types/dataform-layouts/panel/modal.d.ts +5 -5
  277. package/build-types/dataform-layouts/panel/modal.d.ts.map +1 -1
  278. package/build-types/dataform-layouts/regular/index.d.ts +1 -1
  279. package/build-types/dataform-layouts/regular/index.d.ts.map +1 -1
  280. package/build-types/dataform-layouts/row/index.d.ts +1 -1
  281. package/build-types/dataform-layouts/row/index.d.ts.map +1 -1
  282. package/build-types/dataviews-layouts/list/index.d.ts.map +1 -1
  283. package/build-types/field-types/boolean.d.ts +1 -1
  284. package/build-types/field-types/date.d.ts +1 -1
  285. package/build-types/field-types/datetime.d.ts.map +1 -1
  286. package/build-types/field-types/email.d.ts.map +1 -1
  287. package/build-types/field-types/index.d.ts.map +1 -1
  288. package/build-types/field-types/integer.d.ts.map +1 -1
  289. package/build-types/field-types/number.d.ts +1 -1
  290. package/build-types/field-types/number.d.ts.map +1 -1
  291. package/build-types/field-types/password.d.ts +1 -1
  292. package/build-types/field-types/password.d.ts.map +1 -1
  293. package/build-types/field-types/telephone.d.ts.map +1 -1
  294. package/build-types/field-types/text.d.ts.map +1 -1
  295. package/build-types/field-types/url.d.ts.map +1 -1
  296. package/build-types/field-types/utils/render-from-elements.d.ts +1 -1
  297. package/build-types/field-types/utils/render-from-elements.d.ts.map +1 -1
  298. package/build-types/hooks/index.d.ts +5 -0
  299. package/build-types/hooks/index.d.ts.map +1 -0
  300. package/build-types/hooks/use-elements.d.ts +12 -0
  301. package/build-types/hooks/use-elements.d.ts.map +1 -0
  302. package/build-types/hooks/use-form-validity.d.ts +16 -0
  303. package/build-types/hooks/use-form-validity.d.ts.map +1 -0
  304. package/build-types/index.d.ts +1 -1
  305. package/build-types/index.d.ts.map +1 -1
  306. package/build-types/stories/dataform.story.d.ts +14 -4
  307. package/build-types/stories/dataform.story.d.ts.map +1 -1
  308. package/build-types/stories/dataviews.fixtures.d.ts.map +1 -1
  309. package/build-types/stories/field-types.story.d.ts +38 -15
  310. package/build-types/stories/field-types.story.d.ts.map +1 -1
  311. package/build-types/test/use-form-validity.d.ts +2 -0
  312. package/build-types/test/use-form-validity.d.ts.map +1 -0
  313. package/build-types/types/dataform.d.ts +4 -1
  314. package/build-types/types/dataform.d.ts.map +1 -1
  315. package/build-types/types/dataviews.d.ts +10 -2
  316. package/build-types/types/dataviews.d.ts.map +1 -1
  317. package/build-types/types/field-api.d.ts +25 -1
  318. package/build-types/types/field-api.d.ts.map +1 -1
  319. package/build-types/utils/has-elements.d.ts +6 -0
  320. package/build-types/utils/has-elements.d.ts.map +1 -0
  321. package/build-types/utils/normalize-fields.d.ts.map +1 -1
  322. package/build-wp/index.js +1011 -819
  323. package/package.json +15 -15
  324. package/src/components/dataform/index.tsx +7 -1
  325. package/src/components/dataform-context/index.tsx +3 -1
  326. package/src/components/dataviews-bulk-actions/index.tsx +3 -5
  327. package/src/components/dataviews-filters/filter.tsx +11 -5
  328. package/src/components/dataviews-filters/search-widget.tsx +30 -3
  329. package/src/components/dataviews-filters/style.scss +8 -0
  330. package/src/components/dataviews-filters/use-filters.ts +4 -2
  331. package/src/components/dataviews-item-actions/index.tsx +11 -6
  332. package/src/components/dataviews-item-actions/style.scss +1 -0
  333. package/src/dataform-controls/array.tsx +16 -82
  334. package/src/dataform-controls/checkbox.tsx +5 -41
  335. package/src/dataform-controls/color.tsx +5 -37
  336. package/src/dataform-controls/date.tsx +63 -76
  337. package/src/dataform-controls/datetime.tsx +11 -45
  338. package/src/dataform-controls/email.tsx +2 -0
  339. package/src/dataform-controls/index.tsx +2 -1
  340. package/src/dataform-controls/password.tsx +2 -0
  341. package/src/dataform-controls/radio.tsx +24 -55
  342. package/src/dataform-controls/select.tsx +14 -42
  343. package/src/dataform-controls/telephone.tsx +2 -0
  344. package/src/dataform-controls/text.tsx +2 -0
  345. package/src/dataform-controls/textarea.tsx +6 -42
  346. package/src/dataform-controls/toggle-group.tsx +38 -64
  347. package/src/dataform-controls/toggle.tsx +6 -42
  348. package/src/dataform-controls/url.tsx +2 -0
  349. package/src/dataform-controls/utils/get-custom-validity.ts +24 -0
  350. package/src/dataform-controls/utils/validated-input.tsx +4 -40
  351. package/src/dataform-controls/utils/validated-number.tsx +6 -44
  352. package/src/dataform-layouts/card/index.tsx +3 -0
  353. package/src/dataform-layouts/data-form-layout.tsx +18 -3
  354. package/src/dataform-layouts/panel/dropdown.tsx +35 -14
  355. package/src/dataform-layouts/panel/index.tsx +9 -7
  356. package/src/dataform-layouts/panel/modal.tsx +41 -30
  357. package/src/dataform-layouts/regular/index.tsx +4 -0
  358. package/src/dataform-layouts/row/index.tsx +8 -4
  359. package/src/dataviews-layouts/list/index.tsx +9 -7
  360. package/src/dataviews-layouts/table/column-header-menu.tsx +1 -1
  361. package/src/dataviews-layouts/table/style.scss +2 -3
  362. package/src/field-types/boolean.tsx +3 -3
  363. package/src/field-types/color.tsx +3 -3
  364. package/src/field-types/date.tsx +3 -3
  365. package/src/field-types/datetime.tsx +6 -4
  366. package/src/field-types/email.tsx +6 -4
  367. package/src/field-types/index.tsx +6 -4
  368. package/src/field-types/integer.tsx +6 -4
  369. package/src/field-types/number.tsx +8 -12
  370. package/src/field-types/password.tsx +6 -4
  371. package/src/field-types/telephone.tsx +6 -4
  372. package/src/field-types/text.tsx +6 -4
  373. package/src/field-types/url.tsx +6 -4
  374. package/src/field-types/utils/render-from-elements.tsx +29 -0
  375. package/src/hooks/index.ts +4 -0
  376. package/src/hooks/use-elements.ts +66 -0
  377. package/src/hooks/use-form-validity.ts +571 -0
  378. package/src/index.ts +1 -1
  379. package/src/stories/dataform.story.tsx +243 -59
  380. package/src/stories/dataviews.fixtures.tsx +9 -4
  381. package/src/stories/field-types.story.tsx +159 -29
  382. package/src/test/use-form-validity.ts +546 -0
  383. package/src/types/dataform.ts +5 -1
  384. package/src/types/dataviews.ts +12 -2
  385. package/src/types/field-api.ts +32 -1
  386. package/src/utils/has-elements.ts +11 -0
  387. package/src/utils/normalize-fields.ts +7 -2
  388. package/tsconfig.tsbuildinfo +1 -1
  389. package/build/utils/is-item-valid.js +0 -75
  390. package/build/utils/is-item-valid.js.map +0 -7
  391. package/build-module/utils/is-item-valid.js +0 -45
  392. package/build-module/utils/is-item-valid.js.map +0 -7
  393. package/build-types/test/validation.d.ts +0 -2
  394. package/build-types/test/validation.d.ts.map +0 -1
  395. package/build-types/utils/is-item-valid.d.ts +0 -12
  396. package/build-types/utils/is-item-valid.d.ts.map +0 -1
  397. package/src/field-types/utils/render-from-elements.ts +0 -15
  398. package/src/test/validation.ts +0 -322
  399. package/src/utils/is-item-valid.ts +0 -93
@@ -1,19 +1,15 @@
1
- /**
2
- * External dependencies
3
- */
4
- import deepMerge from 'deepmerge';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
9
4
  import { privateApis } from '@wordpress/components';
10
- import { useCallback, useState } from '@wordpress/element';
5
+ import { useCallback } from '@wordpress/element';
11
6
 
12
7
  /**
13
8
  * Internal dependencies
14
9
  */
15
10
  import type { DataFormControlProps } from '../types';
16
11
  import { unlock } from '../lock-unlock';
12
+ import getCustomValidity from './utils/get-custom-validity';
17
13
 
18
14
  const { ValidatedTextareaControl } = unlock( privateApis );
19
15
 
@@ -23,16 +19,11 @@ export default function Textarea< Item >( {
23
19
  onChange,
24
20
  hideLabelFromVision,
25
21
  config,
22
+ validity,
26
23
  }: DataFormControlProps< Item > ) {
27
24
  const { rows = 4 } = config || {};
28
- const { label, placeholder, description, setValue } = field;
25
+ const { label, placeholder, description, setValue, isValid } = field;
29
26
  const value = field.getValue( { item: data } );
30
- const [ customValidity, setCustomValidity ] =
31
- useState<
32
- React.ComponentProps<
33
- typeof ValidatedTextareaControl
34
- >[ 'customValidity' ]
35
- >( undefined );
36
27
 
37
28
  const onChangeControl = useCallback(
38
29
  ( newValue: string ) =>
@@ -40,37 +31,10 @@ export default function Textarea< Item >( {
40
31
  [ data, onChange, setValue ]
41
32
  );
42
33
 
43
- const onValidateControl = useCallback(
44
- ( newValue: any ) => {
45
- const message = field.isValid?.custom?.(
46
- deepMerge(
47
- data,
48
- setValue( {
49
- item: data,
50
- value: newValue,
51
- } ) as Partial< Item >
52
- ),
53
- field
54
- );
55
-
56
- if ( message ) {
57
- setCustomValidity( {
58
- type: 'invalid',
59
- message,
60
- } );
61
- return;
62
- }
63
-
64
- setCustomValidity( undefined );
65
- },
66
- [ data, field, setValue ]
67
- );
68
-
69
34
  return (
70
35
  <ValidatedTextareaControl
71
- required={ !! field.isValid?.required }
72
- onValidate={ onValidateControl }
73
- customValidity={ customValidity }
36
+ required={ !! isValid?.required }
37
+ customValidity={ getCustomValidity( isValid, validity ) }
74
38
  label={ label }
75
39
  placeholder={ placeholder }
76
40
  value={ value ?? '' }
@@ -1,22 +1,20 @@
1
- /**
2
- * External dependencies
3
- */
4
- import deepMerge from 'deepmerge';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
9
4
  import {
10
5
  privateApis,
11
6
  __experimentalToggleGroupControlOption as ToggleGroupControlOption,
7
+ Spinner,
12
8
  } from '@wordpress/components';
13
- import { useCallback, useState } from '@wordpress/element';
9
+ import { useCallback } from '@wordpress/element';
14
10
 
15
11
  /**
16
12
  * Internal dependencies
17
13
  */
18
14
  import type { DataFormControlProps } from '../types';
19
15
  import { unlock } from '../lock-unlock';
16
+ import getCustomValidity from './utils/get-custom-validity';
17
+ import useElements from '../hooks/use-elements';
20
18
 
21
19
  const { ValidatedToggleGroupControl } = unlock( privateApis );
22
20
 
@@ -25,14 +23,9 @@ export default function ToggleGroup< Item >( {
25
23
  field,
26
24
  onChange,
27
25
  hideLabelFromVision,
26
+ validity,
28
27
  }: DataFormControlProps< Item > ) {
29
- const { getValue, setValue } = field;
30
- const [ customValidity, setCustomValidity ] =
31
- useState<
32
- React.ComponentProps<
33
- typeof ValidatedToggleGroupControl
34
- >[ 'customValidity' ]
35
- >( undefined );
28
+ const { getValue, setValue, isValid } = field;
36
29
  const value = getValue( { item: data } );
37
30
 
38
31
  const onChangeControl = useCallback(
@@ -40,60 +33,41 @@ export default function ToggleGroup< Item >( {
40
33
  onChange( setValue( { item: data, value: newValue } ) ),
41
34
  [ data, onChange, setValue ]
42
35
  );
43
- const onValidateControl = useCallback(
44
- ( newValue: any ) => {
45
- const message = field.isValid?.custom?.(
46
- deepMerge(
47
- data,
48
- setValue( {
49
- item: data,
50
- value: newValue,
51
- } ) as Partial< Item >
52
- ),
53
- field
54
- );
55
36
 
56
- if ( message ) {
57
- setCustomValidity( {
58
- type: 'invalid',
59
- message,
60
- } );
61
- return;
62
- }
37
+ const { elements, isLoading } = useElements( {
38
+ elements: field.elements,
39
+ getElements: field.getElements,
40
+ } );
63
41
 
64
- setCustomValidity( undefined );
65
- },
66
- [ data, field, setValue ]
67
- );
42
+ if ( isLoading ) {
43
+ return <Spinner />;
44
+ }
68
45
 
69
- if ( field.elements ) {
70
- const selectedOption = field.elements.find(
71
- ( el ) => el.value === value
72
- );
73
- return (
74
- <ValidatedToggleGroupControl
75
- required={ !! field.isValid?.required }
76
- onValidate={ onValidateControl }
77
- customValidity={ customValidity }
78
- __next40pxDefaultSize
79
- __nextHasNoMarginBottom
80
- isBlock
81
- label={ field.label }
82
- help={ selectedOption?.description || field.description }
83
- onChange={ onChangeControl }
84
- value={ value }
85
- hideLabelFromVision={ hideLabelFromVision }
86
- >
87
- { field.elements.map( ( el ) => (
88
- <ToggleGroupControlOption
89
- key={ el.value }
90
- label={ el.label }
91
- value={ el.value }
92
- />
93
- ) ) }
94
- </ValidatedToggleGroupControl>
95
- );
46
+ if ( elements.length === 0 ) {
47
+ return null;
96
48
  }
97
49
 
98
- return null;
50
+ const selectedOption = elements.find( ( el ) => el.value === value );
51
+ return (
52
+ <ValidatedToggleGroupControl
53
+ required={ !! field.isValid?.required }
54
+ customValidity={ getCustomValidity( isValid, validity ) }
55
+ __next40pxDefaultSize
56
+ __nextHasNoMarginBottom
57
+ isBlock
58
+ label={ field.label }
59
+ help={ selectedOption?.description || field.description }
60
+ onChange={ onChangeControl }
61
+ value={ value }
62
+ hideLabelFromVision={ hideLabelFromVision }
63
+ >
64
+ { elements.map( ( el ) => (
65
+ <ToggleGroupControlOption
66
+ key={ el.value }
67
+ label={ el.label }
68
+ value={ el.value }
69
+ />
70
+ ) ) }
71
+ </ValidatedToggleGroupControl>
72
+ );
99
73
  }
@@ -1,19 +1,15 @@
1
- /**
2
- * External dependencies
3
- */
4
- import deepMerge from 'deepmerge';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
9
4
  import { privateApis } from '@wordpress/components';
10
- import { useCallback, useState } from '@wordpress/element';
5
+ import { useCallback } from '@wordpress/element';
11
6
 
12
7
  /**
13
8
  * Internal dependencies
14
9
  */
15
10
  import type { DataFormControlProps } from '../types';
16
11
  import { unlock } from '../lock-unlock';
12
+ import getCustomValidity from './utils/get-custom-validity';
17
13
 
18
14
  const { ValidatedToggleControl } = unlock( privateApis );
19
15
 
@@ -22,14 +18,9 @@ export default function Toggle< Item >( {
22
18
  onChange,
23
19
  data,
24
20
  hideLabelFromVision,
21
+ validity,
25
22
  }: DataFormControlProps< Item > ) {
26
- const { label, description, getValue, setValue } = field;
27
- const [ customValidity, setCustomValidity ] =
28
- useState<
29
- React.ComponentProps<
30
- typeof ValidatedToggleControl
31
- >[ 'customValidity' ]
32
- >( undefined );
23
+ const { label, description, getValue, setValue, isValid } = field;
33
24
 
34
25
  const onChangeControl = useCallback( () => {
35
26
  onChange(
@@ -37,37 +28,10 @@ export default function Toggle< Item >( {
37
28
  );
38
29
  }, [ onChange, setValue, data, getValue ] );
39
30
 
40
- const onValidateControl = useCallback(
41
- ( newValue: any ) => {
42
- const message = field.isValid?.custom?.(
43
- deepMerge(
44
- data,
45
- setValue( {
46
- item: data,
47
- value: newValue,
48
- } ) as Partial< Item >
49
- ),
50
- field
51
- );
52
-
53
- if ( message ) {
54
- setCustomValidity( {
55
- type: 'invalid',
56
- message,
57
- } );
58
- return;
59
- }
60
-
61
- setCustomValidity( undefined );
62
- },
63
- [ data, field, setValue ]
64
- );
65
-
66
31
  return (
67
32
  <ValidatedToggleControl
68
- required={ !! field.isValid.required }
69
- onValidate={ onValidateControl }
70
- customValidity={ customValidity }
33
+ required={ !! isValid.required }
34
+ customValidity={ getCustomValidity( isValid, validity ) }
71
35
  hidden={ hideLabelFromVision }
72
36
  __nextHasNoMarginBottom
73
37
  label={ label }
@@ -18,6 +18,7 @@ export default function Url< Item >( {
18
18
  field,
19
19
  onChange,
20
20
  hideLabelFromVision,
21
+ validity,
21
22
  }: DataFormControlProps< Item > ) {
22
23
  return (
23
24
  <ValidatedText
@@ -26,6 +27,7 @@ export default function Url< Item >( {
26
27
  field,
27
28
  onChange,
28
29
  hideLabelFromVision,
30
+ validity,
29
31
  type: 'url',
30
32
  prefix: (
31
33
  <InputControlPrefixWrapper variant="icon">
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import type { Rules, FieldValidity } from '../../types';
5
+
6
+ export default function getCustomValidity< Item >(
7
+ isValid: Rules< Item >,
8
+ validity: FieldValidity | undefined
9
+ ) {
10
+ let customValidity;
11
+ if ( isValid?.required && validity?.required ) {
12
+ // If the consumer provides a message for required,
13
+ // use it instead of the native built-in message.
14
+ customValidity = validity?.required?.message
15
+ ? validity.required
16
+ : undefined;
17
+ } else if ( isValid?.elements && validity?.elements ) {
18
+ customValidity = validity.elements;
19
+ } else if ( validity?.custom ) {
20
+ customValidity = validity.custom;
21
+ }
22
+
23
+ return customValidity;
24
+ }
@@ -1,19 +1,15 @@
1
- /**
2
- * External dependencies
3
- */
4
- import deepMerge from 'deepmerge';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
9
4
  import { privateApis } from '@wordpress/components';
10
- import { useCallback, useState } from '@wordpress/element';
5
+ import { useCallback } from '@wordpress/element';
11
6
 
12
7
  /**
13
8
  * Internal dependencies
14
9
  */
15
10
  import type { DataFormControlProps } from '../../types';
16
11
  import { unlock } from '../../lock-unlock';
12
+ import getCustomValidity from './get-custom-validity';
17
13
 
18
14
  const { ValidatedInputControl } = unlock( privateApis );
19
15
 
@@ -41,16 +37,11 @@ export default function ValidatedText< Item >( {
41
37
  type,
42
38
  prefix,
43
39
  suffix,
40
+ validity,
44
41
  }: DataFormValidatedTextControlProps< Item > ) {
45
42
  const { label, placeholder, description, getValue, setValue, isValid } =
46
43
  field;
47
44
  const value = getValue( { item: data } );
48
- const [ customValidity, setCustomValidity ] =
49
- useState<
50
- React.ComponentProps<
51
- typeof ValidatedInputControl
52
- >[ 'customValidity' ]
53
- >( undefined );
54
45
 
55
46
  const onChangeControl = useCallback(
56
47
  ( newValue: string ) =>
@@ -63,37 +54,10 @@ export default function ValidatedText< Item >( {
63
54
  [ data, setValue, onChange ]
64
55
  );
65
56
 
66
- const onValidateControl = useCallback(
67
- ( newValue: any ) => {
68
- const message = isValid?.custom?.(
69
- deepMerge(
70
- data,
71
- setValue( {
72
- item: data,
73
- value: newValue,
74
- } ) as Partial< Item >
75
- ),
76
- field
77
- );
78
-
79
- if ( message ) {
80
- setCustomValidity( {
81
- type: 'invalid',
82
- message,
83
- } );
84
- return;
85
- }
86
-
87
- setCustomValidity( undefined );
88
- },
89
- [ data, field, isValid, setValue ]
90
- );
91
-
92
57
  return (
93
58
  <ValidatedInputControl
94
59
  required={ !! isValid?.required }
95
- onValidate={ onValidateControl }
96
- customValidity={ customValidity }
60
+ customValidity={ getCustomValidity( isValid, validity ) }
97
61
  label={ label }
98
62
  placeholder={ placeholder }
99
63
  value={ value ?? '' }
@@ -1,8 +1,3 @@
1
- /**
2
- * External dependencies
3
- */
4
- import deepMerge from 'deepmerge';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
@@ -12,7 +7,7 @@ import {
12
7
  __experimentalNumberControl as NumberControl,
13
8
  privateApis,
14
9
  } from '@wordpress/components';
15
- import { useCallback, useState } from '@wordpress/element';
10
+ import { useCallback } from '@wordpress/element';
16
11
  import { __ } from '@wordpress/i18n';
17
12
 
18
13
  /**
@@ -21,6 +16,7 @@ import { __ } from '@wordpress/i18n';
21
16
  import { OPERATOR_BETWEEN } from '../../constants';
22
17
  import type { DataFormControlProps } from '../../types';
23
18
  import { unlock } from '../../lock-unlock';
19
+ import getCustomValidity from './get-custom-validity';
24
20
 
25
21
  const { ValidatedNumberControl } = unlock( privateApis );
26
22
 
@@ -103,16 +99,11 @@ export default function ValidatedNumber< Item >( {
103
99
  hideLabelFromVision,
104
100
  operator,
105
101
  decimals,
102
+ validity,
106
103
  }: DataFormValidatedNumberControlProps< Item > ) {
107
104
  const step = Math.pow( 10, Math.abs( decimals ) * -1 );
108
- const { label, description, getValue, setValue } = field;
105
+ const { label, description, getValue, setValue, isValid } = field;
109
106
  const value = getValue( { item: data } ) ?? '';
110
- const [ customValidity, setCustomValidity ] =
111
- useState<
112
- React.ComponentProps<
113
- typeof ValidatedNumberControl
114
- >[ 'customValidity' ]
115
- >( undefined );
116
107
 
117
108
  const onChangeControl = useCallback(
118
109
  ( newValue: string | undefined ) => {
@@ -143,34 +134,6 @@ export default function ValidatedNumber< Item >( {
143
134
  [ data, onChange, setValue ]
144
135
  );
145
136
 
146
- const onValidateControl = useCallback(
147
- ( newValue: any ) => {
148
- const message = field.isValid?.custom?.(
149
- deepMerge(
150
- data,
151
- setValue( {
152
- item: data,
153
- value: [ undefined, '', null ].includes( newValue )
154
- ? undefined
155
- : Number( newValue ),
156
- } ) as Partial< Item >
157
- ),
158
- field
159
- );
160
-
161
- if ( message ) {
162
- setCustomValidity( {
163
- type: 'invalid',
164
- message,
165
- } );
166
- return;
167
- }
168
-
169
- setCustomValidity( undefined );
170
- },
171
- [ data, field, setValue ]
172
- );
173
-
174
137
  if ( operator === OPERATOR_BETWEEN ) {
175
138
  let valueBetween: NumberBetween = [ '', '' ];
176
139
  if (
@@ -194,9 +157,8 @@ export default function ValidatedNumber< Item >( {
194
157
 
195
158
  return (
196
159
  <ValidatedNumberControl
197
- required={ !! field.isValid?.required }
198
- onValidate={ onValidateControl }
199
- customValidity={ customValidity }
160
+ required={ !! isValid?.required }
161
+ customValidity={ getCustomValidity( isValid, validity ) }
200
162
  label={ label }
201
163
  help={ description }
202
164
  value={ value }
@@ -127,6 +127,7 @@ export default function FormCardField< Item >( {
127
127
  field,
128
128
  onChange,
129
129
  hideLabelFromVision,
130
+ validity,
130
131
  }: FieldLayoutProps< Item > ) {
131
132
  const { fields } = useContext( DataFormContext );
132
133
 
@@ -191,6 +192,7 @@ export default function FormCardField< Item >( {
191
192
  data={ data }
192
193
  form={ form }
193
194
  onChange={ onChange }
195
+ validity={ validity?.children }
194
196
  />
195
197
  </CardBody>
196
198
  ) }
@@ -242,6 +244,7 @@ export default function FormCardField< Item >( {
242
244
  hideLabelFromVision={
243
245
  hideLabelFromVision || withHeader
244
246
  }
247
+ validity={ validity }
245
248
  />
246
249
  </CardBody>
247
250
  ) }
@@ -7,7 +7,13 @@ import { useContext, useMemo } from '@wordpress/element';
7
7
  /**
8
8
  * Internal dependencies
9
9
  */
10
- import type { Form, FormField, SimpleFormField } from '../types';
10
+ import type {
11
+ FieldValidity,
12
+ Form,
13
+ FormField,
14
+ FormValidity,
15
+ SimpleFormField,
16
+ } from '../types';
11
17
  import { getFormFieldLayout } from './index';
12
18
  import DataFormContext from '../components/dataform-context';
13
19
  import { isCombinedField } from './is-combined-field';
@@ -23,20 +29,24 @@ export function DataFormLayout< Item >( {
23
29
  data,
24
30
  form,
25
31
  onChange,
32
+ validity,
26
33
  children,
27
34
  as,
28
35
  }: {
29
36
  data: Item;
30
37
  form: Form;
31
38
  onChange: ( value: any ) => void;
39
+ validity?: FormValidity;
32
40
  children?: (
33
41
  FieldLayout: ( props: {
34
42
  data: Item;
35
43
  field: FormField;
36
44
  onChange: ( value: any ) => void;
37
45
  hideLabelFromVision?: boolean;
46
+ validity?: FieldValidity;
38
47
  } ) => React.JSX.Element | null,
39
- field: FormField
48
+ childField: FormField,
49
+ childFieldValidity?: FieldValidity
40
50
  ) => React.JSX.Element;
41
51
  as?: React.ComponentType< { children: React.ReactNode } >;
42
52
  } ) {
@@ -84,7 +94,11 @@ export function DataFormLayout< Item >( {
84
94
  }
85
95
 
86
96
  if ( children ) {
87
- return children( FieldLayout, formField );
97
+ return children(
98
+ FieldLayout,
99
+ formField,
100
+ validity?.[ formField.id ]
101
+ );
88
102
  }
89
103
 
90
104
  return (
@@ -93,6 +107,7 @@ export function DataFormLayout< Item >( {
93
107
  data={ data }
94
108
  field={ formField }
95
109
  onChange={ onChange }
110
+ validity={ validity?.[ formField.id ] }
96
111
  />
97
112
  );
98
113
  } ) }
@@ -16,7 +16,13 @@ import { closeSmall } from '@wordpress/icons';
16
16
  /**
17
17
  * Internal dependencies
18
18
  */
19
- import type { Form, FormField, NormalizedField } from '../../types';
19
+ import type {
20
+ FieldValidity,
21
+ Form,
22
+ FormField,
23
+ FormValidity,
24
+ NormalizedField,
25
+ } from '../../types';
20
26
  import { DataFormLayout } from '../data-form-layout';
21
27
  import { isCombinedField } from '../is-combined-field';
22
28
  import { DEFAULT_LAYOUT } from '../normalize-form-fields';
@@ -55,21 +61,23 @@ function DropdownHeader( {
55
61
  }
56
62
 
57
63
  function PanelDropdown< Item >( {
58
- fieldDefinition,
59
- summaryFields,
60
- popoverAnchor,
61
- labelPosition = 'side',
62
64
  data,
63
- onChange,
64
65
  field,
66
+ onChange,
67
+ validity,
68
+ labelPosition = 'side',
69
+ summaryFields,
70
+ fieldDefinition,
71
+ popoverAnchor,
65
72
  }: {
66
- fieldDefinition: NormalizedField< Item >;
67
- summaryFields: NormalizedField< Item >[];
68
- popoverAnchor: HTMLElement | null;
69
- labelPosition: 'side' | 'top' | 'none';
70
73
  data: Item;
71
- onChange: ( value: any ) => void;
72
74
  field: FormField;
75
+ onChange: ( value: any ) => void;
76
+ validity?: FieldValidity;
77
+ labelPosition: 'side' | 'top' | 'none';
78
+ summaryFields: NormalizedField< Item >[];
79
+ fieldDefinition: NormalizedField< Item >;
80
+ popoverAnchor: HTMLElement | null;
73
81
  } ) {
74
82
  const fieldLabel = isCombinedField( field )
75
83
  ? field.label
@@ -85,6 +93,17 @@ function PanelDropdown< Item >( {
85
93
  } ),
86
94
  [ field ]
87
95
  );
96
+ const formValidity = useMemo( (): FormValidity => {
97
+ if ( validity === undefined ) {
98
+ return undefined;
99
+ }
100
+
101
+ if ( isCombinedField( field ) ) {
102
+ return validity?.children;
103
+ }
104
+
105
+ return { [ field.id ]: validity };
106
+ }, [ validity, field ] );
88
107
 
89
108
  // Memoize popoverProps to avoid returning a new object every time.
90
109
  const popoverProps = useMemo(
@@ -127,16 +146,18 @@ function PanelDropdown< Item >( {
127
146
  data={ data }
128
147
  form={ form }
129
148
  onChange={ onChange }
149
+ validity={ formValidity }
130
150
  >
131
- { ( FieldLayout, nestedField ) => (
151
+ { ( FieldLayout, childField, childFieldValidity ) => (
132
152
  <FieldLayout
133
- key={ nestedField.id }
153
+ key={ childField.id }
134
154
  data={ data }
135
- field={ nestedField }
155
+ field={ childField }
136
156
  onChange={ onChange }
137
157
  hideLabelFromVision={
138
158
  ( form?.fields ?? [] ).length < 2
139
159
  }
160
+ validity={ childFieldValidity }
140
161
  />
141
162
  ) }
142
163
  </DataFormLayout>