@auronui/vue 1.2.1 → 1.3.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 (218) hide show
  1. package/ai-rules.md +243 -0
  2. package/dist/cjs/index.cjs +12349 -8683
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/components/autocomplete/Autocomplete.js.map +1 -1
  5. package/dist/components/autocomplete/Autocomplete.vue_vue_type_script_setup_true_lang.js +4 -1
  6. package/dist/components/autocomplete/Autocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  7. package/dist/components/combo-box/ComboBox.js.map +1 -1
  8. package/dist/components/combo-box/ComboBox.vue_vue_type_script_setup_true_lang.js +1 -1
  9. package/dist/components/combo-box/ComboBox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  10. package/dist/components/context-menu/ContextMenu.js +7 -0
  11. package/dist/components/context-menu/ContextMenu.js.map +1 -0
  12. package/dist/components/context-menu/ContextMenu.vue_vue_type_script_setup_true_lang.js +38 -0
  13. package/dist/components/context-menu/ContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
  14. package/dist/components/context-menu/ContextMenuCheckboxItem.js +7 -0
  15. package/dist/components/context-menu/ContextMenuCheckboxItem.js.map +1 -0
  16. package/dist/components/context-menu/ContextMenuCheckboxItem.vue_vue_type_script_setup_true_lang.js +89 -0
  17. package/dist/components/context-menu/ContextMenuCheckboxItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  18. package/dist/components/context-menu/ContextMenuContent.js +7 -0
  19. package/dist/components/context-menu/ContextMenuContent.js.map +1 -0
  20. package/dist/components/context-menu/ContextMenuContent.vue_vue_type_script_setup_true_lang.js +135 -0
  21. package/dist/components/context-menu/ContextMenuContent.vue_vue_type_script_setup_true_lang.js.map +1 -0
  22. package/dist/components/context-menu/ContextMenuItem.js +7 -0
  23. package/dist/components/context-menu/ContextMenuItem.js.map +1 -0
  24. package/dist/components/context-menu/ContextMenuItem.vue_vue_type_script_setup_true_lang.js +72 -0
  25. package/dist/components/context-menu/ContextMenuItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  26. package/dist/components/context-menu/ContextMenuRadioGroup.js +7 -0
  27. package/dist/components/context-menu/ContextMenuRadioGroup.js.map +1 -0
  28. package/dist/components/context-menu/ContextMenuRadioGroup.vue_vue_type_script_setup_true_lang.js +40 -0
  29. package/dist/components/context-menu/ContextMenuRadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  30. package/dist/components/context-menu/ContextMenuRadioItem.js +7 -0
  31. package/dist/components/context-menu/ContextMenuRadioItem.js.map +1 -0
  32. package/dist/components/context-menu/ContextMenuRadioItem.vue_vue_type_script_setup_true_lang.js +75 -0
  33. package/dist/components/context-menu/ContextMenuRadioItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  34. package/dist/components/context-menu/ContextMenuSection.js +7 -0
  35. package/dist/components/context-menu/ContextMenuSection.js.map +1 -0
  36. package/dist/components/context-menu/ContextMenuSection.vue_vue_type_script_setup_true_lang.js +55 -0
  37. package/dist/components/context-menu/ContextMenuSection.vue_vue_type_script_setup_true_lang.js.map +1 -0
  38. package/dist/components/context-menu/ContextMenuSub.js +7 -0
  39. package/dist/components/context-menu/ContextMenuSub.js.map +1 -0
  40. package/dist/components/context-menu/ContextMenuSub.vue_vue_type_script_setup_true_lang.js +35 -0
  41. package/dist/components/context-menu/ContextMenuSub.vue_vue_type_script_setup_true_lang.js.map +1 -0
  42. package/dist/components/context-menu/ContextMenuSubContent.js +7 -0
  43. package/dist/components/context-menu/ContextMenuSubContent.js.map +1 -0
  44. package/dist/components/context-menu/ContextMenuSubContent.vue_vue_type_script_setup_true_lang.js +155 -0
  45. package/dist/components/context-menu/ContextMenuSubContent.vue_vue_type_script_setup_true_lang.js.map +1 -0
  46. package/dist/components/context-menu/ContextMenuSubTrigger.js +7 -0
  47. package/dist/components/context-menu/ContextMenuSubTrigger.js.map +1 -0
  48. package/dist/components/context-menu/ContextMenuSubTrigger.vue_vue_type_script_setup_true_lang.js +64 -0
  49. package/dist/components/context-menu/ContextMenuSubTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -0
  50. package/dist/components/context-menu/ContextMenuTrigger.js +7 -0
  51. package/dist/components/context-menu/ContextMenuTrigger.js.map +1 -0
  52. package/dist/components/context-menu/ContextMenuTrigger.vue_vue_type_script_setup_true_lang.js +38 -0
  53. package/dist/components/context-menu/ContextMenuTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -0
  54. package/dist/components/editable/Editable.js +7 -0
  55. package/dist/components/editable/Editable.js.map +1 -0
  56. package/dist/components/editable/Editable.vue_vue_type_script_setup_true_lang.js +106 -0
  57. package/dist/components/editable/Editable.vue_vue_type_script_setup_true_lang.js.map +1 -0
  58. package/dist/components/editable/EditableArea.js +7 -0
  59. package/dist/components/editable/EditableArea.js.map +1 -0
  60. package/dist/components/editable/EditableArea.vue_vue_type_script_setup_true_lang.js +41 -0
  61. package/dist/components/editable/EditableArea.vue_vue_type_script_setup_true_lang.js.map +1 -0
  62. package/dist/components/editable/EditableCancelTrigger.js +7 -0
  63. package/dist/components/editable/EditableCancelTrigger.js.map +1 -0
  64. package/dist/components/editable/EditableCancelTrigger.vue_vue_type_script_setup_true_lang.js +63 -0
  65. package/dist/components/editable/EditableCancelTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -0
  66. package/dist/components/editable/EditableEditTrigger.js +7 -0
  67. package/dist/components/editable/EditableEditTrigger.js.map +1 -0
  68. package/dist/components/editable/EditableEditTrigger.vue_vue_type_script_setup_true_lang.js +53 -0
  69. package/dist/components/editable/EditableEditTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -0
  70. package/dist/components/editable/EditableInput.js +7 -0
  71. package/dist/components/editable/EditableInput.js.map +1 -0
  72. package/dist/components/editable/EditableInput.vue_vue_type_script_setup_true_lang.js +38 -0
  73. package/dist/components/editable/EditableInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
  74. package/dist/components/editable/EditablePreview.js +7 -0
  75. package/dist/components/editable/EditablePreview.js.map +1 -0
  76. package/dist/components/editable/EditablePreview.vue_vue_type_script_setup_true_lang.js +38 -0
  77. package/dist/components/editable/EditablePreview.vue_vue_type_script_setup_true_lang.js.map +1 -0
  78. package/dist/components/editable/EditableSubmitTrigger.js +7 -0
  79. package/dist/components/editable/EditableSubmitTrigger.js.map +1 -0
  80. package/dist/components/editable/EditableSubmitTrigger.vue_vue_type_script_setup_true_lang.js +53 -0
  81. package/dist/components/editable/EditableSubmitTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -0
  82. package/dist/components/form/Form.js.map +1 -1
  83. package/dist/components/form/Form.vue_vue_type_script_setup_true_lang.js +32 -156
  84. package/dist/components/form/Form.vue_vue_type_script_setup_true_lang.js.map +1 -1
  85. package/dist/components/form/FormField.js.map +1 -1
  86. package/dist/components/form/FormField.vue_vue_type_script_setup_true_lang.js +44 -23
  87. package/dist/components/form/FormField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  88. package/dist/components/form/form.context.js.map +1 -1
  89. package/dist/components/form/form.state.js +166 -0
  90. package/dist/components/form/form.state.js.map +1 -0
  91. package/dist/components/form/useField.js +112 -0
  92. package/dist/components/form/useField.js.map +1 -0
  93. package/dist/components/form/useForm.js +17 -0
  94. package/dist/components/form/useForm.js.map +1 -0
  95. package/dist/components/hover-card/HoverCard.js +7 -0
  96. package/dist/components/hover-card/HoverCard.js.map +1 -0
  97. package/dist/components/hover-card/HoverCard.vue_vue_type_script_lang.js +52 -0
  98. package/dist/components/hover-card/HoverCard.vue_vue_type_script_lang.js.map +1 -0
  99. package/dist/components/hover-card/HoverCardArrow.js +7 -0
  100. package/dist/components/hover-card/HoverCardArrow.js.map +1 -0
  101. package/dist/components/hover-card/HoverCardArrow.vue_vue_type_script_setup_true_lang.js +35 -0
  102. package/dist/components/hover-card/HoverCardArrow.vue_vue_type_script_setup_true_lang.js.map +1 -0
  103. package/dist/components/hover-card/HoverCardContent.js +7 -0
  104. package/dist/components/hover-card/HoverCardContent.js.map +1 -0
  105. package/dist/components/hover-card/HoverCardContent.vue_vue_type_script_setup_true_lang.js +104 -0
  106. package/dist/components/hover-card/HoverCardContent.vue_vue_type_script_setup_true_lang.js.map +1 -0
  107. package/dist/components/hover-card/HoverCardTrigger.js +7 -0
  108. package/dist/components/hover-card/HoverCardTrigger.js.map +1 -0
  109. package/dist/components/hover-card/HoverCardTrigger.vue_vue_type_script_setup_true_lang.js +26 -0
  110. package/dist/components/hover-card/HoverCardTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -0
  111. package/dist/components/menubar/Menubar.js +7 -0
  112. package/dist/components/menubar/Menubar.js.map +1 -0
  113. package/dist/components/menubar/Menubar.vue_vue_type_script_setup_true_lang.js +58 -0
  114. package/dist/components/menubar/Menubar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  115. package/dist/components/menubar/MenubarCheckboxItem.js +7 -0
  116. package/dist/components/menubar/MenubarCheckboxItem.js.map +1 -0
  117. package/dist/components/menubar/MenubarCheckboxItem.vue_vue_type_script_setup_true_lang.js +89 -0
  118. package/dist/components/menubar/MenubarCheckboxItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  119. package/dist/components/menubar/MenubarContent.js +7 -0
  120. package/dist/components/menubar/MenubarContent.js.map +1 -0
  121. package/dist/components/menubar/MenubarContent.vue_vue_type_script_setup_true_lang.js +162 -0
  122. package/dist/components/menubar/MenubarContent.vue_vue_type_script_setup_true_lang.js.map +1 -0
  123. package/dist/components/menubar/MenubarItem.js +7 -0
  124. package/dist/components/menubar/MenubarItem.js.map +1 -0
  125. package/dist/components/menubar/MenubarItem.vue_vue_type_script_setup_true_lang.js +72 -0
  126. package/dist/components/menubar/MenubarItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  127. package/dist/components/menubar/MenubarMenu.js +7 -0
  128. package/dist/components/menubar/MenubarMenu.js.map +1 -0
  129. package/dist/components/menubar/MenubarMenu.vue_vue_type_script_setup_true_lang.js +20 -0
  130. package/dist/components/menubar/MenubarMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
  131. package/dist/components/menubar/MenubarRadioGroup.js +7 -0
  132. package/dist/components/menubar/MenubarRadioGroup.js.map +1 -0
  133. package/dist/components/menubar/MenubarRadioGroup.vue_vue_type_script_setup_true_lang.js +40 -0
  134. package/dist/components/menubar/MenubarRadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  135. package/dist/components/menubar/MenubarRadioItem.js +7 -0
  136. package/dist/components/menubar/MenubarRadioItem.js.map +1 -0
  137. package/dist/components/menubar/MenubarRadioItem.vue_vue_type_script_setup_true_lang.js +75 -0
  138. package/dist/components/menubar/MenubarRadioItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  139. package/dist/components/menubar/MenubarSection.js +7 -0
  140. package/dist/components/menubar/MenubarSection.js.map +1 -0
  141. package/dist/components/menubar/MenubarSection.vue_vue_type_script_setup_true_lang.js +55 -0
  142. package/dist/components/menubar/MenubarSection.vue_vue_type_script_setup_true_lang.js.map +1 -0
  143. package/dist/components/menubar/MenubarSub.js +7 -0
  144. package/dist/components/menubar/MenubarSub.js.map +1 -0
  145. package/dist/components/menubar/MenubarSub.vue_vue_type_script_setup_true_lang.js +35 -0
  146. package/dist/components/menubar/MenubarSub.vue_vue_type_script_setup_true_lang.js.map +1 -0
  147. package/dist/components/menubar/MenubarSubContent.js +7 -0
  148. package/dist/components/menubar/MenubarSubContent.js.map +1 -0
  149. package/dist/components/menubar/MenubarSubContent.vue_vue_type_script_setup_true_lang.js +155 -0
  150. package/dist/components/menubar/MenubarSubContent.vue_vue_type_script_setup_true_lang.js.map +1 -0
  151. package/dist/components/menubar/MenubarSubTrigger.js +7 -0
  152. package/dist/components/menubar/MenubarSubTrigger.js.map +1 -0
  153. package/dist/components/menubar/MenubarSubTrigger.vue_vue_type_script_setup_true_lang.js +64 -0
  154. package/dist/components/menubar/MenubarSubTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -0
  155. package/dist/components/menubar/MenubarTrigger.js +7 -0
  156. package/dist/components/menubar/MenubarTrigger.js.map +1 -0
  157. package/dist/components/menubar/MenubarTrigger.vue_vue_type_script_setup_true_lang.js +53 -0
  158. package/dist/components/menubar/MenubarTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -0
  159. package/dist/components/month-picker/MonthPicker.js +7 -0
  160. package/dist/components/month-picker/MonthPicker.js.map +1 -0
  161. package/dist/components/month-picker/MonthPicker.vue_vue_type_script_setup_true_lang.js +185 -0
  162. package/dist/components/month-picker/MonthPicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  163. package/dist/components/month-range-picker/MonthRangePicker.js +7 -0
  164. package/dist/components/month-range-picker/MonthRangePicker.js.map +1 -0
  165. package/dist/components/month-range-picker/MonthRangePicker.vue_vue_type_script_setup_true_lang.js +196 -0
  166. package/dist/components/month-range-picker/MonthRangePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  167. package/dist/components/navigation-menu/NavigationMenu.js +7 -0
  168. package/dist/components/navigation-menu/NavigationMenu.js.map +1 -0
  169. package/dist/components/navigation-menu/NavigationMenu.vue_vue_type_script_setup_true_lang.js +85 -0
  170. package/dist/components/navigation-menu/NavigationMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
  171. package/dist/components/navigation-menu/NavigationMenuContent.js +7 -0
  172. package/dist/components/navigation-menu/NavigationMenuContent.js.map +1 -0
  173. package/dist/components/navigation-menu/NavigationMenuContent.vue_vue_type_script_setup_true_lang.js +70 -0
  174. package/dist/components/navigation-menu/NavigationMenuContent.vue_vue_type_script_setup_true_lang.js.map +1 -0
  175. package/dist/components/navigation-menu/NavigationMenuIndicator.js +7 -0
  176. package/dist/components/navigation-menu/NavigationMenuIndicator.js.map +1 -0
  177. package/dist/components/navigation-menu/NavigationMenuIndicator.vue_vue_type_script_setup_true_lang.js +53 -0
  178. package/dist/components/navigation-menu/NavigationMenuIndicator.vue_vue_type_script_setup_true_lang.js.map +1 -0
  179. package/dist/components/navigation-menu/NavigationMenuItem.js +7 -0
  180. package/dist/components/navigation-menu/NavigationMenuItem.js.map +1 -0
  181. package/dist/components/navigation-menu/NavigationMenuItem.vue_vue_type_script_setup_true_lang.js +20 -0
  182. package/dist/components/navigation-menu/NavigationMenuItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  183. package/dist/components/navigation-menu/NavigationMenuLink.js +7 -0
  184. package/dist/components/navigation-menu/NavigationMenuLink.js.map +1 -0
  185. package/dist/components/navigation-menu/NavigationMenuLink.vue_vue_type_script_setup_true_lang.js +70 -0
  186. package/dist/components/navigation-menu/NavigationMenuLink.vue_vue_type_script_setup_true_lang.js.map +1 -0
  187. package/dist/components/navigation-menu/NavigationMenuList.js +7 -0
  188. package/dist/components/navigation-menu/NavigationMenuList.js.map +1 -0
  189. package/dist/components/navigation-menu/NavigationMenuList.vue_vue_type_script_setup_true_lang.js +47 -0
  190. package/dist/components/navigation-menu/NavigationMenuList.vue_vue_type_script_setup_true_lang.js.map +1 -0
  191. package/dist/components/navigation-menu/NavigationMenuSub.js +7 -0
  192. package/dist/components/navigation-menu/NavigationMenuSub.js.map +1 -0
  193. package/dist/components/navigation-menu/NavigationMenuSub.vue_vue_type_script_setup_true_lang.js +37 -0
  194. package/dist/components/navigation-menu/NavigationMenuSub.vue_vue_type_script_setup_true_lang.js.map +1 -0
  195. package/dist/components/navigation-menu/NavigationMenuTrigger.js +7 -0
  196. package/dist/components/navigation-menu/NavigationMenuTrigger.js.map +1 -0
  197. package/dist/components/navigation-menu/NavigationMenuTrigger.vue_vue_type_script_setup_true_lang.js +66 -0
  198. package/dist/components/navigation-menu/NavigationMenuTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -0
  199. package/dist/components/navigation-menu/NavigationMenuViewport.js +7 -0
  200. package/dist/components/navigation-menu/NavigationMenuViewport.js.map +1 -0
  201. package/dist/components/navigation-menu/NavigationMenuViewport.vue_vue_type_script_setup_true_lang.js +53 -0
  202. package/dist/components/navigation-menu/NavigationMenuViewport.vue_vue_type_script_setup_true_lang.js.map +1 -0
  203. package/dist/components/select/Select.js.map +1 -1
  204. package/dist/components/select/Select.vue_vue_type_script_setup_true_lang.js +1 -1
  205. package/dist/components/select/Select.vue_vue_type_script_setup_true_lang.js.map +1 -1
  206. package/dist/components/time-range-field/TimeRangeField.js +7 -0
  207. package/dist/components/time-range-field/TimeRangeField.js.map +1 -0
  208. package/dist/components/time-range-field/TimeRangeField.vue_vue_type_script_setup_true_lang.js +364 -0
  209. package/dist/components/time-range-field/TimeRangeField.vue_vue_type_script_setup_true_lang.js.map +1 -0
  210. package/dist/components/year-range-picker/YearRangePicker.js +7 -0
  211. package/dist/components/year-range-picker/YearRangePicker.js.map +1 -0
  212. package/dist/components/year-range-picker/YearRangePicker.vue_vue_type_script_setup_true_lang.js +199 -0
  213. package/dist/components/year-range-picker/YearRangePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  214. package/dist/index.d.ts +5393 -2896
  215. package/dist/index.js +50 -1
  216. package/dist/packages/styles/dist/components/hover-card/hover-card.styles.js +10 -0
  217. package/dist/packages/styles/dist/components/hover-card/hover-card.styles.js.map +1 -0
  218. package/package.json +4 -4
@@ -10,7 +10,8 @@ var FormField_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defi
10
10
  defaultValue: {},
11
11
  rules: {},
12
12
  validate: { type: Function },
13
- validationMode: {}
13
+ validationMode: {},
14
+ deps: {}
14
15
  }, {
15
16
  "modelValue": { default: void 0 },
16
17
  "modelModifiers": {}
@@ -20,9 +21,13 @@ var FormField_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defi
20
21
  const props = __props;
21
22
  const modelValue = useModel(__props, "modelValue");
22
23
  const ctx = useFormInject();
24
+ const resolvedDefault = computed(() => {
25
+ if (props.defaultValue !== void 0) return props.defaultValue;
26
+ return ctx?.defaultValues[props.name];
27
+ });
23
28
  const localError = ref(void 0);
24
29
  const touched = ref(false);
25
- const dirty = ref(props.defaultValue !== void 0 && modelValue.value !== props.defaultValue);
30
+ const dirty = ref(resolvedDefault.value !== void 0 && modelValue.value !== resolvedDefault.value);
26
31
  const fieldError = computed(() => ctx ? ctx.errors.value[props.name] : localError.value);
27
32
  const hasBeenInvalid = ref(false);
28
33
  watch(fieldError, (error) => {
@@ -32,20 +37,51 @@ var FormField_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defi
32
37
  const isDisabled = computed(() => ctx?.isDisabled.value ?? false);
33
38
  const validationMode = computed(() => props.validationMode ?? ctx?.validationMode.value ?? "on-submit");
34
39
  watch(modelValue, (val) => {
35
- dirty.value = val !== props.defaultValue;
40
+ dirty.value = val !== resolvedDefault.value;
36
41
  });
42
+ async function triggerValidation(val) {
43
+ const context = ctx ? { values: ctx.getValues() } : void 0;
44
+ const error = await runValidation(val, props.rules, props.validate, context);
45
+ if (ctx) {
46
+ const next = { ...ctx.errors.value };
47
+ if (error) next[props.name] = error;
48
+ else delete next[props.name];
49
+ ctx.errors.value = next;
50
+ } else localError.value = error;
51
+ }
52
+ async function handleUpdate(val) {
53
+ modelValue.value = val;
54
+ if (validationMode.value === "on-change" || hasBeenInvalid.value) await triggerValidation(val);
55
+ }
56
+ async function handleBlur() {
57
+ touched.value = true;
58
+ if (validationMode.value === "on-blur") await triggerValidation(modelValue.value);
59
+ }
60
+ const depStoppers = [];
61
+ function setupDepWatchers(deps) {
62
+ for (const stop of depStoppers) stop();
63
+ depStoppers.length = 0;
64
+ if (!ctx || !deps?.length) return;
65
+ for (const dep of deps) {
66
+ const depRef = ctx.getFieldRef(dep);
67
+ if (!depRef) continue;
68
+ depStoppers.push(watch(depRef, () => void triggerValidation(modelValue.value)));
69
+ }
70
+ }
37
71
  function resetField() {
38
- modelValue.value = props.defaultValue;
72
+ modelValue.value = resolvedDefault.value;
39
73
  localError.value = void 0;
40
74
  touched.value = false;
41
75
  dirty.value = false;
42
76
  hasBeenInvalid.value = false;
43
77
  }
44
78
  onMounted(() => {
79
+ if (modelValue.value === void 0 && resolvedDefault.value !== void 0) modelValue.value = resolvedDefault.value;
45
80
  ctx?.registerField({
46
81
  name: props.name,
82
+ valueRef: modelValue,
47
83
  getValue: () => modelValue.value,
48
- getDefaultValue: () => props.defaultValue,
84
+ getDefaultValue: () => resolvedDefault.value,
49
85
  setValue: (val) => {
50
86
  modelValue.value = val;
51
87
  },
@@ -55,28 +91,13 @@ var FormField_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defi
55
91
  rules: props.rules,
56
92
  validate: props.validate
57
93
  });
94
+ setupDepWatchers(props.deps);
58
95
  });
96
+ watch(() => props.deps?.join("\0") ?? "", () => setupDepWatchers(props.deps));
59
97
  onUnmounted(() => {
98
+ for (const stop of depStoppers) stop();
60
99
  ctx?.unregisterField(props.name);
61
100
  });
62
- async function triggerValidation(val) {
63
- const context = ctx ? { values: ctx.getValues() } : void 0;
64
- const error = await runValidation(val, props.rules, props.validate, context);
65
- if (ctx) {
66
- const next = { ...ctx.errors.value };
67
- if (error) next[props.name] = error;
68
- else delete next[props.name];
69
- ctx.errors.value = next;
70
- } else localError.value = error;
71
- }
72
- async function handleUpdate(val) {
73
- modelValue.value = val;
74
- if (validationMode.value === "on-change" || hasBeenInvalid.value) await triggerValidation(val);
75
- }
76
- async function handleBlur() {
77
- touched.value = true;
78
- if (validationMode.value === "on-blur") await triggerValidation(modelValue.value);
79
- }
80
101
  const fieldProps = computed(() => ({
81
102
  name: props.name,
82
103
  modelValue: modelValue.value,
@@ -1 +1 @@
1
- {"version":3,"file":"FormField.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/form/FormField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, onUnmounted, ref, watch } from 'vue'\nimport { useFormInject } from './form.context'\nimport { runValidation } from './validation'\nimport type { FieldRules, CustomValidator } from './validation'\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = defineProps<{\n name: string\n defaultValue?: unknown\n rules?: FieldRules\n validate?: CustomValidator\n /** Override validation mode for this field. */\n validationMode?: 'on-submit' | 'on-blur' | 'on-change'\n}>()\n\nconst modelValue = defineModel<unknown>({ default: undefined })\n\nconst ctx = useFormInject()\n\n// ── Field state ──────────────────────────────────────────────────────────────\n\nconst localError = ref<string | undefined>(undefined)\nconst touched = ref(false)\nconst dirty = ref(props.defaultValue !== undefined && modelValue.value !== props.defaultValue)\n\nconst fieldError = computed<string | undefined>(() =>\n ctx ? ctx.errors.value[props.name] : localError.value,\n)\n\nconst hasBeenInvalid = ref(false)\nwatch(fieldError, (error) => { if (error) hasBeenInvalid.value = true })\n\nconst isInvalid = computed(() => !!fieldError.value)\nconst isDisabled = computed(() => ctx?.isDisabled.value ?? false)\nconst validationMode = computed(() => props.validationMode ?? ctx?.validationMode.value ?? 'on-submit')\n\n// ── Dirty tracking ───────────────────────────────────────────────────────────\n\nwatch(modelValue, (val) => {\n dirty.value = val !== props.defaultValue\n})\n\n// ── Registration ─────────────────────────────────────────────────────────────\n\nfunction resetField(): void {\n modelValue.value = props.defaultValue\n localError.value = undefined\n touched.value = false\n dirty.value = false\n hasBeenInvalid.value = false\n}\n\nonMounted(() => {\n ctx?.registerField({\n name: props.name,\n getValue: () => modelValue.value,\n getDefaultValue: () => props.defaultValue,\n setValue: (val: unknown) => { modelValue.value = val },\n reset: resetField,\n touched,\n dirty,\n rules: props.rules,\n validate: props.validate,\n })\n})\n\nonUnmounted(() => {\n ctx?.unregisterField(props.name)\n})\n\n// ── Validation ───────────────────────────────────────────────────────────────\n\nasync function triggerValidation(val: unknown): Promise<void> {\n const context = ctx ? { values: ctx.getValues() } : undefined\n const error = await runValidation(val, props.rules, props.validate, context)\n\n if (ctx) {\n const next = { ...ctx.errors.value }\n if (error) {\n next[props.name] = error\n } else {\n delete next[props.name]\n }\n ctx.errors.value = next\n } else {\n localError.value = error\n }\n}\n\nasync function handleUpdate(val: unknown): Promise<void> {\n modelValue.value = val\n if (validationMode.value === 'on-change' || hasBeenInvalid.value) {\n await triggerValidation(val)\n }\n}\n\nasync function handleBlur(): Promise<void> {\n touched.value = true\n if (validationMode.value === 'on-blur') {\n await triggerValidation(modelValue.value)\n }\n}\n\n// ── Slot bindings ─────────────────────────────────────────────────────────────\n\nconst fieldProps = computed(() => ({\n name: props.name,\n modelValue: modelValue.value,\n 'onUpdate:modelValue': handleUpdate,\n isInvalid: isInvalid.value,\n errorMessage: fieldError.value,\n isDisabled: isDisabled.value,\n onBlur: handleBlur,\n}))\n</script>\n\n<template>\n <slot\n :field-props=\"fieldProps\"\n :touched=\"touched\"\n :dirty=\"dirty\"\n :error=\"fieldError\"\n :is-invalid=\"isInvalid\"\n />\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;EAQA,MAAM,QAAQ;EASd,MAAM,aAAa,SAAoB,SAAA,aAAuB;EAE9D,MAAM,MAAM,eAAc;EAI1B,MAAM,aAAa,IAAwB,KAAA,EAAS;EACpD,MAAM,UAAU,IAAI,MAAK;EACzB,MAAM,QAAQ,IAAI,MAAM,iBAAiB,KAAA,KAAa,WAAW,UAAU,MAAM,aAAY;EAE7F,MAAM,aAAa,eACjB,MAAM,IAAI,OAAO,MAAM,MAAM,QAAQ,WAAW,MAClD;EAEA,MAAM,iBAAiB,IAAI,MAAK;AAChC,QAAM,aAAa,UAAU;AAAE,OAAI,MAAO,gBAAe,QAAQ;IAAM;EAEvE,MAAM,YAAY,eAAe,CAAC,CAAC,WAAW,MAAK;EACnD,MAAM,aAAa,eAAe,KAAK,WAAW,SAAS,MAAK;EAChE,MAAM,iBAAiB,eAAe,MAAM,kBAAkB,KAAK,eAAe,SAAS,YAAW;AAItG,QAAM,aAAa,QAAQ;AACzB,SAAM,QAAQ,QAAQ,MAAM;IAC7B;EAID,SAAS,aAAmB;AAC1B,cAAW,QAAQ,MAAM;AACzB,cAAW,QAAQ,KAAA;AACnB,WAAQ,QAAQ;AAChB,SAAM,QAAQ;AACd,kBAAe,QAAQ;;AAGzB,kBAAgB;AACd,QAAK,cAAc;IACjB,MAAM,MAAM;IACZ,gBAAgB,WAAW;IAC3B,uBAAuB,MAAM;IAC7B,WAAW,QAAiB;AAAE,gBAAW,QAAQ;;IACjD,OAAO;IACP;IACA;IACA,OAAO,MAAM;IACb,UAAU,MAAM;IACjB,CAAA;IACF;AAED,oBAAkB;AAChB,QAAK,gBAAgB,MAAM,KAAI;IAChC;EAID,eAAe,kBAAkB,KAA6B;GAC5D,MAAM,UAAU,MAAM,EAAE,QAAQ,IAAI,WAAW,EAAE,GAAG,KAAA;GACpD,MAAM,QAAQ,MAAM,cAAc,KAAK,MAAM,OAAO,MAAM,UAAU,QAAO;AAE3E,OAAI,KAAK;IACP,MAAM,OAAO,EAAE,GAAG,IAAI,OAAO,OAAM;AACnC,QAAI,MACF,MAAK,MAAM,QAAQ;QAEnB,QAAO,KAAK,MAAM;AAEpB,QAAI,OAAO,QAAQ;SAEnB,YAAW,QAAQ;;EAIvB,eAAe,aAAa,KAA6B;AACvD,cAAW,QAAQ;AACnB,OAAI,eAAe,UAAU,eAAe,eAAe,MACzD,OAAM,kBAAkB,IAAG;;EAI/B,eAAe,aAA4B;AACzC,WAAQ,QAAQ;AAChB,OAAI,eAAe,UAAU,UAC3B,OAAM,kBAAkB,WAAW,MAAK;;EAM5C,MAAM,aAAa,gBAAgB;GACjC,MAAM,MAAM;GACZ,YAAY,WAAW;GACvB,uBAAuB;GACvB,WAAW,UAAU;GACrB,cAAc,WAAW;GACzB,YAAY,WAAW;GACvB,QAAQ;GACT,EAAC;;UAIA,WAME,KAAA,QAAA,WAAA;IALC,YAAa,WAAA;IACb,SAAS,QAAA;IACT,OAAO,MAAA;IACP,OAAO,WAAA;IACP,WAAY,UAAA"}
1
+ {"version":3,"file":"FormField.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/form/FormField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, onUnmounted, ref, watch } from 'vue'\nimport { useFormInject } from './form.context'\nimport { runValidation } from './validation'\nimport type { FieldRules, CustomValidator } from './validation'\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = defineProps<{\n name: string\n defaultValue?: unknown\n rules?: FieldRules\n validate?: CustomValidator\n /** Override validation mode for this field. */\n validationMode?: 'on-submit' | 'on-blur' | 'on-change'\n /** Field names whose changes trigger re-validation of this field. */\n deps?: string[]\n}>()\n\nconst modelValue = defineModel<unknown>({ default: undefined })\n\nconst ctx = useFormInject()\n\n// ── Default value resolution ─────────────────────────────────────────────────\n// Priority: field-level defaultValue prop > form-level defaultValues[name] > undefined\n\nconst resolvedDefault = computed(() => {\n if (props.defaultValue !== undefined) return props.defaultValue\n return ctx?.defaultValues[props.name]\n})\n\n// ── Field state ──────────────────────────────────────────────────────────────\n\nconst localError = ref<string | undefined>(undefined)\nconst touched = ref(false)\nconst dirty = ref(\n resolvedDefault.value !== undefined && modelValue.value !== resolvedDefault.value,\n)\n\nconst fieldError = computed<string | undefined>(() =>\n ctx ? ctx.errors.value[props.name] : localError.value,\n)\n\nconst hasBeenInvalid = ref(false)\nwatch(fieldError, (error) => { if (error) hasBeenInvalid.value = true })\n\nconst isInvalid = computed(() => !!fieldError.value)\nconst isDisabled = computed(() => ctx?.isDisabled.value ?? false)\nconst validationMode = computed(() => props.validationMode ?? ctx?.validationMode.value ?? 'on-submit')\n\n// ── Dirty tracking ───────────────────────────────────────────────────────────\n\nwatch(modelValue, (val) => {\n dirty.value = val !== resolvedDefault.value\n})\n\n// ── Validation ───────────────────────────────────────────────────────────────\n\nasync function triggerValidation(val: unknown): Promise<void> {\n const context = ctx ? { values: ctx.getValues() } : undefined\n const error = await runValidation(val, props.rules, props.validate, context)\n\n if (ctx) {\n const next = { ...ctx.errors.value }\n if (error) {\n next[props.name] = error\n } else {\n delete next[props.name]\n }\n ctx.errors.value = next\n } else {\n localError.value = error\n }\n}\n\nasync function handleUpdate(val: unknown): Promise<void> {\n modelValue.value = val\n if (validationMode.value === 'on-change' || hasBeenInvalid.value) {\n await triggerValidation(val)\n }\n}\n\nasync function handleBlur(): Promise<void> {\n touched.value = true\n if (validationMode.value === 'on-blur') {\n await triggerValidation(modelValue.value)\n }\n}\n\n// ── Deps watching ─────────────────────────────────────────────────────────────\n\nconst depStoppers: (() => void)[] = []\n\nfunction setupDepWatchers(deps: string[] | undefined): void {\n for (const stop of depStoppers) stop()\n depStoppers.length = 0\n if (!ctx || !deps?.length) return\n for (const dep of deps) {\n const depRef = ctx.getFieldRef(dep)\n if (!depRef) continue\n depStoppers.push(watch(depRef, () => void triggerValidation(modelValue.value)))\n }\n}\n\n// ── Registration ─────────────────────────────────────────────────────────────\n\nfunction resetField(): void {\n modelValue.value = resolvedDefault.value\n localError.value = undefined\n touched.value = false\n dirty.value = false\n hasBeenInvalid.value = false\n}\n\nonMounted(() => {\n // Initialize to resolved default when no value was passed by the parent\n if (modelValue.value === undefined && resolvedDefault.value !== undefined) {\n modelValue.value = resolvedDefault.value\n }\n\n ctx?.registerField({\n name: props.name,\n valueRef: modelValue,\n getValue: () => modelValue.value,\n getDefaultValue: () => resolvedDefault.value,\n setValue: (val: unknown) => { modelValue.value = val },\n reset: resetField,\n touched,\n dirty,\n rules: props.rules,\n validate: props.validate,\n })\n\n setupDepWatchers(props.deps)\n})\n\n// Watch a stable string key so the watcher only tears down/rebuilds when the\n// dep list contents actually change — not on every re-render where the parent\n// passes a new array literal with the same elements (Object.is differs by ref).\nwatch(\n () => props.deps?.join('\\0') ?? '',\n () => setupDepWatchers(props.deps),\n)\n\nonUnmounted(() => {\n for (const stop of depStoppers) stop()\n ctx?.unregisterField(props.name)\n})\n\n// ── Slot bindings ─────────────────────────────────────────────────────────────\n\nconst fieldProps = computed(() => ({\n name: props.name,\n modelValue: modelValue.value,\n 'onUpdate:modelValue': handleUpdate,\n isInvalid: isInvalid.value,\n errorMessage: fieldError.value,\n isDisabled: isDisabled.value,\n onBlur: handleBlur,\n}))\n</script>\n\n<template>\n <slot\n :field-props=\"fieldProps\"\n :touched=\"touched\"\n :dirty=\"dirty\"\n :error=\"fieldError\"\n :is-invalid=\"isInvalid\"\n />\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"form.context.js","names":[],"sources":["../../../src/components/form/form.context.ts"],"sourcesContent":["import { inject, type Ref, type ComputedRef } from 'vue'\nimport { createContext } from '../../utils/context'\nimport type { FieldRules, CustomValidator } from './validation'\n\nexport type { FieldRules, CustomValidator }\n\nexport type ValidationMode = 'on-submit' | 'on-blur' | 'on-change'\n\nexport interface FieldRegistration {\n name: string\n getValue: () => unknown\n getDefaultValue: () => unknown\n setValue: (value: unknown) => void\n reset: () => void\n touched: Ref<boolean>\n dirty: Ref<boolean>\n rules?: FieldRules\n validate?: CustomValidator\n}\n\nexport interface FormContext {\n errors: Ref<Record<string, string>>\n isSubmitting: Ref<boolean>\n isSubmitted: Ref<boolean>\n submitCount: Ref<number>\n isDisabled: ComputedRef<boolean>\n isValid: ComputedRef<boolean>\n isDirty: ComputedRef<boolean>\n isTouched: ComputedRef<boolean>\n validationMode: ComputedRef<ValidationMode>\n registerField(reg: FieldRegistration): void\n unregisterField(name: string): void\n triggerFieldValidation(name: string): Promise<void>\n setErrors(newErrors: Record<string, string>): void\n setError(name: string, message: string): void\n clearErrors(name?: string): void\n getValues(): Record<string, unknown>\n setValue(name: string, value: unknown): void\n trigger(name?: string): Promise<boolean>\n reset(): void\n}\n\nexport const {\n useProvide: useFormProvide,\n useInject: _useFormInjectStrict,\n key: formContextKey,\n} = createContext<FormContext>('Form')\n\n/**\n * Inject Form context. Returns null when called outside a <Form> — callers\n * handle standalone mode themselves.\n */\nexport function useFormInject(): FormContext | null {\n return inject(formContextKey, null)\n}\n"],"mappings":";;;AA0CA,IAAa,EACX,YAAY,gBACZ,WAAW,sBACX,KAAK,mBACH,cAA2B,OAAO;;;;;AAMtC,SAAgB,gBAAoC;AAClD,QAAO,OAAO,gBAAgB,KAAK"}
1
+ {"version":3,"file":"form.context.js","names":[],"sources":["../../../src/components/form/form.context.ts"],"sourcesContent":["import { inject, type Ref, type ComputedRef } from 'vue'\nimport { createContext } from '../../utils/context'\nimport type { FieldRules, CustomValidator } from './validation'\n\nexport type { FieldRules, CustomValidator }\n\nexport type ValidationMode = 'on-submit' | 'on-blur' | 'on-change'\n\nexport interface FieldRegistration {\n name: string\n valueRef: Ref<unknown> // reactive ref — powers values computed and deps watching\n getValue: () => unknown\n getDefaultValue: () => unknown\n setValue: (value: unknown) => void\n reset: () => void\n touched: Ref<boolean>\n dirty: Ref<boolean>\n rules?: FieldRules\n validate?: CustomValidator\n}\n\nexport interface FormOptions {\n defaultValues?: Record<string, unknown>\n validationMode?: ValidationMode\n isDisabled?: boolean\n}\n\nexport interface FormContext {\n errors: Ref<Record<string, string>>\n isSubmitting: Ref<boolean>\n isSubmitted: Ref<boolean>\n submitCount: Ref<number>\n isDisabled: ComputedRef<boolean>\n isValid: ComputedRef<boolean>\n isDirty: ComputedRef<boolean>\n isTouched: ComputedRef<boolean>\n validationMode: ComputedRef<ValidationMode>\n values: ComputedRef<Record<string, unknown>>\n defaultValues: Record<string, unknown>\n registerField(reg: FieldRegistration): void\n unregisterField(name: string): void\n triggerFieldValidation(name: string): Promise<void>\n getFieldRef(name: string): Ref<unknown> | undefined\n setErrors(newErrors: Record<string, string>): void\n setError(name: string, message: string): void\n clearErrors(name?: string): void\n getValues(): Record<string, unknown>\n setValue(name: string, value: unknown): void\n trigger(name?: string): Promise<boolean>\n reset(): void\n handleSubmit(\n onValid: (\n values: Record<string, unknown>,\n helpers: { setErrors(errors: Record<string, string>): void },\n ) => void | Promise<void>,\n onInvalid?: (errors: Record<string, string>) => void,\n ): Promise<void>\n}\n\nexport const {\n useProvide: useFormProvide,\n useInject: _useFormInjectStrict,\n key: formContextKey,\n} = createContext<FormContext>('Form')\n\n/**\n * Inject Form context. Returns null when called outside a <Form> — callers\n * handle standalone mode themselves.\n */\nexport function useFormInject(): FormContext | null {\n return inject(formContextKey, null)\n}\n"],"mappings":";;;AA2DA,IAAa,EACX,YAAY,gBACZ,WAAW,sBACX,KAAK,mBACH,cAA2B,OAAO;;;;;AAMtC,SAAgB,gBAAoC;AAClD,QAAO,OAAO,gBAAgB,KAAK"}
@@ -0,0 +1,166 @@
1
+ import { runValidation } from "./validation.js";
2
+ import { computed, ref } from "vue";
3
+ //#region src/components/form/form.state.ts
4
+ function createFormState(options = {}) {
5
+ const { defaultValues = {} } = options;
6
+ const errors = ref({});
7
+ const isSubmitting = ref(false);
8
+ const isSubmitted = ref(false);
9
+ const submitCount = ref(0);
10
+ const fields = /* @__PURE__ */ new Map();
11
+ const fieldCount = ref(0);
12
+ function registerField(reg) {
13
+ fields.set(reg.name, reg);
14
+ fieldCount.value++;
15
+ }
16
+ function unregisterField(name) {
17
+ fields.delete(name);
18
+ fieldCount.value--;
19
+ const next = { ...errors.value };
20
+ delete next[name];
21
+ errors.value = next;
22
+ }
23
+ const values = computed(() => {
24
+ fieldCount.value;
25
+ const result = {};
26
+ for (const [name, field] of fields.entries()) result[name] = field.valueRef.value;
27
+ return result;
28
+ });
29
+ function getFieldRef(name) {
30
+ return fields.get(name)?.valueRef;
31
+ }
32
+ const isValid = computed(() => {
33
+ fieldCount.value;
34
+ return Object.keys(errors.value).length === 0;
35
+ });
36
+ const isDirty = computed(() => {
37
+ fieldCount.value;
38
+ for (const field of fields.values()) if (field.dirty.value) return true;
39
+ return false;
40
+ });
41
+ const isTouched = computed(() => {
42
+ fieldCount.value;
43
+ for (const field of fields.values()) if (field.touched.value) return true;
44
+ return false;
45
+ });
46
+ const validationMode = computed(() => options.validationMode?.value ?? "on-submit");
47
+ const isDisabled = computed(() => options.isDisabled?.value ?? false);
48
+ function getAllValues() {
49
+ const result = {};
50
+ for (const [name, field] of fields.entries()) result[name] = field.getValue();
51
+ return result;
52
+ }
53
+ async function triggerFieldValidation(name) {
54
+ const field = fields.get(name);
55
+ if (!field) return;
56
+ const error = await runValidation(field.getValue(), field.rules, field.validate, { values: getAllValues() });
57
+ const next = { ...errors.value };
58
+ if (error) next[name] = error;
59
+ else delete next[name];
60
+ errors.value = next;
61
+ }
62
+ async function trigger(name) {
63
+ if (name) {
64
+ await triggerFieldValidation(name);
65
+ return !errors.value[name];
66
+ }
67
+ const results = await Promise.all([...fields.entries()].map(async ([fieldName, field]) => {
68
+ return {
69
+ name: fieldName,
70
+ error: await runValidation(field.getValue(), field.rules, field.validate, { values: getAllValues() })
71
+ };
72
+ }));
73
+ const next = {};
74
+ for (const { name: fieldName, error } of results) if (error) next[fieldName] = error;
75
+ errors.value = next;
76
+ return Object.keys(next).length === 0;
77
+ }
78
+ function setErrors(newErrors) {
79
+ errors.value = {
80
+ ...errors.value,
81
+ ...newErrors
82
+ };
83
+ isSubmitting.value = false;
84
+ }
85
+ function setError(name, message) {
86
+ errors.value = {
87
+ ...errors.value,
88
+ [name]: message
89
+ };
90
+ }
91
+ function clearErrors(name) {
92
+ if (name) {
93
+ const next = { ...errors.value };
94
+ delete next[name];
95
+ errors.value = next;
96
+ } else errors.value = {};
97
+ }
98
+ function getValues() {
99
+ return getAllValues();
100
+ }
101
+ function setValue(name, value) {
102
+ const field = fields.get(name);
103
+ if (field) field.setValue(value);
104
+ }
105
+ function reset() {
106
+ for (const field of fields.values()) field.reset();
107
+ errors.value = {};
108
+ isSubmitting.value = false;
109
+ isSubmitted.value = false;
110
+ submitCount.value = 0;
111
+ }
112
+ async function handleSubmit(onValid, onInvalid) {
113
+ isSubmitting.value = true;
114
+ submitCount.value++;
115
+ const currentValues = getAllValues();
116
+ const context = { values: currentValues };
117
+ const results = await Promise.all([...fields.entries()].map(async ([name, field]) => {
118
+ return {
119
+ name,
120
+ error: await runValidation(field.getValue(), field.rules, field.validate, context)
121
+ };
122
+ }));
123
+ const nextErrors = {};
124
+ for (const { name, error } of results) if (error) nextErrors[name] = error;
125
+ if (Object.keys(nextErrors).length > 0) {
126
+ errors.value = nextErrors;
127
+ isSubmitting.value = false;
128
+ isSubmitted.value = true;
129
+ onInvalid?.(nextErrors);
130
+ return;
131
+ }
132
+ errors.value = {};
133
+ isSubmitted.value = true;
134
+ isSubmitting.value = false;
135
+ await onValid(currentValues, { setErrors });
136
+ }
137
+ return {
138
+ errors,
139
+ isSubmitting,
140
+ isSubmitted,
141
+ submitCount,
142
+ isDisabled,
143
+ isValid,
144
+ isDirty,
145
+ isTouched,
146
+ validationMode,
147
+ values,
148
+ defaultValues,
149
+ registerField,
150
+ unregisterField,
151
+ triggerFieldValidation,
152
+ getFieldRef,
153
+ setErrors,
154
+ setError,
155
+ clearErrors,
156
+ getValues,
157
+ setValue,
158
+ trigger,
159
+ reset,
160
+ handleSubmit
161
+ };
162
+ }
163
+ //#endregion
164
+ export { createFormState };
165
+
166
+ //# sourceMappingURL=form.state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form.state.js","names":[],"sources":["../../../src/components/form/form.state.ts"],"sourcesContent":["import { computed, ref, type Ref, type ComputedRef } from 'vue'\nimport { runValidation } from './validation'\nimport type { FormContext, FieldRegistration, ValidationMode } from './form.context'\n\n// Internal options — callers pass Refs so reactive props (from Form.vue's toRef) stay live\ninterface FormStateOptions {\n defaultValues?: Record<string, unknown>\n validationMode?: Ref<ValidationMode>\n isDisabled?: Ref<boolean>\n}\n\nexport function createFormState(options: FormStateOptions = {}): FormContext {\n const { defaultValues = {} } = options\n\n const errors = ref<Record<string, string>>({})\n const isSubmitting = ref(false)\n const isSubmitted = ref(false)\n const submitCount = ref(0)\n const fields = new Map<string, FieldRegistration>()\n const fieldCount = ref(0)\n\n // ── Registration ─────────────────────────────────────────────────────────────\n\n function registerField(reg: FieldRegistration): void {\n fields.set(reg.name, reg)\n fieldCount.value++\n }\n\n function unregisterField(name: string): void {\n fields.delete(name)\n fieldCount.value--\n const next = { ...errors.value }\n delete next[name]\n errors.value = next\n }\n\n // ── Reactive values ─────────────────────────────────────────────────────────\n\n const values: ComputedRef<Record<string, unknown>> = computed(() => {\n void fieldCount.value // track register/unregister events\n const result: Record<string, unknown> = {}\n for (const [name, field] of fields.entries()) {\n result[name] = field.valueRef.value\n }\n return result\n })\n\n function getFieldRef(name: string): Ref<unknown> | undefined {\n return fields.get(name)?.valueRef\n }\n\n // ── Computed state ──────────────────────────────────────────────────────────\n\n const isValid: ComputedRef<boolean> = computed(() => {\n void fieldCount.value\n return Object.keys(errors.value).length === 0\n })\n\n const isDirty: ComputedRef<boolean> = computed(() => {\n void fieldCount.value\n for (const field of fields.values()) {\n if (field.dirty.value) return true\n }\n return false\n })\n\n const isTouched: ComputedRef<boolean> = computed(() => {\n void fieldCount.value\n for (const field of fields.values()) {\n if (field.touched.value) return true\n }\n return false\n })\n\n const validationMode: ComputedRef<ValidationMode> = computed(\n () => options.validationMode?.value ?? 'on-submit',\n )\n\n const isDisabled: ComputedRef<boolean> = computed(\n () => options.isDisabled?.value ?? false,\n )\n\n // ── Helpers ─────────────────────────────────────────────────────────────────\n\n function getAllValues(): Record<string, unknown> {\n const result: Record<string, unknown> = {}\n for (const [name, field] of fields.entries()) {\n result[name] = field.getValue()\n }\n return result\n }\n\n // ── Validation ───────────────────────────────────────────────────────────────\n\n async function triggerFieldValidation(name: string): Promise<void> {\n const field = fields.get(name)\n if (!field) return\n const error = await runValidation(\n field.getValue(),\n field.rules,\n field.validate,\n { values: getAllValues() },\n )\n const next = { ...errors.value }\n if (error) {\n next[name] = error\n } else {\n delete next[name]\n }\n errors.value = next\n }\n\n async function trigger(name?: string): Promise<boolean> {\n if (name) {\n await triggerFieldValidation(name)\n return !errors.value[name]\n }\n const results = await Promise.all(\n [...fields.entries()].map(async ([fieldName, field]) => {\n const error = await runValidation(\n field.getValue(),\n field.rules,\n field.validate,\n { values: getAllValues() },\n )\n return { name: fieldName, error }\n }),\n )\n const next: Record<string, string> = {}\n for (const { name: fieldName, error } of results) {\n if (error) next[fieldName] = error\n }\n errors.value = next\n return Object.keys(next).length === 0\n }\n\n // ── Error management ─────────────────────────────────────────────────────────\n\n function setErrors(newErrors: Record<string, string>): void {\n errors.value = { ...errors.value, ...newErrors }\n isSubmitting.value = false\n }\n\n function setError(name: string, message: string): void {\n errors.value = { ...errors.value, [name]: message }\n }\n\n function clearErrors(name?: string): void {\n if (name) {\n const next = { ...errors.value }\n delete next[name]\n errors.value = next\n } else {\n errors.value = {}\n }\n }\n\n // ── Values ───────────────────────────────────────────────────────────────────\n\n function getValues(): Record<string, unknown> {\n return getAllValues()\n }\n\n function setValue(name: string, value: unknown): void {\n const field = fields.get(name)\n if (field) field.setValue(value)\n }\n\n // ── Reset ────────────────────────────────────────────────────────────────────\n\n function reset(): void {\n for (const field of fields.values()) {\n field.reset()\n }\n errors.value = {}\n isSubmitting.value = false\n isSubmitted.value = false\n submitCount.value = 0\n }\n\n // ── Submit ───────────────────────────────────────────────────────────────────\n\n async function handleSubmit(\n onValid: (\n values: Record<string, unknown>,\n helpers: { setErrors(errors: Record<string, string>): void },\n ) => void | Promise<void>,\n onInvalid?: (errors: Record<string, string>) => void,\n ): Promise<void> {\n isSubmitting.value = true\n submitCount.value++\n\n const currentValues = getAllValues()\n const context = { values: currentValues }\n\n const results = await Promise.all(\n [...fields.entries()].map(async ([name, field]) => {\n const error = await runValidation(field.getValue(), field.rules, field.validate, context)\n return { name, error }\n }),\n )\n\n const nextErrors: Record<string, string> = {}\n for (const { name, error } of results) {\n if (error) nextErrors[name] = error\n }\n\n if (Object.keys(nextErrors).length > 0) {\n errors.value = nextErrors\n isSubmitting.value = false\n isSubmitted.value = true\n onInvalid?.(nextErrors)\n return\n }\n\n errors.value = {}\n isSubmitted.value = true\n isSubmitting.value = false\n await onValid(currentValues, { setErrors })\n }\n\n return {\n errors,\n isSubmitting,\n isSubmitted,\n submitCount,\n isDisabled,\n isValid,\n isDirty,\n isTouched,\n validationMode,\n values,\n defaultValues,\n registerField,\n unregisterField,\n triggerFieldValidation,\n getFieldRef,\n setErrors,\n setError,\n clearErrors,\n getValues,\n setValue,\n trigger,\n reset,\n handleSubmit,\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ import { useFormInject } from "./form.context.js";
2
+ import { runValidation } from "./validation.js";
3
+ import { computed, onMounted, onUnmounted, ref, watch } from "vue";
4
+ //#region src/components/form/useField.ts
5
+ function useField(name, options = {}) {
6
+ const ctx = useFormInject();
7
+ const modelValue = ref(options.defaultValue !== void 0 ? options.defaultValue : ctx?.defaultValues[name]);
8
+ const localError = ref(void 0);
9
+ const touched = ref(false);
10
+ const dirty = ref(false);
11
+ const hasBeenInvalid = ref(false);
12
+ const resolvedDefault = computed(() => {
13
+ if (options.defaultValue !== void 0) return options.defaultValue;
14
+ return ctx?.defaultValues[name];
15
+ });
16
+ const error = computed(() => ctx ? ctx.errors.value[name] : localError.value);
17
+ const isInvalid = computed(() => !!error.value);
18
+ const isDisabled = computed(() => ctx?.isDisabled.value ?? false);
19
+ const effectiveMode = computed(() => options.validationMode ?? ctx?.validationMode.value ?? "on-submit");
20
+ watch(error, (e) => {
21
+ if (e) hasBeenInvalid.value = true;
22
+ });
23
+ watch(modelValue, (val) => {
24
+ dirty.value = val !== resolvedDefault.value;
25
+ });
26
+ async function triggerValidation(val) {
27
+ const context = ctx ? { values: ctx.getValues() } : void 0;
28
+ const err = await runValidation(val, options.rules, options.validate, context);
29
+ if (ctx) {
30
+ const next = { ...ctx.errors.value };
31
+ if (err) next[name] = err;
32
+ else delete next[name];
33
+ ctx.errors.value = next;
34
+ } else localError.value = err;
35
+ }
36
+ async function handleUpdate(val) {
37
+ modelValue.value = val;
38
+ if (!ctx || effectiveMode.value === "on-change" || hasBeenInvalid.value) await triggerValidation(val);
39
+ }
40
+ async function handleBlur() {
41
+ touched.value = true;
42
+ if (effectiveMode.value === "on-blur") await triggerValidation(modelValue.value);
43
+ }
44
+ function reset() {
45
+ modelValue.value = resolvedDefault.value;
46
+ localError.value = void 0;
47
+ touched.value = false;
48
+ dirty.value = false;
49
+ hasBeenInvalid.value = false;
50
+ if (ctx) {
51
+ const next = { ...ctx.errors.value };
52
+ delete next[name];
53
+ ctx.errors.value = next;
54
+ }
55
+ }
56
+ const depStoppers = [];
57
+ function setupDepWatchers(deps) {
58
+ for (const stop of depStoppers) stop();
59
+ depStoppers.length = 0;
60
+ if (!ctx || !deps?.length) return;
61
+ for (const dep of deps) {
62
+ const depRef = ctx.getFieldRef(dep);
63
+ if (!depRef) continue;
64
+ depStoppers.push(watch(depRef, () => void triggerValidation(modelValue.value)));
65
+ }
66
+ }
67
+ onMounted(() => {
68
+ ctx?.registerField({
69
+ name,
70
+ valueRef: modelValue,
71
+ getValue: () => modelValue.value,
72
+ getDefaultValue: () => resolvedDefault.value,
73
+ setValue: (val) => {
74
+ modelValue.value = val;
75
+ },
76
+ reset,
77
+ touched,
78
+ dirty,
79
+ rules: options.rules,
80
+ validate: options.validate
81
+ });
82
+ setupDepWatchers(options.deps);
83
+ });
84
+ onUnmounted(() => {
85
+ for (const stop of depStoppers) stop();
86
+ ctx?.unregisterField(name);
87
+ });
88
+ return {
89
+ modelValue,
90
+ error,
91
+ isInvalid,
92
+ isTouched: touched,
93
+ isDirty: dirty,
94
+ isDisabled,
95
+ fieldProps: computed(() => ({
96
+ name,
97
+ modelValue: modelValue.value,
98
+ "onUpdate:modelValue": handleUpdate,
99
+ isInvalid: isInvalid.value,
100
+ errorMessage: error.value,
101
+ isDisabled: isDisabled.value,
102
+ onBlur: handleBlur
103
+ })),
104
+ handleUpdate,
105
+ handleBlur,
106
+ reset
107
+ };
108
+ }
109
+ //#endregion
110
+ export { useField };
111
+
112
+ //# sourceMappingURL=useField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useField.js","names":[],"sources":["../../../src/components/form/useField.ts"],"sourcesContent":["import { computed, onMounted, onUnmounted, ref, watch, type ComputedRef, type Ref } from 'vue'\nimport { useFormInject } from './form.context'\nimport { runValidation } from './validation'\nimport type { FieldRules, CustomValidator, ValidationMode } from './form.context'\n\nexport interface FieldOptions {\n defaultValue?: unknown\n rules?: FieldRules\n validate?: CustomValidator\n validationMode?: ValidationMode\n deps?: string[]\n}\n\nexport interface FieldProps {\n name: string\n modelValue: unknown\n 'onUpdate:modelValue': (value: unknown) => Promise<void>\n isInvalid: boolean\n errorMessage: string | undefined\n isDisabled: boolean\n onBlur: () => Promise<void>\n}\n\nexport interface FieldHandle {\n modelValue: Ref<unknown>\n error: ComputedRef<string | undefined>\n isInvalid: ComputedRef<boolean>\n isTouched: Ref<boolean>\n isDirty: Ref<boolean>\n isDisabled: ComputedRef<boolean>\n fieldProps: ComputedRef<FieldProps>\n handleUpdate(value: unknown): Promise<void>\n handleBlur(): Promise<void>\n reset(): void\n}\n\nexport function useField(name: string, options: FieldOptions = {}): FieldHandle {\n const ctx = useFormInject()\n\n const modelValue = ref<unknown>(\n options.defaultValue !== undefined\n ? options.defaultValue\n : ctx?.defaultValues[name],\n )\n\n const localError = ref<string | undefined>(undefined)\n const touched = ref(false)\n const dirty = ref(false)\n const hasBeenInvalid = ref(false)\n\n const resolvedDefault = computed(() => {\n if (options.defaultValue !== undefined) return options.defaultValue\n return ctx?.defaultValues[name]\n })\n\n const error: ComputedRef<string | undefined> = computed(() =>\n ctx ? ctx.errors.value[name] : localError.value,\n )\n const isInvalid: ComputedRef<boolean> = computed(() => !!error.value)\n const isDisabled: ComputedRef<boolean> = computed(() => ctx?.isDisabled.value ?? false)\n const effectiveMode = computed(() => options.validationMode ?? ctx?.validationMode.value ?? 'on-submit')\n\n watch(error, (e) => { if (e) hasBeenInvalid.value = true })\n watch(modelValue, (val) => { dirty.value = val !== resolvedDefault.value })\n\n // ── Validation ───────────────────────────────────────────────────────────────\n\n async function triggerValidation(val: unknown): Promise<void> {\n const context = ctx ? { values: ctx.getValues() } : undefined\n const err = await runValidation(val, options.rules, options.validate, context)\n\n if (ctx) {\n const next = { ...ctx.errors.value }\n if (err) {\n next[name] = err\n } else {\n delete next[name]\n }\n ctx.errors.value = next\n } else {\n localError.value = err\n }\n }\n\n async function handleUpdate(val: unknown): Promise<void> {\n modelValue.value = val\n // In standalone mode (no form) there is no submit event, so always validate on change.\n // In form mode, respect the configured validation mode.\n if (!ctx || effectiveMode.value === 'on-change' || hasBeenInvalid.value) {\n await triggerValidation(val)\n }\n }\n\n async function handleBlur(): Promise<void> {\n touched.value = true\n if (effectiveMode.value === 'on-blur') {\n await triggerValidation(modelValue.value)\n }\n }\n\n function reset(): void {\n modelValue.value = resolvedDefault.value\n localError.value = undefined\n touched.value = false\n dirty.value = false\n hasBeenInvalid.value = false\n if (ctx) {\n const next = { ...ctx.errors.value }\n delete next[name]\n ctx.errors.value = next\n }\n }\n\n // ── Deps watching ─────────────────────────────────────────────────────────────\n\n const depStoppers: (() => void)[] = []\n\n function setupDepWatchers(deps: string[] | undefined): void {\n for (const stop of depStoppers) stop()\n depStoppers.length = 0\n if (!ctx || !deps?.length) return\n for (const dep of deps) {\n const depRef = ctx.getFieldRef(dep)\n if (!depRef) continue\n depStoppers.push(watch(depRef, () => void triggerValidation(modelValue.value)))\n }\n }\n\n // ── Registration ─────────────────────────────────────────────────────────────\n\n onMounted(() => {\n ctx?.registerField({\n name,\n valueRef: modelValue,\n getValue: () => modelValue.value,\n getDefaultValue: () => resolvedDefault.value,\n setValue: (val) => { modelValue.value = val },\n reset,\n touched,\n dirty,\n rules: options.rules,\n validate: options.validate,\n })\n setupDepWatchers(options.deps)\n })\n\n onUnmounted(() => {\n for (const stop of depStoppers) stop()\n ctx?.unregisterField(name)\n })\n\n // ── fieldProps ────────────────────────────────────────────────────────────────\n\n const fieldProps: ComputedRef<FieldProps> = computed(() => ({\n name,\n modelValue: modelValue.value,\n 'onUpdate:modelValue': handleUpdate,\n isInvalid: isInvalid.value,\n errorMessage: error.value,\n isDisabled: isDisabled.value,\n onBlur: handleBlur,\n }))\n\n return {\n modelValue,\n error,\n isInvalid,\n isTouched: touched,\n isDirty: dirty,\n isDisabled,\n fieldProps,\n handleUpdate,\n handleBlur,\n reset,\n }\n}\n"],"mappings":";;;;AAoCA,SAAgB,SAAS,MAAc,UAAwB,EAAE,EAAe;CAC9E,MAAM,MAAM,eAAe;CAE3B,MAAM,aAAa,IACjB,QAAQ,iBAAiB,KAAA,IACrB,QAAQ,eACR,KAAK,cAAc,MACxB;CAED,MAAM,aAAa,IAAwB,KAAA,EAAU;CACrD,MAAM,UAAU,IAAI,MAAM;CAC1B,MAAM,QAAQ,IAAI,MAAM;CACxB,MAAM,iBAAiB,IAAI,MAAM;CAEjC,MAAM,kBAAkB,eAAe;AACrC,MAAI,QAAQ,iBAAiB,KAAA,EAAW,QAAO,QAAQ;AACvD,SAAO,KAAK,cAAc;GAC1B;CAEF,MAAM,QAAyC,eAC7C,MAAM,IAAI,OAAO,MAAM,QAAQ,WAAW,MAC3C;CACD,MAAM,YAAkC,eAAe,CAAC,CAAC,MAAM,MAAM;CACrE,MAAM,aAAmC,eAAe,KAAK,WAAW,SAAS,MAAM;CACvF,MAAM,gBAAgB,eAAe,QAAQ,kBAAkB,KAAK,eAAe,SAAS,YAAY;AAExG,OAAM,QAAQ,MAAM;AAAE,MAAI,EAAG,gBAAe,QAAQ;GAAO;AAC3D,OAAM,aAAa,QAAQ;AAAE,QAAM,QAAQ,QAAQ,gBAAgB;GAAQ;CAI3E,eAAe,kBAAkB,KAA6B;EAC5D,MAAM,UAAU,MAAM,EAAE,QAAQ,IAAI,WAAW,EAAE,GAAG,KAAA;EACpD,MAAM,MAAM,MAAM,cAAc,KAAK,QAAQ,OAAO,QAAQ,UAAU,QAAQ;AAE9E,MAAI,KAAK;GACP,MAAM,OAAO,EAAE,GAAG,IAAI,OAAO,OAAO;AACpC,OAAI,IACF,MAAK,QAAQ;OAEb,QAAO,KAAK;AAEd,OAAI,OAAO,QAAQ;QAEnB,YAAW,QAAQ;;CAIvB,eAAe,aAAa,KAA6B;AACvD,aAAW,QAAQ;AAGnB,MAAI,CAAC,OAAO,cAAc,UAAU,eAAe,eAAe,MAChE,OAAM,kBAAkB,IAAI;;CAIhC,eAAe,aAA4B;AACzC,UAAQ,QAAQ;AAChB,MAAI,cAAc,UAAU,UAC1B,OAAM,kBAAkB,WAAW,MAAM;;CAI7C,SAAS,QAAc;AACrB,aAAW,QAAQ,gBAAgB;AACnC,aAAW,QAAQ,KAAA;AACnB,UAAQ,QAAQ;AAChB,QAAM,QAAQ;AACd,iBAAe,QAAQ;AACvB,MAAI,KAAK;GACP,MAAM,OAAO,EAAE,GAAG,IAAI,OAAO,OAAO;AACpC,UAAO,KAAK;AACZ,OAAI,OAAO,QAAQ;;;CAMvB,MAAM,cAA8B,EAAE;CAEtC,SAAS,iBAAiB,MAAkC;AAC1D,OAAK,MAAM,QAAQ,YAAa,OAAM;AACtC,cAAY,SAAS;AACrB,MAAI,CAAC,OAAO,CAAC,MAAM,OAAQ;AAC3B,OAAK,MAAM,OAAO,MAAM;GACtB,MAAM,SAAS,IAAI,YAAY,IAAI;AACnC,OAAI,CAAC,OAAQ;AACb,eAAY,KAAK,MAAM,cAAc,KAAK,kBAAkB,WAAW,MAAM,CAAC,CAAC;;;AAMnF,iBAAgB;AACd,OAAK,cAAc;GACjB;GACA,UAAU;GACV,gBAAgB,WAAW;GAC3B,uBAAuB,gBAAgB;GACvC,WAAW,QAAQ;AAAE,eAAW,QAAQ;;GACxC;GACA;GACA;GACA,OAAO,QAAQ;GACf,UAAU,QAAQ;GACnB,CAAC;AACF,mBAAiB,QAAQ,KAAK;GAC9B;AAEF,mBAAkB;AAChB,OAAK,MAAM,QAAQ,YAAa,OAAM;AACtC,OAAK,gBAAgB,KAAK;GAC1B;AAcF,QAAO;EACL;EACA;EACA;EACA,WAAW;EACX,SAAS;EACT;EACA,YAjB0C,gBAAgB;GAC1D;GACA,YAAY,WAAW;GACvB,uBAAuB;GACvB,WAAW,UAAU;GACrB,cAAc,MAAM;GACpB,YAAY,WAAW;GACvB,QAAQ;GACT,EAAE;EAUD;EACA;EACA;EACD"}
@@ -0,0 +1,17 @@
1
+ import { formContextKey } from "./form.context.js";
2
+ import { createFormState } from "./form.state.js";
3
+ import { provide, ref } from "vue";
4
+ //#region src/components/form/useForm.ts
5
+ function useForm(options = {}) {
6
+ const ctx = createFormState({
7
+ defaultValues: options.defaultValues,
8
+ validationMode: ref(options.validationMode ?? "on-submit"),
9
+ isDisabled: ref(options.isDisabled ?? false)
10
+ });
11
+ provide(formContextKey, ctx);
12
+ return ctx;
13
+ }
14
+ //#endregion
15
+ export { useForm };
16
+
17
+ //# sourceMappingURL=useForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useForm.js","names":[],"sources":["../../../src/components/form/useForm.ts"],"sourcesContent":["import { provide, ref } from 'vue'\nimport { formContextKey, type FormContext, type FormOptions } from './form.context'\nimport { createFormState } from './form.state'\n\nexport function useForm(options: FormOptions = {}): FormContext {\n const ctx = createFormState({\n defaultValues: options.defaultValues,\n validationMode: ref(options.validationMode ?? 'on-submit'),\n isDisabled: ref(options.isDisabled ?? false),\n })\n provide(formContextKey, ctx)\n return ctx\n}\n"],"mappings":";;;;AAIA,SAAgB,QAAQ,UAAuB,EAAE,EAAe;CAC9D,MAAM,MAAM,gBAAgB;EAC1B,eAAe,QAAQ;EACvB,gBAAgB,IAAI,QAAQ,kBAAkB,YAAY;EAC1D,YAAY,IAAI,QAAQ,cAAc,MAAM;EAC7C,CAAC;AACF,SAAQ,gBAAgB,IAAI;AAC5B,QAAO"}
@@ -0,0 +1,7 @@
1
+ import HoverCard_vue_vue_type_script_lang_default from "./HoverCard.vue_vue_type_script_lang.js";
2
+ //#region src/components/hover-card/HoverCard.vue
3
+ var HoverCard_default = HoverCard_vue_vue_type_script_lang_default;
4
+ //#endregion
5
+ export { HoverCard_default as default };
6
+
7
+ //# sourceMappingURL=HoverCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HoverCard.js","names":[],"sources":["../../../src/components/hover-card/HoverCard.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { defineComponent, computed, h } from 'vue'\nimport { HoverCardRoot } from 'reka-ui'\n\n/**\n * HoverCard root component. Wraps Reka UI's HoverCardRoot.\n *\n * Important: we use the Options-API / render-function style here (not `<script setup>`)\n * to avoid Vue SFC's compiled template from forwarding `open: undefined` to HoverCardRoot.\n * Reka's `useVModel` checks `props.open === undefined` to choose uncontrolled vs controlled\n * mode, but a template `:open=\"props.open\"` always provides the key (even as `undefined`),\n * forcing controlled mode and breaking `defaultOpen`. The render function lets us omit the\n * key entirely when `open` is not provided by the consumer. This mirrors Popover.vue.\n */\nexport default defineComponent({\n name: 'HoverCard',\n props: {\n defaultOpen: { type: Boolean, default: false },\n open: { type: Boolean, default: undefined },\n openDelay: { type: Number, default: 700 },\n closeDelay: { type: Number, default: 300 },\n },\n emits: ['update:open'],\n setup(props, { slots, emit }) {\n const rootProps = computed(() => {\n const p: Record<string, unknown> = {\n defaultOpen: props.defaultOpen,\n openDelay: props.openDelay,\n closeDelay: props.closeDelay,\n 'onUpdate:open': (val: boolean) => emit('update:open', val),\n }\n if (props.open !== undefined) {\n p.open = props.open\n }\n return p\n })\n\n return () => h(HoverCardRoot, rootProps.value, slots)\n },\n})\n</script>\n"],"mappings":""}
@@ -0,0 +1,52 @@
1
+ import { computed, defineComponent, h } from "vue";
2
+ import { HoverCardRoot } from "reka-ui";
3
+ //#region src/components/hover-card/HoverCard.vue?vue&type=script&lang.ts
4
+ /**
5
+ * HoverCard root component. Wraps Reka UI's HoverCardRoot.
6
+ *
7
+ * Important: we use the Options-API / render-function style here (not `<script setup>`)
8
+ * to avoid Vue SFC's compiled template from forwarding `open: undefined` to HoverCardRoot.
9
+ * Reka's `useVModel` checks `props.open === undefined` to choose uncontrolled vs controlled
10
+ * mode, but a template `:open="props.open"` always provides the key (even as `undefined`),
11
+ * forcing controlled mode and breaking `defaultOpen`. The render function lets us omit the
12
+ * key entirely when `open` is not provided by the consumer. This mirrors Popover.vue.
13
+ */
14
+ var HoverCard_vue_vue_type_script_lang_default = defineComponent({
15
+ name: "HoverCard",
16
+ props: {
17
+ defaultOpen: {
18
+ type: Boolean,
19
+ default: false
20
+ },
21
+ open: {
22
+ type: Boolean,
23
+ default: void 0
24
+ },
25
+ openDelay: {
26
+ type: Number,
27
+ default: 700
28
+ },
29
+ closeDelay: {
30
+ type: Number,
31
+ default: 300
32
+ }
33
+ },
34
+ emits: ["update:open"],
35
+ setup(props, { slots, emit }) {
36
+ const rootProps = computed(() => {
37
+ const p = {
38
+ defaultOpen: props.defaultOpen,
39
+ openDelay: props.openDelay,
40
+ closeDelay: props.closeDelay,
41
+ "onUpdate:open": (val) => emit("update:open", val)
42
+ };
43
+ if (props.open !== void 0) p.open = props.open;
44
+ return p;
45
+ });
46
+ return () => h(HoverCardRoot, rootProps.value, slots);
47
+ }
48
+ });
49
+ //#endregion
50
+ export { HoverCard_vue_vue_type_script_lang_default as default };
51
+
52
+ //# sourceMappingURL=HoverCard.vue_vue_type_script_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HoverCard.vue_vue_type_script_lang.js","names":[],"sources":["../../../src/components/hover-card/HoverCard.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { defineComponent, computed, h } from 'vue'\nimport { HoverCardRoot } from 'reka-ui'\n\n/**\n * HoverCard root component. Wraps Reka UI's HoverCardRoot.\n *\n * Important: we use the Options-API / render-function style here (not `<script setup>`)\n * to avoid Vue SFC's compiled template from forwarding `open: undefined` to HoverCardRoot.\n * Reka's `useVModel` checks `props.open === undefined` to choose uncontrolled vs controlled\n * mode, but a template `:open=\"props.open\"` always provides the key (even as `undefined`),\n * forcing controlled mode and breaking `defaultOpen`. The render function lets us omit the\n * key entirely when `open` is not provided by the consumer. This mirrors Popover.vue.\n */\nexport default defineComponent({\n name: 'HoverCard',\n props: {\n defaultOpen: { type: Boolean, default: false },\n open: { type: Boolean, default: undefined },\n openDelay: { type: Number, default: 700 },\n closeDelay: { type: Number, default: 300 },\n },\n emits: ['update:open'],\n setup(props, { slots, emit }) {\n const rootProps = computed(() => {\n const p: Record<string, unknown> = {\n defaultOpen: props.defaultOpen,\n openDelay: props.openDelay,\n closeDelay: props.closeDelay,\n 'onUpdate:open': (val: boolean) => emit('update:open', val),\n }\n if (props.open !== undefined) {\n p.open = props.open\n }\n return p\n })\n\n return () => h(HoverCardRoot, rootProps.value, slots)\n },\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;AAcA,IAAA,6CAAe,gBAAgB;CAC7B,MAAM;CACN,OAAO;EACL,aAAa;GAAE,MAAM;GAAS,SAAS;GAAO;EAC9C,MAAM;GAAE,MAAM;GAAS,SAAS,KAAA;GAAW;EAC3C,WAAW;GAAE,MAAM;GAAQ,SAAS;GAAK;EACzC,YAAY;GAAE,MAAM;GAAQ,SAAS;GAAK;EAC3C;CACD,OAAO,CAAC,cAAc;CACtB,MAAM,OAAO,EAAE,OAAO,QAAQ;EAC5B,MAAM,YAAY,eAAe;GAC/B,MAAM,IAA6B;IACjC,aAAa,MAAM;IACnB,WAAW,MAAM;IACjB,YAAY,MAAM;IAClB,kBAAkB,QAAiB,KAAK,eAAe,IAAI;IAC7D;AACA,OAAI,MAAM,SAAS,KAAA,EACjB,GAAE,OAAO,MAAM;AAEjB,UAAO;IACR;AAED,eAAa,EAAE,eAAe,UAAU,OAAO,MAAK;;CAEvD,CAAA"}
@@ -0,0 +1,7 @@
1
+ import HoverCardArrow_vue_vue_type_script_setup_true_lang_default from "./HoverCardArrow.vue_vue_type_script_setup_true_lang.js";
2
+ //#region src/components/hover-card/HoverCardArrow.vue
3
+ var HoverCardArrow_default = HoverCardArrow_vue_vue_type_script_setup_true_lang_default;
4
+ //#endregion
5
+ export { HoverCardArrow_default as default };
6
+
7
+ //# sourceMappingURL=HoverCardArrow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HoverCardArrow.js","names":[],"sources":["../../../src/components/hover-card/HoverCardArrow.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { HoverCardArrow } from 'reka-ui'\n\nconst props = defineProps<{\n as?: string | object\n asChild?: boolean\n width?: number\n height?: number\n class?: string\n}>()\n</script>\n\n<template>\n <HoverCardArrow\n :as=\"props.as\"\n :as-child=\"props.asChild\"\n :width=\"props.width\"\n :height=\"props.height\"\n :class=\"props.class\"\n v-bind=\"$attrs\"\n />\n</template>\n"],"mappings":""}
@@ -0,0 +1,35 @@
1
+ import { createBlock, defineComponent, mergeProps, openBlock, unref } from "vue";
2
+ import { HoverCardArrow } from "reka-ui";
3
+ //#region src/components/hover-card/HoverCardArrow.vue?vue&type=script&setup=true&lang.ts
4
+ var HoverCardArrow_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
5
+ __name: "HoverCardArrow",
6
+ props: {
7
+ as: {},
8
+ asChild: { type: Boolean },
9
+ width: {},
10
+ height: {},
11
+ class: {}
12
+ },
13
+ setup(__props) {
14
+ const props = __props;
15
+ return (_ctx, _cache) => {
16
+ return openBlock(), createBlock(unref(HoverCardArrow), mergeProps({
17
+ as: props.as,
18
+ "as-child": props.asChild,
19
+ width: props.width,
20
+ height: props.height,
21
+ class: props.class
22
+ }, _ctx.$attrs), null, 16, [
23
+ "as",
24
+ "as-child",
25
+ "width",
26
+ "height",
27
+ "class"
28
+ ]);
29
+ };
30
+ }
31
+ });
32
+ //#endregion
33
+ export { HoverCardArrow_vue_vue_type_script_setup_true_lang_default as default };
34
+
35
+ //# sourceMappingURL=HoverCardArrow.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HoverCardArrow.vue_vue_type_script_setup_true_lang.js","names":["$attrs"],"sources":["../../../src/components/hover-card/HoverCardArrow.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { HoverCardArrow } from 'reka-ui'\n\nconst props = defineProps<{\n as?: string | object\n asChild?: boolean\n width?: number\n height?: number\n class?: string\n}>()\n</script>\n\n<template>\n <HoverCardArrow\n :as=\"props.as\"\n :as-child=\"props.asChild\"\n :width=\"props.width\"\n :height=\"props.height\"\n :class=\"props.class\"\n v-bind=\"$attrs\"\n />\n</template>\n"],"mappings":";;;;;;;;;;;;;EAGA,MAAM,QAAQ;;uBAUZ,YAOE,MAAA,eAAA,EAPF,WAOE;IANC,IAAI,MAAM;IACV,YAAU,MAAM;IAChB,OAAO,MAAM;IACb,QAAQ,MAAM;IACd,OAAO,MAAM;MACNA,KAAAA,OAAM,EAAA,MAAA,IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA,CAAA"}
@@ -0,0 +1,7 @@
1
+ import HoverCardContent_vue_vue_type_script_setup_true_lang_default from "./HoverCardContent.vue_vue_type_script_setup_true_lang.js";
2
+ //#region src/components/hover-card/HoverCardContent.vue
3
+ var HoverCardContent_default = HoverCardContent_vue_vue_type_script_setup_true_lang_default;
4
+ //#endregion
5
+ export { HoverCardContent_default as default };
6
+
7
+ //# sourceMappingURL=HoverCardContent.js.map