@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,75 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var is_item_valid_exports = {};
30
- __export(is_item_valid_exports, {
31
- default: () => isItemValid
32
- });
33
- module.exports = __toCommonJS(is_item_valid_exports);
34
- var import_normalize_fields = __toESM(require("./normalize-fields"));
35
- function isItemValid(item, fields, form) {
36
- const _fields = (0, import_normalize_fields.default)(
37
- fields.filter(({ id }) => !!form.fields?.includes(id))
38
- );
39
- const isEmptyNullOrUndefined = (value) => [void 0, "", null].includes(value);
40
- const isArrayOrElementsEmptyNullOrUndefined = (value) => {
41
- return !Array.isArray(value) || value.length === 0 || value.every((element) => isEmptyNullOrUndefined(element));
42
- };
43
- return _fields.every((field) => {
44
- const value = field.getValue({ item });
45
- if (field.isValid.required) {
46
- if (field.type === "text" && isEmptyNullOrUndefined(value) || field.type === "email" && isEmptyNullOrUndefined(value) || field.type === "url" && isEmptyNullOrUndefined(value) || field.type === "telephone" && isEmptyNullOrUndefined(value) || field.type === "password" && isEmptyNullOrUndefined(value) || field.type === "integer" && isEmptyNullOrUndefined(value) || field.type === "number" && isEmptyNullOrUndefined(value) || field.type === "array" && isArrayOrElementsEmptyNullOrUndefined(value) || field.type === void 0 && isEmptyNullOrUndefined(value)) {
47
- return false;
48
- }
49
- if (field.type === "boolean" && value !== true) {
50
- return false;
51
- }
52
- }
53
- if (field.isValid.elements) {
54
- if (field.elements) {
55
- const validValues = field.elements.map(
56
- (element) => element.value
57
- );
58
- if (field.type === "array") {
59
- if (Array.isArray(value)) {
60
- return value.every(
61
- (arrayItem) => validValues.includes(arrayItem)
62
- );
63
- }
64
- return false;
65
- }
66
- return validValues.includes(value);
67
- }
68
- }
69
- if (typeof field.isValid.custom === "function" && field.isValid.custom(item, field) !== null) {
70
- return false;
71
- }
72
- return true;
73
- });
74
- }
75
- //# sourceMappingURL=is-item-valid.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/utils/is-item-valid.ts"],
4
- "sourcesContent": ["/**\n * Internal dependencies\n */\nimport normalizeFields from './normalize-fields';\nimport type { Field, Form } from '../types';\n\n/**\n * Whether or not the given item's value is valid according to the fields and form config.\n *\n * @param item The item to validate.\n * @param fields Fields config.\n * @param form Form config.\n *\n * @return A boolean indicating if the item is valid (true) or not (false).\n */\nexport default function isItemValid< Item >(\n\titem: Item,\n\tfields: Field< Item >[],\n\tform: Form\n): boolean {\n\tconst _fields = normalizeFields(\n\t\tfields.filter( ( { id } ) => !! form.fields?.includes( id ) )\n\t);\n\n\tconst isEmptyNullOrUndefined = ( value: any ) =>\n\t\t[ undefined, '', null ].includes( value );\n\n\tconst isArrayOrElementsEmptyNullOrUndefined = ( value: any ) => {\n\t\treturn (\n\t\t\t! Array.isArray( value ) ||\n\t\t\tvalue.length === 0 ||\n\t\t\tvalue.every( ( element: any ) => isEmptyNullOrUndefined( element ) )\n\t\t);\n\t};\n\n\treturn _fields.every( ( field ) => {\n\t\tconst value = field.getValue( { item } );\n\n\t\tif ( field.isValid.required ) {\n\t\t\tif (\n\t\t\t\t( field.type === 'text' && isEmptyNullOrUndefined( value ) ) ||\n\t\t\t\t( field.type === 'email' && isEmptyNullOrUndefined( value ) ) ||\n\t\t\t\t( field.type === 'url' && isEmptyNullOrUndefined( value ) ) ||\n\t\t\t\t( field.type === 'telephone' &&\n\t\t\t\t\tisEmptyNullOrUndefined( value ) ) ||\n\t\t\t\t( field.type === 'password' &&\n\t\t\t\t\tisEmptyNullOrUndefined( value ) ) ||\n\t\t\t\t( field.type === 'integer' &&\n\t\t\t\t\tisEmptyNullOrUndefined( value ) ) ||\n\t\t\t\t( field.type === 'number' &&\n\t\t\t\t\tisEmptyNullOrUndefined( value ) ) ||\n\t\t\t\t( field.type === 'array' &&\n\t\t\t\t\tisArrayOrElementsEmptyNullOrUndefined( value ) ) ||\n\t\t\t\t( field.type === undefined && isEmptyNullOrUndefined( value ) )\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif ( field.type === 'boolean' && value !== true ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tif ( field.isValid.elements ) {\n\t\t\tif ( field.elements ) {\n\t\t\t\tconst validValues = field.elements.map(\n\t\t\t\t\t( element ) => element.value\n\t\t\t\t);\n\n\t\t\t\tif ( field.type === 'array' ) {\n\t\t\t\t\t// For arrays, check if all values are valid elements\n\t\t\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\t\t\treturn value.every( ( arrayItem ) =>\n\t\t\t\t\t\t\tvalidValues.includes( arrayItem )\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// For single-value fields, check if the value is a valid element\n\t\t\t\treturn validValues.includes( value );\n\t\t\t}\n\t\t}\n\n\t\tif (\n\t\t\ttypeof field.isValid.custom === 'function' &&\n\t\t\tfield.isValid.custom( item, field ) !== null\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} );\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,8BAA4B;AAYb,SAAR,YACN,MACA,QACA,MACU;AACV,QAAM,cAAU,wBAAAA;AAAA,IACf,OAAO,OAAQ,CAAE,EAAE,GAAG,MAAO,CAAC,CAAE,KAAK,QAAQ,SAAU,EAAG,CAAE;AAAA,EAC7D;AAEA,QAAM,yBAAyB,CAAE,UAChC,CAAE,QAAW,IAAI,IAAK,EAAE,SAAU,KAAM;AAEzC,QAAM,wCAAwC,CAAE,UAAgB;AAC/D,WACC,CAAE,MAAM,QAAS,KAAM,KACvB,MAAM,WAAW,KACjB,MAAM,MAAO,CAAE,YAAkB,uBAAwB,OAAQ,CAAE;AAAA,EAErE;AAEA,SAAO,QAAQ,MAAO,CAAE,UAAW;AAClC,UAAM,QAAQ,MAAM,SAAU,EAAE,KAAK,CAAE;AAEvC,QAAK,MAAM,QAAQ,UAAW;AAC7B,UACG,MAAM,SAAS,UAAU,uBAAwB,KAAM,KACvD,MAAM,SAAS,WAAW,uBAAwB,KAAM,KACxD,MAAM,SAAS,SAAS,uBAAwB,KAAM,KACtD,MAAM,SAAS,eAChB,uBAAwB,KAAM,KAC7B,MAAM,SAAS,cAChB,uBAAwB,KAAM,KAC7B,MAAM,SAAS,aAChB,uBAAwB,KAAM,KAC7B,MAAM,SAAS,YAChB,uBAAwB,KAAM,KAC7B,MAAM,SAAS,WAChB,sCAAuC,KAAM,KAC5C,MAAM,SAAS,UAAa,uBAAwB,KAAM,GAC3D;AACD,eAAO;AAAA,MACR;AAEA,UAAK,MAAM,SAAS,aAAa,UAAU,MAAO;AACjD,eAAO;AAAA,MACR;AAAA,IACD;AAEA,QAAK,MAAM,QAAQ,UAAW;AAC7B,UAAK,MAAM,UAAW;AACrB,cAAM,cAAc,MAAM,SAAS;AAAA,UAClC,CAAE,YAAa,QAAQ;AAAA,QACxB;AAEA,YAAK,MAAM,SAAS,SAAU;AAE7B,cAAK,MAAM,QAAS,KAAM,GAAI;AAC7B,mBAAO,MAAM;AAAA,cAAO,CAAE,cACrB,YAAY,SAAU,SAAU;AAAA,YACjC;AAAA,UACD;AACA,iBAAO;AAAA,QACR;AAEA,eAAO,YAAY,SAAU,KAAM;AAAA,MACpC;AAAA,IACD;AAEA,QACC,OAAO,MAAM,QAAQ,WAAW,cAChC,MAAM,QAAQ,OAAQ,MAAM,KAAM,MAAM,MACvC;AACD,aAAO;AAAA,IACR;AAEA,WAAO;AAAA,EACR,CAAE;AACH;",
6
- "names": ["normalizeFields"]
7
- }
@@ -1,45 +0,0 @@
1
- import normalizeFields from "./normalize-fields";
2
- function isItemValid(item, fields, form) {
3
- const _fields = normalizeFields(
4
- fields.filter(({ id }) => !!form.fields?.includes(id))
5
- );
6
- const isEmptyNullOrUndefined = (value) => [void 0, "", null].includes(value);
7
- const isArrayOrElementsEmptyNullOrUndefined = (value) => {
8
- return !Array.isArray(value) || value.length === 0 || value.every((element) => isEmptyNullOrUndefined(element));
9
- };
10
- return _fields.every((field) => {
11
- const value = field.getValue({ item });
12
- if (field.isValid.required) {
13
- if (field.type === "text" && isEmptyNullOrUndefined(value) || field.type === "email" && isEmptyNullOrUndefined(value) || field.type === "url" && isEmptyNullOrUndefined(value) || field.type === "telephone" && isEmptyNullOrUndefined(value) || field.type === "password" && isEmptyNullOrUndefined(value) || field.type === "integer" && isEmptyNullOrUndefined(value) || field.type === "number" && isEmptyNullOrUndefined(value) || field.type === "array" && isArrayOrElementsEmptyNullOrUndefined(value) || field.type === void 0 && isEmptyNullOrUndefined(value)) {
14
- return false;
15
- }
16
- if (field.type === "boolean" && value !== true) {
17
- return false;
18
- }
19
- }
20
- if (field.isValid.elements) {
21
- if (field.elements) {
22
- const validValues = field.elements.map(
23
- (element) => element.value
24
- );
25
- if (field.type === "array") {
26
- if (Array.isArray(value)) {
27
- return value.every(
28
- (arrayItem) => validValues.includes(arrayItem)
29
- );
30
- }
31
- return false;
32
- }
33
- return validValues.includes(value);
34
- }
35
- }
36
- if (typeof field.isValid.custom === "function" && field.isValid.custom(item, field) !== null) {
37
- return false;
38
- }
39
- return true;
40
- });
41
- }
42
- export {
43
- isItemValid as default
44
- };
45
- //# sourceMappingURL=is-item-valid.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/utils/is-item-valid.ts"],
4
- "sourcesContent": ["/**\n * Internal dependencies\n */\nimport normalizeFields from './normalize-fields';\nimport type { Field, Form } from '../types';\n\n/**\n * Whether or not the given item's value is valid according to the fields and form config.\n *\n * @param item The item to validate.\n * @param fields Fields config.\n * @param form Form config.\n *\n * @return A boolean indicating if the item is valid (true) or not (false).\n */\nexport default function isItemValid< Item >(\n\titem: Item,\n\tfields: Field< Item >[],\n\tform: Form\n): boolean {\n\tconst _fields = normalizeFields(\n\t\tfields.filter( ( { id } ) => !! form.fields?.includes( id ) )\n\t);\n\n\tconst isEmptyNullOrUndefined = ( value: any ) =>\n\t\t[ undefined, '', null ].includes( value );\n\n\tconst isArrayOrElementsEmptyNullOrUndefined = ( value: any ) => {\n\t\treturn (\n\t\t\t! Array.isArray( value ) ||\n\t\t\tvalue.length === 0 ||\n\t\t\tvalue.every( ( element: any ) => isEmptyNullOrUndefined( element ) )\n\t\t);\n\t};\n\n\treturn _fields.every( ( field ) => {\n\t\tconst value = field.getValue( { item } );\n\n\t\tif ( field.isValid.required ) {\n\t\t\tif (\n\t\t\t\t( field.type === 'text' && isEmptyNullOrUndefined( value ) ) ||\n\t\t\t\t( field.type === 'email' && isEmptyNullOrUndefined( value ) ) ||\n\t\t\t\t( field.type === 'url' && isEmptyNullOrUndefined( value ) ) ||\n\t\t\t\t( field.type === 'telephone' &&\n\t\t\t\t\tisEmptyNullOrUndefined( value ) ) ||\n\t\t\t\t( field.type === 'password' &&\n\t\t\t\t\tisEmptyNullOrUndefined( value ) ) ||\n\t\t\t\t( field.type === 'integer' &&\n\t\t\t\t\tisEmptyNullOrUndefined( value ) ) ||\n\t\t\t\t( field.type === 'number' &&\n\t\t\t\t\tisEmptyNullOrUndefined( value ) ) ||\n\t\t\t\t( field.type === 'array' &&\n\t\t\t\t\tisArrayOrElementsEmptyNullOrUndefined( value ) ) ||\n\t\t\t\t( field.type === undefined && isEmptyNullOrUndefined( value ) )\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif ( field.type === 'boolean' && value !== true ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tif ( field.isValid.elements ) {\n\t\t\tif ( field.elements ) {\n\t\t\t\tconst validValues = field.elements.map(\n\t\t\t\t\t( element ) => element.value\n\t\t\t\t);\n\n\t\t\t\tif ( field.type === 'array' ) {\n\t\t\t\t\t// For arrays, check if all values are valid elements\n\t\t\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\t\t\treturn value.every( ( arrayItem ) =>\n\t\t\t\t\t\t\tvalidValues.includes( arrayItem )\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// For single-value fields, check if the value is a valid element\n\t\t\t\treturn validValues.includes( value );\n\t\t\t}\n\t\t}\n\n\t\tif (\n\t\t\ttypeof field.isValid.custom === 'function' &&\n\t\t\tfield.isValid.custom( item, field ) !== null\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} );\n}\n"],
5
- "mappings": "AAGA,OAAO,qBAAqB;AAYb,SAAR,YACN,MACA,QACA,MACU;AACV,QAAM,UAAU;AAAA,IACf,OAAO,OAAQ,CAAE,EAAE,GAAG,MAAO,CAAC,CAAE,KAAK,QAAQ,SAAU,EAAG,CAAE;AAAA,EAC7D;AAEA,QAAM,yBAAyB,CAAE,UAChC,CAAE,QAAW,IAAI,IAAK,EAAE,SAAU,KAAM;AAEzC,QAAM,wCAAwC,CAAE,UAAgB;AAC/D,WACC,CAAE,MAAM,QAAS,KAAM,KACvB,MAAM,WAAW,KACjB,MAAM,MAAO,CAAE,YAAkB,uBAAwB,OAAQ,CAAE;AAAA,EAErE;AAEA,SAAO,QAAQ,MAAO,CAAE,UAAW;AAClC,UAAM,QAAQ,MAAM,SAAU,EAAE,KAAK,CAAE;AAEvC,QAAK,MAAM,QAAQ,UAAW;AAC7B,UACG,MAAM,SAAS,UAAU,uBAAwB,KAAM,KACvD,MAAM,SAAS,WAAW,uBAAwB,KAAM,KACxD,MAAM,SAAS,SAAS,uBAAwB,KAAM,KACtD,MAAM,SAAS,eAChB,uBAAwB,KAAM,KAC7B,MAAM,SAAS,cAChB,uBAAwB,KAAM,KAC7B,MAAM,SAAS,aAChB,uBAAwB,KAAM,KAC7B,MAAM,SAAS,YAChB,uBAAwB,KAAM,KAC7B,MAAM,SAAS,WAChB,sCAAuC,KAAM,KAC5C,MAAM,SAAS,UAAa,uBAAwB,KAAM,GAC3D;AACD,eAAO;AAAA,MACR;AAEA,UAAK,MAAM,SAAS,aAAa,UAAU,MAAO;AACjD,eAAO;AAAA,MACR;AAAA,IACD;AAEA,QAAK,MAAM,QAAQ,UAAW;AAC7B,UAAK,MAAM,UAAW;AACrB,cAAM,cAAc,MAAM,SAAS;AAAA,UAClC,CAAE,YAAa,QAAQ;AAAA,QACxB;AAEA,YAAK,MAAM,SAAS,SAAU;AAE7B,cAAK,MAAM,QAAS,KAAM,GAAI;AAC7B,mBAAO,MAAM;AAAA,cAAO,CAAE,cACrB,YAAY,SAAU,SAAU;AAAA,YACjC;AAAA,UACD;AACA,iBAAO;AAAA,QACR;AAEA,eAAO,YAAY,SAAU,KAAM;AAAA,MACpC;AAAA,IACD;AAEA,QACC,OAAO,MAAM,QAAQ,WAAW,cAChC,MAAM,QAAQ,OAAQ,MAAM,KAAM,MAAM,MACvC;AACD,aAAO;AAAA,IACR;AAEA,WAAO;AAAA,EACR,CAAE;AACH;",
6
- "names": []
7
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=validation.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/test/validation.ts"],"names":[],"mappings":""}
@@ -1,12 +0,0 @@
1
- import type { Field, Form } from '../types';
2
- /**
3
- * Whether or not the given item's value is valid according to the fields and form config.
4
- *
5
- * @param item The item to validate.
6
- * @param fields Fields config.
7
- * @param form Form config.
8
- *
9
- * @return A boolean indicating if the item is valid (true) or not (false).
10
- */
11
- export default function isItemValid<Item>(item: Item, fields: Field<Item>[], form: Form): boolean;
12
- //# sourceMappingURL=is-item-valid.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"is-item-valid.d.ts","sourceRoot":"","sources":["../../src/utils/is-item-valid.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,UAAU,WAAW,CAAE,IAAI,EACxC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,KAAK,CAAE,IAAI,CAAE,EAAE,EACvB,IAAI,EAAE,IAAI,GACR,OAAO,CAyET"}
@@ -1,15 +0,0 @@
1
- /**
2
- * Internal dependencies
3
- */
4
- import type { DataViewRenderFieldProps } from '../../types';
5
-
6
- export default function renderFromElements< Item >( {
7
- item,
8
- field,
9
- }: DataViewRenderFieldProps< Item > ) {
10
- const value = field.getValue( { item } );
11
- return (
12
- field?.elements?.find( ( element ) => element.value === value )
13
- ?.label || field.getValue( { item } )
14
- );
15
- }
@@ -1,322 +0,0 @@
1
- /**
2
- * Internal dependencies
3
- */
4
- import isItemValid from '../utils/is-item-valid';
5
- import type { Field } from '../types';
6
-
7
- describe( 'validation', () => {
8
- it( 'operates on form fields', () => {
9
- const item = { id: 1, valid_order: 2, invalid_order: 'd' };
10
- const fields: Field< {} >[] = [
11
- {
12
- id: 'valid_order',
13
- type: 'integer',
14
- },
15
- {
16
- id: 'invalid_order',
17
- type: 'integer',
18
- },
19
- ];
20
- const form = { fields: [ 'valid_order' ] };
21
- const result = isItemValid( item, fields, form );
22
- expect( result ).toBe( true );
23
- } );
24
-
25
- it( 'fields can override the defaults', () => {
26
- const item = { id: 1, order: 'd' };
27
- const fields: Field< {} >[] = [
28
- {
29
- id: 'order',
30
- type: 'integer',
31
- elements: [
32
- { value: 'a', label: 'A' },
33
- { value: 'b', label: 'B' },
34
- ],
35
- isValid: {
36
- elements: false,
37
- custom: () => null, // Overrides the validation provided for integer types.
38
- },
39
- },
40
- ];
41
- const form = { fields: [ 'order' ] };
42
- const result = isItemValid( item, fields, form );
43
- expect( result ).toBe( true );
44
- } );
45
-
46
- describe( 'isValid.required', () => {
47
- it( 'array is invalid when required but empty', () => {
48
- const item = { id: 1, tags: [] };
49
- const fields: Field< {} >[] = [
50
- {
51
- id: 'tags',
52
- type: 'array',
53
- isValid: {
54
- required: true,
55
- },
56
- },
57
- ];
58
- const form = { fields: [ 'tags' ] };
59
- const result = isItemValid( item, fields, form );
60
- expect( result ).toBe( false );
61
- } );
62
-
63
- it( 'array is invalid when required but not an array', () => {
64
- const item = { id: 1, tags: null };
65
- const fields: Field< {} >[] = [
66
- {
67
- id: 'tags',
68
- type: 'array',
69
- isValid: {
70
- required: true,
71
- },
72
- },
73
- ];
74
- const form = { fields: [ 'tags' ] };
75
- const result = isItemValid( item, fields, form );
76
- expect( result ).toBe( false );
77
- } );
78
-
79
- it( 'array is valid when required and has values', () => {
80
- const item = { id: 1, tags: [ 'tag1', 'tag2' ] };
81
- const fields: Field< {} >[] = [
82
- {
83
- id: 'tags',
84
- type: 'array',
85
- isValid: {
86
- required: true,
87
- },
88
- },
89
- ];
90
- const form = { fields: [ 'tags' ] };
91
- const result = isItemValid( item, fields, form );
92
- expect( result ).toBe( true );
93
- } );
94
- } );
95
-
96
- describe( 'isValid.elements', () => {
97
- it( 'untyped is invalid if value is not one of the elements', () => {
98
- const item = { id: 1, author: 'not-in-elements' };
99
- const fields: Field< {} >[] = [
100
- {
101
- id: 'author',
102
- elements: [
103
- { value: 'jane', label: 'Jane' },
104
- { value: 'john', label: 'John' },
105
- ],
106
- },
107
- ];
108
- const form = { fields: [ 'author' ] };
109
- const result = isItemValid( item, fields, form );
110
- expect( result ).toBe( false );
111
- } );
112
-
113
- it( 'text is valid when value is one of the elements', () => {
114
- const item = { id: 1, status: 'published' };
115
- const fields: Field< {} >[] = [
116
- {
117
- id: 'status',
118
- type: 'text',
119
- elements: [
120
- { value: 'draft', label: 'Draft' },
121
- { value: 'published', label: 'Published' },
122
- ],
123
- isValid: {
124
- elements: true,
125
- },
126
- },
127
- ];
128
- const form = { fields: [ 'status' ] };
129
- const result = isItemValid( item, fields, form );
130
- expect( result ).toBe( true );
131
- } );
132
-
133
- it( 'text is invalid when value is not one of the elements', () => {
134
- const item = { id: 1, status: 'invalid-status' };
135
- const fields: Field< {} >[] = [
136
- {
137
- id: 'status',
138
- type: 'text',
139
- elements: [
140
- { value: 'draft', label: 'Draft' },
141
- { value: 'published', label: 'Published' },
142
- ],
143
- isValid: {
144
- elements: true,
145
- },
146
- },
147
- ];
148
- const form = { fields: [ 'status' ] };
149
- const result = isItemValid( item, fields, form );
150
- expect( result ).toBe( false );
151
- } );
152
-
153
- it( 'integer is valid when value is one of the elements', () => {
154
- const item = { id: 1, priority: 2 };
155
- const fields: Field< {} >[] = [
156
- {
157
- id: 'priority',
158
- type: 'integer',
159
- elements: [
160
- { value: 1, label: 'Low' },
161
- { value: 2, label: 'Medium' },
162
- { value: 3, label: 'High' },
163
- ],
164
- isValid: {
165
- elements: true,
166
- },
167
- },
168
- ];
169
- const form = { fields: [ 'priority' ] };
170
- const result = isItemValid( item, fields, form );
171
- expect( result ).toBe( true );
172
- } );
173
-
174
- it( 'integer is invalid when value is not one of the elements', () => {
175
- const item = { id: 1, priority: 5 };
176
- const fields: Field< {} >[] = [
177
- {
178
- id: 'priority',
179
- type: 'integer',
180
- elements: [
181
- { value: 1, label: 'Low' },
182
- { value: 2, label: 'Medium' },
183
- { value: 3, label: 'High' },
184
- ],
185
- isValid: {
186
- elements: true,
187
- },
188
- },
189
- ];
190
- const form = { fields: [ 'priority' ] };
191
- const result = isItemValid( item, fields, form );
192
- expect( result ).toBe( false );
193
- } );
194
-
195
- it( 'number is invalid if value is not one of the elements', () => {
196
- const item = { id: 1, price: 4.5 };
197
- const fields: Field< {} >[] = [
198
- {
199
- id: 'price',
200
- type: 'number',
201
- elements: [
202
- { value: 1.5, label: 'Bronze' },
203
- { value: 2.5, label: 'Silver' },
204
- ],
205
- },
206
- ];
207
- const form = { fields: [ 'price' ] };
208
- const result = isItemValid( item, fields, form );
209
- expect( result ).toBe( false );
210
- } );
211
-
212
- it( 'array is valid if all items are part of the elements', () => {
213
- const item = { id: 1, tags: [ 'red', 'blue' ] };
214
- const fields: Field< {} >[] = [
215
- {
216
- id: 'tags',
217
- type: 'array',
218
- elements: [
219
- { value: 'red', label: 'Red' },
220
- { value: 'blue', label: 'Blue' },
221
- { value: 'green', label: 'Green' },
222
- ],
223
- },
224
- ];
225
- const form = { fields: [ 'tags' ] };
226
- const result = isItemValid( item, fields, form );
227
- expect( result ).toBe( true );
228
- } );
229
-
230
- it( 'array is invalid when not all items are part of the elements', () => {
231
- const item = { id: 1, tags: [ 'red', 'yellow' ] };
232
- const fields: Field< {} >[] = [
233
- {
234
- id: 'tags',
235
- type: 'array',
236
- elements: [
237
- { value: 'red', label: 'Red' },
238
- { value: 'blue', label: 'Blue' },
239
- { value: 'green', label: 'Green' },
240
- ],
241
- },
242
- ];
243
- const form = { fields: [ 'tags' ] };
244
- const result = isItemValid( item, fields, form );
245
- expect( result ).toBe( false );
246
- } );
247
-
248
- it( 'array is invalid when value is not an array', () => {
249
- const item = { id: 1, tags: 'not-an-array' };
250
- const fields: Field< {} >[] = [
251
- {
252
- id: 'tags',
253
- type: 'array',
254
- elements: [
255
- { value: 'red', label: 'Red' },
256
- { value: 'blue', label: 'Blue' },
257
- ],
258
- isValid: {
259
- custom: () => null, // Disable to make sure the only validation triggered is elements
260
- },
261
- },
262
- ];
263
- const form = { fields: [ 'tags' ] };
264
- const result = isItemValid( item, fields, form );
265
- expect( result ).toBe( false );
266
- } );
267
- } );
268
- } );
269
-
270
- describe( 'isValid.custom', () => {
271
- it( 'integer is valid if value is integer', () => {
272
- const item = { id: 1, order: 2, title: 'hi' };
273
- const fields: Field< {} >[] = [
274
- {
275
- type: 'integer',
276
- id: 'order',
277
- },
278
- ];
279
- const form = { fields: [ 'order' ] };
280
- const result = isItemValid( item, fields, form );
281
- expect( result ).toBe( true );
282
- } );
283
-
284
- it( 'integer is invalid if value is not integer when not empty', () => {
285
- const item = { id: 1, order: 'd' };
286
- const fields: Field< {} >[] = [
287
- {
288
- id: 'order',
289
- type: 'integer',
290
- },
291
- ];
292
- const form = { fields: [ 'order' ] };
293
- const result = isItemValid( item, fields, form );
294
- expect( result ).toBe( false );
295
- } );
296
-
297
- it( 'number is valid if value is finite', () => {
298
- const item = { id: 1, price: 2.5 };
299
- const fields: Field< {} >[] = [
300
- {
301
- id: 'price',
302
- type: 'number',
303
- },
304
- ];
305
- const form = { fields: [ 'price' ] };
306
- const result = isItemValid( item, fields, form );
307
- expect( result ).toBe( true );
308
- } );
309
-
310
- it( 'number is invalid if value is not finite when not empty', () => {
311
- const item = { id: 1, price: Number.NaN };
312
- const fields: Field< {} >[] = [
313
- {
314
- id: 'price',
315
- type: 'number',
316
- },
317
- ];
318
- const form = { fields: [ 'price' ] };
319
- const result = isItemValid( item, fields, form );
320
- expect( result ).toBe( false );
321
- } );
322
- } );
@@ -1,93 +0,0 @@
1
- /**
2
- * Internal dependencies
3
- */
4
- import normalizeFields from './normalize-fields';
5
- import type { Field, Form } from '../types';
6
-
7
- /**
8
- * Whether or not the given item's value is valid according to the fields and form config.
9
- *
10
- * @param item The item to validate.
11
- * @param fields Fields config.
12
- * @param form Form config.
13
- *
14
- * @return A boolean indicating if the item is valid (true) or not (false).
15
- */
16
- export default function isItemValid< Item >(
17
- item: Item,
18
- fields: Field< Item >[],
19
- form: Form
20
- ): boolean {
21
- const _fields = normalizeFields(
22
- fields.filter( ( { id } ) => !! form.fields?.includes( id ) )
23
- );
24
-
25
- const isEmptyNullOrUndefined = ( value: any ) =>
26
- [ undefined, '', null ].includes( value );
27
-
28
- const isArrayOrElementsEmptyNullOrUndefined = ( value: any ) => {
29
- return (
30
- ! Array.isArray( value ) ||
31
- value.length === 0 ||
32
- value.every( ( element: any ) => isEmptyNullOrUndefined( element ) )
33
- );
34
- };
35
-
36
- return _fields.every( ( field ) => {
37
- const value = field.getValue( { item } );
38
-
39
- if ( field.isValid.required ) {
40
- if (
41
- ( field.type === 'text' && isEmptyNullOrUndefined( value ) ) ||
42
- ( field.type === 'email' && isEmptyNullOrUndefined( value ) ) ||
43
- ( field.type === 'url' && isEmptyNullOrUndefined( value ) ) ||
44
- ( field.type === 'telephone' &&
45
- isEmptyNullOrUndefined( value ) ) ||
46
- ( field.type === 'password' &&
47
- isEmptyNullOrUndefined( value ) ) ||
48
- ( field.type === 'integer' &&
49
- isEmptyNullOrUndefined( value ) ) ||
50
- ( field.type === 'number' &&
51
- isEmptyNullOrUndefined( value ) ) ||
52
- ( field.type === 'array' &&
53
- isArrayOrElementsEmptyNullOrUndefined( value ) ) ||
54
- ( field.type === undefined && isEmptyNullOrUndefined( value ) )
55
- ) {
56
- return false;
57
- }
58
-
59
- if ( field.type === 'boolean' && value !== true ) {
60
- return false;
61
- }
62
- }
63
-
64
- if ( field.isValid.elements ) {
65
- if ( field.elements ) {
66
- const validValues = field.elements.map(
67
- ( element ) => element.value
68
- );
69
-
70
- if ( field.type === 'array' ) {
71
- // For arrays, check if all values are valid elements
72
- if ( Array.isArray( value ) ) {
73
- return value.every( ( arrayItem ) =>
74
- validValues.includes( arrayItem )
75
- );
76
- }
77
- return false;
78
- }
79
- // For single-value fields, check if the value is a valid element
80
- return validValues.includes( value );
81
- }
82
- }
83
-
84
- if (
85
- typeof field.isValid.custom === 'function' &&
86
- field.isValid.custom( item, field ) !== null
87
- ) {
88
- return false;
89
- }
90
-
91
- return true;
92
- } );
93
- }