@datum-cloud/datum-ui 0.6.0-alpha.b817c77 → 0.6.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 (152) hide show
  1. package/README.md +4 -0
  2. package/dist/autocomplete/index.mjs +1 -1
  3. package/dist/{autocomplete-V5-qslzS.mjs → autocomplete-CkYJueBL.mjs} +2 -2
  4. package/dist/autosearch/index.mjs +199 -0
  5. package/dist/{calendar-date-picker-DWK94_DC.mjs → calendar-date-picker-CDT-8Ha8.mjs} +2 -1
  6. package/dist/combobox/index.mjs +2 -0
  7. package/dist/combobox-B-C9lJeD.mjs +97 -0
  8. package/dist/components/features/autocomplete/autocomplete.d.ts +1 -1
  9. package/dist/components/features/autocomplete/autocomplete.d.ts.map +1 -1
  10. package/dist/components/features/autocomplete/autocomplete.types.d.ts +2 -0
  11. package/dist/components/features/autocomplete/autocomplete.types.d.ts.map +1 -1
  12. package/dist/components/features/autosearch/autosearch.d.ts +35 -0
  13. package/dist/components/features/autosearch/autosearch.d.ts.map +1 -0
  14. package/dist/components/features/autosearch/autosearch.types.d.ts +51 -0
  15. package/dist/components/features/autosearch/autosearch.types.d.ts.map +1 -0
  16. package/dist/components/features/autosearch/index.d.ts +3 -0
  17. package/dist/components/features/autosearch/index.d.ts.map +1 -0
  18. package/dist/components/features/calendar-date-picker/calendar-date-picker.d.ts +2 -1
  19. package/dist/components/features/calendar-date-picker/calendar-date-picker.d.ts.map +1 -1
  20. package/dist/components/features/combobox/combobox.d.ts +27 -0
  21. package/dist/components/features/combobox/combobox.d.ts.map +1 -0
  22. package/dist/components/features/combobox/index.d.ts +3 -0
  23. package/dist/components/features/combobox/index.d.ts.map +1 -0
  24. package/dist/components/features/combobox/types.d.ts +84 -0
  25. package/dist/components/features/combobox/types.d.ts.map +1 -0
  26. package/dist/components/features/date-time-picker/date-time-picker.d.ts +9 -0
  27. package/dist/components/features/date-time-picker/date-time-picker.d.ts.map +1 -0
  28. package/dist/components/features/date-time-picker/index.d.ts +3 -0
  29. package/dist/components/features/date-time-picker/index.d.ts.map +1 -0
  30. package/dist/components/features/date-time-picker/types.d.ts +59 -0
  31. package/dist/components/features/date-time-picker/types.d.ts.map +1 -0
  32. package/dist/components/features/date-time-picker/utils/format.d.ts +13 -0
  33. package/dist/components/features/date-time-picker/utils/format.d.ts.map +1 -0
  34. package/dist/components/features/date-time-picker/utils/index.d.ts +3 -0
  35. package/dist/components/features/date-time-picker/utils/index.d.ts.map +1 -0
  36. package/dist/components/features/date-time-picker/utils/timezone.d.ts +23 -0
  37. package/dist/components/features/date-time-picker/utils/timezone.d.ts.map +1 -0
  38. package/dist/components/features/form/adapter-types.d.ts +26 -0
  39. package/dist/components/features/form/adapter-types.d.ts.map +1 -1
  40. package/dist/components/features/form/adapters/conform/conform-adapter.d.ts.map +1 -1
  41. package/dist/components/features/form/adapters/rhf/rhf-adapter.d.ts.map +1 -1
  42. package/dist/components/features/form/components/form-autocomplete.d.ts.map +1 -1
  43. package/dist/components/features/form/components/form-autosearch.d.ts +37 -0
  44. package/dist/components/features/form/components/form-autosearch.d.ts.map +1 -0
  45. package/dist/components/features/form/components/form-checkbox.d.ts.map +1 -1
  46. package/dist/components/features/form/components/form-combobox.d.ts +80 -0
  47. package/dist/components/features/form/components/form-combobox.d.ts.map +1 -0
  48. package/dist/components/features/form/components/form-copy-box.d.ts +3 -0
  49. package/dist/components/features/form/components/form-copy-box.d.ts.map +1 -1
  50. package/dist/components/features/form/components/form-custom.d.ts.map +1 -1
  51. package/dist/components/features/form/components/form-date-picker.d.ts +40 -0
  52. package/dist/components/features/form/components/form-date-picker.d.ts.map +1 -0
  53. package/dist/components/features/form/components/form-date-time-picker.d.ts +39 -0
  54. package/dist/components/features/form/components/form-date-time-picker.d.ts.map +1 -0
  55. package/dist/components/features/form/components/form-dialog.d.ts.map +1 -1
  56. package/dist/components/features/form/components/form-field.d.ts.map +1 -1
  57. package/dist/components/features/form/components/form-radio-group.d.ts.map +1 -1
  58. package/dist/components/features/form/components/form-root.d.ts.map +1 -1
  59. package/dist/components/features/form/components/form-switch.d.ts.map +1 -1
  60. package/dist/components/features/form/components/form-time-picker.d.ts +21 -0
  61. package/dist/components/features/form/components/form-time-picker.d.ts.map +1 -0
  62. package/dist/components/features/form/components/form-transfer.d.ts +37 -0
  63. package/dist/components/features/form/components/form-transfer.d.ts.map +1 -0
  64. package/dist/components/features/form/components/index.d.ts +7 -1
  65. package/dist/components/features/form/components/index.d.ts.map +1 -1
  66. package/dist/components/features/form/components/stepper/form-stepper.d.ts +3 -1
  67. package/dist/components/features/form/components/stepper/form-stepper.d.ts.map +1 -1
  68. package/dist/components/features/form/hooks/index.d.ts +1 -1
  69. package/dist/components/features/form/hooks/index.d.ts.map +1 -1
  70. package/dist/components/features/form/hooks/use-display-touched.d.ts +20 -0
  71. package/dist/components/features/form/hooks/use-display-touched.d.ts.map +1 -0
  72. package/dist/components/features/form/hooks/use-field.d.ts +4 -0
  73. package/dist/components/features/form/hooks/use-field.d.ts.map +1 -1
  74. package/dist/components/features/form/hooks/use-form-state.d.ts +36 -0
  75. package/dist/components/features/form/hooks/use-form-state.d.ts.map +1 -0
  76. package/dist/components/features/form/index.d.ts +39 -21
  77. package/dist/components/features/form/index.d.ts.map +1 -1
  78. package/dist/components/features/form/stepper/index.d.ts +17 -0
  79. package/dist/components/features/form/stepper/index.d.ts.map +1 -0
  80. package/dist/components/features/form/types/index.d.ts +46 -0
  81. package/dist/components/features/form/types/index.d.ts.map +1 -1
  82. package/dist/components/features/form/utils/get-field-constraints.d.ts +23 -1
  83. package/dist/components/features/form/utils/get-field-constraints.d.ts.map +1 -1
  84. package/dist/components/features/form/utils/get-schema-defaults.d.ts +24 -0
  85. package/dist/components/features/form/utils/get-schema-defaults.d.ts.map +1 -0
  86. package/dist/components/features/form/utils/zod-helpers.d.ts +12 -0
  87. package/dist/components/features/form/utils/zod-helpers.d.ts.map +1 -0
  88. package/dist/components/features/time-picker/index.d.ts +3 -0
  89. package/dist/components/features/time-picker/index.d.ts.map +1 -0
  90. package/dist/components/features/time-picker/time-picker.d.ts +22 -0
  91. package/dist/components/features/time-picker/time-picker.d.ts.map +1 -0
  92. package/dist/components/features/time-picker/types.d.ts +31 -0
  93. package/dist/components/features/time-picker/types.d.ts.map +1 -0
  94. package/dist/components/features/transfer/components/index.d.ts +9 -0
  95. package/dist/components/features/transfer/components/index.d.ts.map +1 -0
  96. package/dist/components/features/transfer/components/transfer-group.d.ts +7 -0
  97. package/dist/components/features/transfer/components/transfer-group.d.ts.map +1 -0
  98. package/dist/components/features/transfer/components/transfer-item.d.ts +10 -0
  99. package/dist/components/features/transfer/components/transfer-item.d.ts.map +1 -0
  100. package/dist/components/features/transfer/components/transfer-panel.d.ts +18 -0
  101. package/dist/components/features/transfer/components/transfer-panel.d.ts.map +1 -0
  102. package/dist/components/features/transfer/components/transfer-search.d.ts +9 -0
  103. package/dist/components/features/transfer/components/transfer-search.d.ts.map +1 -0
  104. package/dist/components/features/transfer/hooks/use-transfer-dnd.d.ts +26 -0
  105. package/dist/components/features/transfer/hooks/use-transfer-dnd.d.ts.map +1 -0
  106. package/dist/components/features/transfer/hooks/use-transfer-state.d.ts +20 -0
  107. package/dist/components/features/transfer/hooks/use-transfer-state.d.ts.map +1 -0
  108. package/dist/components/features/transfer/index.d.ts +3 -0
  109. package/dist/components/features/transfer/index.d.ts.map +1 -0
  110. package/dist/components/features/transfer/transfer.d.ts +6 -0
  111. package/dist/components/features/transfer/transfer.d.ts.map +1 -0
  112. package/dist/components/features/transfer/types.d.ts +69 -0
  113. package/dist/components/features/transfer/types.d.ts.map +1 -0
  114. package/dist/data-table/index.mjs +1 -1
  115. package/dist/date-picker/index.mjs +2 -2
  116. package/dist/date-time-picker/index.mjs +2 -0
  117. package/dist/date-time-picker-BomrW07W.mjs +178 -0
  118. package/dist/form/adapters/conform/index.mjs +110 -13
  119. package/dist/form/adapters/rhf/index.mjs +116 -27
  120. package/dist/form/index.mjs +3 -3
  121. package/dist/form/stepper/index.mjs +519 -0
  122. package/dist/{form-BE1xBne4.mjs → form-B3rQ4CH9.mjs} +447 -605
  123. package/dist/form-context-Ccxm-wqL.mjs +17 -0
  124. package/dist/grid/index.mjs +1 -1
  125. package/dist/hooks/index.mjs +2 -2
  126. package/dist/index.mjs +16 -16
  127. package/dist/input-number/index.mjs +1 -1
  128. package/dist/map/index.mjs +1 -1
  129. package/dist/{map-Cw7u8r6E.mjs → map-CWIQ-eql.mjs} +1 -1
  130. package/dist/more-actions/index.mjs +1 -1
  131. package/dist/page-title/index.mjs +1 -1
  132. package/dist/stepper/index.mjs +1 -320
  133. package/dist/stepper-DvIOp0hh.mjs +321 -0
  134. package/dist/tag-input/index.mjs +1 -1
  135. package/dist/task-queue/index.mjs +1 -1
  136. package/dist/time-picker/index.mjs +2 -0
  137. package/dist/time-picker-BoF7pZZ2.mjs +43 -0
  138. package/dist/transfer/index.mjs +2 -0
  139. package/dist/transfer-46C-rFFW.mjs +264 -0
  140. package/dist/{get-field-constraints-BPMW8VvY.mjs → use-display-touched-I39aXEBD.mjs} +51 -16
  141. package/package.json +42 -1
  142. /package/dist/{adapter-context-B7L2ucTr.mjs → adapter-context-rWveHhDd.mjs} +0 -0
  143. /package/dist/{col-YBbQ5wlb.mjs → col-1T0Q3SlH.mjs} +0 -0
  144. /package/dist/{hooks-DYjN7lvC.mjs → hooks-D8r2M2U6.mjs} +0 -0
  145. /package/dist/{input-number-DEjXG2I6.mjs → input-number-a7uydAsw.mjs} +0 -0
  146. /package/dist/{map-leaflet-imports-D6nTEOIh.mjs → map-leaflet-imports-CRSKA79m.mjs} +0 -0
  147. /package/dist/{more-actions-BNQ2yfWZ.mjs → more-actions-ILnEZq_E.mjs} +0 -0
  148. /package/dist/{page-title-CNiRNZ7p.mjs → page-title-ChsnpBiH.mjs} +0 -0
  149. /package/dist/{tag-input-BKed-cul.mjs → tag-input-T9cUX9-G.mjs} +0 -0
  150. /package/dist/{task-queue-dropdown-Di_Wjspz.mjs → task-queue-dropdown-Wcbj-f0V.mjs} +0 -0
  151. /package/dist/{to-api-format-Cq4prffn.mjs → to-api-format-Bh3c01gr.mjs} +0 -0
  152. /package/dist/{use-copy-to-clipboard-BGdTmkFV.mjs → use-copy-to-clipboard-uNeeVHC4.mjs} +0 -0
@@ -0,0 +1,519 @@
1
+ import { t as cn } from "../../cn-D2KYQ917.mjs";
2
+ import { t as Button } from "../../button-BllvE9Lm.mjs";
3
+ import { n as useFormContext, t as FormProvider } from "../../form-context-Ccxm-wqL.mjs";
4
+ import { n as useAdapter } from "../../adapter-context-rWveHhDd.mjs";
5
+ import { t as defineStepper } from "../../stepper-DvIOp0hh.mjs";
6
+ import { CheckIcon } from "lucide-react";
7
+ import * as React$1 from "react";
8
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
+ //#region src/components/features/form/components/stepper/form-stepper.tsx
10
+ const FormStepperContext = React$1.createContext(null);
11
+ function useFormStepperContext() {
12
+ const context = React$1.use(FormStepperContext);
13
+ if (!context) throw new Error("useFormStepperContext must be used within a Form.Stepper component");
14
+ return context;
15
+ }
16
+ /**
17
+ * Convert StepConfig[] to Stepperize step format
18
+ */
19
+ function toStepperizeSteps(steps) {
20
+ return steps.map((step) => ({
21
+ id: step.id,
22
+ label: step.label,
23
+ description: step.description
24
+ }));
25
+ }
26
+ /**
27
+ * Form.Stepper - Multi-step form container
28
+ *
29
+ * Uses Stepperize internally for step navigation and a single Conform form
30
+ * instance for all steps. Schemas are auto-merged for unified validation.
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * const steps = [
35
+ * { id: 'account', label: 'Account', schema: accountSchema },
36
+ * { id: 'profile', label: 'Profile', schema: profileSchema },
37
+ * ];
38
+ *
39
+ * <Form.Stepper steps={steps} onComplete={handleComplete}>
40
+ * <Form.StepperNavigation />
41
+ *
42
+ * <Form.Step id="account">
43
+ * <Form.Field name="email" label="Email" required>
44
+ * <Form.Input type="email" />
45
+ * </Form.Field>
46
+ * </Form.Step>
47
+ *
48
+ * <Form.Step id="profile">
49
+ * <Form.Field name="name" label="Full Name" required>
50
+ * <Form.Input />
51
+ * </Form.Field>
52
+ * </Form.Step>
53
+ *
54
+ * <Form.StepperControls />
55
+ * </Form.Stepper>
56
+ * ```
57
+ */
58
+ function FormStepper({ steps, children, onComplete, onStepChange, initialStep, className, defaultValues, id, formComponent, mode = "onSubmit" }) {
59
+ const stepperDef = React$1.useMemo(() => {
60
+ return defineStepper(...toStepperizeSteps(steps));
61
+ }, [steps]);
62
+ const initialStepIndex = React$1.useMemo(() => {
63
+ if (!initialStep) return void 0;
64
+ const index = steps.findIndex((s) => s.id === initialStep);
65
+ return index >= 0 ? steps[index].id : void 0;
66
+ }, [initialStep, steps]);
67
+ const { Stepper } = stepperDef;
68
+ const providerProps = initialStepIndex ? { initialStep: initialStepIndex } : {};
69
+ return /* @__PURE__ */ jsx(Stepper.Provider, {
70
+ ...providerProps,
71
+ children: /* @__PURE__ */ jsx(FormStepperContent, {
72
+ steps,
73
+ stepperDef,
74
+ onComplete,
75
+ onStepChange,
76
+ className,
77
+ defaultValues,
78
+ id,
79
+ formComponent,
80
+ mode,
81
+ children
82
+ })
83
+ });
84
+ }
85
+ FormStepper.displayName = "Form.Stepper";
86
+ function FormStepperContent({ steps, stepperDef, children, onComplete, onStepChange, className, defaultValues, id, formComponent, mode }) {
87
+ const { useStepper } = stepperDef;
88
+ const stepper = useStepper();
89
+ return /* @__PURE__ */ jsx(StepForm, {
90
+ steps,
91
+ stepper,
92
+ currentStepConfig: React$1.useMemo(() => steps.find((s) => s.id === stepper.state.current.data.id) ?? steps[0], [steps, stepper.state.current.data.id]),
93
+ storedValues: React$1.useMemo(() => {
94
+ const allMetadata = steps.reduce((acc, step) => ({
95
+ ...acc,
96
+ ...stepper.metadata.get(step.id) || {}
97
+ }), {});
98
+ return {
99
+ ...defaultValues,
100
+ ...allMetadata
101
+ };
102
+ }, [
103
+ steps,
104
+ stepper,
105
+ defaultValues,
106
+ stepper.state.current.data.id
107
+ ]),
108
+ onComplete,
109
+ onStepChange,
110
+ className,
111
+ id,
112
+ formComponent,
113
+ mode,
114
+ children
115
+ }, stepper.state.current.data.id);
116
+ }
117
+ function StepForm({ steps, stepper, currentStepConfig, storedValues, children, onComplete, onStepChange, className, id, formComponent: FormComp = "form", mode }) {
118
+ const adapter = useAdapter();
119
+ const [isSubmitting, setIsSubmitting] = React$1.useState(false);
120
+ const [isSubmitted, setIsSubmitted] = React$1.useState(false);
121
+ const [submitCount, setSubmitCount] = React$1.useState(0);
122
+ const formRef = React$1.useRef(null);
123
+ const currentIndex = stepper.lookup.getIndex(stepper.state.current.data.id);
124
+ const handleStepSubmit = React$1.useCallback(async (data) => {
125
+ setIsSubmitted(true);
126
+ setSubmitCount((prev) => prev + 1);
127
+ stepper.metadata.set(stepper.state.current.data.id, data);
128
+ if (stepper.state.isLast) {
129
+ setIsSubmitting(true);
130
+ try {
131
+ await onComplete({
132
+ ...steps.reduce((acc, step) => ({
133
+ ...acc,
134
+ ...stepper.metadata.get(step.id) || {}
135
+ }), {}),
136
+ ...data
137
+ });
138
+ } catch {} finally {
139
+ setIsSubmitting(false);
140
+ }
141
+ } else {
142
+ const nextStepId = stepper.lookup.getNext(stepper.state.current.data.id)?.id;
143
+ if (nextStepId) {
144
+ stepper.navigation.goTo(nextStepId);
145
+ onStepChange?.(nextStepId, "next");
146
+ }
147
+ }
148
+ }, [
149
+ stepper,
150
+ steps,
151
+ onComplete,
152
+ onStepChange
153
+ ]);
154
+ const instance = adapter.useCreateForm({
155
+ schema: currentStepConfig.schema,
156
+ defaultValues: storedValues,
157
+ mode,
158
+ id: `${id ?? "stepper"}-${currentStepConfig.id}`,
159
+ onSubmit: handleStepSubmit,
160
+ formRef
161
+ });
162
+ const next = React$1.useCallback(() => {
163
+ formRef.current?.requestSubmit();
164
+ }, []);
165
+ const prev = React$1.useCallback(() => {
166
+ const currentValues = instance.getValues();
167
+ if (Object.keys(currentValues).length > 0) stepper.metadata.set(stepper.state.current.data.id, currentValues);
168
+ const prevStepId = stepper.lookup.getPrev(stepper.state.current.data.id)?.id;
169
+ if (prevStepId) {
170
+ stepper.navigation.goTo(prevStepId);
171
+ onStepChange?.(prevStepId, "prev");
172
+ }
173
+ }, [
174
+ instance,
175
+ stepper,
176
+ onStepChange
177
+ ]);
178
+ const goTo = React$1.useCallback((stepId) => {
179
+ if (stepper.lookup.getIndex(stepId) < currentIndex) {
180
+ const currentValues = instance.getValues();
181
+ if (Object.keys(currentValues).length > 0) stepper.metadata.set(stepper.state.current.data.id, currentValues);
182
+ stepper.navigation.goTo(stepId);
183
+ onStepChange?.(stepId, "prev");
184
+ }
185
+ }, [
186
+ instance,
187
+ stepper,
188
+ currentIndex,
189
+ onStepChange
190
+ ]);
191
+ const getStepData = React$1.useCallback((stepId) => stepper.metadata.get(stepId), [stepper]);
192
+ const getAllStepData = React$1.useCallback(() => {
193
+ return steps.reduce((acc, step) => ({
194
+ ...acc,
195
+ ...stepper.metadata.get(step.id) || {}
196
+ }), {});
197
+ }, [steps, stepper]);
198
+ const stepperContextValue = React$1.useMemo(() => ({
199
+ steps,
200
+ current: currentStepConfig,
201
+ currentIndex,
202
+ next,
203
+ prev,
204
+ goTo,
205
+ isFirst: stepper.state.isFirst,
206
+ isLast: stepper.state.isLast,
207
+ getStepData,
208
+ getAllStepData,
209
+ utils: { getIndex: (stepId) => stepper.lookup.getIndex(stepId) }
210
+ }), [
211
+ steps,
212
+ currentStepConfig,
213
+ currentIndex,
214
+ stepper,
215
+ next,
216
+ prev,
217
+ goTo,
218
+ getStepData,
219
+ getAllStepData
220
+ ]);
221
+ const contextValue = React$1.useMemo(() => ({
222
+ form: instance,
223
+ fields: instance.fields,
224
+ isSubmitting,
225
+ isDirty: instance.formState.isDirty,
226
+ isValid: instance.formState.isValid,
227
+ isSubmitted,
228
+ submitCount,
229
+ dirtyFields: instance.formState.dirtyFields,
230
+ touchedFields: instance.formState.touchedFields,
231
+ mode,
232
+ displayTouchedFields: instance.touchedFields,
233
+ markFieldTouched: instance.markFieldTouched,
234
+ markAllFieldsTouched: instance.markAllFieldsTouched,
235
+ submit: () => formRef.current?.requestSubmit(),
236
+ reset: () => instance.reset(),
237
+ formId: instance.id
238
+ }), [
239
+ instance,
240
+ isSubmitting,
241
+ isSubmitted,
242
+ submitCount,
243
+ mode,
244
+ instance.formState
245
+ ]);
246
+ const renderProps = {
247
+ steps,
248
+ current: currentStepConfig,
249
+ currentIndex,
250
+ next,
251
+ prev,
252
+ goTo,
253
+ isFirst: stepper.state.isFirst,
254
+ isLast: stepper.state.isLast,
255
+ getStepData,
256
+ getAllStepData
257
+ };
258
+ const resolvedChildren = typeof children === "function" ? children(renderProps) : children;
259
+ return /* @__PURE__ */ jsx(FormStepperContext, {
260
+ value: stepperContextValue,
261
+ children: /* @__PURE__ */ jsx(FormProvider, {
262
+ value: contextValue,
263
+ children: /* @__PURE__ */ jsx(adapter.FormProvider, {
264
+ instance,
265
+ children: /* @__PURE__ */ jsx(FormComp, {
266
+ ref: formRef,
267
+ ...instance.formProps,
268
+ className: cn("space-y-6", className),
269
+ autoComplete: "off",
270
+ noValidate: true,
271
+ onSubmit: (e) => {
272
+ e.stopPropagation();
273
+ const adapterSubmit = instance.formProps.onSubmit;
274
+ adapterSubmit?.(e);
275
+ },
276
+ children: resolvedChildren
277
+ })
278
+ })
279
+ })
280
+ });
281
+ }
282
+ //#endregion
283
+ //#region src/components/features/form/components/stepper/form-step.tsx
284
+ /**
285
+ * Form.Step - Individual step content container
286
+ *
287
+ * Only renders its children when the step is active.
288
+ * Works with the single-form architecture - fields remain registered
289
+ * even when unmounted, preserving their values.
290
+ *
291
+ * @example
292
+ * ```tsx
293
+ * <Form.Step id="account">
294
+ * <Form.Field name="email" label="Email" required>
295
+ * <Form.Input type="email" />
296
+ * </Form.Field>
297
+ * </Form.Step>
298
+ * ```
299
+ */
300
+ function FormStep({ id, children }) {
301
+ const { current } = useFormStepperContext();
302
+ if (current.id !== id) return null;
303
+ return /* @__PURE__ */ jsx(Fragment$1, { children });
304
+ }
305
+ FormStep.displayName = "Form.Step";
306
+ //#endregion
307
+ //#region src/components/features/form/components/stepper/stepper-controls.tsx
308
+ /**
309
+ * Form.StepperControls - Navigation buttons (Previous/Next/Submit)
310
+ *
311
+ * Provides Previous and Next/Submit buttons for navigating between steps.
312
+ * The Next button triggers form validation before advancing.
313
+ * The Previous button navigates back without validation.
314
+ *
315
+ * @example
316
+ * ```tsx
317
+ * <Form.StepperControls
318
+ * prevLabel={(isFirst) => isFirst ? 'Cancel' : 'Previous'}
319
+ * nextLabel={(isLast) => isLast ? 'Submit' : 'Next'}
320
+ * loadingText="Creating..."
321
+ * onCancel={() => setOpen(false)}
322
+ * />
323
+ * ```
324
+ *
325
+ * @example With external loading state
326
+ * ```tsx
327
+ * <Form.StepperControls
328
+ * loading={fetcher.state === 'submitting'}
329
+ * disabled={!isValid}
330
+ * loadingText="Saving..."
331
+ * />
332
+ * ```
333
+ */
334
+ function StepperControls({ prevLabel = "Previous", nextLabel = (isLast) => isLast ? "Submit" : "Next", loadingText = "Submitting...", showPrev = true, loading, disabled, onPrev, onCancel, className }) {
335
+ const { prev, isFirst, isLast } = useFormStepperContext();
336
+ const { isSubmitting: formIsSubmitting } = useFormContext();
337
+ const isLoading = loading ?? formIsSubmitting;
338
+ const isDisabled = disabled ?? false;
339
+ const getPrevLabel = () => {
340
+ if (typeof prevLabel === "function") return prevLabel(isFirst);
341
+ return prevLabel;
342
+ };
343
+ const getNextLabel = () => {
344
+ if (typeof nextLabel === "function") return nextLabel(isLast);
345
+ return nextLabel;
346
+ };
347
+ const handlePrev = () => {
348
+ if (isFirst && onCancel) onCancel();
349
+ else {
350
+ onPrev?.();
351
+ prev();
352
+ }
353
+ };
354
+ return /* @__PURE__ */ jsxs("div", {
355
+ className: cn("flex items-center justify-between gap-3", className),
356
+ children: [/* @__PURE__ */ jsx("div", { children: showPrev && /* @__PURE__ */ jsx(Button, {
357
+ htmlType: "button",
358
+ type: "quaternary",
359
+ theme: "outline",
360
+ size: "small",
361
+ onClick: handlePrev,
362
+ disabled: isLoading || isDisabled,
363
+ children: getPrevLabel()
364
+ }) }), /* @__PURE__ */ jsx(Button, {
365
+ htmlType: "submit",
366
+ type: "primary",
367
+ size: "small",
368
+ loading: isLoading,
369
+ disabled: isLoading || isDisabled,
370
+ children: isLoading && isLast ? loadingText : getNextLabel()
371
+ })]
372
+ });
373
+ }
374
+ StepperControls.displayName = "Form.StepperControls";
375
+ //#endregion
376
+ //#region src/components/features/form/components/stepper/stepper-navigation.tsx
377
+ /**
378
+ * Form.StepperNavigation - Step indicators/progress
379
+ *
380
+ * Displays visual step indicators showing current progress through the form.
381
+ * Supports horizontal and vertical variants with optional label orientation.
382
+ *
383
+ * @example
384
+ * ```tsx
385
+ * <Form.StepperNavigation variant="horizontal" labelOrientation="vertical" />
386
+ * ```
387
+ */
388
+ function StepperNavigation({ variant = "horizontal", labelOrientation = "vertical", className }) {
389
+ const { steps, currentIndex } = useFormStepperContext();
390
+ if (variant === "horizontal" && labelOrientation === "vertical") return /* @__PURE__ */ jsx("nav", {
391
+ "aria-label": "Form steps",
392
+ className: cn("flex flex-row items-start justify-between", className),
393
+ children: steps.map((step, index) => {
394
+ const isActive = index === currentIndex;
395
+ const isCompleted = index < currentIndex;
396
+ return /* @__PURE__ */ jsxs("div", {
397
+ className: "relative flex flex-1 flex-col items-center",
398
+ children: [
399
+ !(index === steps.length - 1) && /* @__PURE__ */ jsx("div", { className: "bg-stepper-line absolute top-4 right-[calc(-50%+20px)] left-[calc(50%+20px)] h-0.5" }),
400
+ /* @__PURE__ */ jsx("div", {
401
+ className: cn("relative z-10 flex h-8 w-8 items-center justify-center rounded-full border bg-transparent text-sm font-medium transition-colors", isActive && "border-primary bg-primary text-primary-foreground", isCompleted && "border-tertiary-foreground bg-tertiary-foreground text-tertiary", !isActive && !isCompleted && "border-stepper-label text-stepper-label"),
402
+ "aria-current": isActive ? "step" : void 0,
403
+ children: isCompleted ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-tertiary h-4 w-4" }) : index + 1
404
+ }),
405
+ /* @__PURE__ */ jsxs("div", {
406
+ className: "mt-1",
407
+ children: [/* @__PURE__ */ jsx("span", {
408
+ className: cn("text-xs font-medium", isActive && "text-foreground", isCompleted && "text-stepper-label", !isActive && !isCompleted && "text-stepper-label"),
409
+ children: step.label
410
+ }), step.description && /* @__PURE__ */ jsx("p", {
411
+ className: "text-muted-foreground mt-0.5 text-xs",
412
+ children: step.description
413
+ })]
414
+ })
415
+ ]
416
+ }, step.id);
417
+ })
418
+ });
419
+ if (variant === "horizontal") return /* @__PURE__ */ jsx("nav", {
420
+ "aria-label": "Form steps",
421
+ className: cn("flex flex-row items-center", className),
422
+ children: steps.map((step, index) => {
423
+ const isActive = index === currentIndex;
424
+ const isCompleted = index < currentIndex;
425
+ const isLast = index === steps.length - 1;
426
+ return /* @__PURE__ */ jsxs(React$1.Fragment, { children: [/* @__PURE__ */ jsxs("div", {
427
+ className: "flex items-center",
428
+ children: [/* @__PURE__ */ jsx("div", {
429
+ className: cn("flex h-8 w-8 items-center justify-center rounded-full border text-sm font-medium transition-colors", isActive && "border-primary bg-primary text-primary-foreground", isCompleted && "border-tertiary-foreground bg-tertiary-foreground text-tertiary", !isActive && !isCompleted && "border-stepper-label text-stepper-label"),
430
+ "aria-current": isActive ? "step" : void 0,
431
+ children: isCompleted ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-tertiary size-4" }) : index + 1
432
+ }), /* @__PURE__ */ jsx("div", {
433
+ className: "ml-2",
434
+ children: /* @__PURE__ */ jsx("span", {
435
+ className: cn("text-sm font-medium", isActive && "text-foreground", isCompleted && "text-stepper-label", !isActive && !isCompleted && "text-stepper-label"),
436
+ children: step.label
437
+ })
438
+ })]
439
+ }), !isLast && /* @__PURE__ */ jsx("div", { className: "bg-stepper-line mx-4 h-0.5 min-w-8 flex-1" })] }, step.id);
440
+ })
441
+ });
442
+ return /* @__PURE__ */ jsx("nav", {
443
+ "aria-label": "Form steps",
444
+ className: cn("flex flex-col", className),
445
+ children: steps.map((step, index) => {
446
+ const isActive = index === currentIndex;
447
+ const isCompleted = index < currentIndex;
448
+ const isLast = index === steps.length - 1;
449
+ return /* @__PURE__ */ jsxs("div", {
450
+ className: "flex flex-row",
451
+ children: [/* @__PURE__ */ jsxs("div", {
452
+ className: "flex flex-col items-center",
453
+ children: [/* @__PURE__ */ jsx("div", {
454
+ className: cn("flex h-8 w-8 items-center justify-center rounded-full border text-sm font-medium transition-colors", isActive && "border-primary bg-primary text-primary-foreground", isCompleted && "border-tertiary-foreground bg-tertiary-foreground text-tertiary", !isActive && !isCompleted && "border-stepper-label text-stepper-label"),
455
+ "aria-current": isActive ? "step" : void 0,
456
+ children: isCompleted ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-tertiary size-4" }) : index + 1
457
+ }), !isLast && /* @__PURE__ */ jsx("div", { className: "bg-stepper-line my-1 min-h-8 w-0.5 flex-1" })]
458
+ }), /* @__PURE__ */ jsxs("div", {
459
+ className: "ml-3 pb-8",
460
+ children: [/* @__PURE__ */ jsx("span", {
461
+ className: cn("text-sm font-medium", isActive && "text-foreground", isCompleted && "text-stepper-label", !isActive && !isCompleted && "text-stepper-label"),
462
+ children: step.label
463
+ }), step.description && /* @__PURE__ */ jsx("p", {
464
+ className: "text-muted-foreground mt-0.5 text-xs",
465
+ children: step.description
466
+ })]
467
+ })]
468
+ }, step.id);
469
+ })
470
+ });
471
+ }
472
+ StepperNavigation.displayName = "Form.StepperNavigation";
473
+ //#endregion
474
+ //#region src/components/features/form/hooks/use-stepper.ts
475
+ /**
476
+ * Hook to access the stepper context
477
+ * Must be used within a Form.Stepper component
478
+ *
479
+ * @example
480
+ * ```tsx
481
+ * function StepContent() {
482
+ * const {
483
+ * current,
484
+ * currentIndex,
485
+ * steps,
486
+ * next,
487
+ * prev,
488
+ * goTo,
489
+ * isFirst,
490
+ * isLast,
491
+ * } = useStepper();
492
+ *
493
+ * return (
494
+ * <div>
495
+ * <h2>Step {currentIndex + 1}: {current.label}</h2>
496
+ * <button onClick={prev} disabled={isFirst}>Previous</button>
497
+ * <button onClick={next} disabled={isLast}>Next</button>
498
+ * </div>
499
+ * );
500
+ * }
501
+ * ```
502
+ */
503
+ function useStepper() {
504
+ const context = useFormStepperContext();
505
+ return {
506
+ steps: context.steps,
507
+ current: context.current,
508
+ currentIndex: context.currentIndex,
509
+ next: context.next,
510
+ prev: context.prev,
511
+ goTo: context.goTo,
512
+ isFirst: context.isFirst,
513
+ isLast: context.isLast,
514
+ getStepData: context.getStepData,
515
+ getAllStepData: context.getAllStepData
516
+ };
517
+ }
518
+ //#endregion
519
+ export { FormStep, FormStepper, StepperControls, StepperNavigation, useStepper };