@maz-ui/mcp 5.0.1-beta.0 → 5.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (343) hide show
  1. package/README.md +61 -228
  2. package/bin/maz-ui-mcp.mjs +2 -5
  3. package/dist/cli.d.mts +7 -0
  4. package/dist/cli.d.ts +7 -0
  5. package/dist/cli.mjs +16 -0
  6. package/dist/index.d.mts +345 -0
  7. package/dist/index.d.ts +345 -0
  8. package/dist/index.mjs +16 -0
  9. package/dist/shared/mcp.DseFuKdl.mjs +2968 -0
  10. package/docs/README.md +207 -0
  11. package/docs/agents/agents-md.md +52 -0
  12. package/docs/agents/claude-rule.md +52 -0
  13. package/docs/components/maz-accordion.md +78 -0
  14. package/docs/{src/components → components}/maz-alert.md +31 -164
  15. package/docs/components/maz-animated-counter.md +87 -0
  16. package/docs/components/maz-animated-element.md +46 -0
  17. package/docs/components/maz-animated-text.md +53 -0
  18. package/docs/components/maz-avatar.md +193 -0
  19. package/docs/components/maz-backdrop.md +178 -0
  20. package/docs/{src/components → components}/maz-badge.md +26 -67
  21. package/docs/components/maz-bottom-sheet.md +257 -0
  22. package/docs/{src/components → components}/maz-btn-group.md +27 -189
  23. package/docs/{src/components → components}/maz-btn.md +62 -245
  24. package/docs/components/maz-card-spotlight.md +84 -0
  25. package/docs/{src/components → components}/maz-card.md +67 -192
  26. package/docs/components/maz-carousel.md +153 -0
  27. package/docs/{src/components → components}/maz-chart.md +17 -161
  28. package/docs/components/maz-checkbox.md +138 -0
  29. package/docs/components/maz-checklist.md +251 -0
  30. package/docs/components/maz-circular-progress-bar.md +109 -0
  31. package/docs/{src/components → components}/maz-code-highlight.md +15 -93
  32. package/docs/components/maz-container.md +241 -0
  33. package/docs/{src/components → components}/maz-date-picker.md +85 -454
  34. package/docs/components/maz-dialog-confirm.md +215 -0
  35. package/docs/components/maz-dialog.md +143 -0
  36. package/docs/components/maz-drawer.md +107 -0
  37. package/docs/components/maz-dropdown.md +419 -0
  38. package/docs/{src/components → components}/maz-dropzone.md +80 -221
  39. package/docs/components/maz-expand-animation.md +82 -0
  40. package/docs/components/maz-fullscreen-loader.md +58 -0
  41. package/docs/components/maz-gallery.md +79 -0
  42. package/docs/{src/components → components}/maz-icon.md +32 -83
  43. package/docs/components/maz-input-code.md +73 -0
  44. package/docs/components/maz-input-number.md +79 -0
  45. package/docs/components/maz-input-phone-number.md +536 -0
  46. package/docs/components/maz-input-price.md +68 -0
  47. package/docs/components/maz-input-tags.md +112 -0
  48. package/docs/{src/components → components}/maz-input.md +74 -221
  49. package/docs/components/maz-lazy-img.md +113 -0
  50. package/docs/components/maz-link.md +146 -0
  51. package/docs/components/maz-loading-bar.md +38 -0
  52. package/docs/{src/components → components}/maz-markdown-editor.md +72 -125
  53. package/docs/components/maz-pagination.md +82 -0
  54. package/docs/components/maz-popover.md +794 -0
  55. package/docs/{src/components → components}/maz-pull-to-refresh.md +59 -45
  56. package/docs/components/maz-radio-buttons.md +313 -0
  57. package/docs/components/maz-radio.md +119 -0
  58. package/docs/{src/components → components}/maz-read-more.md +31 -122
  59. package/docs/components/maz-reading-progress-bar.md +96 -0
  60. package/docs/{src/components → components}/maz-select-country.md +80 -340
  61. package/docs/{src/components → components}/maz-select.md +76 -206
  62. package/docs/components/maz-sidebar-content.md +25 -0
  63. package/docs/components/maz-sidebar-footer.md +25 -0
  64. package/docs/components/maz-sidebar-group.md +27 -0
  65. package/docs/components/maz-sidebar-header.md +25 -0
  66. package/docs/components/maz-sidebar-menu-button.md +41 -0
  67. package/docs/components/maz-sidebar-menu-item.md +25 -0
  68. package/docs/components/maz-sidebar-menu-sub.md +32 -0
  69. package/docs/components/maz-sidebar-menu.md +25 -0
  70. package/docs/components/maz-sidebar-separator.md +21 -0
  71. package/docs/components/maz-sidebar-trigger.md +25 -0
  72. package/docs/{src/components → components}/maz-sidebar.md +117 -329
  73. package/docs/{src/components → components}/maz-skeleton.md +27 -156
  74. package/docs/{src/components → components}/maz-slider.md +33 -66
  75. package/docs/components/maz-spinner.md +84 -0
  76. package/docs/{src/components → components}/maz-stepper.md +48 -185
  77. package/docs/components/maz-switch.md +86 -0
  78. package/docs/components/maz-table-cell.md +27 -0
  79. package/docs/components/maz-table-row.md +28 -0
  80. package/docs/components/maz-table-title.md +27 -0
  81. package/docs/components/maz-table-virtualizer.md +31 -0
  82. package/docs/components/maz-table.md +426 -0
  83. package/docs/components/maz-tabs-bar.md +43 -0
  84. package/docs/components/maz-tabs-content-item.md +27 -0
  85. package/docs/components/maz-tabs-content.md +27 -0
  86. package/docs/{src/components → components}/maz-tabs.md +89 -126
  87. package/docs/components/maz-textarea.md +255 -0
  88. package/docs/components/maz-ticker.md +427 -0
  89. package/docs/components/maz-timeline.md +304 -0
  90. package/docs/components/maz-ui-provider.md +26 -0
  91. package/docs/{src/components → components}/maz-window-mockup.md +38 -105
  92. package/docs/composables/use-aos.md +41 -0
  93. package/docs/composables/use-breakpoints.md +42 -0
  94. package/docs/composables/use-dialog.md +58 -0
  95. package/docs/{src/composables → composables}/use-display-names.md +12 -59
  96. package/docs/{src/composables → composables}/use-drag.md +14 -68
  97. package/docs/{src/composables → composables}/use-form-validator.md +22 -696
  98. package/docs/{src/composables → composables}/use-idle-timeout.md +13 -97
  99. package/docs/{src/composables → composables}/use-pull-to-refresh.md +14 -7
  100. package/docs/{src/composables → composables}/use-reading-time.md +20 -56
  101. package/docs/composables/use-string-matching.md +41 -0
  102. package/docs/{src/composables → composables}/use-swipe.md +14 -81
  103. package/docs/{src/composables → composables}/use-timer.md +12 -38
  104. package/docs/composables/use-toast.md +50 -0
  105. package/docs/{src/composables → composables}/use-user-visibility.md +14 -56
  106. package/docs/composables/use-wait.md +50 -0
  107. package/docs/composables/use-window-size.md +25 -0
  108. package/docs/{src/directives → directives}/click-outside.md +13 -99
  109. package/docs/{src/directives → directives}/fullscreen-img.md +10 -28
  110. package/docs/{src/directives → directives}/lazy-img.md +14 -49
  111. package/docs/{src/directives → directives}/tooltip.md +12 -217
  112. package/docs/{src/directives → directives}/zoom-img.md +11 -38
  113. package/docs/{src/ecosystem → ecosystem}/eslint-config.md +37 -29
  114. package/docs/ecosystem/icons/icon-set.md +25 -0
  115. package/docs/{src/ecosystem → ecosystem}/icons/index.md +21 -15
  116. package/docs/ecosystem/mcp.md +165 -0
  117. package/docs/{src/ecosystem → ecosystem}/node/exec-promise.md +12 -6
  118. package/docs/ecosystem/node/index.md +53 -0
  119. package/docs/{src/ecosystem → ecosystem}/node/logger.md +12 -6
  120. package/docs/{src/ecosystem → ecosystem}/node/print-banner.md +12 -4
  121. package/docs/ecosystem/node/setup-agents.md +102 -0
  122. package/docs/{src/ecosystem → ecosystem}/nuxt.md +50 -19
  123. package/docs/{src/ecosystem → ecosystem}/stylelint-config.md +33 -25
  124. package/docs/{src/ecosystem → ecosystem}/themes.md +72 -235
  125. package/docs/{src/ecosystem → ecosystem}/translations.md +25 -23
  126. package/docs/ecosystem/utils/camel-case.md +37 -0
  127. package/docs/ecosystem/utils/capitalize.md +37 -0
  128. package/docs/{src/ecosystem → ecosystem}/utils/check-availability.md +14 -8
  129. package/docs/{src/ecosystem → ecosystem}/utils/cookie.md +18 -12
  130. package/docs/ecosystem/utils/country-code-to-unicode-flag.md +128 -0
  131. package/docs/{src/ecosystem → ecosystem}/utils/currency.md +12 -26
  132. package/docs/{src/ecosystem → ecosystem}/utils/date.md +10 -24
  133. package/docs/ecosystem/utils/debounce-callback.md +44 -0
  134. package/docs/{src/ecosystem → ecosystem}/utils/debounce-id.md +14 -8
  135. package/docs/{src/ecosystem → ecosystem}/utils/debounce.md +14 -8
  136. package/docs/ecosystem/utils/fetch-locale-ip.md +39 -0
  137. package/docs/{src/ecosystem → ecosystem}/utils/format-json.md +11 -5
  138. package/docs/{src/ecosystem → ecosystem}/utils/format-phone-number.md +12 -6
  139. package/docs/ecosystem/utils/get-browser-locale.md +35 -0
  140. package/docs/ecosystem/utils/get-country-flag-url.md +67 -0
  141. package/docs/{src/ecosystem → ecosystem}/utils/get-error-message.md +10 -4
  142. package/docs/{src/ecosystem → ecosystem}/utils/idle-timeout.md +15 -9
  143. package/docs/{src/ecosystem → ecosystem}/utils/index.md +10 -13
  144. package/docs/{src/ecosystem → ecosystem}/utils/is-client.md +11 -5
  145. package/docs/{src/ecosystem → ecosystem}/utils/is-equal.md +14 -8
  146. package/docs/{src/ecosystem → ecosystem}/utils/is-ios.md +12 -6
  147. package/docs/ecosystem/utils/is-server.md +37 -0
  148. package/docs/ecosystem/utils/is-standalone-mode.md +49 -0
  149. package/docs/{src/ecosystem → ecosystem}/utils/kebab-case.md +10 -4
  150. package/docs/{src/ecosystem → ecosystem}/utils/normalize-string.md +10 -4
  151. package/docs/{src/ecosystem → ecosystem}/utils/number.md +10 -24
  152. package/docs/{src/ecosystem → ecosystem}/utils/pascal-case.md +11 -5
  153. package/docs/{src/ecosystem → ecosystem}/utils/prevent-ios-input-zoom.md +14 -8
  154. package/docs/{src/ecosystem → ecosystem}/utils/script-loader.md +16 -8
  155. package/docs/{src/ecosystem → ecosystem}/utils/sleep.md +10 -4
  156. package/docs/{src/ecosystem → ecosystem}/utils/snake-case.md +10 -4
  157. package/docs/{src/ecosystem → ecosystem}/utils/swipe-handler.md +14 -8
  158. package/docs/{src/ecosystem → ecosystem}/utils/textarea-autogrow.md +12 -6
  159. package/docs/{src/ecosystem → ecosystem}/utils/throttle-id.md +13 -7
  160. package/docs/{src/ecosystem → ecosystem}/utils/throttle.md +14 -8
  161. package/docs/ecosystem/utils/truthy-filter.md +37 -0
  162. package/docs/{src/ecosystem → ecosystem}/utils/types/deep-key-of.md +11 -5
  163. package/docs/{src/ecosystem → ecosystem}/utils/types/deep-partial.md +10 -4
  164. package/docs/ecosystem/utils/types/deep-required.md +45 -0
  165. package/docs/ecosystem/utils/types/flatten-object-keys.md +50 -0
  166. package/docs/{src/ecosystem → ecosystem}/utils/types/generic-instance-type.md +10 -4
  167. package/docs/{src/ecosystem → ecosystem}/utils/types/infer-maybe-ref.md +10 -4
  168. package/docs/ecosystem/utils/upper-first.md +38 -0
  169. package/docs/{src/ecosystem → ecosystem}/utils/user-visibility.md +12 -6
  170. package/docs/guide/ai-agents.md +239 -0
  171. package/docs/{src/guide → guide}/browser-support.md +22 -15
  172. package/docs/{src/guide → guide}/getting-started.md +34 -139
  173. package/docs/{src/guide → guide}/global-defaults.md +12 -11
  174. package/docs/{src/guide → guide}/maz-ui-provider.md +17 -16
  175. package/docs/{src/guide → guide}/migration-v5.md +95 -88
  176. package/docs/{src/guide → guide}/resolvers.md +33 -100
  177. package/docs/guide/tailwind.md +507 -0
  178. package/docs/{src/guide → guide}/vue.md +33 -39
  179. package/docs/manifest.json +1 -0
  180. package/docs/{src/plugins → plugins}/aos.md +20 -55
  181. package/docs/{src/plugins → plugins}/dialog.md +14 -161
  182. package/docs/plugins/toast.md +221 -0
  183. package/docs/plugins/wait.md +78 -0
  184. package/docs/reference/icons.md +46 -0
  185. package/docs/reference/tailwind-tokens.md +191 -0
  186. package/docs/rules.md +59 -0
  187. package/package.json +86 -22
  188. package/dist/mcp.d.mts +0 -153
  189. package/dist/mcp.d.ts +0 -153
  190. package/dist/mcp.mjs +0 -1511
  191. package/docs/generated-docs/maz-accordion.doc.md +0 -21
  192. package/docs/generated-docs/maz-alert.doc.md +0 -20
  193. package/docs/generated-docs/maz-animated-counter.doc.md +0 -17
  194. package/docs/generated-docs/maz-animated-element.doc.md +0 -14
  195. package/docs/generated-docs/maz-animated-text.doc.md +0 -17
  196. package/docs/generated-docs/maz-avatar.doc.md +0 -45
  197. package/docs/generated-docs/maz-backdrop.doc.md +0 -55
  198. package/docs/generated-docs/maz-badge.doc.md +0 -16
  199. package/docs/generated-docs/maz-bottom-sheet.doc.md +0 -24
  200. package/docs/generated-docs/maz-btn-group.doc.md +0 -20
  201. package/docs/generated-docs/maz-btn.doc.md +0 -33
  202. package/docs/generated-docs/maz-card-spotlight.doc.md +0 -16
  203. package/docs/generated-docs/maz-card.doc.md +0 -39
  204. package/docs/generated-docs/maz-carousel.doc.md +0 -17
  205. package/docs/generated-docs/maz-chart.doc.md +0 -10
  206. package/docs/generated-docs/maz-checkbox.doc.md +0 -33
  207. package/docs/generated-docs/maz-checklist.doc.md +0 -30
  208. package/docs/generated-docs/maz-circular-progress-bar.doc.md +0 -27
  209. package/docs/generated-docs/maz-code-highlight.doc.md +0 -11
  210. package/docs/generated-docs/maz-container.doc.md +0 -26
  211. package/docs/generated-docs/maz-date-picker.doc.md +0 -56
  212. package/docs/generated-docs/maz-dialog-confirm.doc.md +0 -24
  213. package/docs/generated-docs/maz-dialog.doc.md +0 -22
  214. package/docs/generated-docs/maz-drawer.doc.md +0 -25
  215. package/docs/generated-docs/maz-dropdown.doc.md +0 -45
  216. package/docs/generated-docs/maz-dropzone.doc.md +0 -82
  217. package/docs/generated-docs/maz-expand-animation.doc.md +0 -12
  218. package/docs/generated-docs/maz-fullscreen-loader.doc.md +0 -13
  219. package/docs/generated-docs/maz-gallery.doc.md +0 -17
  220. package/docs/generated-docs/maz-icon.doc.md +0 -16
  221. package/docs/generated-docs/maz-input-code.doc.md +0 -25
  222. package/docs/generated-docs/maz-input-number.doc.md +0 -33
  223. package/docs/generated-docs/maz-input-phone-number.doc.md +0 -62
  224. package/docs/generated-docs/maz-input-price.doc.md +0 -26
  225. package/docs/generated-docs/maz-input-tags.doc.md +0 -24
  226. package/docs/generated-docs/maz-input.doc.md +0 -54
  227. package/docs/generated-docs/maz-lazy-img.doc.md +0 -49
  228. package/docs/generated-docs/maz-link.doc.md +0 -31
  229. package/docs/generated-docs/maz-loading-bar.doc.md +0 -6
  230. package/docs/generated-docs/maz-markdown-editor.doc.md +0 -65
  231. package/docs/generated-docs/maz-pagination.doc.md +0 -21
  232. package/docs/generated-docs/maz-popover.doc.md +0 -79
  233. package/docs/generated-docs/maz-pull-to-refresh.doc.md +0 -50
  234. package/docs/generated-docs/maz-radio-buttons.doc.md +0 -34
  235. package/docs/generated-docs/maz-radio.doc.md +0 -33
  236. package/docs/generated-docs/maz-read-more.doc.md +0 -18
  237. package/docs/generated-docs/maz-reading-progress-bar.doc.md +0 -18
  238. package/docs/generated-docs/maz-select-country.doc.md +0 -45
  239. package/docs/generated-docs/maz-select.doc.md +0 -32
  240. package/docs/generated-docs/maz-sidebar-content.doc.md +0 -5
  241. package/docs/generated-docs/maz-sidebar-footer.doc.md +0 -5
  242. package/docs/generated-docs/maz-sidebar-group.doc.md +0 -11
  243. package/docs/generated-docs/maz-sidebar-header.doc.md +0 -5
  244. package/docs/generated-docs/maz-sidebar-menu-button.doc.md +0 -27
  245. package/docs/generated-docs/maz-sidebar-menu-item.doc.md +0 -5
  246. package/docs/generated-docs/maz-sidebar-menu-sub.doc.md +0 -16
  247. package/docs/generated-docs/maz-sidebar-menu.doc.md +0 -5
  248. package/docs/generated-docs/maz-sidebar-separator.doc.md +0 -0
  249. package/docs/generated-docs/maz-sidebar-trigger.doc.md +0 -5
  250. package/docs/generated-docs/maz-sidebar.doc.md +0 -36
  251. package/docs/generated-docs/maz-skeleton.doc.md +0 -12
  252. package/docs/generated-docs/maz-slider.doc.md +0 -20
  253. package/docs/generated-docs/maz-spinner.doc.md +0 -6
  254. package/docs/generated-docs/maz-stepper.doc.md +0 -30
  255. package/docs/generated-docs/maz-switch.doc.md +0 -31
  256. package/docs/generated-docs/maz-table-cell.doc.md +0 -5
  257. package/docs/generated-docs/maz-table-row.doc.md +0 -12
  258. package/docs/generated-docs/maz-table-title.doc.md +0 -5
  259. package/docs/generated-docs/maz-table-virtualizer.doc.md +0 -20
  260. package/docs/generated-docs/maz-table.doc.md +0 -72
  261. package/docs/generated-docs/maz-tabs-bar.doc.md +0 -29
  262. package/docs/generated-docs/maz-tabs-content-item.doc.md +0 -11
  263. package/docs/generated-docs/maz-tabs-content.doc.md +0 -5
  264. package/docs/generated-docs/maz-tabs.doc.md +0 -20
  265. package/docs/generated-docs/maz-textarea.doc.md +0 -46
  266. package/docs/generated-docs/maz-ticker.doc.md +0 -25
  267. package/docs/generated-docs/maz-timeline.doc.md +0 -32
  268. package/docs/generated-docs/maz-ui-provider.doc.md +0 -12
  269. package/docs/generated-docs/maz-window-mockup.doc.md +0 -23
  270. package/docs/src/blog/v4.md +0 -276
  271. package/docs/src/blog/v5.md +0 -184
  272. package/docs/src/changelog.md +0 -7
  273. package/docs/src/components/index.md +0 -8
  274. package/docs/src/components/maz-accordion.md +0 -80
  275. package/docs/src/components/maz-animated-counter.md +0 -124
  276. package/docs/src/components/maz-animated-element.md +0 -36
  277. package/docs/src/components/maz-animated-text.md +0 -36
  278. package/docs/src/components/maz-avatar.md +0 -227
  279. package/docs/src/components/maz-backdrop.md +0 -250
  280. package/docs/src/components/maz-bottom-sheet.md +0 -533
  281. package/docs/src/components/maz-card-spotlight.md +0 -163
  282. package/docs/src/components/maz-carousel.md +0 -231
  283. package/docs/src/components/maz-checkbox.md +0 -168
  284. package/docs/src/components/maz-checklist.md +0 -414
  285. package/docs/src/components/maz-circular-progress-bar.md +0 -145
  286. package/docs/src/components/maz-container.md +0 -363
  287. package/docs/src/components/maz-dialog-confirm.md +0 -240
  288. package/docs/src/components/maz-dialog.md +0 -164
  289. package/docs/src/components/maz-drawer.md +0 -181
  290. package/docs/src/components/maz-dropdown.md +0 -691
  291. package/docs/src/components/maz-expand-animation.md +0 -99
  292. package/docs/src/components/maz-fullscreen-loader.md +0 -58
  293. package/docs/src/components/maz-gallery.md +0 -85
  294. package/docs/src/components/maz-input-code.md +0 -61
  295. package/docs/src/components/maz-input-number.md +0 -81
  296. package/docs/src/components/maz-input-phone-number.md +0 -942
  297. package/docs/src/components/maz-input-price.md +0 -67
  298. package/docs/src/components/maz-input-tags.md +0 -114
  299. package/docs/src/components/maz-lazy-img.md +0 -88
  300. package/docs/src/components/maz-link.md +0 -178
  301. package/docs/src/components/maz-loading-bar.md +0 -26
  302. package/docs/src/components/maz-pagination.md +0 -79
  303. package/docs/src/components/maz-popover.md +0 -1416
  304. package/docs/src/components/maz-radio-buttons.md +0 -462
  305. package/docs/src/components/maz-radio.md +0 -142
  306. package/docs/src/components/maz-reading-progress-bar.md +0 -74
  307. package/docs/src/components/maz-spinner.md +0 -93
  308. package/docs/src/components/maz-switch.md +0 -92
  309. package/docs/src/components/maz-table.md +0 -732
  310. package/docs/src/components/maz-textarea.md +0 -400
  311. package/docs/src/components/maz-ticker.md +0 -692
  312. package/docs/src/components/maz-timeline.md +0 -478
  313. package/docs/src/composables/use-aos.md +0 -34
  314. package/docs/src/composables/use-breakpoints.md +0 -35
  315. package/docs/src/composables/use-dialog.md +0 -88
  316. package/docs/src/composables/use-string-matching.md +0 -63
  317. package/docs/src/composables/use-toast.md +0 -71
  318. package/docs/src/composables/use-wait.md +0 -62
  319. package/docs/src/composables/use-window-size.md +0 -18
  320. package/docs/src/ecosystem/icons/icon-set.md +0 -123
  321. package/docs/src/ecosystem/mcp.md +0 -210
  322. package/docs/src/ecosystem/node/index.md +0 -53
  323. package/docs/src/ecosystem/utils/camel-case.md +0 -31
  324. package/docs/src/ecosystem/utils/capitalize.md +0 -50
  325. package/docs/src/ecosystem/utils/country-code-to-unicode-flag.md +0 -213
  326. package/docs/src/ecosystem/utils/debounce-callback.md +0 -38
  327. package/docs/src/ecosystem/utils/fetch-locale-ip.md +0 -33
  328. package/docs/src/ecosystem/utils/get-browser-locale.md +0 -29
  329. package/docs/src/ecosystem/utils/get-country-flag-url.md +0 -156
  330. package/docs/src/ecosystem/utils/is-server.md +0 -31
  331. package/docs/src/ecosystem/utils/is-standalone-mode.md +0 -43
  332. package/docs/src/ecosystem/utils/truthy-filter.md +0 -31
  333. package/docs/src/ecosystem/utils/types/deep-required.md +0 -39
  334. package/docs/src/ecosystem/utils/types/flatten-object-keys.md +0 -44
  335. package/docs/src/ecosystem/utils/upper-first.md +0 -32
  336. package/docs/src/guide/cli.md +0 -144
  337. package/docs/src/guide/migration-v4.md +0 -925
  338. package/docs/src/guide/tailwind.md +0 -158
  339. package/docs/src/index.md +0 -603
  340. package/docs/src/made-with-maz-ui.md +0 -58
  341. package/docs/src/plugins/toast.md +0 -349
  342. package/docs/src/plugins/wait.md +0 -109
  343. package/docs/src/theme-editor.md +0 -21
@@ -1,15 +1,22 @@
1
1
  ---
2
- title: useFormValidator
3
- description: Vue composables for form validation with any Standard Schema library (Valibot, Zod, ArkType...) - useFormValidator and useFormField provide a flexible and typed approach to handle form validation in your Vue applications.
2
+ title: "useFormValidator"
3
+ description: "Vue composables for form validation with any Standard Schema library (Valibot, Zod, ArkType...) - useFormValidator and useFormField provide a flexible and typed approach to handle form validation in your Vue applications."
4
+ package: "maz-ui"
5
+ url: "https://maz-ui.com/composables/use-form-validator"
4
6
  ---
5
7
 
6
- # {{ $frontmatter.title }}
8
+ # useFormValidator
7
9
 
8
- {{ $frontmatter.description }}
10
+ > Vue composables for form validation with any Standard Schema library (Valibot, Zod, ArkType...) - useFormValidator and useFormField provide a flexible and typed approach to handle form validation in your Vue applications.
11
+
12
+ - Package: `maz-ui`
13
+ - Import: `import { useFormValidator } from 'maz-ui/composables/useFormValidator'`
14
+ - Nuxt: auto-imported by `@maz-ui/nuxt`, no import needed in a Nuxt app
15
+ - Web: https://maz-ui.com/composables/use-form-validator
9
16
 
10
17
  ## Introduction
11
18
 
12
- `useFormValidator` and `useFormField` are two Vue composables that work together to provide powerful form validation. They are **validation library agnostic**: any library implementing [Standard Schema](https://standardschema.dev) works out of the box, like [Valibot](https://valibot.dev), [Zod](https://zod.dev) or [ArkType](https://arktype.io). See [Validation Libraries](#validation-libraries).
19
+ `useFormValidator` and `useFormField` are two Vue composables that work together to provide powerful form validation. They are **validation library agnostic**: any library implementing [Standard Schema](https://standardschema.dev) works out of the box, like [Valibot](https://valibot.dev), [Zod](https://zod.dev) or [ArkType](https://arktype.io). See Validation Libraries.
13
20
 
14
21
  - **useFormValidator**: Initializes form validation for your entire form. Use it in your form's parent component.
15
22
  - **useFormField**: Manages individual field validation states. Use it when you need fine-grained control over a field or when fields are in child components.
@@ -25,8 +32,6 @@ description: Vue composables for form validation with any Standard Schema librar
25
32
 
26
33
  Install the validation library of your choice (Valibot is used in most examples of this page):
27
34
 
28
- ::: code-group
29
-
30
35
  ```bash [valibot]
31
36
  pnpm add valibot
32
37
  ```
@@ -39,35 +44,8 @@ pnpm add zod
39
44
  pnpm add arktype
40
45
  ```
41
46
 
42
- :::
43
-
44
47
  Here's the simplest form you can create with `useFormValidator`:
45
48
 
46
- <ComponentDemo>
47
- <form class="maz:flex maz:flex-col maz:gap-4" @submit="onSubmitQuickStart">
48
- <MazInput
49
- v-model="quickStartModel.email"
50
- label="Email"
51
- type="email"
52
- :hint="quickStartErrors.email"
53
- :error="!!quickStartErrors.email"
54
- :success="quickStartStates.email.valid"
55
- />
56
- <MazInput
57
- v-model="quickStartModel.password"
58
- label="Password"
59
- type="password"
60
- :hint="quickStartErrors.password"
61
- :error="!!quickStartErrors.password"
62
- :success="quickStartStates.password.valid"
63
- />
64
- <MazBtn type="submit" :loading="quickStartSubmitting">
65
- Login
66
- </MazBtn>
67
- </form>
68
-
69
- <template #code>
70
-
71
49
  ```vue
72
50
  <script lang="ts" setup>
73
51
  import { useFormValidator } from 'maz-ui/composables'
@@ -119,9 +97,6 @@ const onSubmit = handleSubmit((data) => {
119
97
  </template>
120
98
  ```
121
99
 
122
- </template>
123
- </ComponentDemo>
124
-
125
100
  ## Validation Libraries
126
101
 
127
102
  `useFormValidator` relies on [Standard Schema](https://standardschema.dev), a common interface shared by the main validation libraries. Maz-UI does not ship any validation library: install the one you prefer and pass its schemas. Valibot, Zod and ArkType are declared as optional peer dependencies of `maz-ui`, so your package manager warns you if the installed version is not supported.
@@ -137,8 +112,6 @@ The `schema` option is always a **plain object** where each key is a field name
137
112
 
138
113
  ### Same form, different libraries
139
114
 
140
- ::: code-group
141
-
142
115
  ```ts [valibot]
143
116
  import { useFormValidator } from 'maz-ui/composables'
144
117
  import { email, minLength, nonEmpty, pipe, string } from 'valibot'
@@ -175,34 +148,8 @@ const { model, errorMessages, handleSubmit } = useFormValidator({
175
148
  })
176
149
  ```
177
150
 
178
- :::
179
-
180
151
  ### Live example with Zod
181
152
 
182
- <ComponentDemo>
183
- <form class="maz:flex maz:flex-col maz:gap-4" @submit="onSubmitZod">
184
- <MazInput
185
- v-model="zodModel.username"
186
- label="Username"
187
- :hint="zodErrors.username"
188
- :error="!!zodErrors.username"
189
- :success="zodStates.username.valid"
190
- />
191
- <MazInput
192
- v-model="zodModel.age"
193
- label="Age"
194
- type="number"
195
- :hint="zodErrors.age"
196
- :error="!!zodErrors.age"
197
- :success="zodStates.age.valid"
198
- />
199
- <MazBtn type="submit" :loading="zodSubmitting">
200
- Submit
201
- </MazBtn>
202
- </form>
203
-
204
- <template #code>
205
-
206
153
  ```vue
207
154
  <script lang="ts" setup>
208
155
  import { useFormValidator } from 'maz-ui/composables'
@@ -251,9 +198,6 @@ const onSubmit = handleSubmit((data) => {
251
198
  </template>
252
199
  ```
253
200
 
254
- </template>
255
- </ComponentDemo>
256
-
257
201
  ### Mixing libraries
258
202
 
259
203
  Each field is validated by its own schema, so you can mix libraries in the same form (useful during a progressive migration from one library to another):
@@ -335,36 +279,6 @@ Each field in `fieldsStates` contains:
335
279
  | `validated` | `boolean` | Validation has run at least once |
336
280
  | `validating` | `boolean` | Async validation is in progress |
337
281
 
338
- <ComponentDemo>
339
- <div class="maz:flex maz:flex-col maz:gap-4">
340
- <form class="maz:flex maz:flex-col maz:gap-4" @submit="onSubmitState">
341
- <MazInput
342
- v-model="stateModel.name"
343
- label="Name (min 3 characters)"
344
- :hint="stateErrors.name"
345
- :error="!!stateErrors.name"
346
- :success="stateFields.name.valid"
347
- />
348
- <MazInput
349
- v-model="stateModel.age"
350
- label="Age (18-100)"
351
- type="number"
352
- :hint="stateErrors.age"
353
- :error="!!stateErrors.age"
354
- :success="stateFields.age.valid"
355
- />
356
- <MazBtn type="submit">Submit</MazBtn>
357
- </form>
358
- <div class="maz:rounded-md">
359
- <p class="maz:font-semibold maz:mb-2">Form State:</p>
360
- <pre class="maz:text-xs maz:bg-surface-600/70 maz:dark:bg-surface-600/60 maz:p-2 maz:rounded-md">{{ JSON.stringify({ isValid: stateValid, isDirty: stateDirty, isSubmitted: stateSubmitted, isSubmitting: stateSubmitting }, null, 2) }}</pre>
361
- <p class="maz:font-semibold maz:mb-2 maz:mt-4">Fields States:</p>
362
- <pre class="maz:text-xs maz:bg-surface-600/70 maz:dark:bg-surface-600/60 maz:p-2 maz:rounded-md">{{ JSON.stringify(stateFields, null, 2) }}</pre>
363
- </div>
364
- </div>
365
-
366
- <template #code>
367
-
368
282
  ```vue
369
283
  <script lang="ts" setup>
370
284
  import { useFormValidator } from 'maz-ui/composables'
@@ -403,9 +317,6 @@ const onSubmit = handleSubmit((data) => {
403
317
  </template>
404
318
  ```
405
319
 
406
- </template>
407
- </ComponentDemo>
408
-
409
320
  ## Validation Modes
410
321
 
411
322
  Validation modes control **when** validation runs and **when** errors are displayed. Choose the mode that best fits your UX needs.
@@ -418,41 +329,14 @@ Validation modes control **when** validation runs and **when** errors are displa
418
329
  | `blur` | Only on blur | After blur | Minimal interruption |
419
330
  | `progressive` | Silently, shows on blur if invalid | After blur or validation | Optimal UX |
420
331
 
421
- ::: tip
332
+ **Tip:**
333
+
422
334
  For `eager`, `blur`, and `progressive` modes, you must use `useFormField` with the `ref` option or `validationEvents` to capture blur events.
423
- :::
424
335
 
425
336
  ### Lazy Mode (Default)
426
337
 
427
338
  The default mode. Validates when field values change. Errors only appear if the field is not empty.
428
339
 
429
- <ComponentDemo>
430
- <div class="maz:mb-4">
431
- <p class="maz:text-sm maz:text-muted">Type in the field and clear it - notice the error appears only when there's content.</p>
432
- </div>
433
- <form class="maz:flex maz:flex-col maz:gap-4" @submit="onSubmitLazy">
434
- <MazInput
435
- v-model="lazyModel.name"
436
- label="Name (min 3 characters)"
437
- :hint="lazyErrors.name"
438
- :error="!!lazyErrors.name"
439
- :success="lazyStates.name.valid"
440
- :class="{ 'has-error-lazy': !!lazyErrors.name }"
441
- />
442
- <MazInput
443
- v-model="lazyModel.email"
444
- label="Email"
445
- type="email"
446
- :hint="lazyErrors.email"
447
- :error="!!lazyErrors.email"
448
- :success="lazyStates.email.valid"
449
- :class="{ 'has-error-lazy': !!lazyErrors.email }"
450
- />
451
- <MazBtn type="submit" :loading="lazySubmitting">Submit</MazBtn>
452
- </form>
453
-
454
- <template #code>
455
-
456
340
  ```vue
457
341
  <script lang="ts" setup>
458
342
  import { useFormValidator } from 'maz-ui/composables'
@@ -477,38 +361,10 @@ const onSubmit = handleSubmit((data) => {
477
361
  </script>
478
362
  ```
479
363
 
480
- </template>
481
- </ComponentDemo>
482
-
483
364
  ### Aggressive Mode
484
365
 
485
366
  Validates all fields immediately when the form is created and on every change. Errors are always displayed.
486
367
 
487
- <ComponentDemo>
488
- <div class="maz:mb-4">
489
- <p class="maz:text-sm maz:text-muted">Notice all fields show errors immediately, even before any interaction.</p>
490
- </div>
491
- <form class="maz:flex maz:flex-col maz:gap-4" @submit="onSubmitAggressive">
492
- <MazInput
493
- v-model="aggressiveModel.name"
494
- label="Name (min 3 characters)"
495
- :hint="aggressiveErrors.name"
496
- :error="!!aggressiveErrors.name"
497
- :success="aggressiveStates.name.valid"
498
- />
499
- <MazInput
500
- v-model="aggressiveModel.email"
501
- label="Email"
502
- type="email"
503
- :hint="aggressiveErrors.email"
504
- :error="!!aggressiveErrors.email"
505
- :success="aggressiveStates.email.valid"
506
- />
507
- <MazBtn type="submit" :loading="aggressiveSubmitting">Submit</MazBtn>
508
- </form>
509
-
510
- <template #code>
511
-
512
368
  ```vue
513
369
  <script lang="ts" setup>
514
370
  import { useFormValidator } from 'maz-ui/composables'
@@ -528,45 +384,13 @@ const { model, errorMessages, fieldsStates, isSubmitting, handleSubmit } = useFo
528
384
  </script>
529
385
  ```
530
386
 
531
- </template>
532
- </ComponentDemo>
533
-
534
387
  ### Eager Mode (Recommended)
535
388
 
536
389
  Validates on blur first (if the field is not empty), then on every change. This provides a good balance between immediate feedback and not overwhelming the user.
537
390
 
538
- ::: warning
539
- Requires `useFormField` with `ref` option or `validationEvents`.
540
- :::
541
-
542
- <ComponentDemo>
543
- <div class="maz:mb-4">
544
- <p class="maz:text-sm maz:text-muted">Type something, then click outside the field (blur) to see validation. After that, errors update as you type.</p>
545
- </div>
546
- <form class="maz:flex maz:flex-col maz:gap-4" @submit="onSubmitEager">
547
- <MazInput
548
- ref="eagerNameRef"
549
- v-model="eagerName"
550
- label="Name (min 3 characters)"
551
- :hint="eagerNameError"
552
- :error="eagerNameHasError"
553
- :success="eagerNameValid"
554
- :class="{ 'has-error-eager': eagerNameHasError }"
555
- />
556
- <MazInput
557
- ref="eagerEmailRef"
558
- v-model="eagerEmail"
559
- label="Email"
560
- type="email"
561
- :hint="eagerEmailError"
562
- :error="eagerEmailHasError"
563
- :success="eagerEmailValid"
564
- :class="{ 'has-error-eager': eagerEmailHasError }"
565
- />
566
- <MazBtn type="submit" :loading="eagerSubmitting" :disabled="!eagerIsValid">Submit</MazBtn>
567
- </form>
391
+ **Warning:**
568
392
 
569
- <template #code>
393
+ Requires `useFormField` with `ref` option or `validationEvents`.
570
394
 
571
395
  ```vue
572
396
  <script lang="ts" setup>
@@ -634,46 +458,14 @@ const {
634
458
  </template>
635
459
  ```
636
460
 
637
- </template>
638
- </ComponentDemo>
639
-
640
461
  ### Blur Mode
641
462
 
642
- ::: warning
463
+ **Warning:**
464
+
643
465
  Requires `useFormField` with `ref` option or `validationEvents`.
644
- :::
645
466
 
646
467
  Validates only when the field loses focus. Errors are only shown after blur.
647
468
 
648
- <ComponentDemo>
649
- <div class="maz:mb-4">
650
- <p class="maz:text-sm maz:text-muted">Type in the field, then click outside. Errors only appear after blur, and don't update while typing.</p>
651
- </div>
652
- <form class="maz:flex maz:flex-col maz:gap-4" @submit="onSubmitBlur">
653
- <MazInput
654
- ref="blurNameRef"
655
- v-model="blurName"
656
- label="Name (min 3 characters)"
657
- :hint="blurNameError"
658
- :error="blurNameHasError"
659
- :success="blurNameValid"
660
- :class="{ 'has-error-blur': blurNameHasError }"
661
- />
662
- <MazInput
663
- ref="blurEmailRef"
664
- v-model="blurEmail"
665
- label="Email"
666
- type="email"
667
- :hint="blurEmailError"
668
- :error="blurEmailHasError"
669
- :success="blurEmailValid"
670
- :class="{ 'has-error-blur': blurEmailHasError }"
671
- />
672
- <MazBtn type="submit" :loading="blurSubmitting">Submit</MazBtn>
673
- </form>
674
-
675
- <template #code>
676
-
677
469
  ```vue
678
470
  <script lang="ts" setup>
679
471
  import { useFormValidator, useFormField } from 'maz-ui/composables'
@@ -705,55 +497,14 @@ const { value: email, hasError: emailHasError, errorMessage: emailError, isValid
705
497
  </script>
706
498
  ```
707
499
 
708
- </template>
709
- </ComponentDemo>
710
-
711
500
  ### Progressive Mode
712
501
 
713
- ::: warning
502
+ **Warning:**
503
+
714
504
  Requires `useFormField` with `ref` option or `validationEvents`.
715
- :::
716
505
 
717
506
  The most user-friendly mode. Validates silently in the background. Shows errors only on blur if the field is invalid. Once valid, it stays valid until it becomes invalid again.
718
507
 
719
- <ComponentDemo>
720
- <div class="maz:mb-4">
721
- <p class="maz:text-sm maz:text-muted">Start typing - the field becomes valid (green) as soon as validation passes. Errors only show after blur.</p>
722
- </div>
723
- <form class="maz:flex maz:flex-col maz:gap-4" @submit="onSubmitProgressive">
724
- <MazInput
725
- ref="progressiveNameRef"
726
- v-model="progressiveName"
727
- label="Name (min 3 characters)"
728
- :hint="progressiveNameError"
729
- :error="progressiveNameHasError"
730
- :success="progressiveNameValid"
731
- :class="{ 'has-error-progressive': progressiveNameHasError }"
732
- />
733
- <MazInput
734
- ref="progressiveEmailRef"
735
- v-model="progressiveEmail"
736
- label="Email"
737
- type="email"
738
- :hint="progressiveEmailError"
739
- :error="progressiveEmailHasError"
740
- :success="progressiveEmailValid"
741
- :class="{ 'has-error-progressive': progressiveEmailHasError }"
742
- />
743
- <MazCheckbox
744
- ref="progressiveAgreeRef"
745
- v-model="progressiveAgree"
746
- :hint="progressiveAgreeError"
747
- :error="progressiveAgreeHasError"
748
- :class="{ 'has-error-progressive': progressiveAgreeHasError }"
749
- >
750
- I agree to the terms and conditions
751
- </MazCheckbox>
752
- <MazBtn type="submit" :loading="progressiveSubmitting">Submit</MazBtn>
753
- </form>
754
-
755
- <template #code>
756
-
757
508
  ```vue
758
509
  <script lang="ts" setup>
759
510
  import { useFormValidator, useFormField } from 'maz-ui/composables'
@@ -782,9 +533,6 @@ const { value: name, hasError, errorMessage, isValid } = useFormField<string>('n
782
533
  </script>
783
534
  ```
784
535
 
785
- </template>
786
- </ComponentDemo>
787
-
788
536
  ## useFormField for Child Components
789
537
 
790
538
  `useFormField` is essential when:
@@ -918,7 +666,8 @@ const { value } = useFormField<string>('name', { formIdentifier: 'my-form' })
918
666
  // value is typed as WritableComputedRef<string>
919
667
  ```
920
668
 
921
- ::: warning Common TypeScript Errors
669
+ **Warning: Common TypeScript Errors**
670
+
922
671
  If you get circular reference errors with `useTemplateRef`, use the classic `ref()` instead:
923
672
 
924
673
  ```ts
@@ -939,8 +688,6 @@ const { value: email } = useFormField<string>('email', {
939
688
  })
940
689
  ```
941
690
 
942
- :::
943
-
944
691
  ## Async Validation
945
692
 
946
693
  Async validations (like checking username availability) are supported by every library: Valibot's `pipeAsync` and `checkAsync`, Zod's async `refine`, etc. The example below uses Valibot, here is the Zod equivalent of the schema:
@@ -961,26 +708,6 @@ const schema = {
961
708
  }
962
709
  ```
963
710
 
964
- <ComponentDemo>
965
- <div class="maz:mb-4">
966
- <p class="maz:text-sm maz:text-muted">Try typing "taken" - the async validator will reject it after a 2-second delay.</p>
967
- </div>
968
- <form class="maz:flex maz:gap-4" @submit="onSubmitAsync">
969
- <MazInput
970
- ref="asyncUsernameRef"
971
- v-model="asyncUsername"
972
- label="Username"
973
- :hint="asyncUsernameError"
974
- :error="asyncUsernameHasError"
975
- :success="asyncUsernameValid"
976
- :loading="asyncUsernameValidating"
977
- class="maz:flex-1"
978
- />
979
- <MazBtn type="submit" :loading="asyncSubmitting">Submit</MazBtn>
980
- </form>
981
-
982
- <template #code>
983
-
984
711
  ```vue
985
712
  <script lang="ts" setup>
986
713
  import { useFormValidator, useFormField } from 'maz-ui/composables'
@@ -1029,9 +756,6 @@ const {
1029
756
  </template>
1030
757
  ```
1031
758
 
1032
- </template>
1033
- </ComponentDemo>
1034
-
1035
759
  ## Throttling and Debouncing
1036
760
 
1037
761
  For expensive validations (like API calls), use throttling or debouncing to limit how often validation runs.
@@ -1041,31 +765,6 @@ For expensive validations (like API calls), use throttling or debouncing to limi
1041
765
  | `debouncedFields` | Waits until user stops typing | 300ms | Search fields, API calls |
1042
766
  | `throttledFields` | Runs at most once per interval | 1000ms | Rate-limited APIs |
1043
767
 
1044
- <ComponentDemo>
1045
- <div class="maz:mb-4">
1046
- <p class="maz:text-sm maz:text-muted">Name has 500ms debounce, Age has 1000ms throttle. Watch the console to see validation timing.</p>
1047
- </div>
1048
- <form class="maz:flex maz:flex-col maz:gap-4" @submit="onSubmitDebounced">
1049
- <MazInput
1050
- v-model="debouncedModel.name"
1051
- label="Name (debounced 500ms)"
1052
- :hint="debouncedErrors.name"
1053
- :error="debouncedStates.name.error"
1054
- :success="debouncedStates.name.valid"
1055
- />
1056
- <MazInput
1057
- v-model="debouncedModel.age"
1058
- label="Age (throttled 1000ms)"
1059
- type="number"
1060
- :hint="debouncedErrors.age"
1061
- :error="debouncedStates.age.error"
1062
- :success="debouncedStates.age.valid"
1063
- />
1064
- <MazBtn type="submit" :loading="debouncedSubmitting">Submit</MazBtn>
1065
- </form>
1066
-
1067
- <template #code>
1068
-
1069
768
  ```vue
1070
769
  <script lang="ts" setup>
1071
770
  import { useFormValidator } from 'maz-ui/composables'
@@ -1087,38 +786,10 @@ const { model, errorMessages, fieldsStates, isSubmitting, handleSubmit } = useFo
1087
786
  </script>
1088
787
  ```
1089
788
 
1090
- </template>
1091
- </ComponentDemo>
1092
-
1093
789
  ## Reset Form
1094
790
 
1095
791
  Use `resetForm()` to reset the form to its initial state, or set `resetOnSuccess` to automatically reset after successful submission.
1096
792
 
1097
- <ComponentDemo>
1098
- <form class="maz:flex maz:flex-col maz:gap-4" @submit="onSubmitReset">
1099
- <MazInput
1100
- v-model="resetModel.name"
1101
- label="Name"
1102
- :hint="resetErrors.name"
1103
- :error="resetStates.name.error"
1104
- :success="resetStates.name.valid"
1105
- />
1106
- <MazInput
1107
- v-model="resetModel.age"
1108
- label="Age"
1109
- type="number"
1110
- :hint="resetErrors.age"
1111
- :error="resetStates.age.error"
1112
- :success="resetStates.age.valid"
1113
- />
1114
- <div class="maz:flex maz:gap-2">
1115
- <MazBtn type="submit" :loading="resetSubmitting">Submit</MazBtn>
1116
- <MazBtn type="button" color="destructive" @click="resetFormFn">Reset</MazBtn>
1117
- </div>
1118
- </form>
1119
-
1120
- <template #code>
1121
-
1122
793
  ```vue
1123
794
  <script lang="ts" setup>
1124
795
  import { useFormValidator } from 'maz-ui/composables'
@@ -1149,9 +820,6 @@ function handleReset() {
1149
820
  </script>
1150
821
  ```
1151
822
 
1152
- </template>
1153
- </ComponentDemo>
1154
-
1155
823
  ## Multiple Forms on Same Page
1156
824
 
1157
825
  Use the `identifier` option to have multiple independent forms on the same page. Make sure to match the identifier in both `useFormValidator` and `useFormField`.
@@ -1453,345 +1121,3 @@ const { value } = useFormField<string>('email', {
1453
1121
  formIdentifier: 'my-form', // ...must match this one
1454
1122
  })
1455
1123
  ```
1456
-
1457
- <script lang="ts" setup>
1458
- import { ref, useTemplateRef } from 'vue'
1459
- import { useFormValidator } from 'maz-ui/composables/useFormValidator'
1460
- import { useFormField } from 'maz-ui/composables/useFormField'
1461
- import { useToast } from 'maz-ui/composables/useToast'
1462
- import { sleep } from '@maz-ui/utils'
1463
- import {
1464
- string,
1465
- nonEmpty,
1466
- pipe,
1467
- number,
1468
- minValue,
1469
- maxValue,
1470
- boolean,
1471
- literal,
1472
- minLength,
1473
- email,
1474
- pipeAsync,
1475
- checkAsync,
1476
- } from 'valibot'
1477
- import { z } from 'zod'
1478
-
1479
- const toast = useToast()
1480
-
1481
- // Zod Demo
1482
- const zodSchema = {
1483
- username: z.string().min(1, 'Username is required').min(3, 'Min 3 characters'),
1484
- age: z.number({ error: 'Age is required' }).min(18, 'Min 18').max(100, 'Max 100'),
1485
- }
1486
-
1487
- const {
1488
- model: zodModel,
1489
- errorMessages: zodErrors,
1490
- fieldsStates: zodStates,
1491
- isSubmitting: zodSubmitting,
1492
- handleSubmit: handleZod,
1493
- } = useFormValidator({ schema: zodSchema })
1494
-
1495
- const onSubmitZod = handleZod(async (data) => {
1496
- await sleep(1000)
1497
- toast.success(`Welcome ${data.username} (${data.age})!`, { position: 'top' })
1498
- })
1499
-
1500
- // Quick Start Demo
1501
- const quickStartSchema = {
1502
- email: pipe(string(), nonEmpty('Email is required'), email('Invalid email')),
1503
- password: pipe(string(), nonEmpty('Password is required'), minLength(8, 'Min 8 characters')),
1504
- }
1505
-
1506
- const {
1507
- model: quickStartModel,
1508
- errorMessages: quickStartErrors,
1509
- fieldsStates: quickStartStates,
1510
- isSubmitting: quickStartSubmitting,
1511
- handleSubmit: handleQuickStart,
1512
- } = useFormValidator({ schema: quickStartSchema })
1513
-
1514
- const onSubmitQuickStart = handleQuickStart(async () => {
1515
- await sleep(1000)
1516
- toast.success('Login successful!', { position: 'top' })
1517
- })
1518
-
1519
- // Form State Demo
1520
- const stateSchema = {
1521
- name: pipe(string(), nonEmpty('Required'), minLength(3, 'Min 3 characters')),
1522
- age: pipe(number('Must be a number'), minValue(18, 'Min 18'), maxValue(100, 'Max 100')),
1523
- }
1524
-
1525
- const {
1526
- model: stateModel,
1527
- errorMessages: stateErrors,
1528
- fieldsStates: stateFields,
1529
- isValid: stateValid,
1530
- isDirty: stateDirty,
1531
- isSubmitted: stateSubmitted,
1532
- isSubmitting: stateSubmitting,
1533
- handleSubmit: handleState,
1534
- } = useFormValidator({ schema: stateSchema })
1535
-
1536
- const onSubmitState = handleState(() => {
1537
- toast.success('Submitted!', { position: 'top' })
1538
- })
1539
-
1540
- // Lazy Mode Demo
1541
- const lazySchema = {
1542
- name: pipe(string(), nonEmpty('Required'), minLength(3, 'Min 3 characters')),
1543
- email: pipe(string(), nonEmpty('Required'), email('Invalid email')),
1544
- }
1545
-
1546
- const {
1547
- model: lazyModel,
1548
- errorMessages: lazyErrors,
1549
- fieldsStates: lazyStates,
1550
- isSubmitting: lazySubmitting,
1551
- handleSubmit: handleLazy,
1552
- } = useFormValidator({
1553
- schema: lazySchema,
1554
- options: { mode: 'lazy', scrollToError: '.has-error-lazy' },
1555
- })
1556
-
1557
- const onSubmitLazy = handleLazy(async () => {
1558
- await sleep(1000)
1559
- toast.success('Submitted!', { position: 'top' })
1560
- })
1561
-
1562
- // Aggressive Mode Demo
1563
- const aggressiveSchema = {
1564
- name: pipe(string(), nonEmpty('Required'), minLength(3, 'Min 3 characters')),
1565
- email: pipe(string(), nonEmpty('Required'), email('Invalid email')),
1566
- }
1567
-
1568
- const {
1569
- model: aggressiveModel,
1570
- errorMessages: aggressiveErrors,
1571
- fieldsStates: aggressiveStates,
1572
- isSubmitting: aggressiveSubmitting,
1573
- handleSubmit: handleAggressive,
1574
- } = useFormValidator({
1575
- schema: aggressiveSchema,
1576
- options: { mode: 'aggressive' },
1577
- })
1578
-
1579
- const onSubmitAggressive = handleAggressive(async () => {
1580
- await sleep(1000)
1581
- toast.success('Submitted!', { position: 'top' })
1582
- })
1583
-
1584
- // Eager Mode Demo
1585
- const eagerSchema = {
1586
- name: pipe(string(), nonEmpty('Required'), minLength(3, 'Min 3 characters')),
1587
- email: pipe(string(), nonEmpty('Required'), email('Invalid email')),
1588
- }
1589
-
1590
- const {
1591
- isSubmitting: eagerSubmitting,
1592
- handleSubmit: handleEager,
1593
- isValid: eagerIsValid,
1594
- } = useFormValidator({
1595
- schema: eagerSchema,
1596
- options: { mode: 'eager', scrollToError: '.has-error-eager', identifier: 'form-eager' },
1597
- })
1598
-
1599
- const {
1600
- value: eagerName,
1601
- hasError: eagerNameHasError,
1602
- errorMessage: eagerNameError,
1603
- isValid: eagerNameValid,
1604
- } = useFormField<string>('name', {
1605
- ref: useTemplateRef<HTMLInputElement>('eagerNameRef'),
1606
- formIdentifier: 'form-eager',
1607
- })
1608
-
1609
- const {
1610
- value: eagerEmail,
1611
- hasError: eagerEmailHasError,
1612
- errorMessage: eagerEmailError,
1613
- isValid: eagerEmailValid,
1614
- } = useFormField<string>('email', {
1615
- ref: useTemplateRef<HTMLInputElement>('eagerEmailRef'),
1616
- formIdentifier: 'form-eager',
1617
- })
1618
-
1619
- const onSubmitEager = handleEager(async () => {
1620
- await sleep(1000)
1621
- toast.success('Submitted!', { position: 'top' })
1622
- })
1623
-
1624
- // Blur Mode Demo
1625
- const blurSchema = {
1626
- name: pipe(string(), nonEmpty('Required'), minLength(3, 'Min 3 characters')),
1627
- email: pipe(string(), nonEmpty('Required'), email('Invalid email')),
1628
- }
1629
-
1630
- const {
1631
- isSubmitting: blurSubmitting,
1632
- handleSubmit: handleBlur,
1633
- } = useFormValidator({
1634
- schema: blurSchema,
1635
- options: { mode: 'blur', scrollToError: '.has-error-blur', identifier: 'form-blur' },
1636
- })
1637
-
1638
- const {
1639
- value: blurName,
1640
- hasError: blurNameHasError,
1641
- errorMessage: blurNameError,
1642
- isValid: blurNameValid,
1643
- } = useFormField<string>('name', {
1644
- ref: useTemplateRef<HTMLInputElement>('blurNameRef'),
1645
- formIdentifier: 'form-blur',
1646
- })
1647
-
1648
- const {
1649
- value: blurEmail,
1650
- hasError: blurEmailHasError,
1651
- errorMessage: blurEmailError,
1652
- isValid: blurEmailValid,
1653
- } = useFormField<string>('email', {
1654
- ref: useTemplateRef<HTMLInputElement>('blurEmailRef'),
1655
- formIdentifier: 'form-blur',
1656
- })
1657
-
1658
- const onSubmitBlur = handleBlur(async () => {
1659
- await sleep(1000)
1660
- toast.success('Submitted!', { position: 'top' })
1661
- })
1662
-
1663
- // Progressive Mode Demo
1664
- const progressiveSchema = {
1665
- name: pipe(string(), nonEmpty('Required'), minLength(3, 'Min 3 characters')),
1666
- email: pipe(string(), nonEmpty('Required'), email('Invalid email')),
1667
- agree: pipe(boolean(), literal(true, 'You must agree')),
1668
- }
1669
-
1670
- const {
1671
- isSubmitting: progressiveSubmitting,
1672
- handleSubmit: handleProgressive,
1673
- } = useFormValidator({
1674
- schema: progressiveSchema,
1675
- options: { mode: 'progressive', scrollToError: '.has-error-progressive', identifier: 'form-progressive' },
1676
- })
1677
-
1678
- const {
1679
- value: progressiveName,
1680
- hasError: progressiveNameHasError,
1681
- errorMessage: progressiveNameError,
1682
- isValid: progressiveNameValid,
1683
- } = useFormField<string>('name', {
1684
- ref: useTemplateRef<HTMLInputElement>('progressiveNameRef'),
1685
- formIdentifier: 'form-progressive',
1686
- })
1687
-
1688
- const {
1689
- value: progressiveEmail,
1690
- hasError: progressiveEmailHasError,
1691
- errorMessage: progressiveEmailError,
1692
- isValid: progressiveEmailValid,
1693
- } = useFormField<string>('email', {
1694
- ref: useTemplateRef<HTMLInputElement>('progressiveEmailRef'),
1695
- formIdentifier: 'form-progressive',
1696
- })
1697
-
1698
- const {
1699
- value: progressiveAgree,
1700
- hasError: progressiveAgreeHasError,
1701
- errorMessage: progressiveAgreeError,
1702
- } = useFormField<boolean>('agree', {
1703
- ref: useTemplateRef<HTMLInputElement>('progressiveAgreeRef'),
1704
- formIdentifier: 'form-progressive',
1705
- })
1706
-
1707
- const onSubmitProgressive = handleProgressive(async () => {
1708
- await sleep(1000)
1709
- toast.success('Submitted!', { position: 'top' })
1710
- })
1711
-
1712
- // Async Validation Demo
1713
- const asyncSchema = {
1714
- username: pipeAsync(
1715
- string(),
1716
- nonEmpty('Username is required'),
1717
- minLength(3, 'Min 3 characters'),
1718
- checkAsync(async (value) => {
1719
- await sleep(2000)
1720
- return value !== 'taken'
1721
- }, 'Username is already taken'),
1722
- ),
1723
- }
1724
-
1725
- const {
1726
- isSubmitting: asyncSubmitting,
1727
- handleSubmit: handleAsync,
1728
- } = useFormValidator({
1729
- schema: asyncSchema,
1730
- options: { mode: 'eager', identifier: 'form-async' },
1731
- })
1732
-
1733
- const {
1734
- value: asyncUsername,
1735
- hasError: asyncUsernameHasError,
1736
- errorMessage: asyncUsernameError,
1737
- isValid: asyncUsernameValid,
1738
- isValidating: asyncUsernameValidating,
1739
- } = useFormField<string>('username', {
1740
- ref: useTemplateRef<HTMLInputElement>('asyncUsernameRef'),
1741
- formIdentifier: 'form-async',
1742
- })
1743
-
1744
- const onSubmitAsync = handleAsync(async () => {
1745
- await sleep(1000)
1746
- toast.success('Submitted!', { position: 'top' })
1747
- })
1748
-
1749
- // Debounce/Throttle Demo
1750
- const debouncedSchema = {
1751
- name: pipe(string(), nonEmpty('Required'), minLength(3, 'Min 3 characters')),
1752
- age: pipe(number('Must be a number'), minValue(18, 'Must be 18+')),
1753
- }
1754
-
1755
- const {
1756
- model: debouncedModel,
1757
- errorMessages: debouncedErrors,
1758
- fieldsStates: debouncedStates,
1759
- isSubmitting: debouncedSubmitting,
1760
- handleSubmit: handleDebounced,
1761
- } = useFormValidator({
1762
- schema: debouncedSchema,
1763
- options: {
1764
- debouncedFields: { name: 500 },
1765
- throttledFields: { age: 1000 },
1766
- },
1767
- })
1768
-
1769
- const onSubmitDebounced = handleDebounced(async () => {
1770
- await sleep(1000)
1771
- toast.success('Submitted!', { position: 'top' })
1772
- })
1773
-
1774
- // Reset Form Demo
1775
- const resetSchema = {
1776
- name: pipe(string(), nonEmpty('Required'), minLength(3, 'Min 3 characters')),
1777
- age: pipe(number('Must be a number'), minValue(18, 'Must be 18+')),
1778
- }
1779
-
1780
- const {
1781
- model: resetModel,
1782
- errorMessages: resetErrors,
1783
- fieldsStates: resetStates,
1784
- isSubmitting: resetSubmitting,
1785
- handleSubmit: handleReset,
1786
- resetForm: resetFormFn,
1787
- } = useFormValidator({
1788
- schema: resetSchema,
1789
- defaultValues: { name: 'John', age: 25 },
1790
- options: { resetOnSuccess: false },
1791
- })
1792
-
1793
- const onSubmitReset = handleReset(async () => {
1794
- await sleep(1000)
1795
- toast.success('Submitted!', { position: 'top' })
1796
- })
1797
- </script>