@byyuurin/ui 0.0.11 → 0.2.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 (297) hide show
  1. package/README.md +170 -58
  2. package/dist/module.d.mts +4 -13
  3. package/dist/module.json +4 -4
  4. package/dist/module.mjs +54 -20
  5. package/dist/runtime/components/Accordion.vue +28 -23
  6. package/dist/runtime/components/Accordion.vue.d.ts +51 -29
  7. package/dist/runtime/components/Alert.vue +47 -27
  8. package/dist/runtime/components/Alert.vue.d.ts +37 -25
  9. package/dist/runtime/components/App.vue +9 -8
  10. package/dist/runtime/components/App.vue.d.ts +22 -20
  11. package/dist/runtime/components/Avatar.vue +65 -21
  12. package/dist/runtime/components/Avatar.vue.d.ts +27 -13
  13. package/dist/runtime/components/AvatarGroup.vue +14 -10
  14. package/dist/runtime/components/AvatarGroup.vue.d.ts +12 -9
  15. package/dist/runtime/components/Badge.vue +64 -32
  16. package/dist/runtime/components/Badge.vue.d.ts +30 -29
  17. package/dist/runtime/components/Breadcrumb.vue +40 -22
  18. package/dist/runtime/components/Breadcrumb.vue.d.ts +48 -21
  19. package/dist/runtime/components/Button.vue +113 -52
  20. package/dist/runtime/components/Button.vue.d.ts +36 -20
  21. package/dist/runtime/components/Calendar.vue +50 -43
  22. package/dist/runtime/components/Calendar.vue.d.ts +58 -31
  23. package/dist/runtime/components/Card.vue +18 -14
  24. package/dist/runtime/components/Card.vue.d.ts +18 -14
  25. package/dist/runtime/components/Carousel.vue +99 -46
  26. package/dist/runtime/components/Carousel.vue.d.ts +46 -25
  27. package/dist/runtime/components/Checkbox.vue +60 -35
  28. package/dist/runtime/components/Checkbox.vue.d.ts +35 -28
  29. package/dist/runtime/components/CheckboxGroup.vue +131 -0
  30. package/dist/runtime/components/CheckboxGroup.vue.d.ts +89 -0
  31. package/dist/runtime/components/Chip.vue +35 -32
  32. package/dist/runtime/components/Chip.vue.d.ts +33 -15
  33. package/dist/runtime/components/Collapsible.vue +13 -9
  34. package/dist/runtime/components/Collapsible.vue.d.ts +16 -8
  35. package/dist/runtime/components/Drawer.vue +80 -70
  36. package/dist/runtime/components/Drawer.vue.d.ts +51 -28
  37. package/dist/runtime/components/DropdownMenu.vue +23 -16
  38. package/dist/runtime/components/DropdownMenu.vue.d.ts +77 -36
  39. package/dist/runtime/components/DropdownMenuContent.vue +136 -106
  40. package/dist/runtime/components/DropdownMenuContent.vue.d.ts +38 -26
  41. package/dist/runtime/components/FieldGroup.vue +33 -0
  42. package/dist/runtime/components/FieldGroup.vue.d.ts +33 -0
  43. package/dist/runtime/components/Form.vue +172 -88
  44. package/dist/runtime/components/Form.vue.d.ts +69 -44
  45. package/dist/runtime/components/FormField.vue +108 -0
  46. package/dist/runtime/components/FormField.vue.d.ts +63 -0
  47. package/dist/runtime/components/Icon.vue +20 -0
  48. package/dist/runtime/components/Icon.vue.d.ts +9 -0
  49. package/dist/runtime/components/Input.vue +84 -79
  50. package/dist/runtime/components/Input.vue.d.ts +55 -43
  51. package/dist/runtime/components/InputNumber.vue +66 -52
  52. package/dist/runtime/components/InputNumber.vue.d.ts +50 -109
  53. package/dist/runtime/components/InputTags.vue +155 -0
  54. package/dist/runtime/components/InputTags.vue.d.ts +85 -0
  55. package/dist/runtime/components/Kbd.vue +11 -5
  56. package/dist/runtime/components/Kbd.vue.d.ts +17 -11
  57. package/dist/runtime/components/Link.vue +54 -197
  58. package/dist/runtime/components/Link.vue.d.ts +17 -17
  59. package/dist/runtime/components/LinkBase.vue +11 -33
  60. package/dist/runtime/components/LinkBase.vue.d.ts +8 -3
  61. package/dist/runtime/components/Marquee.vue +38 -0
  62. package/dist/runtime/components/Marquee.vue.d.ts +54 -0
  63. package/dist/runtime/components/Modal.vue +53 -39
  64. package/dist/runtime/components/Modal.vue.d.ts +64 -34
  65. package/dist/runtime/components/NavigationMenu.vue +345 -0
  66. package/dist/runtime/components/NavigationMenu.vue.d.ts +216 -0
  67. package/dist/runtime/components/OverlayProvider.vue +3 -3
  68. package/dist/runtime/components/OverlayProvider.vue.d.ts +2 -1
  69. package/dist/runtime/components/Pagination.vue +39 -47
  70. package/dist/runtime/components/Pagination.vue.d.ts +54 -31
  71. package/dist/runtime/components/PinInput.vue +46 -32
  72. package/dist/runtime/components/PinInput.vue.d.ts +40 -21
  73. package/dist/runtime/components/Popover.vue +33 -19
  74. package/dist/runtime/components/Popover.vue.d.ts +57 -32
  75. package/dist/runtime/components/Progress.vue +31 -26
  76. package/dist/runtime/components/Progress.vue.d.ts +32 -23
  77. package/dist/runtime/components/RadioGroup.vue +75 -48
  78. package/dist/runtime/components/RadioGroup.vue.d.ts +58 -36
  79. package/dist/runtime/components/ScrollArea.vue +33 -31
  80. package/dist/runtime/components/ScrollArea.vue.d.ts +9 -5
  81. package/dist/runtime/components/Select.vue +166 -76
  82. package/dist/runtime/components/Select.vue.d.ts +206 -65
  83. package/dist/runtime/components/Separator.vue +42 -16
  84. package/dist/runtime/components/Separator.vue.d.ts +35 -14
  85. package/dist/runtime/components/Skeleton.vue +18 -6
  86. package/dist/runtime/components/Skeleton.vue.d.ts +4 -4
  87. package/dist/runtime/components/Slider.vue +42 -24
  88. package/dist/runtime/components/Slider.vue.d.ts +43 -27
  89. package/dist/runtime/components/Switch.vue +40 -31
  90. package/dist/runtime/components/Switch.vue.d.ts +36 -27
  91. package/dist/runtime/components/Table.vue +329 -79
  92. package/dist/runtime/components/Table.vue.d.ts +152 -66
  93. package/dist/runtime/components/Tabs.vue +70 -23
  94. package/dist/runtime/components/Tabs.vue.d.ts +61 -29
  95. package/dist/runtime/components/Textarea.vue +102 -54
  96. package/dist/runtime/components/Textarea.vue.d.ts +57 -41
  97. package/dist/runtime/components/Timeline.vue +102 -0
  98. package/dist/runtime/components/Timeline.vue.d.ts +74 -0
  99. package/dist/runtime/components/Toast.vue +84 -38
  100. package/dist/runtime/components/Toast.vue.d.ts +48 -27
  101. package/dist/runtime/components/ToastProvider.vue +31 -22
  102. package/dist/runtime/components/ToastProvider.vue.d.ts +30 -17
  103. package/dist/runtime/components/Tooltip.vue +33 -21
  104. package/dist/runtime/components/Tooltip.vue.d.ts +37 -15
  105. package/dist/runtime/composables/defineShortcuts.d.ts +16 -0
  106. package/dist/runtime/composables/defineShortcuts.js +129 -0
  107. package/dist/runtime/composables/useAvatarGroup.d.ts +8 -3
  108. package/dist/runtime/composables/useAvatarGroup.js +10 -3
  109. package/dist/runtime/composables/useComponentIcons.d.ts +9 -6
  110. package/dist/runtime/composables/useComponentIcons.js +4 -4
  111. package/dist/runtime/composables/useFieldGroup.d.ts +8 -0
  112. package/dist/runtime/composables/useFieldGroup.js +14 -0
  113. package/dist/runtime/composables/useFormField.d.ts +62 -0
  114. package/dist/runtime/composables/useFormField.js +99 -0
  115. package/dist/runtime/composables/useKbd.d.ts +3 -2
  116. package/dist/runtime/composables/useKbd.js +3 -2
  117. package/dist/runtime/composables/useLocale.d.ts +68 -5
  118. package/dist/runtime/composables/useLocale.js +11 -11
  119. package/dist/runtime/composables/useOverlay.d.ts +51 -15
  120. package/dist/runtime/composables/useOverlay.js +44 -30
  121. package/dist/runtime/composables/usePortal.d.ts +6 -0
  122. package/dist/runtime/composables/usePortal.js +17 -0
  123. package/dist/runtime/composables/useToast.d.ts +12 -5
  124. package/dist/runtime/composables/useToast.js +12 -7
  125. package/dist/runtime/locale/en.d.ts +30 -1
  126. package/dist/runtime/locale/en.js +2 -1
  127. package/dist/runtime/locale/index.d.ts +2 -2
  128. package/dist/runtime/locale/index.js +1 -1
  129. package/dist/runtime/locale/zh_tw.d.ts +31 -0
  130. package/dist/runtime/locale/{zh-tw.js → zh_tw.js} +2 -1
  131. package/dist/runtime/plugins/colors.d.ts +2 -0
  132. package/dist/runtime/plugins/colors.js +50 -0
  133. package/dist/runtime/types/app.config.d.ts +6 -0
  134. package/dist/runtime/types/form.d.ts +58 -17
  135. package/dist/runtime/types/form.js +11 -0
  136. package/dist/runtime/types/index.d.ts +56 -8
  137. package/dist/runtime/types/index.js +49 -1
  138. package/dist/runtime/types/input.d.ts +8 -0
  139. package/dist/runtime/types/locale.d.ts +5 -0
  140. package/dist/runtime/types/style.d.ts +33 -0
  141. package/dist/runtime/types/style.js +0 -0
  142. package/dist/runtime/types/unocss.d.ts +4 -0
  143. package/dist/runtime/types/utils.d.ts +41 -37
  144. package/dist/runtime/utils/form.d.ts +5 -1
  145. package/dist/runtime/utils/form.js +49 -0
  146. package/dist/runtime/utils/index.d.ts +10 -13
  147. package/dist/runtime/utils/index.js +41 -48
  148. package/dist/runtime/utils/link.d.ts +3 -2
  149. package/dist/runtime/utils/link.js +16 -2
  150. package/dist/runtime/utils/locale.d.ts +5 -0
  151. package/dist/runtime/utils/locale.js +10 -0
  152. package/dist/runtime/utils/style.d.ts +94 -0
  153. package/dist/runtime/utils/style.js +37 -0
  154. package/dist/runtime/vue/components/Icon.vue +15 -0
  155. package/dist/runtime/vue/components/Icon.vue.d.ts +7 -0
  156. package/dist/runtime/vue/components/Link.vue +163 -0
  157. package/dist/runtime/vue/components/Link.vue.d.ts +95 -0
  158. package/dist/runtime/vue/composables/useAppConfig.d.ts +1 -0
  159. package/dist/runtime/vue/composables/useAppConfig.js +4 -0
  160. package/dist/runtime/vue/plugins/color-mode.d.ts +4 -0
  161. package/dist/runtime/vue/plugins/color-mode.js +6 -0
  162. package/dist/runtime/vue/plugins/head.d.ts +4 -0
  163. package/dist/runtime/vue/plugins/head.js +9 -0
  164. package/dist/runtime/vue/stubs.d.ts +16 -1
  165. package/dist/runtime/vue/stubs.js +32 -1
  166. package/dist/setup.d.mts +13 -0
  167. package/dist/setup.mjs +12 -0
  168. package/dist/shared/ui.CzIlLITK.mjs +51 -0
  169. package/dist/shared/ui.DLOxhmP0.mjs +4242 -0
  170. package/dist/shared/ui.DpbffTXs.d.mts +84 -0
  171. package/dist/shared/ui.IulR-OYx.d.mts +64 -0
  172. package/dist/types.d.mts +3 -1
  173. package/dist/unocss.d.mts +12 -52
  174. package/dist/unocss.mjs +144 -254
  175. package/dist/unplugin.d.mts +13 -26
  176. package/dist/unplugin.mjs +193 -18
  177. package/dist/vite.d.mts +10 -1
  178. package/dist/vite.mjs +12 -3
  179. package/package.json +154 -87
  180. package/vue-plugin.d.ts +5 -0
  181. package/dist/module.d.ts +0 -13
  182. package/dist/module.mjs.map +0 -1
  183. package/dist/runtime/app/injections.d.ts +0 -9331
  184. package/dist/runtime/app/injections.js +0 -61
  185. package/dist/runtime/components/ButtonGroup.vue +0 -26
  186. package/dist/runtime/components/ButtonGroup.vue.d.ts +0 -26
  187. package/dist/runtime/components/FormItem.vue +0 -90
  188. package/dist/runtime/components/FormItem.vue.d.ts +0 -60
  189. package/dist/runtime/composables/useButtonGroup.d.ts +0 -5
  190. package/dist/runtime/composables/useButtonGroup.js +0 -9
  191. package/dist/runtime/composables/useFormItem.d.ts +0 -27
  192. package/dist/runtime/composables/useFormItem.js +0 -64
  193. package/dist/runtime/composables/useTheme.d.ts +0 -9
  194. package/dist/runtime/composables/useTheme.js +0 -23
  195. package/dist/runtime/index.d.ts +0 -44
  196. package/dist/runtime/index.js +0 -44
  197. package/dist/runtime/locale/zh-tw.d.ts +0 -2
  198. package/dist/runtime/theme/accordion.d.ts +0 -50
  199. package/dist/runtime/theme/accordion.js +0 -28
  200. package/dist/runtime/theme/alert.d.ts +0 -119
  201. package/dist/runtime/theme/alert.js +0 -47
  202. package/dist/runtime/theme/app.d.ts +0 -19
  203. package/dist/runtime/theme/app.js +0 -19
  204. package/dist/runtime/theme/avatar-group.d.ts +0 -46
  205. package/dist/runtime/theme/avatar-group.js +0 -32
  206. package/dist/runtime/theme/avatar.d.ts +0 -50
  207. package/dist/runtime/theme/avatar.js +0 -34
  208. package/dist/runtime/theme/badge.d.ts +0 -76
  209. package/dist/runtime/theme/badge.js +0 -92
  210. package/dist/runtime/theme/breadcrumb.d.ts +0 -61
  211. package/dist/runtime/theme/breadcrumb.js +0 -44
  212. package/dist/runtime/theme/button-group.d.ts +0 -60
  213. package/dist/runtime/theme/button-group.js +0 -42
  214. package/dist/runtime/theme/button.d.ts +0 -184
  215. package/dist/runtime/theme/button.js +0 -164
  216. package/dist/runtime/theme/calendar.d.ts +0 -58
  217. package/dist/runtime/theme/calendar.js +0 -86
  218. package/dist/runtime/theme/card.d.ts +0 -56
  219. package/dist/runtime/theme/card.js +0 -37
  220. package/dist/runtime/theme/carousel.d.ts +0 -107
  221. package/dist/runtime/theme/carousel.js +0 -43
  222. package/dist/runtime/theme/checkbox.d.ts +0 -82
  223. package/dist/runtime/theme/checkbox.js +0 -54
  224. package/dist/runtime/theme/chip.d.ts +0 -61
  225. package/dist/runtime/theme/chip.js +0 -66
  226. package/dist/runtime/theme/collapsible.d.ts +0 -32
  227. package/dist/runtime/theme/collapsible.js +0 -10
  228. package/dist/runtime/theme/drawer.d.ts +0 -142
  229. package/dist/runtime/theme/drawer.js +0 -113
  230. package/dist/runtime/theme/dropdown-menu.d.ts +0 -65
  231. package/dist/runtime/theme/dropdown-menu.js +0 -83
  232. package/dist/runtime/theme/form-item.d.ts +0 -70
  233. package/dist/runtime/theme/form-item.js +0 -34
  234. package/dist/runtime/theme/form.d.ts +0 -2
  235. package/dist/runtime/theme/form.js +0 -7
  236. package/dist/runtime/theme/index.d.ts +0 -41
  237. package/dist/runtime/theme/index.js +0 -41
  238. package/dist/runtime/theme/input-number.d.ts +0 -115
  239. package/dist/runtime/theme/input-number.js +0 -95
  240. package/dist/runtime/theme/input.d.ts +0 -172
  241. package/dist/runtime/theme/input.js +0 -151
  242. package/dist/runtime/theme/kbd.d.ts +0 -33
  243. package/dist/runtime/theme/kbd.js +0 -26
  244. package/dist/runtime/theme/link.d.ts +0 -38
  245. package/dist/runtime/theme/link.js +0 -26
  246. package/dist/runtime/theme/modal.d.ts +0 -42
  247. package/dist/runtime/theme/modal.js +0 -55
  248. package/dist/runtime/theme/pagination.d.ts +0 -74
  249. package/dist/runtime/theme/pagination.js +0 -17
  250. package/dist/runtime/theme/pinInput.d.ts +0 -94
  251. package/dist/runtime/theme/pinInput.js +0 -111
  252. package/dist/runtime/theme/popover.d.ts +0 -32
  253. package/dist/runtime/theme/popover.js +0 -13
  254. package/dist/runtime/theme/progress.d.ts +0 -180
  255. package/dist/runtime/theme/progress.js +0 -95
  256. package/dist/runtime/theme/radio-group.d.ts +0 -104
  257. package/dist/runtime/theme/radio-group.js +0 -61
  258. package/dist/runtime/theme/scroll-area.d.ts +0 -67
  259. package/dist/runtime/theme/scroll-area.js +0 -33
  260. package/dist/runtime/theme/select.d.ts +0 -186
  261. package/dist/runtime/theme/select.js +0 -173
  262. package/dist/runtime/theme/separator.d.ts +0 -74
  263. package/dist/runtime/theme/separator.js +0 -53
  264. package/dist/runtime/theme/skeleton.d.ts +0 -2
  265. package/dist/runtime/theme/skeleton.js +0 -7
  266. package/dist/runtime/theme/slider.d.ts +0 -70
  267. package/dist/runtime/theme/slider.js +0 -52
  268. package/dist/runtime/theme/switch.d.ts +0 -116
  269. package/dist/runtime/theme/switch.js +0 -78
  270. package/dist/runtime/theme/table.d.ts +0 -86
  271. package/dist/runtime/theme/table.js +0 -36
  272. package/dist/runtime/theme/tabs.d.ts +0 -129
  273. package/dist/runtime/theme/tabs.js +0 -146
  274. package/dist/runtime/theme/textarea.d.ts +0 -90
  275. package/dist/runtime/theme/textarea.js +0 -116
  276. package/dist/runtime/theme/toast-provider.d.ts +0 -116
  277. package/dist/runtime/theme/toast-provider.js +0 -97
  278. package/dist/runtime/theme/toast.d.ts +0 -83
  279. package/dist/runtime/theme/toast.js +0 -35
  280. package/dist/runtime/theme/tooltip.d.ts +0 -38
  281. package/dist/runtime/theme/tooltip.js +0 -11
  282. package/dist/runtime/types/components.d.ts +0 -42
  283. package/dist/runtime/utils/extend-theme.d.ts +0 -9
  284. package/dist/runtime/utils/extend-theme.js +0 -27
  285. package/dist/runtime/utils/styler.d.ts +0 -4
  286. package/dist/runtime/utils/styler.js +0 -10
  287. package/dist/runtime/utils/translator.d.ts +0 -18
  288. package/dist/runtime/utils/translator.js +0 -8
  289. package/dist/shared/ui.D1BTWZFB.mjs +0 -5
  290. package/dist/shared/ui.D1BTWZFB.mjs.map +0 -1
  291. package/dist/unocss.d.ts +0 -52
  292. package/dist/unocss.mjs.map +0 -1
  293. package/dist/unplugin.d.ts +0 -26
  294. package/dist/unplugin.mjs.map +0 -1
  295. package/dist/vite.d.ts +0 -9
  296. package/dist/vite.mjs.map +0 -1
  297. /package/dist/runtime/types/{components.js → input.js} +0 -0
@@ -1,48 +1,59 @@
1
1
  <script>
2
- export class FormValidationExceptionError extends Error {
3
- formId;
4
- errors;
5
- children;
6
- constructor(formId, errors, childErrors) {
7
- super("Form validation exception");
8
- this.name = "FormValidationExceptionError";
9
- this.formId = formId;
10
- this.errors = errors;
11
- this.children = childErrors;
12
- Object.setPrototypeOf(this, FormValidationExceptionError.prototype);
13
- }
14
- }
2
+ import theme from "#build/ui/form";
15
3
  </script>
16
4
 
17
5
  <script setup>
18
6
  import { useEventBus } from "@vueuse/core";
19
- import { computed, nextTick, onMounted, onUnmounted, readonly, ref, useId } from "vue";
20
- import { injectFormBus, provideFormBus, provideFormErrors, provideFormInputs, provideFormLoading, provideFormOptions } from "../app/injections";
21
- import { useTheme } from "../composables/useTheme";
22
- import { validateSchema } from "../utils";
7
+ import { computed, nextTick, onMounted, onUnmounted, reactive, readonly, ref, shallowRef, useId } from "vue";
8
+ import { useAppConfig } from "#imports";
9
+ import { injectFormBus, injectFormState, provideFormBus, provideFormErrors, provideFormInputs, provideFormLoading, provideFormOptions, provideFormState } from "../composables/useFormField";
10
+ import { FormValidationException } from "../types/form";
11
+ import { getAtPath, setAtPath, validateSchema } from "../utils/form";
12
+ import { cv, merge } from "../utils/style";
23
13
  const props = defineProps({
24
14
  id: { type: [String, Number], required: false },
25
15
  schema: { type: null, required: false },
26
- state: { type: Object, required: true },
16
+ state: { type: null, required: true },
27
17
  validate: { type: Function, required: false },
28
18
  validateOn: { type: Array, required: false, default: () => ["input", "blur", "change"] },
29
19
  disabled: { type: Boolean, required: false },
20
+ name: { type: null, required: false },
30
21
  validateOnInputDelay: { type: Number, required: false, default: 300 },
31
22
  transform: { type: Boolean, required: false, default: true },
23
+ nested: { type: Boolean, required: false },
24
+ loadingAuto: { type: Boolean, required: false, default: true },
32
25
  onSubmit: { type: Function, required: false },
33
- class: { type: null, required: false }
26
+ class: { type: [Object, String, Number, Boolean, null, Array], required: false, skipCheck: true }
34
27
  });
35
28
  const emit = defineEmits(["submit", "error"]);
36
29
  defineSlots();
37
30
  const formId = props.id ?? useId();
38
31
  const bus = useEventBus(`form-${formId}`);
39
- const parentBus = injectFormBus();
32
+ const parentBus = props.nested && injectFormBus();
33
+ const parentState = props.nested ? injectFormState() : void 0;
34
+ const state = computed(() => {
35
+ if (parentState?.value)
36
+ return props.name ? getAtPath(parentState.value, props.name) : parentState.value;
37
+ return props.state;
38
+ });
40
39
  provideFormBus(bus);
40
+ provideFormState(state);
41
41
  const nestedForms = ref(/* @__PURE__ */ new Map());
42
+ onMounted(async () => {
43
+ if (parentBus) {
44
+ await nextTick();
45
+ parentBus.emit({ type: "attach", validate: validateFn, formId, name: props.name, api });
46
+ }
47
+ });
48
+ onUnmounted(() => {
49
+ bus.reset();
50
+ if (parentBus)
51
+ parentBus.emit({ type: "detach", formId });
52
+ });
42
53
  onMounted(() => {
43
54
  bus.on(async (event) => {
44
55
  if (event.type === "attach") {
45
- nestedForms.value.set(event.formId, { validate: event.validate });
56
+ nestedForms.value.set(event.formId, { validate: event.validate, name: event.name, api: event.api });
46
57
  } else if (event.type === "detach") {
47
58
  nestedForms.value.delete(event.formId);
48
59
  } else if (props.validateOn?.includes(event.type) && !loading.value) {
@@ -59,26 +70,13 @@ onMounted(() => {
59
70
  dirtyFields.add(event.name);
60
71
  });
61
72
  });
62
- onUnmounted(() => {
63
- bus.reset();
64
- });
65
- onMounted(async () => {
66
- if (parentBus) {
67
- await nextTick();
68
- parentBus.emit({ type: "attach", validate: validateFn, formId });
69
- }
70
- });
71
- onUnmounted(() => {
72
- if (parentBus)
73
- parentBus.emit({ type: "detach", formId });
74
- });
75
73
  const errors = ref([]);
76
74
  provideFormErrors(errors);
77
75
  const inputs = ref({});
78
76
  provideFormInputs(inputs);
79
- const dirtyFields = /* @__PURE__ */ new Set();
80
- const touchedFields = /* @__PURE__ */ new Set();
81
- const blurredFields = /* @__PURE__ */ new Set();
77
+ const dirtyFields = reactive(/* @__PURE__ */ new Set());
78
+ const touchedFields = reactive(/* @__PURE__ */ new Set());
79
+ const blurredFields = reactive(/* @__PURE__ */ new Set());
82
80
  function resolveErrorIds(errs) {
83
81
  return errs.map((err) => ({
84
82
  ...err,
@@ -97,61 +95,50 @@ async function getErrors() {
97
95
  }
98
96
  return resolveErrorIds(errs);
99
97
  }
100
- async function validateFn(options) {
101
- const _options = {
102
- silent: false,
103
- nested: true,
104
- transform: false,
105
- ...options
106
- };
107
- const names = _options.name && !Array.isArray(_options.name) ? [_options.name] : _options.name;
108
- const nestedValidatePromises = !names && _options.nested ? Array.from(nestedForms.value.values()).map(
109
- ({ validate }) => validate(_options).then(() => {
110
- }).catch((error) => {
111
- if (!(error instanceof FormValidationExceptionError))
112
- throw error;
113
- return error;
114
- })
115
- ) : [];
116
- if (names) {
117
- const otherErrors = errors.value.filter((error) => !names.some((name) => {
118
- const pattern = inputs.value?.[name]?.pattern;
119
- return name === error.name || pattern && error.name?.match(pattern);
120
- }));
121
- const pathErrors = (await getErrors()).filter((error) => names.some((name) => {
122
- const pattern = inputs.value?.[name]?.pattern;
123
- return name === error.name || pattern && error.name?.match(pattern);
124
- }));
125
- errors.value = otherErrors.concat(pathErrors);
126
- } else {
127
- errors.value = await getErrors();
98
+ async function validateFn(opts = { silent: false, nested: false, transform: false }) {
99
+ const names = opts.name && !Array.isArray(opts.name) ? [opts.name] : opts.name;
100
+ let nestedResults = [];
101
+ let nestedErrors = [];
102
+ if (!names && opts.nested) {
103
+ const validations = Array.from(nestedForms.value.values()).map((form) => validateNestedForm(form, opts));
104
+ const results = await Promise.all(validations);
105
+ nestedErrors = results.filter((r) => r.error).flatMap((r) => r.error.errors.map((e) => addFormPath(e, r.name)));
106
+ nestedResults = results.filter((r) => r.output !== void 0);
128
107
  }
129
- const childErrors = (await Promise.all(nestedValidatePromises)).filter((val) => val !== void 0);
130
- if (errors.value.length + childErrors.length > 0) {
131
- if (_options.silent)
108
+ const currentErrors = await getErrors();
109
+ const allErrors = [...currentErrors, ...nestedErrors];
110
+ errors.value = names ? filterErrorsByNames(allErrors, names) : allErrors;
111
+ if (errors.value?.length) {
112
+ if (opts.silent)
132
113
  return false;
133
- throw new FormValidationExceptionError(formId, errors.value, childErrors);
114
+ throw new FormValidationException(formId, errors.value);
134
115
  }
135
- if (_options.transform)
136
- Object.assign(props.state, transformedState.value);
137
- return props.state;
116
+ if (opts.transform) {
117
+ nestedResults.forEach((result) => {
118
+ if (result.name)
119
+ setAtPath(transformedState.value, result.name, result.output);
120
+ else
121
+ Object.assign(transformedState.value, result.output);
122
+ });
123
+ return transformedState.value ?? state.value;
124
+ }
125
+ return state.value;
138
126
  }
139
- const loading = ref(false);
127
+ const loading = shallowRef(false);
140
128
  provideFormLoading(readonly(loading));
141
129
  async function onSubmitWrapper(payload) {
142
- loading.value = true;
130
+ loading.value = props.loadingAuto && true;
143
131
  const event = payload;
144
132
  try {
145
133
  event.data = await validateFn({ nested: true, transform: props.transform });
146
134
  await props.onSubmit?.(event);
147
135
  dirtyFields.clear();
148
136
  } catch (error) {
149
- if (!(error instanceof FormValidationExceptionError))
137
+ if (!(error instanceof FormValidationException))
150
138
  throw error;
151
139
  const errorEvent = {
152
140
  ...event,
153
- errors: error.errors,
154
- children: error.children
141
+ errors: error.errors
155
142
  };
156
143
  emit("error", errorEvent);
157
144
  } finally {
@@ -163,35 +150,132 @@ provideFormOptions(computed(() => ({
163
150
  disabled: disabled.value,
164
151
  validateOnInputDelay: props.validateOnInputDelay
165
152
  })));
166
- defineExpose({
153
+ async function validateNestedForm(form, opts) {
154
+ try {
155
+ const result = await form.validate({ ...opts, silent: false });
156
+ return { name: form.name, output: result };
157
+ } catch (error) {
158
+ if (!(error instanceof FormValidationException))
159
+ throw error;
160
+ return { name: form.name, error };
161
+ }
162
+ }
163
+ function addFormPath(error, formPath) {
164
+ if (!formPath || !error.name)
165
+ return error;
166
+ return { ...error, name: `${formPath}.${error.name}` };
167
+ }
168
+ function stripFormPath(error, formPath) {
169
+ const prefix = `${formPath}.`;
170
+ const name = error?.name?.startsWith(prefix) ? error.name.slice(prefix.length) : error.name;
171
+ return { ...error, name };
172
+ }
173
+ function filterFormErrors(errors2, formPath) {
174
+ if (!formPath)
175
+ return errors2;
176
+ return errors2.filter((e) => e?.name?.startsWith(`${formPath}.`)).map((e) => stripFormPath(e, formPath));
177
+ }
178
+ function getFormErrors(form) {
179
+ return form.api.getErrors().map((e) => form.name ? { ...e, name: `${form.name}.${e.name}` } : e);
180
+ }
181
+ function matchesTarget(target, path) {
182
+ if (!target || !path)
183
+ return true;
184
+ if (target instanceof RegExp)
185
+ return target.test(path);
186
+ return path === target || typeof target === "string" && target.startsWith(`${path}.`);
187
+ }
188
+ function getNestedTarget(target, formPath) {
189
+ if (!target || target instanceof RegExp)
190
+ return target;
191
+ if (formPath === target)
192
+ return void 0;
193
+ if (typeof target === "string" && target.startsWith(`${formPath}.`))
194
+ return target.slice(Math.max(0, formPath.length + 1));
195
+ return target;
196
+ }
197
+ function filterErrorsByNames(allErrors, names) {
198
+ const nameSet = new Set(names);
199
+ const patterns = names.map((name) => inputs.value?.[name]?.pattern).filter(Boolean);
200
+ const matchesNames = (error) => {
201
+ if (!error.name)
202
+ return false;
203
+ if (nameSet.has(error.name))
204
+ return true;
205
+ return patterns.some((pattern) => pattern.test(error.name));
206
+ };
207
+ const keepErrors = errors.value.filter((error) => !matchesNames(error));
208
+ const newErrors = allErrors.filter(matchesNames);
209
+ return [...keepErrors, ...newErrors];
210
+ }
211
+ function filterErrorsByTarget(currentErrors, target) {
212
+ return currentErrors.filter((err) => target instanceof RegExp ? !(err.name && target.test(err.name)) : !err.name || err.name !== target);
213
+ }
214
+ function isLocalError(error) {
215
+ return !error.name || !!inputs.value[error.name];
216
+ }
217
+ const api = {
167
218
  validate: validateFn,
219
+ // FIXME: type issue
168
220
  errors,
169
221
  setErrors(errs, name) {
170
- errors.value = name ? errors.value.filter((error) => error.name !== name).concat(resolveErrorIds(errs)) : resolveErrorIds(errs);
222
+ const localErrors = resolveErrorIds(errs.filter(isLocalError));
223
+ const nestedErrors = [];
224
+ for (const form of nestedForms.value.values()) {
225
+ if (matchesTarget(name, form.name)) {
226
+ const formErrors = filterFormErrors(errs, form.name);
227
+ form.api.setErrors(formErrors, getNestedTarget(name, form.name || ""));
228
+ nestedErrors.push(...getFormErrors(form));
229
+ }
230
+ }
231
+ if (name) {
232
+ const keepErrors = filterErrorsByTarget(errors.value, name);
233
+ errors.value = [...keepErrors, ...localErrors, ...nestedErrors];
234
+ } else {
235
+ errors.value = [...localErrors, ...nestedErrors];
236
+ }
171
237
  },
172
238
  async submit() {
173
239
  await onSubmitWrapper(new Event("submit"));
174
240
  },
175
241
  getErrors(name) {
176
- if (name)
177
- return errors.value.filter((err) => err.name === name);
178
- return errors.value;
242
+ if (!name)
243
+ return errors.value;
244
+ return errors.value.filter((err) => name instanceof RegExp ? err.name && name.test(err.name) : err.name === name);
179
245
  },
180
246
  clear(name) {
181
- errors.value = name ? errors.value.filter((err) => err.name !== name) : [];
247
+ const localErrors = name ? errors.value.filter((err) => isLocalError(err) && (name instanceof RegExp ? !(err.name && name.test(err.name)) : err.name !== name)) : [];
248
+ const nestedErrors = [];
249
+ for (const form of nestedForms.value.values()) {
250
+ if (matchesTarget(name, form.name))
251
+ form.api.clear();
252
+ nestedErrors.push(...getFormErrors(form));
253
+ }
254
+ errors.value = [...localErrors, ...nestedErrors];
182
255
  },
183
256
  disabled,
184
- dirty: computed(() => dirtyFields.size > 0),
257
+ loading,
258
+ dirty: computed(() => !!dirtyFields.size),
185
259
  dirtyFields: readonly(dirtyFields),
186
260
  blurredFields: readonly(blurredFields),
187
261
  touchedFields: readonly(touchedFields)
262
+ };
263
+ defineExpose(api);
264
+ const appConfig = useAppConfig();
265
+ const ui = computed(() => {
266
+ const styler = cv(merge(theme, appConfig.ui.form));
267
+ return styler(props);
188
268
  });
189
- const { generateStyle } = useTheme();
190
- const style = computed(() => generateStyle("form", props));
191
269
  </script>
192
270
 
193
271
  <template>
194
- <component :is="parentBus ? 'div' : 'form'" :id="formId" :class="style.base()" data-part="base" @submit.prevent="onSubmitWrapper">
195
- <slot :errors="errors"></slot>
272
+ <component
273
+ :is="parentBus ? 'div' : 'form'"
274
+ :id="formId"
275
+ :class="ui.base({ class: props.class })"
276
+ data-part="base"
277
+ @submit.prevent="onSubmitWrapper"
278
+ >
279
+ <slot :errors="errors" :loading="loading"></slot>
196
280
  </component>
197
281
  </template>
@@ -1,47 +1,30 @@
1
- import type { ComputedRef, DeepReadonly, Ref } from 'vue';
2
- import type { form } from '../theme/index.js';
3
- import type { ComponentAttrs, FormError, FormErrorEvent, FormErrorWithId, FormInputEvents, FormSchema, FormSubmitEvent, FormValidateOptions } from '../types/index.js';
4
- export interface FormEmits<T extends object> {
5
- submit: [payload: FormSubmitEvent<T>];
6
- error: [payload: FormErrorEvent];
7
- }
8
- export interface FormSlots {
9
- default?: (props?: {
10
- errors: FormError[];
11
- }) => any;
12
- }
13
- export interface FormExpose<T extends object> {
14
- validate: (options?: FormValidateOptions<T>) => Promise<T | false>;
15
- clear: (path?: string) => void;
16
- errors: Ref<FormError[]>;
17
- setErrors: (errors: FormError[], name?: keyof T) => void;
18
- getErrors: (name?: keyof T) => FormError[];
19
- submit: () => Promise<void>;
20
- disabled: ComputedRef<boolean>;
21
- dirty: ComputedRef<boolean>;
22
- dirtyFields: DeepReadonly<Set<keyof T>>;
23
- touchedFields: DeepReadonly<Set<keyof T>>;
24
- blurredFields: DeepReadonly<Set<keyof T>>;
25
- }
26
- export interface FormProps<T extends object> extends Omit<ComponentAttrs<typeof form>, 'ui'> {
1
+ import type { ComponentBaseProps, FormData, FormError, FormErrorEvent, FormErrorWithId, FormInputEvents, FormSchema, FormSubmitEvent, InferInput } from '../types';
2
+ import type { StaticSlot } from '../types/utils';
3
+ export interface FormProps<S extends FormSchema, T extends boolean = true, N extends boolean = false> extends ComponentBaseProps {
27
4
  id?: string | number;
28
- /** Schema to validate the form state. */
29
- schema?: FormSchema<T>;
5
+ /** Schema to validate the form state. Supports Standard Schema objects, Yup, Joi, and Superstructs. */
6
+ schema?: S;
30
7
  /** An object representing the current state of the form. */
31
- state: Partial<T>;
8
+ state: N extends false ? Partial<InferInput<S>> : never;
32
9
  /**
33
10
  * Custom validation function to validate the form state.
34
11
  * @param state - The current state of the form.
35
12
  * @returns A promise that resolves to an array of FormError objects, or an array of FormError objects directly.
36
13
  */
37
- validate?: (state: Partial<T>) => Promise<FormError[]> | FormError[];
14
+ validate?: (state: Partial<InferInput<S>>) => Promise<FormError[]> | FormError[];
38
15
  /**
39
16
  * The list of input events that trigger the form validation.
17
+ * @remarks The form always validates on submit.
40
18
  * @default ["blur", "change", "input"]
41
19
  */
42
20
  validateOn?: FormInputEvents[];
43
21
  /** Disable all inputs inside the form. */
44
22
  disabled?: boolean;
23
+ /**
24
+ * Path of the form's state within it's parent form.
25
+ * Used for nesting forms. Only available if `nested` is true.
26
+ */
27
+ name?: N extends true ? string : never;
45
28
  /**
46
29
  * Delay in milliseconds before validating the form on input events.
47
30
  * @default 300
@@ -51,28 +34,70 @@ export interface FormProps<T extends object> extends Omit<ComponentAttrs<typeof
51
34
  * If true, schema transformations will be applied to the state on submit.
52
35
  * @default true
53
36
  */
54
- transform?: boolean;
37
+ transform?: T & boolean;
38
+ /**
39
+ * If true, this form will attach to its parent Form and validate at the same time.
40
+ * @default false
41
+ */
42
+ nested?: N & boolean;
43
+ /**
44
+ * When `true`, all form elements will be disabled on `@submit` event.
45
+ *
46
+ * This will cause any focused input elements to lose their focus state.
47
+ * @default true
48
+ */
49
+ loadingAuto?: boolean;
55
50
  onSubmit?: ((event: FormSubmitEvent<T>) => void | Promise<void>) | (() => void | Promise<void>);
56
51
  }
57
- export declare class FormValidationExceptionError extends Error {
58
- formId: string | number;
59
- errors: FormErrorWithId[];
60
- children?: FormValidationExceptionError[];
61
- constructor(formId: string | number, errors: FormErrorWithId[], childErrors?: FormValidationExceptionError[]);
52
+ export interface FormEmits<S extends FormSchema, T extends boolean = true> {
53
+ submit: [event: FormSubmitEvent<FormData<S, T>>];
54
+ error: [event: FormErrorEvent];
55
+ }
56
+ export interface FormSlots {
57
+ default: StaticSlot<{
58
+ errors: FormError[];
59
+ loading: boolean;
60
+ }>;
62
61
  }
63
- declare const _default: <T extends object>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
64
- props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
65
- readonly onError?: ((payload: FormErrorEvent) => any) | undefined;
66
- readonly onSubmit?: ((payload: FormSubmitEvent<T>) => any) | undefined;
67
- } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onSubmit" | "onError"> & FormProps<T> & Partial<{}>> & import("vue").PublicProps;
68
- expose(exposed: import("vue").ShallowUnwrapRef<FormExpose<T>>): void;
62
+ declare const __VLS_export: <S extends FormSchema, T extends boolean = true, N extends boolean = false>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
63
+ props: __VLS_PrettifyLocal<FormProps<S, T, N> & {
64
+ onError?: ((event: FormErrorEvent) => any) | undefined;
65
+ onSubmit?: ((event: FormSubmitEvent<FormData<S, T>>) => any) | undefined;
66
+ }> & import("vue").PublicProps;
67
+ expose: (exposed: import("vue").ShallowUnwrapRef<{
68
+ validate: any;
69
+ errors: import("vue").Ref<{
70
+ id?: string | undefined;
71
+ name?: string | undefined;
72
+ message: string;
73
+ }[], FormErrorWithId[] | {
74
+ id?: string | undefined;
75
+ name?: string | undefined;
76
+ message: string;
77
+ }[]>;
78
+ setErrors(errs: FormError[], name?: keyof InferInput<S> | string | RegExp): void;
79
+ submit(): Promise<void>;
80
+ getErrors(name?: keyof InferInput<S> | string | RegExp): {
81
+ id?: string | undefined;
82
+ name?: string | undefined;
83
+ message: string;
84
+ }[];
85
+ clear(name?: keyof InferInput<S> | string | RegExp): void;
86
+ disabled: import("vue").ComputedRef<boolean>;
87
+ loading: import("vue").ShallowRef<boolean, boolean>;
88
+ dirty: import("vue").ComputedRef<boolean>;
89
+ dirtyFields: ReadonlySet<import("vue").DeepReadonly<import("@vue/reactivity").UnwrapRefSimple<keyof InferInput<S>>>>;
90
+ blurredFields: ReadonlySet<import("vue").DeepReadonly<import("@vue/reactivity").UnwrapRefSimple<keyof InferInput<S>>>>;
91
+ touchedFields: ReadonlySet<import("vue").DeepReadonly<import("@vue/reactivity").UnwrapRefSimple<keyof InferInput<S>>>>;
92
+ }>) => void;
69
93
  attrs: any;
70
94
  slots: FormSlots;
71
- emit: ((evt: "error", payload: FormErrorEvent) => void) & ((evt: "submit", payload: FormSubmitEvent<T>) => void);
95
+ emit: ((evt: "error", event: FormErrorEvent) => void) & ((evt: "submit", event: FormSubmitEvent<FormData<S, T>>) => void);
72
96
  }>) => import("vue").VNode & {
73
97
  __ctx?: Awaited<typeof __VLS_setup>;
74
98
  };
99
+ declare const _default: typeof __VLS_export;
75
100
  export default _default;
76
101
  type __VLS_PrettifyLocal<T> = {
77
- [K in keyof T]: T[K];
102
+ [K in keyof T as K]: T[K];
78
103
  } & {};
@@ -0,0 +1,108 @@
1
+ <script>
2
+ import theme from "#build/ui/form-field";
3
+ </script>
4
+
5
+ <script setup>
6
+ import { Label, Primitive } from "reka-ui";
7
+ import { computed, ref, useId, watch } from "vue";
8
+ import { useAppConfig } from "#imports";
9
+ import { injectFormErrors, injectFormInputs, provideFormField, provideFormInputId } from "../composables/useFormField";
10
+ import { cv, merge } from "../utils/style";
11
+ const props = defineProps({
12
+ as: { type: null, required: false },
13
+ name: { type: String, required: false },
14
+ errorPattern: { type: null, required: false },
15
+ label: { type: String, required: false },
16
+ description: { type: String, required: false },
17
+ help: { type: String, required: false },
18
+ error: { type: [String, Boolean], required: false },
19
+ hint: { type: String, required: false },
20
+ size: { type: null, required: false },
21
+ required: { type: Boolean, required: false },
22
+ eagerValidation: { type: Boolean, required: false },
23
+ validateOnInputDelay: { type: Number, required: false },
24
+ ui: { type: null, required: false },
25
+ class: { type: [Object, String, Number, Boolean, null, Array], required: false, skipCheck: true }
26
+ });
27
+ const slots = defineSlots();
28
+ const formErrors = injectFormErrors();
29
+ const error = computed(() => {
30
+ if (props.error)
31
+ return props.error;
32
+ const formError = formErrors?.value.find((error2) => {
33
+ if (error2.name && error2.name === props.name)
34
+ return true;
35
+ if (error2.name && props.errorPattern)
36
+ return error2.name.match(props.errorPattern);
37
+ return false;
38
+ });
39
+ return formError?.message;
40
+ });
41
+ const id = ref(useId());
42
+ const ariaId = id.value;
43
+ const formInputs = injectFormInputs();
44
+ watch(id, () => {
45
+ if (formInputs && props.name)
46
+ formInputs.value[props.name] = { id: id.value, pattern: props.errorPattern };
47
+ }, {
48
+ immediate: true
49
+ });
50
+ provideFormInputId(id);
51
+ provideFormField(computed(() => ({
52
+ name: props.name,
53
+ size: props.size,
54
+ eagerValidation: props.eagerValidation,
55
+ validateOnInputDelay: props.validateOnInputDelay,
56
+ errorPattern: props.errorPattern,
57
+ hint: props.hint,
58
+ description: props.description,
59
+ help: props.help,
60
+ ariaId,
61
+ error: error.value
62
+ })));
63
+ const appConfig = useAppConfig();
64
+ const ui = computed(() => {
65
+ const styler = cv(merge(theme, appConfig.ui.formField));
66
+ return styler(props);
67
+ });
68
+ </script>
69
+
70
+ <template>
71
+ <Primitive :as="props.as" :class="ui.root({ class: [props.ui?.root, props.class] })" data-part="root">
72
+ <div :class="ui.wrapper({ class: props.ui?.wrapper })" data-part="wrapper">
73
+ <div v-if="props.label || !!slots.label" :class="ui.labelWrapper({ class: props.ui?.labelWrapper })" data-part="labelWrapper">
74
+ <Label :for="id" :class="ui.label({ class: props.ui?.label })" data-part="label">
75
+ <slot name="label" :label="props.label">
76
+ {{ props.label }}
77
+ </slot>
78
+ </Label>
79
+ <span v-if="props.hint || !!slots.hint" :id="`${ariaId}-hint`" :class="ui.hint({ class: props.ui?.hint })" data-part="hint">
80
+ <slot name="hint" :hint="props.hint">
81
+ {{ props.hint }}
82
+ </slot>
83
+ </span>
84
+ </div>
85
+
86
+ <p v-if="props.description || !!slots.description" :id="`${ariaId}-description`" :class="ui.description({ class: props.ui?.description })" data-part="description">
87
+ <slot name="description" :description="props.description">
88
+ {{ props.description }}
89
+ </slot>
90
+ </p>
91
+ </div>
92
+
93
+ <div :class="(props.label || !!slots.label || props.description || !!slots.description) && ui.container({ class: props.ui?.container })" data-part="container">
94
+ <slot :error="error"></slot>
95
+
96
+ <div v-if="typeof error === 'string' && error || !!slots.error" :id="`${ariaId}-error`" :class="ui.error({ class: props.ui?.error })" data-part="error">
97
+ <slot name="error" :error="error">
98
+ {{ error }}
99
+ </slot>
100
+ </div>
101
+ <div v-else-if="props.help || !!slots.help" :class="ui.help({ class: props.ui?.help })" data-part="help">
102
+ <slot name="help" :help="props.help">
103
+ {{ props.help }}
104
+ </slot>
105
+ </div>
106
+ </div>
107
+ </Primitive>
108
+ </template>
@@ -0,0 +1,63 @@
1
+ import type { VariantProps } from '@byyuurin/ui-kit';
2
+ import type { PrimitiveProps } from 'reka-ui';
3
+ import theme from '#build/ui/form-field';
4
+ import type { ComponentBaseProps, ComponentUIProps } from '../types';
5
+ import type { StaticSlot } from '../types/utils';
6
+ type ThemeVariants = VariantProps<typeof theme>;
7
+ export interface FormFieldProps extends ComponentBaseProps {
8
+ /**
9
+ * The element or component this component should render as.
10
+ * @default "div"
11
+ */
12
+ as?: PrimitiveProps['as'];
13
+ /** The name of the FormField. Also used to match form errors. */
14
+ name?: string;
15
+ /** A regular expression to match form error names. */
16
+ errorPattern?: RegExp;
17
+ label?: string;
18
+ description?: string;
19
+ help?: string;
20
+ error?: string | boolean;
21
+ hint?: string;
22
+ /**
23
+ * @default "md"
24
+ */
25
+ size?: ThemeVariants['size'];
26
+ required?: boolean;
27
+ /** If true, validation on input will be active immediately instead of waiting for a blur event. */
28
+ eagerValidation?: boolean;
29
+ /**
30
+ * Delay in milliseconds before validating the form on input events.
31
+ * @default 300
32
+ */
33
+ validateOnInputDelay?: number;
34
+ ui?: ComponentUIProps<typeof theme>;
35
+ }
36
+ export interface FormFieldSlots {
37
+ label: StaticSlot<{
38
+ label?: string;
39
+ }>;
40
+ hint: StaticSlot<{
41
+ hint?: string;
42
+ }>;
43
+ description: StaticSlot<{
44
+ description?: string;
45
+ }>;
46
+ help: StaticSlot<{
47
+ help?: string;
48
+ }>;
49
+ error: StaticSlot<{
50
+ error?: boolean | string;
51
+ }>;
52
+ default: StaticSlot<{
53
+ error?: boolean | string;
54
+ }>;
55
+ }
56
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<FormFieldProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormFieldProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, FormFieldSlots>;
57
+ declare const _default: typeof __VLS_export;
58
+ export default _default;
59
+ type __VLS_WithSlots<T, S> = T & {
60
+ new (): {
61
+ $slots: S;
62
+ };
63
+ };