@datum-cloud/datum-ui 0.4.0 → 0.6.0-alpha.b817c77

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 (195) hide show
  1. package/README.md +78 -39
  2. package/dist/adapter-context-B7L2ucTr.mjs +25 -0
  3. package/dist/alert/index.mjs +2 -3
  4. package/dist/{alert-BC2Mccfo.mjs → alert-BDj6od5I.mjs} +2 -4
  5. package/dist/app-navigation/index.mjs +4 -12
  6. package/dist/{app-navigation-DsCKgfPe.mjs → app-navigation-84ro28PU.mjs} +5 -8
  7. package/dist/autocomplete/index.mjs +2 -7
  8. package/dist/{autocomplete-DRB_kSVx.mjs → autocomplete-V5-qslzS.mjs} +5 -7
  9. package/dist/avatar/index.mjs +2 -4
  10. package/dist/{avatar-DyLq0xkt.mjs → avatar-BtKVcvO4.mjs} +2 -4
  11. package/dist/avatar-stack/index.mjs +2 -6
  12. package/dist/{avatar-stack-BT0dBswq.mjs → avatar-stack-oVr8tsU7.mjs} +4 -6
  13. package/dist/badge/index.mjs +2 -3
  14. package/dist/{badge-BgFj4Nsc.mjs → badge-DJR33ftJ.mjs} +2 -4
  15. package/dist/breadcrumb/index.mjs +2 -4
  16. package/dist/{breadcrumb-CJNaYyk1.mjs → breadcrumb-B-9G347O.mjs} +2 -4
  17. package/dist/button/index.mjs +3 -4
  18. package/dist/{button-0N61fmAR.mjs → button-BllvE9Lm.mjs} +3 -5
  19. package/dist/{button-D6AORsOz.mjs → button-D3RrsMfQ.mjs} +2 -4
  20. package/dist/{link-button-Cby0p4LW.mjs → button-fO8nazJE.mjs} +3 -5
  21. package/dist/button-group/index.mjs +2 -5
  22. package/dist/{button-group-BDk8btAy.mjs → button-group-CYPka2zz.mjs} +3 -5
  23. package/dist/calendar/index.mjs +2 -5
  24. package/dist/{calendar-BtfraIvX.mjs → calendar-DEkCw7I1.mjs} +4 -6
  25. package/dist/{calendar-date-picker-B9mxJM7f.mjs → calendar-date-picker-DWK94_DC.mjs} +6 -8
  26. package/dist/card/index.mjs +2 -4
  27. package/dist/{card-BiHXFt4s.mjs → card-DKG1Cwlj.mjs} +3 -6
  28. package/dist/chart/index.mjs +2 -4
  29. package/dist/{chart-CL0i-xIt.mjs → chart-CUa21ynK.mjs} +2 -4
  30. package/dist/checkbox/index.mjs +2 -4
  31. package/dist/{checkbox-CQrjygFt.mjs → checkbox-I5BvrMPe.mjs} +3 -6
  32. package/dist/{close.icon-D2r5q3bj.mjs → close.icon-HCfS4Y-N.mjs} +2 -4
  33. package/dist/{cn-DWCc1QRE.mjs → cn-D2KYQ917.mjs} +1 -3
  34. package/dist/code-editor/index.mjs +2 -0
  35. package/dist/{col-C9PDhvm5.mjs → col-YBbQ5wlb.mjs} +2 -7
  36. package/dist/collapsible/index.mjs +2 -3
  37. package/dist/{collapsible-Dw71o2um.mjs → collapsible-CUphkSBt.mjs} +1 -3
  38. package/dist/command/index.mjs +2 -5
  39. package/dist/{command-DVroicgn.mjs → command-DqHWukGK.mjs} +3 -5
  40. package/dist/components/features/code-editor/code-editor-tabs.d.ts +63 -0
  41. package/dist/components/features/code-editor/code-editor-tabs.d.ts.map +1 -0
  42. package/dist/components/features/code-editor/code-editor.d.ts +58 -0
  43. package/dist/components/features/code-editor/code-editor.d.ts.map +1 -0
  44. package/dist/components/features/code-editor/index.d.ts +6 -0
  45. package/dist/components/features/code-editor/index.d.ts.map +1 -0
  46. package/dist/components/features/code-editor/lib/editor.d.ts +7 -0
  47. package/dist/components/features/code-editor/lib/editor.d.ts.map +1 -0
  48. package/dist/components/features/code-editor/types.d.ts +98 -0
  49. package/dist/components/features/code-editor/types.d.ts.map +1 -0
  50. package/dist/components/features/form/adapter-context.d.ts +17 -0
  51. package/dist/components/features/form/adapter-context.d.ts.map +1 -0
  52. package/dist/components/features/form/adapter-types.d.ts +100 -0
  53. package/dist/components/features/form/adapter-types.d.ts.map +1 -0
  54. package/dist/components/features/form/adapters/conform/conform-adapter.d.ts +9 -0
  55. package/dist/components/features/form/adapters/conform/conform-adapter.d.ts.map +1 -0
  56. package/dist/components/features/form/adapters/conform/conform-provider.d.ts +22 -0
  57. package/dist/components/features/form/adapters/conform/conform-provider.d.ts.map +1 -0
  58. package/dist/components/features/form/adapters/conform/index.d.ts +3 -0
  59. package/dist/components/features/form/adapters/conform/index.d.ts.map +1 -0
  60. package/dist/components/features/form/adapters/rhf/index.d.ts +3 -0
  61. package/dist/components/features/form/adapters/rhf/index.d.ts.map +1 -0
  62. package/dist/components/features/form/adapters/rhf/rhf-adapter.d.ts +10 -0
  63. package/dist/components/features/form/adapters/rhf/rhf-adapter.d.ts.map +1 -0
  64. package/dist/components/features/form/adapters/rhf/rhf-provider.d.ts +22 -0
  65. package/dist/components/features/form/adapters/rhf/rhf-provider.d.ts.map +1 -0
  66. package/dist/components/features/form/components/form-autocomplete.d.ts.map +1 -1
  67. package/dist/components/features/form/components/form-checkbox.d.ts.map +1 -1
  68. package/dist/components/features/form/components/form-copy-box.d.ts.map +1 -1
  69. package/dist/components/features/form/components/form-field-array.d.ts +5 -17
  70. package/dist/components/features/form/components/form-field-array.d.ts.map +1 -1
  71. package/dist/components/features/form/components/form-field.d.ts +7 -21
  72. package/dist/components/features/form/components/form-field.d.ts.map +1 -1
  73. package/dist/components/features/form/components/form-input-group.d.ts +4 -4
  74. package/dist/components/features/form/components/form-input-group.d.ts.map +1 -1
  75. package/dist/components/features/form/components/form-input.d.ts.map +1 -1
  76. package/dist/components/features/form/components/form-radio-group.d.ts.map +1 -1
  77. package/dist/components/features/form/components/form-root.d.ts +5 -25
  78. package/dist/components/features/form/components/form-root.d.ts.map +1 -1
  79. package/dist/components/features/form/components/form-select.d.ts.map +1 -1
  80. package/dist/components/features/form/components/form-switch.d.ts.map +1 -1
  81. package/dist/components/features/form/components/form-textarea.d.ts.map +1 -1
  82. package/dist/components/features/form/components/stepper/form-stepper.d.ts.map +1 -1
  83. package/dist/components/features/form/context/form-context.d.ts +2 -2
  84. package/dist/components/features/form/context/form-context.d.ts.map +1 -1
  85. package/dist/components/features/form/hooks/use-field.d.ts +12 -18
  86. package/dist/components/features/form/hooks/use-field.d.ts.map +1 -1
  87. package/dist/components/features/form/hooks/use-watch.d.ts +9 -20
  88. package/dist/components/features/form/hooks/use-watch.d.ts.map +1 -1
  89. package/dist/components/features/form/index.d.ts +33 -27
  90. package/dist/components/features/form/index.d.ts.map +1 -1
  91. package/dist/components/features/form/types/index.d.ts +32 -32
  92. package/dist/components/features/form/types/index.d.ts.map +1 -1
  93. package/dist/components/features/form/utils/get-field-constraints.d.ts +11 -0
  94. package/dist/components/features/form/utils/get-field-constraints.d.ts.map +1 -0
  95. package/dist/components/features/index.d.ts +1 -0
  96. package/dist/components/features/index.d.ts.map +1 -1
  97. package/dist/components/toast.d.ts +2 -0
  98. package/dist/components/toast.d.ts.map +1 -0
  99. package/dist/data-table/index.mjs +21 -51
  100. package/dist/date-picker/index.mjs +3 -10
  101. package/dist/dialog/index.mjs +2 -5
  102. package/dist/{dialog-B0B3Kbfk.mjs → dialog-Bm2H9lrx.mjs} +4 -6
  103. package/dist/{dialog-DdrHeboM.mjs → dialog-DASRaFxD.mjs} +2 -4
  104. package/dist/dropdown/index.mjs +2 -3
  105. package/dist/{dropdown-Cdx7rOKv.mjs → dropdown-DZiAt-jS.mjs} +3 -5
  106. package/dist/{dropdown-menu-CdShrDz_.mjs → dropdown-menu-lALvDnab.mjs} +5 -7
  107. package/dist/dropzone/index.mjs +2 -5
  108. package/dist/{dropzone-B6kSN3DY.mjs → dropzone-ogtpQ4fy.mjs} +5 -8
  109. package/dist/empty-content/index.mjs +2 -3
  110. package/dist/{empty-content-B1lwLr40.mjs → empty-content-C63GPJ5d.mjs} +3 -9
  111. package/dist/form/adapters/conform/index.mjs +237 -0
  112. package/dist/form/adapters/rhf/index.mjs +181 -0
  113. package/dist/form/index.mjs +3 -146
  114. package/dist/{use-stepper-DigoyHhX.mjs → form-BE1xBne4.mjs} +447 -601
  115. package/dist/get-field-constraints-BPMW8VvY.mjs +48 -0
  116. package/dist/grid/index.mjs +2 -3
  117. package/dist/hooks/index.mjs +3 -4
  118. package/dist/{use-debounce-MnfjH51L.mjs → hooks-DYjN7lvC.mjs} +1 -3
  119. package/dist/hover-card/index.mjs +2 -4
  120. package/dist/{hover-card-CEIauuie.mjs → hover-card-DDWWD5Hx.mjs} +2 -4
  121. package/dist/{icon-wrapper-BBK4z4tj.mjs → icon-wrapper-DuLp3RM1.mjs} +1 -3
  122. package/dist/icons/index.mjs +4 -5
  123. package/dist/index.mjs +66 -71
  124. package/dist/input/index.mjs +2 -5
  125. package/dist/{input-DEMoi_8F.mjs → input-DOmNpcQJ.mjs} +2 -4
  126. package/dist/{input-CYFN0Ap2.mjs → input-FKGqZypx.mjs} +3 -5
  127. package/dist/input-group/index.mjs +2 -7
  128. package/dist/{input-group-DJgYpOlq.mjs → input-group-DDtz-RT7.mjs} +5 -7
  129. package/dist/input-number/index.mjs +2 -6
  130. package/dist/{input-number-Cuy9CCg_.mjs → input-number-DEjXG2I6.mjs} +4 -6
  131. package/dist/input-with-addons/index.mjs +28 -3
  132. package/dist/label/index.mjs +2 -4
  133. package/dist/{label-mOg07fuQ.mjs → label-cnAhY-ej.mjs} +3 -6
  134. package/dist/loader-overlay/index.mjs +2 -3
  135. package/dist/{loader-overlay-8IWX_1Ga.mjs → loader-overlay-BTFdkp7W.mjs} +3 -5
  136. package/dist/map/index.mjs +2 -14
  137. package/dist/{map-CaI1EshG.mjs → map-Cw7u8r6E.mjs} +10 -14
  138. package/dist/{map-leaflet-imports-J7w1V7mh.mjs → map-leaflet-imports-D6nTEOIh.mjs} +1 -2
  139. package/dist/more-actions/index.mjs +2 -5
  140. package/dist/{more-actions-BO5ikUxY.mjs → more-actions-BNQ2yfWZ.mjs} +5 -7
  141. package/dist/nprogress/index.mjs +1 -3
  142. package/dist/page-title/index.mjs +2 -3
  143. package/dist/{page-title-DWteBy1E.mjs → page-title-CNiRNZ7p.mjs} +2 -4
  144. package/dist/popover/index.mjs +2 -4
  145. package/dist/{popover-ugw5MpuT.mjs → popover-FJAcbYoH.mjs} +2 -4
  146. package/dist/radio-group/index.mjs +2 -4
  147. package/dist/{radio-group-_gMymwnb.mjs → radio-group-CiITR0LO.mjs} +3 -6
  148. package/dist/select/index.mjs +2 -4
  149. package/dist/{select-BZOKWjlH.mjs → select-CiLR_DiQ.mjs} +3 -6
  150. package/dist/separator/index.mjs +2 -4
  151. package/dist/{separator-BzyALya2.mjs → separator-DXVTncCK.mjs} +2 -4
  152. package/dist/sheet/index.mjs +3 -5
  153. package/dist/{sheet-BX6lae56.mjs → sheet-BzXksqYY.mjs} +4 -6
  154. package/dist/{sheet-DAcFjaGw.mjs → sheet-Di3b-oPu.mjs} +2 -4
  155. package/dist/sidebar/index.mjs +2 -10
  156. package/dist/{sidebar-B3EV33mG.mjs → sidebar-BnhnjvfO.mjs} +10 -14
  157. package/dist/skeleton/index.mjs +2 -5
  158. package/dist/{skeleton-2vQ0vFQk.mjs → skeleton-BKl4mfJt.mjs} +2 -4
  159. package/dist/{skeleton-BgOwIgE0.mjs → skeleton-D1MUhAVo.mjs} +3 -5
  160. package/dist/spinner/index.mjs +2 -4
  161. package/dist/{spinner-osyXAlhr.mjs → spinner-OyOf9-Yu.mjs} +2 -4
  162. package/dist/{spinner.icon-C0MbtgqX.mjs → spinner.icon-C-vjSM6o.mjs} +2 -4
  163. package/dist/stepper/index.mjs +321 -5
  164. package/dist/switch/index.mjs +2 -4
  165. package/dist/{switch-C60FpEal.mjs → switch-DQJQhPIQ.mjs} +3 -6
  166. package/dist/table/index.mjs +2 -4
  167. package/dist/{table-Cl3UzIhI.mjs → table-Cdsh-39-.mjs} +2 -4
  168. package/dist/tabs/index.mjs +50 -3
  169. package/dist/tag-input/index.mjs +2 -5
  170. package/dist/{tag-input-DR2gukhL.mjs → tag-input-BKed-cul.mjs} +5 -7
  171. package/dist/task-queue/index.mjs +2 -7
  172. package/dist/{task-queue-dropdown-C9KHKbGh.mjs → task-queue-dropdown-Di_Wjspz.mjs} +10 -30
  173. package/dist/textarea/index.mjs +2 -5
  174. package/dist/{textarea-CVo38n3S.mjs → textarea-94vq_G_S.mjs} +2 -4
  175. package/dist/{textarea-CZF5n57i.mjs → textarea-BwD-MmTV.mjs} +3 -5
  176. package/dist/theme/index.mjs +2 -3
  177. package/dist/{theme.provider-TUHlMsjM.mjs → themes-DG1md8FI.mjs} +1 -6
  178. package/dist/{to-api-format-naIpF-NI.mjs → to-api-format-Cq4prffn.mjs} +9 -18
  179. package/dist/toast/index.mjs +3 -3
  180. package/dist/{use-toast-By9HuFwP.mjs → toast-BWnN5fax.mjs} +5 -42
  181. package/dist/toast-DpxlFNNx.mjs +37 -0
  182. package/dist/tooltip/index.mjs +2 -4
  183. package/dist/{tooltip-CuX2jQA9.mjs → tooltip-Cruvl5F6.mjs} +3 -6
  184. package/dist/types-BZNk3q65.mjs +357 -0
  185. package/dist/typography/index.mjs +2 -3
  186. package/dist/{typography-Iap9fU5P.mjs → typography-ClB8k55E.mjs} +2 -4
  187. package/dist/{use-copy-to-clipboard-n29wJwvW.mjs → use-copy-to-clipboard-BGdTmkFV.mjs} +2 -4
  188. package/dist/utils/index.mjs +2 -3
  189. package/dist/{utils-DJboNGQM.mjs → utils-C8KwMfT_.mjs} +1 -3
  190. package/dist/visually-hidden/index.mjs +2 -3
  191. package/dist/{visuallyhidden-BJsQCmg-.mjs → visuallyhidden-BLUsJpYH.mjs} +1 -3
  192. package/package.json +44 -3
  193. package/dist/input-with-addons-B8rzNhpq.mjs +0 -30
  194. package/dist/stepper-BMsn7I78.mjs +0 -323
  195. package/dist/tabs-DJU7JA3h.mjs +0 -52
@@ -1,28 +1,25 @@
1
- import { t as cn } from "./cn-DWCc1QRE.mjs";
2
- import { t as Button } from "./button-0N61fmAR.mjs";
3
- import { t as Icon } from "./icon-wrapper-BBK4z4tj.mjs";
4
- import { t as Checkbox } from "./checkbox-CQrjygFt.mjs";
5
- import { t as Dialog } from "./dialog-B0B3Kbfk.mjs";
6
- import { t as Input } from "./input-CYFN0Ap2.mjs";
7
- import { t as Label } from "./label-mOg07fuQ.mjs";
8
- import { n as RadioGroupItem, t as RadioGroup } from "./radio-group-_gMymwnb.mjs";
9
- import { i as SelectItem, l as SelectTrigger, n as SelectContent, t as Select, u as SelectValue } from "./select-BZOKWjlH.mjs";
10
- import { t as Tooltip } from "./tooltip-CuX2jQA9.mjs";
11
- import { t as Switch } from "./switch-C60FpEal.mjs";
12
- import { t as Textarea } from "./textarea-CZF5n57i.mjs";
13
- import { t as Autocomplete } from "./autocomplete-DRB_kSVx.mjs";
14
- import { r as toast } from "./use-toast-By9HuFwP.mjs";
15
- import { t as useCopyToClipboard } from "./use-copy-to-clipboard-n29wJwvW.mjs";
16
- import { t as defineStepper } from "./stepper-BMsn7I78.mjs";
17
- import { t as InputWithAddons } from "./input-with-addons-B8rzNhpq.mjs";
18
- import { Form } from "./form/index.mjs";
1
+ import { t as cn } from "./cn-D2KYQ917.mjs";
2
+ import { t as Button } from "./button-BllvE9Lm.mjs";
3
+ import { t as Icon } from "./icon-wrapper-DuLp3RM1.mjs";
4
+ import { t as Checkbox } from "./checkbox-I5BvrMPe.mjs";
5
+ import { t as Dialog } from "./dialog-Bm2H9lrx.mjs";
6
+ import { t as Input } from "./input-FKGqZypx.mjs";
7
+ import { t as Label } from "./label-cnAhY-ej.mjs";
8
+ import { n as RadioGroupItem, t as RadioGroup } from "./radio-group-CiITR0LO.mjs";
9
+ import { i as SelectItem, l as SelectTrigger, n as SelectContent, t as Select, u as SelectValue } from "./select-CiLR_DiQ.mjs";
10
+ import { t as Tooltip } from "./tooltip-Cruvl5F6.mjs";
11
+ import { t as Switch } from "./switch-DQJQhPIQ.mjs";
12
+ import { t as Textarea } from "./textarea-BwD-MmTV.mjs";
13
+ import { t as Autocomplete } from "./autocomplete-V5-qslzS.mjs";
14
+ import { t as toast } from "./toast-BWnN5fax.mjs";
15
+ import { t as useCopyToClipboard } from "./use-copy-to-clipboard-BGdTmkFV.mjs";
16
+ import { n as useAdapter } from "./adapter-context-B7L2ucTr.mjs";
17
+ import { defineStepper } from "./stepper/index.mjs";
18
+ import { InputWithAddons } from "./input-with-addons/index.mjs";
19
19
  import { CheckIcon, CircleHelp, CopyIcon } from "lucide-react";
20
20
  import * as React$1 from "react";
21
21
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
22
- import { FormProvider, getFormProps, getInputProps, getTextareaProps, useForm, useFormMetadata, useInputControl } from "@conform-to/react";
23
- import { getZodConstraint, parseWithZod } from "@conform-to/zod/v4";
24
22
  import { z } from "zod";
25
-
26
23
  //#region src/components/features/form/context/field-context.tsx
27
24
  const FieldContext = React$1.createContext(null);
28
25
  function FieldProvider({ children, value }) {
@@ -43,7 +40,6 @@ function useFieldContext$1() {
43
40
  function useOptionalFieldContext() {
44
41
  return React$1.use(FieldContext);
45
42
  }
46
-
47
43
  //#endregion
48
44
  //#region src/components/features/form/components/form-autocomplete.tsx
49
45
  /**
@@ -85,28 +81,26 @@ function useOptionalFieldContext() {
85
81
  * ```
86
82
  */
87
83
  function FormAutocomplete({ disabled, className, ...props }) {
88
- const { fieldMeta, disabled: fieldDisabled, errors } = useFieldContext$1();
89
- const control = useInputControl(fieldMeta);
84
+ const { id, errors, disabled: fieldDisabled, fieldState } = useFieldContext$1();
90
85
  const isDisabled = disabled ?? fieldDisabled;
91
86
  const hasErrors = errors && errors.length > 0;
92
- const selectValue = Array.isArray(control.value) ? control.value[0] : control.value;
87
+ const value = fieldState?.value != null ? String(fieldState.value) : "";
93
88
  return /* @__PURE__ */ jsx(Autocomplete, {
94
89
  ...props,
95
- name: fieldMeta.name,
96
- id: fieldMeta.id,
97
- value: selectValue ?? "",
98
- onValueChange: control.change,
90
+ name: fieldState?.name,
91
+ id,
92
+ value,
93
+ onValueChange: (val) => fieldState?.change(val),
99
94
  disabled: isDisabled,
100
95
  triggerClassName: cn(hasErrors && "border-destructive", props.triggerClassName),
101
96
  className
102
97
  });
103
98
  }
104
99
  FormAutocomplete.displayName = "Form.Autocomplete";
105
-
106
100
  //#endregion
107
101
  //#region src/components/features/form/context/form-context.tsx
108
102
  const FormContext = React$1.createContext(null);
109
- function FormProvider$1({ children, value }) {
103
+ function FormProvider({ children, value }) {
110
104
  return /* @__PURE__ */ jsx(FormContext, {
111
105
  value,
112
106
  children
@@ -117,7 +111,6 @@ function useFormContext$1() {
117
111
  if (!context) throw new Error("useFormContext must be used within a Form.Root component");
118
112
  return context;
119
113
  }
120
-
121
114
  //#endregion
122
115
  //#region src/components/features/form/components/form-button.tsx
123
116
  /**
@@ -151,7 +144,6 @@ function FormButton({ children, onClick, type = "quaternary", theme = "borderles
151
144
  });
152
145
  }
153
146
  FormButton.displayName = "Form.Button";
154
-
155
147
  //#endregion
156
148
  //#region src/components/features/form/components/form-checkbox.tsx
157
149
  /**
@@ -167,34 +159,27 @@ FormButton.displayName = "Form.Button";
167
159
  * ```
168
160
  */
169
161
  function FormCheckbox({ label, disabled, className }) {
170
- const { fieldMeta, disabled: fieldDisabled, errors } = useFieldContext$1();
171
- const control = useInputControl(fieldMeta);
162
+ const { id, errors, disabled: fieldDisabled, fieldState } = useFieldContext$1();
172
163
  const isDisabled = disabled ?? fieldDisabled;
173
164
  const hasErrors = errors && errors.length > 0;
174
- const isChecked = control.value === "on" || control.value === "true";
175
- const handleCheckedChange = (checked) => {
176
- control.change(checked ? "on" : "");
177
- };
178
- const checkboxId = fieldMeta.id;
165
+ const checked = Boolean(fieldState?.value);
179
166
  return /* @__PURE__ */ jsxs("div", {
180
167
  className: cn("flex items-center space-x-2", className),
181
168
  children: [/* @__PURE__ */ jsx(Checkbox, {
182
- id: checkboxId,
183
- name: fieldMeta.name,
184
- checked: isChecked,
185
- onCheckedChange: handleCheckedChange,
169
+ id,
170
+ checked,
171
+ onCheckedChange: (value) => fieldState?.change(Boolean(value)),
186
172
  disabled: isDisabled,
187
173
  "aria-invalid": hasErrors || void 0,
188
- "aria-describedby": hasErrors ? `${fieldMeta.id}-error` : void 0
174
+ "aria-describedby": hasErrors ? `${id}-error` : void 0
189
175
  }), label && /* @__PURE__ */ jsx(Label, {
190
- htmlFor: checkboxId,
176
+ htmlFor: id,
191
177
  className: cn("cursor-pointer text-sm font-normal", isDisabled && "cursor-not-allowed opacity-70"),
192
178
  children: label
193
179
  })]
194
180
  });
195
181
  }
196
182
  FormCheckbox.displayName = "Form.Checkbox";
197
-
198
183
  //#endregion
199
184
  //#region src/components/features/form/components/form-copy-box.tsx
200
185
  /**
@@ -225,20 +210,14 @@ FormCheckbox.displayName = "Form.Checkbox";
225
210
  * ```
226
211
  */
227
212
  function FormCopyBox({ variant = "default", className, contentClassName, buttonClassName, placeholder = "" }) {
228
- const { fieldMeta } = useFieldContext$1();
229
- const control = useInputControl(fieldMeta);
230
- const [_, copy] = useCopyToClipboard();
231
- const [copied, setCopied] = React$1.useState(false);
232
- const value = control.value ?? placeholder;
213
+ const { fieldState } = useFieldContext$1();
214
+ const [copied, copy] = useCopyToClipboard();
215
+ const value = fieldState?.value != null ? String(fieldState.value) : "";
216
+ const displayValue = value || placeholder;
233
217
  const copyToClipboard = () => {
234
- const stringValue = String(value);
235
- if (!stringValue) return;
236
- copy(stringValue).then(() => {
218
+ if (!value) return;
219
+ copy(value).then(() => {
237
220
  toast.success("Copied to clipboard");
238
- setCopied(true);
239
- setTimeout(() => {
240
- setCopied(false);
241
- }, 2e3);
242
221
  });
243
222
  };
244
223
  return /* @__PURE__ */ jsxs("div", {
@@ -247,7 +226,7 @@ function FormCopyBox({ variant = "default", className, contentClassName, buttonC
247
226
  className: cn("flex w-full items-center overflow-hidden px-3 py-2 text-xs opacity-50", contentClassName),
248
227
  children: /* @__PURE__ */ jsx("span", {
249
228
  className: "truncate",
250
- children: String(value)
229
+ children: displayValue
251
230
  })
252
231
  }), /* @__PURE__ */ jsx("div", {
253
232
  className: "flex items-center py-2 pr-3",
@@ -267,7 +246,6 @@ function FormCopyBox({ variant = "default", className, contentClassName, buttonC
267
246
  })]
268
247
  });
269
248
  }
270
-
271
249
  //#endregion
272
250
  //#region src/components/features/form/components/form-custom.tsx
273
251
  /**
@@ -302,7 +280,6 @@ function FormCustom({ children }) {
302
280
  }) });
303
281
  }
304
282
  FormCustom.displayName = "Form.Custom";
305
-
306
283
  //#endregion
307
284
  //#region src/components/features/form/components/form-description.tsx
308
285
  /**
@@ -327,7 +304,6 @@ function FormDescription({ children, className }) {
327
304
  });
328
305
  }
329
306
  FormDescription.displayName = "Form.Description";
330
-
331
307
  //#endregion
332
308
  //#region src/components/features/form/components/form-dialog.tsx
333
309
  /**
@@ -461,7 +437,6 @@ function FormDialog({ open, onOpenChange, defaultOpen, title, description, trigg
461
437
  });
462
438
  }
463
439
  FormDialog.displayName = "Form.Dialog";
464
-
465
440
  //#endregion
466
441
  //#region src/components/features/form/components/form-error.tsx
467
442
  /**
@@ -502,12 +477,8 @@ function FormError({ children, className }) {
502
477
  });
503
478
  }
504
479
  FormError.displayName = "Form.Error";
505
-
506
480
  //#endregion
507
481
  //#region src/components/features/form/components/form-field.tsx
508
- /**
509
- * Internal FieldLabel component with hover-reveal tooltip
510
- */
511
482
  function FieldLabel({ htmlFor, label, hasErrors, required, tooltip, className }) {
512
483
  const [isTooltipVisible, setIsTooltipVisible] = React$1.useState(false);
513
484
  return /* @__PURE__ */ jsxs("div", {
@@ -534,93 +505,70 @@ function FieldLabel({ htmlFor, label, hasErrors, required, tooltip, className })
534
505
  });
535
506
  }
536
507
  /**
537
- * Form.Field - Field wrapper component
538
- *
539
- * Provides field context to children with:
540
- * - Automatic label rendering
541
- * - Error display
542
- * - Description text
543
- * - Required indicator
544
- * - Accessibility attributes
545
- *
546
- * Supports two patterns:
547
- * 1. ReactNode children - for standard Form inputs
548
- * 2. Render function - for custom components needing field access
508
+ * Form.Field - Field wrapper that provides label, errors, and description.
509
+ * Uses the active adapter to resolve field state by name.
549
510
  *
550
511
  * @example Standard usage
551
512
  * ```tsx
552
- * <Form.Field name="email" label="Email Address" required>
513
+ * <Form.Field name="email" label="Email" required>
553
514
  * <Form.Input type="email" />
554
515
  * </Form.Field>
555
516
  * ```
556
517
  *
557
518
  * @example Render function for custom components
558
519
  * ```tsx
559
- * <Form.Field name="role" label="Role" required>
560
- * {({ control, meta, fields }) => (
561
- * <CustomSelect
562
- * name={meta.name}
563
- * value={control.value}
564
- * onChange={control.change}
565
- * />
520
+ * <Form.Field name="role" label="Role">
521
+ * {({ control, meta }) => (
522
+ * <CustomSelect value={control.value} onChange={control.change} />
566
523
  * )}
567
524
  * </Form.Field>
568
525
  * ```
569
526
  */
570
527
  function FormField({ name, children, label, description, tooltip, required = false, disabled = false, className, labelClassName }) {
571
- const { fields, form, isSubmitting } = useFormContext$1();
572
- const fieldMeta = React$1.useMemo(() => {
573
- const parts = name.split(".");
574
- let current = fields;
575
- for (let i = 0; i < parts.length; i++) {
576
- const part = parts[i];
577
- if (!current) break;
578
- if (/^\d+$/.test(part)) {
579
- const fieldList = current.getFieldList?.();
580
- if (fieldList) {
581
- const item = fieldList[Number.parseInt(part, 10)];
582
- if (i < parts.length - 1 && item?.getFieldset) current = item.getFieldset();
583
- else current = item;
584
- } else current = current[part];
585
- } else if (current[part] !== void 0) current = current[part];
586
- else if (typeof current.getFieldset === "function") current = current.getFieldset()[part];
587
- else current = void 0;
588
- }
589
- return current;
590
- }, [fields, name]);
591
- const errors = fieldMeta?.errors;
592
- const hasErrors = errors && errors.length > 0;
593
- const fieldId = fieldMeta?.id ?? "";
528
+ const adapter = useAdapter();
529
+ const { fields, isSubmitting, form } = useFormContext$1();
530
+ const fieldState = adapter.useField(name);
531
+ const errors = fieldState.errors;
532
+ const hasErrors = errors.length > 0;
533
+ const fieldId = fieldState.id;
594
534
  const descriptionId = description ? `${fieldId}-description` : void 0;
595
535
  const errorId = hasErrors ? `${fieldId}-error` : void 0;
536
+ const fieldRequired = required || fieldState.required;
596
537
  const contextValue = React$1.useMemo(() => ({
597
- name: fieldMeta?.name ?? "",
538
+ name,
598
539
  id: fieldId,
599
540
  errors,
600
- required,
541
+ required: fieldRequired,
601
542
  disabled,
602
- fieldMeta
543
+ fieldState
603
544
  }), [
604
- fieldMeta,
545
+ name,
605
546
  fieldId,
606
547
  errors,
607
- required,
608
- disabled
548
+ fieldRequired,
549
+ disabled,
550
+ fieldState
609
551
  ]);
610
- if (!fieldMeta) {
611
- console.warn(`Form.Field: Field "${name}" not found in form schema`);
612
- return null;
613
- }
614
552
  const isRenderFunction = typeof children === "function";
615
553
  const renderContent = () => {
616
- if (isRenderFunction) return /* @__PURE__ */ jsx(FormFieldRenderContent, {
617
- fieldMeta,
554
+ if (isRenderFunction) return children({
555
+ field: fieldState,
556
+ control: {
557
+ value: fieldState.value,
558
+ change: fieldState.change,
559
+ blur: fieldState.blur,
560
+ focus: fieldState.focus
561
+ },
562
+ meta: {
563
+ name,
564
+ id: fieldId,
565
+ errors,
566
+ required: fieldRequired,
567
+ disabled
568
+ },
618
569
  fields,
619
570
  form,
620
- isSubmitting,
621
- required,
622
- disabled,
623
- children
571
+ isSubmitting
624
572
  });
625
573
  return children;
626
574
  };
@@ -633,7 +581,7 @@ function FormField({ name, children, label, description, tooltip, required = fal
633
581
  htmlFor: fieldId,
634
582
  label,
635
583
  hasErrors,
636
- required,
584
+ required: fieldRequired,
637
585
  tooltip,
638
586
  className: labelClassName
639
587
  }),
@@ -657,47 +605,11 @@ function FormField({ name, children, label, description, tooltip, required = fal
657
605
  })
658
606
  });
659
607
  }
660
- /**
661
- * Internal component to handle render function pattern
662
- * This is needed because hooks (useInputControl) must be called unconditionally
663
- */
664
- function FormFieldRenderContent({ fieldMeta, fields, form, isSubmitting, required, disabled, children }) {
665
- const control = useInputControl(fieldMeta);
666
- const meta = React$1.useMemo(() => ({
667
- name: fieldMeta.name,
668
- id: fieldMeta.id,
669
- errors: fieldMeta.errors,
670
- required,
671
- disabled
672
- }), [
673
- fieldMeta.name,
674
- fieldMeta.id,
675
- fieldMeta.errors,
676
- required,
677
- disabled
678
- ]);
679
- return /* @__PURE__ */ jsx(Fragment$1, { children: children({
680
- field: fieldMeta,
681
- control: {
682
- value: control.value,
683
- change: control.change,
684
- blur: control.blur,
685
- focus: control.focus
686
- },
687
- meta,
688
- fields,
689
- form,
690
- isSubmitting
691
- }) });
692
- }
693
608
  FormField.displayName = "Form.Field";
694
-
695
609
  //#endregion
696
610
  //#region src/components/features/form/components/form-field-array.tsx
697
611
  /**
698
- * Form.FieldArray - Dynamic array of fields
699
- *
700
- * Provides helpers for managing arrays of form fields.
612
+ * Form.FieldArray - Dynamic array of fields with append/remove/move helpers.
701
613
  *
702
614
  * @example
703
615
  * ```tsx
@@ -705,82 +617,29 @@ FormField.displayName = "Form.Field";
705
617
  * {({ fields, append, remove }) => (
706
618
  * <>
707
619
  * {fields.map((field, index) => (
708
- * <div key={field.key} className="flex gap-2">
620
+ * <div key={field.key}>
709
621
  * <Form.Field name={`members.${index}.email`} label="Email">
710
622
  * <Form.Input type="email" />
711
623
  * </Form.Field>
712
- * <Form.Field name={`members.${index}.role`} label="Role">
713
- * <Form.Select>
714
- * <Form.SelectItem value="admin">Admin</Form.SelectItem>
715
- * <Form.SelectItem value="user">User</Form.SelectItem>
716
- * </Form.Select>
717
- * </Form.Field>
718
- * <button type="button" onClick={() => remove(index)}>
719
- * Remove
720
- * </button>
624
+ * <button onClick={() => remove(index)}>Remove</button>
721
625
  * </div>
722
626
  * ))}
723
- * <button type="button" onClick={() => append({ email: '', role: 'user' })}>
724
- * Add Member
725
- * </button>
627
+ * <button onClick={() => append({})}>Add Member</button>
726
628
  * </>
727
629
  * )}
728
630
  * </Form.FieldArray>
729
631
  * ```
730
632
  */
731
633
  function FormFieldArray({ name, children }) {
732
- const { fields, formId } = useFormContext$1();
733
- const form = useFormMetadata(formId);
734
- const arrayField = React$1.useMemo(() => {
735
- const parts = name.split(".");
736
- let current = fields;
737
- for (const part of parts) {
738
- if (!current) break;
739
- if (typeof current.getFieldset === "function") current = current.getFieldset()[part];
740
- else current = current[part];
741
- }
742
- return current;
743
- }, [fields, name]);
744
- const arrayFieldName = arrayField?.name ?? "";
745
- const append = React$1.useCallback((value = {}) => {
746
- if (!arrayFieldName) return;
747
- form.insert({
748
- name: arrayFieldName,
749
- defaultValue: value
750
- });
751
- }, [form, arrayFieldName]);
752
- const remove = React$1.useCallback((index) => {
753
- if (!arrayFieldName) return;
754
- form.remove({
755
- name: arrayFieldName,
756
- index
757
- });
758
- }, [form, arrayFieldName]);
759
- const move = React$1.useCallback((from, to) => {
760
- if (!arrayFieldName) return;
761
- form.reorder({
762
- name: arrayFieldName,
763
- from,
764
- to
765
- });
766
- }, [form, arrayFieldName]);
767
- if (!arrayField) {
768
- console.warn(`Form.FieldArray: Field "${name}" not found in form schema`);
769
- return null;
770
- }
634
+ const fieldArray = useAdapter().useFieldArray(name);
771
635
  return /* @__PURE__ */ jsx(Fragment$1, { children: children({
772
- fields: (arrayField.getFieldList?.() ?? []).map((field, index) => ({
773
- id: field.id,
774
- key: field.key,
775
- name: `${name}.${index}`
776
- })),
777
- append,
778
- remove,
779
- move
636
+ fields: fieldArray.items,
637
+ append: fieldArray.append,
638
+ remove: fieldArray.remove,
639
+ move: fieldArray.move
780
640
  }) });
781
641
  }
782
642
  FormFieldArray.displayName = "Form.FieldArray";
783
-
784
643
  //#endregion
785
644
  //#region src/components/features/form/components/form-input.tsx
786
645
  /**
@@ -796,23 +655,25 @@ FormFieldArray.displayName = "Form.FieldArray";
796
655
  * ```
797
656
  */
798
657
  function FormInput({ ref, type = "text", className, disabled, ...props }) {
799
- const { fieldMeta, disabled: fieldDisabled, errors } = useFieldContext$1();
800
- const inputProps = getInputProps(fieldMeta, { type });
658
+ const { id, errors, disabled: fieldDisabled, fieldState } = useFieldContext$1();
801
659
  const isDisabled = disabled ?? fieldDisabled;
802
660
  const hasErrors = errors && errors.length > 0;
803
661
  return /* @__PURE__ */ jsx(Input, {
804
- ref,
805
- ...inputProps,
806
662
  ...props,
663
+ ref,
664
+ id,
665
+ name: fieldState?.name,
807
666
  type,
667
+ value: fieldState?.value ?? "",
668
+ onChange: (e) => fieldState?.change(e.target.value),
669
+ onBlur: () => fieldState?.blur(),
670
+ className: cn("!text-xs", className),
808
671
  disabled: isDisabled,
809
672
  "aria-invalid": hasErrors || void 0,
810
- "aria-describedby": hasErrors ? `${fieldMeta.id}-error` : void 0,
811
- className: cn("!text-xs", className)
673
+ "aria-describedby": hasErrors ? `${id}-error` : void 0
812
674
  });
813
675
  }
814
676
  FormInput.displayName = "Form.Input";
815
-
816
677
  //#endregion
817
678
  //#region src/components/features/form/components/form-radio-group.tsx
818
679
  /**
@@ -832,18 +693,15 @@ FormInput.displayName = "Form.Input";
832
693
  * ```
833
694
  */
834
695
  function FormRadioGroup({ orientation = "vertical", disabled, className, children }) {
835
- const { fieldMeta, disabled: fieldDisabled, errors } = useFieldContext$1();
836
- const control = useInputControl(fieldMeta);
696
+ const { id, errors, disabled: fieldDisabled, fieldState } = useFieldContext$1();
837
697
  const isDisabled = disabled ?? fieldDisabled;
838
698
  const hasErrors = errors && errors.length > 0;
839
- const radioValue = Array.isArray(control.value) ? control.value[0] : control.value;
840
699
  return /* @__PURE__ */ jsx(RadioGroup, {
841
- name: fieldMeta.name,
842
- value: radioValue ?? "",
843
- onValueChange: control.change,
700
+ value: fieldState?.value != null ? String(fieldState.value) : void 0,
701
+ onValueChange: (val) => fieldState?.change(val),
844
702
  disabled: isDisabled,
845
703
  "aria-invalid": hasErrors || void 0,
846
- "aria-describedby": hasErrors ? `${fieldMeta.id}-error` : void 0,
704
+ "aria-describedby": hasErrors ? `${id}-error` : void 0,
847
705
  className: cn(orientation === "horizontal" ? "flex flex-row space-x-4" : "flex flex-col space-y-2", className),
848
706
  children
849
707
  });
@@ -880,25 +738,15 @@ function FormRadioItem({ value, label, description, disabled }) {
880
738
  });
881
739
  }
882
740
  FormRadioItem.displayName = "Form.RadioItem";
883
-
884
741
  //#endregion
885
742
  //#region src/components/features/form/components/form-root.tsx
886
743
  /**
887
- * Form.Root - The root form component
888
- *
889
- * Provides form context to all children with built-in:
890
- * - Zod schema validation
891
- * - Conform integration
892
- * - Optional telemetry callbacks
893
- *
894
- * Supports two patterns:
895
- * 1. ReactNode children - for standard forms
896
- * 2. Render function - for forms needing access to form state
744
+ * Form.Root - Root form container that integrates with the active adapter.
897
745
  *
898
746
  * @example Standard usage
899
747
  * ```tsx
900
- * <Form.Root schema={userSchema} onSubmit={handleSubmit}>
901
- * <Form.Field name="email" label="Email" required>
748
+ * <Form.Root schema={schema} onSubmit={handleSubmit}>
749
+ * <Form.Field name="email" label="Email">
902
750
  * <Form.Input type="email" />
903
751
  * </Form.Field>
904
752
  * <Form.Submit>Save</Form.Submit>
@@ -907,153 +755,105 @@ FormRadioItem.displayName = "Form.RadioItem";
907
755
  *
908
756
  * @example Render function for form state access
909
757
  * ```tsx
910
- * <Form.Root schema={userSchema} onSubmit={handleSubmit}>
758
+ * <Form.Root schema={schema}>
911
759
  * {({ form, fields, isSubmitting }) => (
912
- * <>
913
- * <Form.Field name="email" label="Email" required>
914
- * <Form.Input type="email" />
915
- * </Form.Field>
916
- * <Button
917
- * disabled={isSubmitting}
918
- * onClick={() => form.update({ value: { email: '' } })}
919
- * >
920
- * Cancel
921
- * </Button>
922
- * <Form.Submit>Save</Form.Submit>
923
- * </>
760
+ * <Form.Field name="email"><Form.Input /></Form.Field>
924
761
  * )}
925
762
  * </Form.Root>
926
763
  * ```
927
764
  */
928
765
  function FormRoot({ schema, children, onSubmit, action, method = "POST", formComponent: FormComp = "form", id, name, defaultValues, mode = "onBlur", isSubmitting: externalIsSubmitting, onError, onSuccess, telemetry, className }) {
766
+ const adapter = useAdapter();
929
767
  const [internalIsSubmitting, setInternalIsSubmitting] = React$1.useState(false);
930
768
  const isSubmitting = externalIsSubmitting ?? internalIsSubmitting;
931
769
  const formRef = React$1.useRef(null);
932
- const shouldValidate = mode === "onChange" ? "onInput" : mode;
933
- const [form, fields] = useForm({
934
- id,
935
- constraint: getZodConstraint(schema),
936
- shouldValidate,
937
- shouldRevalidate: mode === "onSubmit" ? "onSubmit" : "onInput",
938
- defaultValue: defaultValues,
939
- onValidate({ formData }) {
940
- return parseWithZod(formData, { schema });
941
- },
942
- async onSubmit(event, { submission }) {
943
- const formName = name || id || "unnamed-form";
944
- telemetry?.onSubmit?.({
945
- formName,
770
+ const wrappedOnSubmit = React$1.useCallback(async (data) => {
771
+ setInternalIsSubmitting(true);
772
+ try {
773
+ await onSubmit?.(data);
774
+ telemetry?.onSuccess?.({
775
+ formName: name ?? "",
946
776
  formId: id
947
777
  });
948
- if (!onSubmit) {
949
- setInternalIsSubmitting(true);
950
- return;
951
- }
952
- event.preventDefault();
953
- if (submission?.status === "success") {
954
- setInternalIsSubmitting(true);
955
- try {
956
- await onSubmit(submission.value);
957
- onSuccess?.(submission.value);
958
- telemetry?.onSuccess?.({
959
- formName,
960
- formId: id
961
- });
962
- } catch (error) {
963
- telemetry?.onError?.({
964
- formName,
965
- formId: id,
966
- error
967
- });
968
- telemetry?.captureError?.(error, {
969
- message: `Form submission error: ${formName}`,
970
- tags: {
971
- "form.name": formName,
972
- "form.id": id || "unknown"
973
- }
974
- });
975
- onError?.(error);
976
- } finally {
977
- setInternalIsSubmitting(false);
978
- }
979
- } else if (submission?.status === "error") {
980
- telemetry?.onValidationError?.({
981
- formName,
982
- formId: id,
983
- fieldErrors: submission.error ?? {}
984
- });
985
- if (onError) {
986
- const { ZodError } = await import("zod");
987
- onError(new ZodError(Object.entries(submission.error ?? {}).flatMap(([path, messages]) => (messages ?? []).map((message) => ({
988
- code: "custom",
989
- path: path.split("."),
990
- message
991
- })))));
992
- }
993
- }
778
+ onSuccess?.(data);
779
+ } catch (error) {
780
+ const err = error instanceof Error ? error : new Error(String(error));
781
+ telemetry?.onError?.({
782
+ formName: name ?? "",
783
+ formId: id,
784
+ error: err
785
+ });
786
+ telemetry?.captureError?.(err, {
787
+ formName: name ?? "",
788
+ formId: id
789
+ });
790
+ onError?.(error);
791
+ } finally {
792
+ setInternalIsSubmitting(false);
994
793
  }
794
+ }, [
795
+ onSubmit,
796
+ onSuccess,
797
+ onError,
798
+ telemetry,
799
+ name,
800
+ id
801
+ ]);
802
+ const instance = adapter.useCreateForm({
803
+ schema,
804
+ defaultValues,
805
+ mode,
806
+ id,
807
+ onSubmit: onSubmit ? wrappedOnSubmit : void 0,
808
+ formRef
995
809
  });
996
- const submit = React$1.useCallback(() => {
997
- formRef.current?.requestSubmit();
998
- }, []);
999
- const reset = React$1.useCallback(() => {
1000
- form.reset();
1001
- }, [form]);
1002
810
  const contextValue = React$1.useMemo(() => ({
1003
- form,
1004
- fields,
1005
- isSubmitting,
1006
- submit,
1007
- reset,
1008
- formId: form.id
1009
- }), [
1010
- form,
1011
- fields,
811
+ form: instance,
812
+ fields: instance.fields,
1012
813
  isSubmitting,
1013
- submit,
1014
- reset
1015
- ]);
814
+ submit: () => formRef.current?.requestSubmit(),
815
+ reset: () => instance.reset(),
816
+ formId: instance.id
817
+ }), [instance, isSubmitting]);
1016
818
  const isRenderFunction = typeof children === "function";
1017
- const renderProps = React$1.useMemo(() => ({
1018
- form,
1019
- fields,
1020
- isSubmitting,
1021
- submit,
1022
- reset
1023
- }), [
1024
- form,
1025
- fields,
819
+ const renderProps = {
820
+ form: instance,
821
+ fields: instance.fields,
1026
822
  isSubmitting,
1027
- submit,
1028
- reset
1029
- ]);
823
+ submit: () => formRef.current?.requestSubmit(),
824
+ reset: () => instance.reset()
825
+ };
1030
826
  const renderChildren = () => {
1031
827
  if (isRenderFunction) return children(renderProps);
1032
828
  return children;
1033
829
  };
1034
- const { onSubmit: conformOnSubmit, ...conformFormProps } = getFormProps(form);
1035
- return /* @__PURE__ */ jsx(FormProvider$1, {
830
+ return /* @__PURE__ */ jsx(FormProvider, {
1036
831
  value: contextValue,
1037
- children: /* @__PURE__ */ jsx(FormProvider, {
1038
- context: form.context,
832
+ children: /* @__PURE__ */ jsx(adapter.FormProvider, {
833
+ instance,
1039
834
  children: /* @__PURE__ */ jsx(FormComp, {
1040
835
  ref: formRef,
1041
- ...conformFormProps,
1042
- onSubmit: (e) => {
1043
- e.stopPropagation();
1044
- conformOnSubmit(e);
1045
- },
836
+ ...instance.formProps,
1046
837
  method,
1047
838
  action,
1048
839
  className: cn("space-y-6", className),
1049
840
  autoComplete: "off",
841
+ noValidate: true,
842
+ onSubmit: (e) => {
843
+ e.stopPropagation();
844
+ telemetry?.onSubmit?.({
845
+ formName: name ?? "",
846
+ formId: id
847
+ });
848
+ const adapterSubmit = instance.formProps.onSubmit;
849
+ adapterSubmit?.(e);
850
+ },
1050
851
  children: renderChildren()
1051
852
  })
1052
853
  })
1053
854
  });
1054
855
  }
1055
856
  FormRoot.displayName = "Form.Root";
1056
-
1057
857
  //#endregion
1058
858
  //#region src/components/features/form/components/form-select.tsx
1059
859
  /**
@@ -1073,21 +873,19 @@ FormRoot.displayName = "Form.Root";
1073
873
  * ```
1074
874
  */
1075
875
  function FormSelect({ placeholder, disabled, className, children }) {
1076
- const { fieldMeta, disabled: fieldDisabled, errors } = useFieldContext$1();
1077
- const control = useInputControl(fieldMeta);
876
+ const { id, errors, disabled: fieldDisabled, fieldState } = useFieldContext$1();
1078
877
  const isDisabled = disabled ?? fieldDisabled;
1079
878
  const hasErrors = errors && errors.length > 0;
1080
- const selectValue = Array.isArray(control.value) ? control.value[0] : control.value;
1081
879
  return /* @__PURE__ */ jsxs(Select, {
1082
- name: fieldMeta.name,
1083
- value: selectValue ?? "",
1084
- onValueChange: control.change,
880
+ value: fieldState?.value != null ? String(fieldState.value) : void 0,
881
+ onValueChange: (val) => fieldState?.change(val),
1085
882
  disabled: isDisabled,
1086
883
  children: [/* @__PURE__ */ jsx(SelectTrigger, {
1087
- id: fieldMeta.id,
1088
- "aria-invalid": hasErrors || void 0,
1089
- "aria-describedby": hasErrors ? `${fieldMeta.id}-error` : void 0,
884
+ id,
1090
885
  className: cn(className),
886
+ "aria-invalid": hasErrors || void 0,
887
+ "aria-describedby": hasErrors ? `${id}-error` : void 0,
888
+ onBlur: () => fieldState?.blur(),
1091
889
  children: /* @__PURE__ */ jsx(SelectValue, { placeholder })
1092
890
  }), /* @__PURE__ */ jsx(SelectContent, { children })]
1093
891
  });
@@ -1109,7 +907,6 @@ function FormSelectItem({ value, children, disabled }) {
1109
907
  });
1110
908
  }
1111
909
  FormSelectItem.displayName = "Form.SelectItem";
1112
-
1113
910
  //#endregion
1114
911
  //#region src/components/features/form/components/form-submit.tsx
1115
912
  /**
@@ -1134,7 +931,6 @@ function FormSubmit({ children, loadingText, loading = false, ...props }) {
1134
931
  });
1135
932
  }
1136
933
  FormSubmit.displayName = "Form.Submit";
1137
-
1138
934
  //#endregion
1139
935
  //#region src/components/features/form/components/form-switch.tsx
1140
936
  /**
@@ -1150,34 +946,27 @@ FormSubmit.displayName = "Form.Submit";
1150
946
  * ```
1151
947
  */
1152
948
  function FormSwitch({ label, disabled, className }) {
1153
- const { fieldMeta, disabled: fieldDisabled, errors } = useFieldContext$1();
1154
- const control = useInputControl(fieldMeta);
949
+ const { id, errors, disabled: fieldDisabled, fieldState } = useFieldContext$1();
1155
950
  const isDisabled = disabled ?? fieldDisabled;
1156
951
  const hasErrors = errors && errors.length > 0;
1157
- const isChecked = control.value === "on" || control.value === "true";
1158
- const handleCheckedChange = (checked) => {
1159
- control.change(checked ? "on" : "");
1160
- };
1161
- const switchId = fieldMeta.id;
952
+ const checked = Boolean(fieldState?.value);
1162
953
  return /* @__PURE__ */ jsxs("div", {
1163
954
  className: cn("flex items-center space-x-2", className),
1164
955
  children: [/* @__PURE__ */ jsx(Switch, {
1165
- id: switchId,
1166
- name: fieldMeta.name,
1167
- checked: isChecked,
1168
- onCheckedChange: handleCheckedChange,
956
+ id,
957
+ checked,
958
+ onCheckedChange: (value) => fieldState?.change(Boolean(value)),
1169
959
  disabled: isDisabled,
1170
960
  "aria-invalid": hasErrors || void 0,
1171
- "aria-describedby": hasErrors ? `${fieldMeta.id}-error` : void 0
961
+ "aria-describedby": hasErrors ? `${id}-error` : void 0
1172
962
  }), label && /* @__PURE__ */ jsx(Label, {
1173
- htmlFor: switchId,
963
+ htmlFor: id,
1174
964
  className: cn("cursor-pointer text-sm font-normal", isDisabled && "cursor-not-allowed opacity-70"),
1175
965
  children: label
1176
966
  })]
1177
967
  });
1178
968
  }
1179
969
  FormSwitch.displayName = "Form.Switch";
1180
-
1181
970
  //#endregion
1182
971
  //#region src/components/features/form/components/form-textarea.tsx
1183
972
  /**
@@ -1193,102 +982,60 @@ FormSwitch.displayName = "Form.Switch";
1193
982
  * ```
1194
983
  */
1195
984
  function FormTextarea({ ref, className, disabled, rows = 3, ...props }) {
1196
- const { fieldMeta, disabled: fieldDisabled, errors } = useFieldContext$1();
1197
- const textareaProps = getTextareaProps(fieldMeta);
985
+ const { id, errors, disabled: fieldDisabled, fieldState } = useFieldContext$1();
1198
986
  const isDisabled = disabled ?? fieldDisabled;
1199
987
  const hasErrors = errors && errors.length > 0;
1200
988
  return /* @__PURE__ */ jsx(Textarea, {
1201
- ref,
1202
- ...textareaProps,
1203
989
  ...props,
990
+ ref,
991
+ id,
992
+ name: fieldState?.name,
993
+ value: fieldState?.value ?? "",
994
+ onChange: (e) => fieldState?.change(e.target.value),
995
+ onBlur: () => fieldState?.blur(),
1204
996
  rows,
997
+ className: cn(className),
1205
998
  disabled: isDisabled,
1206
999
  "aria-invalid": hasErrors || void 0,
1207
- "aria-describedby": hasErrors ? `${fieldMeta.id}-error` : void 0,
1208
- className: cn(className)
1000
+ "aria-describedby": hasErrors ? `${id}-error` : void 0
1209
1001
  });
1210
1002
  }
1211
1003
  FormTextarea.displayName = "Form.Textarea";
1212
-
1213
1004
  //#endregion
1214
1005
  //#region src/components/features/form/hooks/use-watch.ts
1215
1006
  /**
1216
- * Hook to watch a field's value
1217
- * Triggers re-render when the watched field value changes
1007
+ * Hook to watch a field's value reactively.
1008
+ * Delegates to the active adapter's useWatch implementation.
1218
1009
  *
1219
1010
  * @example
1220
1011
  * ```tsx
1221
1012
  * function ConditionalField() {
1222
- * const contactMethod = useWatch('contactMethod');
1223
- *
1013
+ * const contactMethod = useWatch('contactMethod')
1224
1014
  * if (contactMethod === 'email') {
1225
- * return <Form.Field name="email"><Form.Input type="email" /></Form.Field>;
1226
- * }
1227
- *
1228
- * if (contactMethod === 'phone') {
1229
- * return <Form.Field name="phone"><Form.Input type="tel" /></Form.Field>;
1015
+ * return <Form.Field name="email"><Form.Input type="email" /></Form.Field>
1230
1016
  * }
1231
- *
1232
- * return null;
1017
+ * return null
1233
1018
  * }
1234
1019
  * ```
1235
1020
  */
1236
1021
  function useWatch(name) {
1237
- const { fields } = useFormContext$1();
1238
- return useInputControl(React$1.useMemo(() => {
1239
- const parts = name.split(".");
1240
- let current = fields;
1241
- for (const part of parts) {
1242
- if (!current) break;
1243
- if (/^\d+$/.test(part)) {
1244
- const fieldList = current.getFieldList?.();
1245
- if (fieldList) current = fieldList[Number.parseInt(part, 10)]?.getFieldset?.();
1246
- else current = current[part];
1247
- } else if (typeof current.getFieldset === "function") current = current.getFieldset()[part];
1248
- else current = current[part];
1249
- }
1250
- return current;
1251
- }, [fields, name])).value;
1022
+ return useAdapter().useWatch(name);
1252
1023
  }
1253
1024
  /**
1254
- * Hook to watch multiple fields at once
1025
+ * Hook to watch multiple fields at once.
1026
+ * Delegates to the active adapter's useWatchAll implementation.
1255
1027
  *
1256
1028
  * @example
1257
1029
  * ```tsx
1258
1030
  * function Summary() {
1259
- * const values = useWatchAll(['firstName', 'lastName', 'email']);
1260
- *
1261
- * return (
1262
- * <div>
1263
- * Name: {values.firstName} {values.lastName}
1264
- * Email: {values.email}
1265
- * </div>
1266
- * );
1031
+ * const values = useWatchAll(['firstName', 'lastName', 'email'])
1032
+ * return <div>Name: {values.firstName} {values.lastName}</div>
1267
1033
  * }
1268
1034
  * ```
1269
1035
  */
1270
1036
  function useWatchAll(names) {
1271
- const { fields } = useFormContext$1();
1272
- return React$1.useMemo(() => {
1273
- const result = {};
1274
- for (const name of names) {
1275
- const parts = name.split(".");
1276
- let current = fields;
1277
- for (const part of parts) {
1278
- if (!current) break;
1279
- if (/^\d+$/.test(part)) {
1280
- const fieldList = current.getFieldList?.();
1281
- if (fieldList) current = fieldList[Number.parseInt(part, 10)]?.getFieldset?.();
1282
- else current = current[part];
1283
- } else if (typeof current.getFieldset === "function") current = current.getFieldset()[part];
1284
- else current = current[part];
1285
- }
1286
- if (current) result[name] = current.value;
1287
- }
1288
- return result;
1289
- }, [fields, names]);
1037
+ return useAdapter().useWatchAll(names);
1290
1038
  }
1291
-
1292
1039
  //#endregion
1293
1040
  //#region src/components/features/form/components/form-when.tsx
1294
1041
  /**
@@ -1330,7 +1077,6 @@ function FormWhen({ field, is, isNot, in: inArray, notIn, children }) {
1330
1077
  return /* @__PURE__ */ jsx(Fragment$1, { children });
1331
1078
  }
1332
1079
  FormWhen.displayName = "Form.When";
1333
-
1334
1080
  //#endregion
1335
1081
  //#region src/components/features/form/components/stepper/form-stepper.tsx
1336
1082
  const FormStepperContext = React$1.createContext(null);
@@ -1475,71 +1221,78 @@ function FormStepperContent({ steps, stepperDef, children, onComplete, onStepCha
1475
1221
  children
1476
1222
  }, stepper.state.current.data.id);
1477
1223
  }
1478
- function StepForm({ steps, stepper, currentStepConfig, combinedSchema, storedValues, children, onComplete, onStepChange, className, id, formComponent: FormComp = "form" }) {
1224
+ function StepForm({ steps, stepper, currentStepConfig, combinedSchema: _combinedSchema, storedValues, children, onComplete, onStepChange, className, id, formComponent: FormComp = "form" }) {
1225
+ const adapter = useAdapter();
1479
1226
  const [isSubmitting, setIsSubmitting] = React$1.useState(false);
1480
1227
  const formRef = React$1.useRef(null);
1481
- const [form, fields] = useForm({
1482
- id: id ?? "stepper-form",
1483
- constraint: getZodConstraint(combinedSchema),
1484
- shouldValidate: "onBlur",
1485
- shouldRevalidate: "onInput",
1486
- defaultValue: storedValues,
1487
- onValidate({ formData }) {
1488
- return parseWithZod(formData, { schema: currentStepConfig.schema });
1489
- },
1490
- async onSubmit(event, { submission }) {
1491
- event.preventDefault();
1492
- if (submission?.status !== "success") return;
1493
- if (submission.value) stepper.metadata.set(stepper.state.current.data.id, submission.value);
1494
- if (stepper.state.isLast) {
1495
- setIsSubmitting(true);
1496
- try {
1497
- await onComplete({
1498
- ...steps.reduce((acc, step) => ({
1499
- ...acc,
1500
- ...stepper.metadata.get(step.id) || {}
1501
- }), {}),
1502
- ...submission.value
1503
- });
1504
- } catch (error) {
1505
- console.error("Stepper form completion error:", error);
1506
- } finally {
1507
- setIsSubmitting(false);
1508
- }
1509
- } else {
1510
- const nextStepId = stepper.lookup.getNext(stepper.state.current.data.id)?.id;
1511
- if (nextStepId) {
1512
- stepper.navigation.goTo(nextStepId);
1513
- onStepChange?.(nextStepId, "next");
1514
- }
1228
+ const currentIndex = stepper.lookup.getIndex(stepper.state.current.data.id);
1229
+ const handleStepSubmit = React$1.useCallback(async (data) => {
1230
+ stepper.metadata.set(stepper.state.current.data.id, data);
1231
+ if (stepper.state.isLast) {
1232
+ setIsSubmitting(true);
1233
+ try {
1234
+ await onComplete({
1235
+ ...steps.reduce((acc, step) => ({
1236
+ ...acc,
1237
+ ...stepper.metadata.get(step.id) || {}
1238
+ }), {}),
1239
+ ...data
1240
+ });
1241
+ } catch (error) {
1242
+ console.error("Stepper form completion error:", error);
1243
+ } finally {
1244
+ setIsSubmitting(false);
1245
+ }
1246
+ } else {
1247
+ const nextStepId = stepper.lookup.getNext(stepper.state.current.data.id)?.id;
1248
+ if (nextStepId) {
1249
+ stepper.navigation.goTo(nextStepId);
1250
+ onStepChange?.(nextStepId, "next");
1515
1251
  }
1516
1252
  }
1253
+ }, [
1254
+ stepper,
1255
+ steps,
1256
+ onComplete,
1257
+ onStepChange
1258
+ ]);
1259
+ const instance = adapter.useCreateForm({
1260
+ schema: currentStepConfig.schema,
1261
+ defaultValues: storedValues,
1262
+ mode: "onSubmit",
1263
+ id: `${id ?? "stepper"}-${currentStepConfig.id}`,
1264
+ onSubmit: handleStepSubmit,
1265
+ formRef
1517
1266
  });
1518
1267
  const next = React$1.useCallback(() => {
1519
1268
  formRef.current?.requestSubmit();
1520
1269
  }, []);
1521
1270
  const prev = React$1.useCallback(() => {
1522
- if (formRef.current) {
1523
- const formData = new FormData(formRef.current);
1524
- const currentData = {};
1525
- formData.forEach((value, key) => {
1526
- if (!key.startsWith("$")) currentData[key] = value;
1527
- });
1528
- if (Object.keys(currentData).length > 0) stepper.metadata.set(stepper.state.current.data.id, currentData);
1529
- }
1271
+ const currentValues = instance.getValues();
1272
+ if (Object.keys(currentValues).length > 0) stepper.metadata.set(stepper.state.current.data.id, currentValues);
1530
1273
  const prevStepId = stepper.lookup.getPrev(stepper.state.current.data.id)?.id;
1531
1274
  if (prevStepId) {
1532
1275
  stepper.navigation.goTo(prevStepId);
1533
1276
  onStepChange?.(prevStepId, "prev");
1534
1277
  }
1535
- }, [stepper, onStepChange]);
1278
+ }, [
1279
+ instance,
1280
+ stepper,
1281
+ onStepChange
1282
+ ]);
1536
1283
  const goTo = React$1.useCallback((stepId) => {
1537
- const currentIndex = stepper.lookup.getIndex(stepper.state.current.data.id);
1538
1284
  if (stepper.lookup.getIndex(stepId) < currentIndex) {
1285
+ const currentValues = instance.getValues();
1286
+ if (Object.keys(currentValues).length > 0) stepper.metadata.set(stepper.state.current.data.id, currentValues);
1539
1287
  stepper.navigation.goTo(stepId);
1540
1288
  onStepChange?.(stepId, "prev");
1541
1289
  }
1542
- }, [stepper, onStepChange]);
1290
+ }, [
1291
+ instance,
1292
+ stepper,
1293
+ currentIndex,
1294
+ onStepChange
1295
+ ]);
1543
1296
  const getStepData = React$1.useCallback((stepId) => stepper.metadata.get(stepId), [stepper]);
1544
1297
  const getAllStepData = React$1.useCallback(() => {
1545
1298
  return steps.reduce((acc, step) => ({
@@ -1550,7 +1303,7 @@ function StepForm({ steps, stepper, currentStepConfig, combinedSchema, storedVal
1550
1303
  const stepperContextValue = React$1.useMemo(() => ({
1551
1304
  steps,
1552
1305
  current: currentStepConfig,
1553
- currentIndex: stepper.lookup.getIndex(stepper.state.current.data.id),
1306
+ currentIndex,
1554
1307
  next,
1555
1308
  prev,
1556
1309
  goTo,
@@ -1558,10 +1311,11 @@ function StepForm({ steps, stepper, currentStepConfig, combinedSchema, storedVal
1558
1311
  isLast: stepper.state.isLast,
1559
1312
  getStepData,
1560
1313
  getAllStepData,
1561
- utils: { getIndex: (id) => stepper.lookup.getIndex(id) }
1314
+ utils: { getIndex: (stepId) => stepper.lookup.getIndex(stepId) }
1562
1315
  }), [
1563
1316
  steps,
1564
1317
  currentStepConfig,
1318
+ currentIndex,
1565
1319
  stepper,
1566
1320
  next,
1567
1321
  prev,
@@ -1569,22 +1323,18 @@ function StepForm({ steps, stepper, currentStepConfig, combinedSchema, storedVal
1569
1323
  getStepData,
1570
1324
  getAllStepData
1571
1325
  ]);
1572
- const formContextValue = React$1.useMemo(() => ({
1573
- form,
1574
- fields,
1326
+ const contextValue = React$1.useMemo(() => ({
1327
+ form: instance,
1328
+ fields: instance.fields,
1575
1329
  isSubmitting,
1576
1330
  submit: () => formRef.current?.requestSubmit(),
1577
- reset: () => form.reset(),
1578
- formId: form.id
1579
- }), [
1580
- form,
1581
- fields,
1582
- isSubmitting
1583
- ]);
1331
+ reset: () => instance.reset(),
1332
+ formId: instance.id
1333
+ }), [instance, isSubmitting]);
1584
1334
  const renderProps = {
1585
1335
  steps,
1586
1336
  current: currentStepConfig,
1587
- currentIndex: stepper.lookup.getIndex(stepper.state.current.data.id),
1337
+ currentIndex,
1588
1338
  next,
1589
1339
  prev,
1590
1340
  goTo,
@@ -1596,23 +1346,27 @@ function StepForm({ steps, stepper, currentStepConfig, combinedSchema, storedVal
1596
1346
  const resolvedChildren = typeof children === "function" ? children(renderProps) : children;
1597
1347
  return /* @__PURE__ */ jsx(FormStepperContext, {
1598
1348
  value: stepperContextValue,
1599
- children: /* @__PURE__ */ jsx(FormProvider$1, {
1600
- value: formContextValue,
1601
- children: /* @__PURE__ */ jsx(FormProvider, {
1602
- context: form.context,
1349
+ children: /* @__PURE__ */ jsx(FormProvider, {
1350
+ value: contextValue,
1351
+ children: /* @__PURE__ */ jsx(adapter.FormProvider, {
1352
+ instance,
1603
1353
  children: /* @__PURE__ */ jsx(FormComp, {
1604
1354
  ref: formRef,
1605
- ...getFormProps(form),
1606
- method: "POST",
1355
+ ...instance.formProps,
1607
1356
  className: cn("space-y-6", className),
1608
1357
  autoComplete: "off",
1358
+ noValidate: true,
1359
+ onSubmit: (e) => {
1360
+ e.stopPropagation();
1361
+ const adapterSubmit = instance.formProps.onSubmit;
1362
+ adapterSubmit?.(e);
1363
+ },
1609
1364
  children: resolvedChildren
1610
1365
  })
1611
1366
  })
1612
1367
  })
1613
1368
  });
1614
1369
  }
1615
-
1616
1370
  //#endregion
1617
1371
  //#region src/components/features/form/components/stepper/form-step.tsx
1618
1372
  /**
@@ -1637,7 +1391,6 @@ function FormStep({ id, children }) {
1637
1391
  return /* @__PURE__ */ jsx(Fragment$1, { children });
1638
1392
  }
1639
1393
  FormStep.displayName = "Form.Step";
1640
-
1641
1394
  //#endregion
1642
1395
  //#region src/components/features/form/components/stepper/stepper-controls.tsx
1643
1396
  /**
@@ -1707,7 +1460,6 @@ function StepperControls({ prevLabel = "Previous", nextLabel = (isLast) => isLas
1707
1460
  });
1708
1461
  }
1709
1462
  StepperControls.displayName = "Form.StepperControls";
1710
-
1711
1463
  //#endregion
1712
1464
  //#region src/components/features/form/components/stepper/stepper-navigation.tsx
1713
1465
  /**
@@ -1806,118 +1558,82 @@ function StepperNavigation({ variant = "horizontal", labelOrientation = "vertica
1806
1558
  });
1807
1559
  }
1808
1560
  StepperNavigation.displayName = "Form.StepperNavigation";
1809
-
1810
1561
  //#endregion
1811
1562
  //#region src/components/features/form/components/form-input-group.tsx
1812
1563
  /**
1813
- * Form.Input - Text input component
1564
+ * Form.InputGroup - Input with leading/trailing addons
1814
1565
  *
1815
1566
  * Automatically wired to the parent Form.Field context.
1816
1567
  *
1817
1568
  * @example
1818
1569
  * ```tsx
1819
- * <Form.Field name="email" label="Email" required>
1820
- * <Form.Input type="email" placeholder="john@example.com" />
1570
+ * <Form.Field name="website" label="Website" required>
1571
+ * <Form.InputGroup leading="https://" placeholder="example.com" />
1821
1572
  * </Form.Field>
1822
1573
  * ```
1823
1574
  */
1824
- function FormInputGroup({ ref, type = "text", className, disabled, ...props }) {
1825
- const { fieldMeta, disabled: fieldDisabled, errors } = useFieldContext$1();
1826
- const inputProps = getInputProps(fieldMeta, { type });
1575
+ function FormInputGroup({ ref, className, disabled, ...props }) {
1576
+ const { id, errors, disabled: fieldDisabled, fieldState } = useFieldContext$1();
1827
1577
  const isDisabled = disabled ?? fieldDisabled;
1828
1578
  const hasErrors = errors && errors.length > 0;
1829
1579
  return /* @__PURE__ */ jsx(InputWithAddons, {
1830
- ref,
1831
- ...inputProps,
1832
1580
  ...props,
1833
- type,
1581
+ ref,
1582
+ id,
1583
+ name: fieldState?.name,
1584
+ value: fieldState?.value ?? "",
1585
+ onChange: (e) => fieldState?.change(e.target.value),
1586
+ onBlur: () => fieldState?.blur(),
1587
+ className: cn("text-xs!", className),
1834
1588
  disabled: isDisabled,
1835
1589
  "aria-invalid": hasErrors || void 0,
1836
- "aria-describedby": hasErrors ? `${fieldMeta.id}-error` : void 0,
1837
- className: cn("text-xs!", className)
1590
+ "aria-describedby": hasErrors ? `${id}-error` : void 0
1838
1591
  });
1839
1592
  }
1840
1593
  FormInputGroup.displayName = "Form.InputGroup";
1841
-
1842
1594
  //#endregion
1843
1595
  //#region src/components/features/form/hooks/use-field.ts
1844
1596
  /**
1845
- * Hook to access and control a specific field
1846
- * Provides field metadata, control methods, and errors
1597
+ * Hook to access and control a specific field.
1598
+ * Delegates to the active adapter's useField implementation.
1847
1599
  *
1848
1600
  * @example
1849
1601
  * ```tsx
1850
1602
  * function MyCustomInput({ name }: { name: string }) {
1851
- * const { field, control, meta, errors } = useField(name);
1852
- *
1603
+ * const { field, control, meta, errors } = useField(name)
1853
1604
  * return (
1854
- * <div>
1855
- * <input
1856
- * name={meta.name}
1857
- * id={meta.id}
1858
- * value={control.value ?? ''}
1859
- * onChange={(e) => control.change(e.target.value)}
1860
- * onBlur={control.blur}
1861
- * aria-invalid={!!errors?.length}
1862
- * />
1863
- * {errors?.map((error) => (
1864
- * <span key={error} className="text-red-500">{error}</span>
1865
- * ))}
1866
- * </div>
1867
- * );
1605
+ * <input
1606
+ * name={meta.name}
1607
+ * id={meta.id}
1608
+ * value={control.value ?? ''}
1609
+ * onChange={(e) => control.change(e.target.value)}
1610
+ * onBlur={control.blur}
1611
+ * aria-invalid={!!errors?.length}
1612
+ * />
1613
+ * )
1868
1614
  * }
1869
1615
  * ```
1870
1616
  */
1871
1617
  function useField(name) {
1872
- const { fields } = useFormContext$1();
1873
- const field = React$1.useMemo(() => {
1874
- const parts = name.split(".");
1875
- let current = fields;
1876
- for (let i = 0; i < parts.length; i++) {
1877
- const part = parts[i];
1878
- if (!current) break;
1879
- if (/^\d+$/.test(part)) {
1880
- const fieldList = current.getFieldList?.();
1881
- if (fieldList) {
1882
- const item = fieldList[Number.parseInt(part, 10)];
1883
- if (i < parts.length - 1 && item?.getFieldset) current = item.getFieldset();
1884
- else current = item;
1885
- } else current = current[part];
1886
- } else if (current[part] !== void 0) current = current[part];
1887
- else if (typeof current.getFieldset === "function") current = current.getFieldset()[part];
1888
- else current = void 0;
1889
- }
1890
- return current;
1891
- }, [fields, name]);
1892
- if (!field) throw new Error(`Field "${name}" not found in form. Make sure the field name matches your schema.`);
1893
- const control = useInputControl(field);
1894
- const controlValue = Array.isArray(control.value) ? control.value[0] : control.value;
1895
- const meta = React$1.useMemo(() => ({
1896
- name: field.name,
1897
- id: field.id,
1898
- errors: field.errors,
1899
- required: field.required ?? false,
1900
- disabled: field.disabled ?? false
1901
- }), [
1902
- field.name,
1903
- field.id,
1904
- field.errors,
1905
- field.required,
1906
- field.disabled
1907
- ]);
1618
+ const fieldState = useAdapter().useField(name);
1908
1619
  return {
1909
- field,
1620
+ field: fieldState,
1910
1621
  control: {
1911
- value: controlValue,
1912
- change: control.change,
1913
- blur: control.blur,
1914
- focus: control.focus
1622
+ value: fieldState.value,
1623
+ change: fieldState.change,
1624
+ blur: fieldState.blur,
1625
+ focus: fieldState.focus
1626
+ },
1627
+ meta: {
1628
+ name: fieldState.name,
1629
+ id: fieldState.id,
1630
+ errors: fieldState.errors,
1631
+ required: fieldState.required,
1632
+ disabled: false
1915
1633
  },
1916
- meta,
1917
- errors: field.errors
1634
+ errors: fieldState.errors
1918
1635
  };
1919
1636
  }
1920
-
1921
1637
  //#endregion
1922
1638
  //#region src/components/features/form/hooks/use-field-context.ts
1923
1639
  /**
@@ -1944,7 +1660,6 @@ function useField(name) {
1944
1660
  function useFieldContext() {
1945
1661
  return useFieldContext$1();
1946
1662
  }
1947
-
1948
1663
  //#endregion
1949
1664
  //#region src/components/features/form/hooks/use-form-context.ts
1950
1665
  /**
@@ -1966,7 +1681,6 @@ function useFieldContext() {
1966
1681
  function useFormContext() {
1967
1682
  return useFormContext$1();
1968
1683
  }
1969
-
1970
1684
  //#endregion
1971
1685
  //#region src/components/features/form/hooks/use-stepper.ts
1972
1686
  /**
@@ -2012,6 +1726,138 @@ function useStepper() {
2012
1726
  getAllStepData: context.getAllStepData
2013
1727
  };
2014
1728
  }
2015
-
2016
1729
  //#endregion
2017
- export { FormButton as A, FormField as C, FormCustom as D, FormDescription as E, FormCopyBox as O, FormFieldArray as S, FormDialog as T, FormSelectItem as _, FormInputGroup as a, FormRadioItem as b, FormStep as c, useWatch as d, useWatchAll as f, FormSelect as g, FormSubmit as h, useField as i, FormAutocomplete as j, FormCheckbox as k, FormStepper as l, FormSwitch as m, useFormContext as n, StepperNavigation as o, FormTextarea as p, useFieldContext as r, StepperControls as s, useStepper as t, FormWhen as u, FormRoot as v, FormError as w, FormInput as x, FormRadioGroup as y };
1730
+ //#region src/components/features/form/index.ts
1731
+ /**
1732
+ * Datum Form Library
1733
+ *
1734
+ * A compound component pattern form library with pluggable adapter support.
1735
+ * Choose between Conform.js or React Hook Form as your form backend,
1736
+ * with Zod for schema validation.
1737
+ *
1738
+ * ## Adapter Setup
1739
+ *
1740
+ * Wrap your app with an adapter provider:
1741
+ *
1742
+ * ```tsx
1743
+ * // Conform adapter
1744
+ * import { ConformAdapter } from '@datum-cloud/datum-ui/form/adapters/conform'
1745
+ * <ConformAdapter><App /></ConformAdapter>
1746
+ *
1747
+ * // React Hook Form adapter
1748
+ * import { RHFAdapter } from '@datum-cloud/datum-ui/form/adapters/rhf'
1749
+ * <RHFAdapter><App /></RHFAdapter>
1750
+ * ```
1751
+ *
1752
+ * @example Basic Usage
1753
+ * ```tsx
1754
+ * import { Form } from '@datum-cloud/datum-ui/form';
1755
+ * import { z } from 'zod';
1756
+ *
1757
+ * const userSchema = z.object({
1758
+ * name: z.string().min(2),
1759
+ * email: z.string().email(),
1760
+ * });
1761
+ *
1762
+ * function UserForm() {
1763
+ * return (
1764
+ * <Form.Root schema={userSchema} onSubmit={(data) => console.log(data)}>
1765
+ * <Form.Field name="name" label="Name" required>
1766
+ * <Form.Input />
1767
+ * </Form.Field>
1768
+ * <Form.Field name="email" label="Email" required>
1769
+ * <Form.Input type="email" />
1770
+ * </Form.Field>
1771
+ * <Form.Submit>Save</Form.Submit>
1772
+ * </Form.Root>
1773
+ * );
1774
+ * }
1775
+ * ```
1776
+ *
1777
+ * @example Multi-Step Form
1778
+ * ```tsx
1779
+ * const steps = [
1780
+ * { id: 'account', label: 'Account', schema: accountSchema },
1781
+ * { id: 'profile', label: 'Profile', schema: profileSchema },
1782
+ * ];
1783
+ *
1784
+ * <Form.Stepper steps={steps} onComplete={handleComplete}>
1785
+ * <Form.StepperNavigation />
1786
+ * <Form.Step id="account">...</Form.Step>
1787
+ * <Form.Step id="profile">...</Form.Step>
1788
+ * <Form.StepperControls />
1789
+ * </Form.Stepper>
1790
+ * ```
1791
+ *
1792
+ * @example Conditional Fields
1793
+ * ```tsx
1794
+ * <Form.Field name="contactMethod">
1795
+ * <Form.Select>
1796
+ * <Form.SelectItem value="email">Email</Form.SelectItem>
1797
+ * <Form.SelectItem value="phone">Phone</Form.SelectItem>
1798
+ * </Form.Select>
1799
+ * </Form.Field>
1800
+ *
1801
+ * <Form.When field="contactMethod" is="email">
1802
+ * <Form.Field name="email"><Form.Input type="email" /></Form.Field>
1803
+ * </Form.When>
1804
+ * ```
1805
+ */
1806
+ /**
1807
+ * Form compound component
1808
+ *
1809
+ * Requires an adapter provider at the application root:
1810
+ * - `<ConformAdapter>` from `@datum-cloud/datum-ui/form/adapters/conform`
1811
+ * - `<RHFAdapter>` from `@datum-cloud/datum-ui/form/adapters/rhf`
1812
+ *
1813
+ * Components:
1814
+ * - Form.Root - Main form container
1815
+ * - Form.Field - Field wrapper with label and error handling
1816
+ * - Form.Input, Form.Textarea, Form.Select, Form.Checkbox, Form.Switch, Form.RadioGroup
1817
+ * - Form.Autocomplete, Form.CopyBox, Form.InputGroup
1818
+ * - Form.When - Conditional rendering
1819
+ * - Form.FieldArray - Dynamic array of fields
1820
+ * - Form.Custom - Escape hatch for custom implementations
1821
+ * - Form.Stepper, Form.Step, Form.StepperNavigation, Form.StepperControls
1822
+ * - Form.Dialog - Form rendered inside a Dialog
1823
+ * - Form.Submit, Form.Button, Form.Error, Form.Description
1824
+ *
1825
+ * Hooks:
1826
+ * - Form.useFormContext, Form.useFieldContext, Form.useField
1827
+ * - Form.useWatch, Form.useWatchAll, Form.useStepper
1828
+ */
1829
+ const Form = {
1830
+ Root: FormRoot,
1831
+ Field: FormField,
1832
+ Submit: FormSubmit,
1833
+ Button: FormButton,
1834
+ Error: FormError,
1835
+ Description: FormDescription,
1836
+ Input: FormInput,
1837
+ Textarea: FormTextarea,
1838
+ Select: FormSelect,
1839
+ SelectItem: FormSelectItem,
1840
+ Checkbox: FormCheckbox,
1841
+ Switch: FormSwitch,
1842
+ RadioGroup: FormRadioGroup,
1843
+ RadioItem: FormRadioItem,
1844
+ CopyBox: FormCopyBox,
1845
+ Autocomplete: FormAutocomplete,
1846
+ InputGroup: FormInputGroup,
1847
+ When: FormWhen,
1848
+ FieldArray: FormFieldArray,
1849
+ Custom: FormCustom,
1850
+ Stepper: FormStepper,
1851
+ Step: FormStep,
1852
+ StepperNavigation,
1853
+ StepperControls,
1854
+ Dialog: FormDialog,
1855
+ useFormContext,
1856
+ useFieldContext,
1857
+ useField,
1858
+ useWatch,
1859
+ useWatchAll,
1860
+ useStepper
1861
+ };
1862
+ //#endregion
1863
+ export { FormButton as A, FormField as C, FormCustom as D, FormDescription as E, FormCopyBox as O, FormFieldArray as S, FormDialog as T, FormSelectItem as _, useField as a, FormRadioItem as b, FormStep as c, useWatch as d, useWatchAll as f, FormSelect as g, FormSubmit as h, useFieldContext as i, FormAutocomplete as j, FormCheckbox as k, FormStepper as l, FormSwitch as m, useStepper as n, StepperNavigation as o, FormTextarea as p, useFormContext as r, StepperControls as s, Form as t, FormWhen as u, FormRoot as v, FormError as w, FormInput as x, FormRadioGroup as y };