@datum-cloud/datum-ui 0.6.0-alpha.b817c77 → 0.6.0-alpha.b8a44ac
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.
- package/README.md +3 -0
- package/dist/combobox/index.mjs +2 -0
- package/dist/combobox-cKTFK4uN.mjs +96 -0
- package/dist/components/features/combobox/combobox.d.ts +27 -0
- package/dist/components/features/combobox/combobox.d.ts.map +1 -0
- package/dist/components/features/combobox/index.d.ts +3 -0
- package/dist/components/features/combobox/index.d.ts.map +1 -0
- package/dist/components/features/combobox/types.d.ts +78 -0
- package/dist/components/features/combobox/types.d.ts.map +1 -0
- package/dist/components/features/date-time-picker/date-time-picker.d.ts +9 -0
- package/dist/components/features/date-time-picker/date-time-picker.d.ts.map +1 -0
- package/dist/components/features/date-time-picker/index.d.ts +3 -0
- package/dist/components/features/date-time-picker/index.d.ts.map +1 -0
- package/dist/components/features/date-time-picker/types.d.ts +53 -0
- package/dist/components/features/date-time-picker/types.d.ts.map +1 -0
- package/dist/components/features/date-time-picker/utils/format.d.ts +13 -0
- package/dist/components/features/date-time-picker/utils/format.d.ts.map +1 -0
- package/dist/components/features/date-time-picker/utils/index.d.ts +3 -0
- package/dist/components/features/date-time-picker/utils/index.d.ts.map +1 -0
- package/dist/components/features/date-time-picker/utils/timezone.d.ts +23 -0
- package/dist/components/features/date-time-picker/utils/timezone.d.ts.map +1 -0
- package/dist/components/features/form/adapter-types.d.ts +20 -0
- package/dist/components/features/form/adapter-types.d.ts.map +1 -1
- package/dist/components/features/form/adapters/conform/conform-adapter.d.ts.map +1 -1
- package/dist/components/features/form/adapters/rhf/rhf-adapter.d.ts.map +1 -1
- package/dist/components/features/form/components/form-autosearch.d.ts +25 -0
- package/dist/components/features/form/components/form-autosearch.d.ts.map +1 -0
- package/dist/components/features/form/components/form-combobox.d.ts +76 -0
- package/dist/components/features/form/components/form-combobox.d.ts.map +1 -0
- package/dist/components/features/form/components/form-copy-box.d.ts +3 -0
- package/dist/components/features/form/components/form-copy-box.d.ts.map +1 -1
- package/dist/components/features/form/components/form-custom.d.ts.map +1 -1
- package/dist/components/features/form/components/form-date-picker.d.ts +38 -0
- package/dist/components/features/form/components/form-date-picker.d.ts.map +1 -0
- package/dist/components/features/form/components/form-date-time-picker.d.ts +37 -0
- package/dist/components/features/form/components/form-date-time-picker.d.ts.map +1 -0
- package/dist/components/features/form/components/form-dialog.d.ts.map +1 -1
- package/dist/components/features/form/components/form-radio-group.d.ts.map +1 -1
- package/dist/components/features/form/components/form-root.d.ts.map +1 -1
- package/dist/components/features/form/components/form-time-picker.d.ts +21 -0
- package/dist/components/features/form/components/form-time-picker.d.ts.map +1 -0
- package/dist/components/features/form/components/form-transfer.d.ts +37 -0
- package/dist/components/features/form/components/form-transfer.d.ts.map +1 -0
- package/dist/components/features/form/components/index.d.ts +7 -1
- package/dist/components/features/form/components/index.d.ts.map +1 -1
- package/dist/components/features/form/components/stepper/form-stepper.d.ts.map +1 -1
- package/dist/components/features/form/hooks/index.d.ts +1 -1
- package/dist/components/features/form/hooks/index.d.ts.map +1 -1
- package/dist/components/features/form/hooks/use-form-state.d.ts +36 -0
- package/dist/components/features/form/hooks/use-form-state.d.ts.map +1 -0
- package/dist/components/features/form/index.d.ts +39 -21
- package/dist/components/features/form/index.d.ts.map +1 -1
- package/dist/components/features/form/stepper/index.d.ts +17 -0
- package/dist/components/features/form/stepper/index.d.ts.map +1 -0
- package/dist/components/features/form/types/index.d.ts +36 -0
- package/dist/components/features/form/types/index.d.ts.map +1 -1
- package/dist/components/features/form/utils/get-field-constraints.d.ts +23 -1
- package/dist/components/features/form/utils/get-field-constraints.d.ts.map +1 -1
- package/dist/components/features/form/utils/get-schema-defaults.d.ts +24 -0
- package/dist/components/features/form/utils/get-schema-defaults.d.ts.map +1 -0
- package/dist/components/features/form/utils/zod-helpers.d.ts +12 -0
- package/dist/components/features/form/utils/zod-helpers.d.ts.map +1 -0
- package/dist/components/features/time-picker/index.d.ts +3 -0
- package/dist/components/features/time-picker/index.d.ts.map +1 -0
- package/dist/components/features/time-picker/time-picker.d.ts +22 -0
- package/dist/components/features/time-picker/time-picker.d.ts.map +1 -0
- package/dist/components/features/time-picker/types.d.ts +31 -0
- package/dist/components/features/time-picker/types.d.ts.map +1 -0
- package/dist/components/features/transfer/components/index.d.ts +9 -0
- package/dist/components/features/transfer/components/index.d.ts.map +1 -0
- package/dist/components/features/transfer/components/transfer-group.d.ts +7 -0
- package/dist/components/features/transfer/components/transfer-group.d.ts.map +1 -0
- package/dist/components/features/transfer/components/transfer-item.d.ts +10 -0
- package/dist/components/features/transfer/components/transfer-item.d.ts.map +1 -0
- package/dist/components/features/transfer/components/transfer-panel.d.ts +18 -0
- package/dist/components/features/transfer/components/transfer-panel.d.ts.map +1 -0
- package/dist/components/features/transfer/components/transfer-search.d.ts +9 -0
- package/dist/components/features/transfer/components/transfer-search.d.ts.map +1 -0
- package/dist/components/features/transfer/hooks/use-transfer-dnd.d.ts +26 -0
- package/dist/components/features/transfer/hooks/use-transfer-dnd.d.ts.map +1 -0
- package/dist/components/features/transfer/hooks/use-transfer-state.d.ts +20 -0
- package/dist/components/features/transfer/hooks/use-transfer-state.d.ts.map +1 -0
- package/dist/components/features/transfer/index.d.ts +3 -0
- package/dist/components/features/transfer/index.d.ts.map +1 -0
- package/dist/components/features/transfer/transfer.d.ts +6 -0
- package/dist/components/features/transfer/transfer.d.ts.map +1 -0
- package/dist/components/features/transfer/types.d.ts +69 -0
- package/dist/components/features/transfer/types.d.ts.map +1 -0
- package/dist/date-picker/index.mjs +1 -1
- package/dist/date-time-picker/index.mjs +2 -0
- package/dist/date-time-picker-Dy2jrJoN.mjs +175 -0
- package/dist/form/adapters/conform/index.mjs +102 -12
- package/dist/form/adapters/rhf/index.mjs +112 -26
- package/dist/form/index.mjs +3 -3
- package/dist/form/stepper/index.mjs +541 -0
- package/dist/form-context-Ccxm-wqL.mjs +17 -0
- package/dist/{form-BE1xBne4.mjs → form-mlNLKaB5.mjs} +350 -592
- package/dist/{get-field-constraints-BPMW8VvY.mjs → get-field-constraints-BicgDkfH.mjs} +19 -16
- package/dist/grid/index.mjs +1 -1
- package/dist/hooks/index.mjs +2 -2
- package/dist/index.mjs +14 -14
- package/dist/input-number/index.mjs +1 -1
- package/dist/map/index.mjs +1 -1
- package/dist/{map-Cw7u8r6E.mjs → map-CWIQ-eql.mjs} +1 -1
- package/dist/more-actions/index.mjs +1 -1
- package/dist/page-title/index.mjs +1 -1
- package/dist/stepper/index.mjs +1 -320
- package/dist/stepper-DvIOp0hh.mjs +321 -0
- package/dist/tag-input/index.mjs +1 -1
- package/dist/task-queue/index.mjs +1 -1
- package/dist/time-picker/index.mjs +2 -0
- package/dist/time-picker-BoF7pZZ2.mjs +43 -0
- package/dist/transfer/index.mjs +2 -0
- package/dist/transfer-B2n8pgEQ.mjs +260 -0
- package/package.json +37 -1
- /package/dist/{adapter-context-B7L2ucTr.mjs → adapter-context-rWveHhDd.mjs} +0 -0
- /package/dist/{col-YBbQ5wlb.mjs → col-1T0Q3SlH.mjs} +0 -0
- /package/dist/{hooks-DYjN7lvC.mjs → hooks-D8r2M2U6.mjs} +0 -0
- /package/dist/{input-number-DEjXG2I6.mjs → input-number-a7uydAsw.mjs} +0 -0
- /package/dist/{map-leaflet-imports-D6nTEOIh.mjs → map-leaflet-imports-CRSKA79m.mjs} +0 -0
- /package/dist/{more-actions-BNQ2yfWZ.mjs → more-actions-ILnEZq_E.mjs} +0 -0
- /package/dist/{page-title-CNiRNZ7p.mjs → page-title-ChsnpBiH.mjs} +0 -0
- /package/dist/{tag-input-BKed-cul.mjs → tag-input-T9cUX9-G.mjs} +0 -0
- /package/dist/{task-queue-dropdown-Di_Wjspz.mjs → task-queue-dropdown-Wcbj-f0V.mjs} +0 -0
- /package/dist/{to-api-format-Cq4prffn.mjs → to-api-format-Bh3c01gr.mjs} +0 -0
- /package/dist/{use-copy-to-clipboard-BGdTmkFV.mjs → use-copy-to-clipboard-uNeeVHC4.mjs} +0 -0
|
@@ -11,15 +11,19 @@ import { t as Tooltip } from "./tooltip-Cruvl5F6.mjs";
|
|
|
11
11
|
import { t as Switch } from "./switch-DQJQhPIQ.mjs";
|
|
12
12
|
import { t as Textarea } from "./textarea-BwD-MmTV.mjs";
|
|
13
13
|
import { t as Autocomplete } from "./autocomplete-V5-qslzS.mjs";
|
|
14
|
+
import { t as CalendarDatePicker } from "./calendar-date-picker-DWK94_DC.mjs";
|
|
14
15
|
import { t as toast } from "./toast-BWnN5fax.mjs";
|
|
15
|
-
import { t as
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
16
|
+
import { n as useFormContext$1, t as FormProvider } from "./form-context-Ccxm-wqL.mjs";
|
|
17
|
+
import { t as Combobox } from "./combobox-cKTFK4uN.mjs";
|
|
18
|
+
import { t as useCopyToClipboard } from "./use-copy-to-clipboard-uNeeVHC4.mjs";
|
|
19
|
+
import { t as DateTimePicker } from "./date-time-picker-Dy2jrJoN.mjs";
|
|
20
|
+
import { n as useAdapter } from "./adapter-context-rWveHhDd.mjs";
|
|
18
21
|
import { InputWithAddons } from "./input-with-addons/index.mjs";
|
|
22
|
+
import { t as TimePicker } from "./time-picker-BoF7pZZ2.mjs";
|
|
23
|
+
import { t as Transfer } from "./transfer-B2n8pgEQ.mjs";
|
|
19
24
|
import { CheckIcon, CircleHelp, CopyIcon } from "lucide-react";
|
|
20
25
|
import * as React$1 from "react";
|
|
21
26
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
22
|
-
import { z } from "zod";
|
|
23
27
|
//#region src/components/features/form/context/field-context.tsx
|
|
24
28
|
const FieldContext = React$1.createContext(null);
|
|
25
29
|
function FieldProvider({ children, value }) {
|
|
@@ -98,19 +102,27 @@ function FormAutocomplete({ disabled, className, ...props }) {
|
|
|
98
102
|
}
|
|
99
103
|
FormAutocomplete.displayName = "Form.Autocomplete";
|
|
100
104
|
//#endregion
|
|
101
|
-
//#region src/components/features/form/
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
105
|
+
//#region src/components/features/form/components/form-autosearch.tsx
|
|
106
|
+
/**
|
|
107
|
+
* Form.Autosearch - Alias to Form.Autocomplete with search-first focus
|
|
108
|
+
*
|
|
109
|
+
* This is a convenience wrapper around Form.Autocomplete that emphasizes
|
|
110
|
+
* the search functionality. It's functionally identical to Form.Autocomplete.
|
|
111
|
+
*
|
|
112
|
+
* @example Basic usage
|
|
113
|
+
* ```tsx
|
|
114
|
+
* <Form.Field name="search" label="Search">
|
|
115
|
+
* <Form.Autosearch
|
|
116
|
+
* options={options}
|
|
117
|
+
* placeholder="Type to search..."
|
|
118
|
+
* />
|
|
119
|
+
* </Form.Field>
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
function FormAutosearch(props) {
|
|
123
|
+
return /* @__PURE__ */ jsx(FormAutocomplete, { ...props });
|
|
113
124
|
}
|
|
125
|
+
FormAutosearch.displayName = "Form.Autosearch";
|
|
114
126
|
//#endregion
|
|
115
127
|
//#region src/components/features/form/components/form-button.tsx
|
|
116
128
|
/**
|
|
@@ -181,6 +193,34 @@ function FormCheckbox({ label, disabled, className }) {
|
|
|
181
193
|
}
|
|
182
194
|
FormCheckbox.displayName = "Form.Checkbox";
|
|
183
195
|
//#endregion
|
|
196
|
+
//#region src/components/features/form/components/form-combobox.tsx
|
|
197
|
+
function FormCombobox({ options, placeholder, searchPlaceholder, emptyMessage, disabled, className, triggerClassName, contentClassName, searchable = true, showDropdownArrow = true, clearable = false, "data-testid": testId }) {
|
|
198
|
+
const { id, errors, disabled: fieldDisabled, fieldState } = useFieldContext$1();
|
|
199
|
+
const isDisabled = disabled ?? fieldDisabled;
|
|
200
|
+
const hasErrors = errors && errors.length > 0;
|
|
201
|
+
const handleChange = React$1.useCallback((value) => {
|
|
202
|
+
fieldState?.change(value ?? "");
|
|
203
|
+
}, [fieldState]);
|
|
204
|
+
return /* @__PURE__ */ jsx(Combobox, {
|
|
205
|
+
id,
|
|
206
|
+
options,
|
|
207
|
+
value: fieldState?.value ?? "",
|
|
208
|
+
onChange: handleChange,
|
|
209
|
+
placeholder,
|
|
210
|
+
searchPlaceholder,
|
|
211
|
+
emptyMessage,
|
|
212
|
+
disabled: isDisabled,
|
|
213
|
+
searchable,
|
|
214
|
+
showDropdownArrow,
|
|
215
|
+
clearable,
|
|
216
|
+
className,
|
|
217
|
+
triggerClassName: cn(hasErrors && "border-destructive", triggerClassName),
|
|
218
|
+
contentClassName,
|
|
219
|
+
"data-testid": testId
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
FormCombobox.displayName = "Form.Combobox";
|
|
223
|
+
//#endregion
|
|
184
224
|
//#region src/components/features/form/components/form-copy-box.tsx
|
|
185
225
|
/**
|
|
186
226
|
* Form.CopyBox - Read-only field with copy-to-clipboard functionality
|
|
@@ -246,6 +286,7 @@ function FormCopyBox({ variant = "default", className, contentClassName, buttonC
|
|
|
246
286
|
})]
|
|
247
287
|
});
|
|
248
288
|
}
|
|
289
|
+
FormCopyBox.displayName = "Form.CopyBox";
|
|
249
290
|
//#endregion
|
|
250
291
|
//#region src/components/features/form/components/form-custom.tsx
|
|
251
292
|
/**
|
|
@@ -270,17 +311,114 @@ function FormCopyBox({ variant = "default", className, contentClassName, buttonC
|
|
|
270
311
|
* ```
|
|
271
312
|
*/
|
|
272
313
|
function FormCustom({ children }) {
|
|
273
|
-
const
|
|
314
|
+
const ctx = useFormContext$1();
|
|
274
315
|
return /* @__PURE__ */ jsx(Fragment$1, { children: children({
|
|
275
|
-
form,
|
|
276
|
-
fields,
|
|
277
|
-
isSubmitting,
|
|
278
|
-
|
|
279
|
-
|
|
316
|
+
form: ctx.form,
|
|
317
|
+
fields: ctx.fields,
|
|
318
|
+
isSubmitting: ctx.isSubmitting,
|
|
319
|
+
isDirty: ctx.isDirty,
|
|
320
|
+
isValid: ctx.isValid,
|
|
321
|
+
isSubmitted: ctx.isSubmitted,
|
|
322
|
+
submitCount: ctx.submitCount,
|
|
323
|
+
dirtyFields: ctx.dirtyFields,
|
|
324
|
+
touchedFields: ctx.touchedFields,
|
|
325
|
+
submit: ctx.submit,
|
|
326
|
+
reset: ctx.reset
|
|
280
327
|
}) });
|
|
281
328
|
}
|
|
282
329
|
FormCustom.displayName = "Form.Custom";
|
|
283
330
|
//#endregion
|
|
331
|
+
//#region src/components/features/form/components/form-date-picker.tsx
|
|
332
|
+
function FormDatePicker({ placeholder, disabled, className, triggerClassName, numberOfMonths = 1, minDate: minDateProp, maxDate: maxDateProp, disableFuture, disablePast }) {
|
|
333
|
+
const { id, errors, disabled: fieldDisabled, fieldState } = useFieldContext$1();
|
|
334
|
+
const isDisabled = disabled ?? fieldDisabled;
|
|
335
|
+
const hasErrors = errors && errors.length > 0;
|
|
336
|
+
const currentValue = React$1.useMemo(() => {
|
|
337
|
+
const val = fieldState?.value;
|
|
338
|
+
if (!val) return {
|
|
339
|
+
from: void 0,
|
|
340
|
+
to: void 0
|
|
341
|
+
};
|
|
342
|
+
if (val instanceof Date) return {
|
|
343
|
+
from: val,
|
|
344
|
+
to: val
|
|
345
|
+
};
|
|
346
|
+
if (typeof val === "string") {
|
|
347
|
+
const date = new Date(val);
|
|
348
|
+
return {
|
|
349
|
+
from: date,
|
|
350
|
+
to: date
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
if (typeof val === "object" && "from" in val) return val;
|
|
354
|
+
return {
|
|
355
|
+
from: void 0,
|
|
356
|
+
to: void 0
|
|
357
|
+
};
|
|
358
|
+
}, [fieldState?.value]);
|
|
359
|
+
const minDate = minDateProp;
|
|
360
|
+
const maxDate = maxDateProp;
|
|
361
|
+
return /* @__PURE__ */ jsx(CalendarDatePicker, {
|
|
362
|
+
id,
|
|
363
|
+
date: currentValue,
|
|
364
|
+
onDateSelect: React$1.useCallback((range) => {
|
|
365
|
+
if (!range) {
|
|
366
|
+
fieldState?.change(void 0);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
if (numberOfMonths === 1) fieldState?.change(range.from.toISOString());
|
|
370
|
+
else fieldState?.change({
|
|
371
|
+
from: range.from.toISOString(),
|
|
372
|
+
to: range.to?.toISOString()
|
|
373
|
+
});
|
|
374
|
+
}, [fieldState, numberOfMonths]),
|
|
375
|
+
numberOfMonths,
|
|
376
|
+
placeholder,
|
|
377
|
+
disabled: isDisabled,
|
|
378
|
+
minDate,
|
|
379
|
+
maxDate,
|
|
380
|
+
disableFuture,
|
|
381
|
+
disablePast,
|
|
382
|
+
variant: "outline",
|
|
383
|
+
className: cn(className),
|
|
384
|
+
triggerClassName: cn(triggerClassName),
|
|
385
|
+
"aria-invalid": hasErrors || void 0,
|
|
386
|
+
"aria-describedby": hasErrors ? `${id}-error` : void 0
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
FormDatePicker.displayName = "Form.DatePicker";
|
|
390
|
+
//#endregion
|
|
391
|
+
//#region src/components/features/form/components/form-date-time-picker.tsx
|
|
392
|
+
function FormDateTimePicker({ minDate: minDateProp, maxDate: maxDateProp, disabledDates, timezone, showTimezoneIndicator, placeholder, disabled, className }) {
|
|
393
|
+
const { id, errors, disabled: fieldDisabled, fieldState } = useFieldContext$1();
|
|
394
|
+
const isDisabled = disabled ?? fieldDisabled;
|
|
395
|
+
const hasErrors = errors && errors.length > 0;
|
|
396
|
+
const currentValue = React$1.useMemo(() => {
|
|
397
|
+
const val = fieldState?.value;
|
|
398
|
+
if (!val) return void 0;
|
|
399
|
+
if (typeof val === "string") return val;
|
|
400
|
+
}, [fieldState?.value]);
|
|
401
|
+
const minDate = minDateProp;
|
|
402
|
+
const maxDate = maxDateProp;
|
|
403
|
+
return /* @__PURE__ */ jsx(DateTimePicker, {
|
|
404
|
+
value: currentValue,
|
|
405
|
+
onChange: React$1.useCallback((value) => {
|
|
406
|
+
fieldState?.change(value);
|
|
407
|
+
}, [fieldState]),
|
|
408
|
+
minDate,
|
|
409
|
+
maxDate,
|
|
410
|
+
disabledDates,
|
|
411
|
+
timezone,
|
|
412
|
+
showTimezoneIndicator,
|
|
413
|
+
placeholder,
|
|
414
|
+
disabled: isDisabled,
|
|
415
|
+
className: cn(className),
|
|
416
|
+
"aria-invalid": hasErrors || void 0,
|
|
417
|
+
"aria-describedby": hasErrors ? `${id}-error` : void 0
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
FormDateTimePicker.displayName = "Form.DateTimePicker";
|
|
421
|
+
//#endregion
|
|
284
422
|
//#region src/components/features/form/components/form-description.tsx
|
|
285
423
|
/**
|
|
286
424
|
* Form.Description - Display field description/helper text
|
|
@@ -377,9 +515,6 @@ function FormDialog({ open, onOpenChange, defaultOpen, title, description, trigg
|
|
|
377
515
|
try {
|
|
378
516
|
await onSubmit?.(data);
|
|
379
517
|
onSuccess?.(data);
|
|
380
|
-
} catch (error) {
|
|
381
|
-
console.error("Form submission error:", error);
|
|
382
|
-
throw error;
|
|
383
518
|
} finally {
|
|
384
519
|
if (loading === void 0) setInternalIsSubmitting(false);
|
|
385
520
|
}
|
|
@@ -675,6 +810,39 @@ function FormInput({ ref, type = "text", className, disabled, ...props }) {
|
|
|
675
810
|
}
|
|
676
811
|
FormInput.displayName = "Form.Input";
|
|
677
812
|
//#endregion
|
|
813
|
+
//#region src/components/features/form/components/form-input-group.tsx
|
|
814
|
+
/**
|
|
815
|
+
* Form.InputGroup - Input with leading/trailing addons
|
|
816
|
+
*
|
|
817
|
+
* Automatically wired to the parent Form.Field context.
|
|
818
|
+
*
|
|
819
|
+
* @example
|
|
820
|
+
* ```tsx
|
|
821
|
+
* <Form.Field name="website" label="Website" required>
|
|
822
|
+
* <Form.InputGroup leading="https://" placeholder="example.com" />
|
|
823
|
+
* </Form.Field>
|
|
824
|
+
* ```
|
|
825
|
+
*/
|
|
826
|
+
function FormInputGroup({ ref, className, disabled, ...props }) {
|
|
827
|
+
const { id, errors, disabled: fieldDisabled, fieldState } = useFieldContext$1();
|
|
828
|
+
const isDisabled = disabled ?? fieldDisabled;
|
|
829
|
+
const hasErrors = errors && errors.length > 0;
|
|
830
|
+
return /* @__PURE__ */ jsx(InputWithAddons, {
|
|
831
|
+
...props,
|
|
832
|
+
ref,
|
|
833
|
+
id,
|
|
834
|
+
name: fieldState?.name,
|
|
835
|
+
value: fieldState?.value ?? "",
|
|
836
|
+
onChange: (e) => fieldState?.change(e.target.value),
|
|
837
|
+
onBlur: () => fieldState?.blur(),
|
|
838
|
+
className: cn("text-xs!", className),
|
|
839
|
+
disabled: isDisabled,
|
|
840
|
+
"aria-invalid": hasErrors || void 0,
|
|
841
|
+
"aria-describedby": hasErrors ? `${id}-error` : void 0
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
FormInputGroup.displayName = "Form.InputGroup";
|
|
845
|
+
//#endregion
|
|
678
846
|
//#region src/components/features/form/components/form-radio-group.tsx
|
|
679
847
|
/**
|
|
680
848
|
* Form.RadioGroup - Radio button group component
|
|
@@ -716,7 +884,8 @@ FormRadioGroup.displayName = "Form.RadioGroup";
|
|
|
716
884
|
* ```
|
|
717
885
|
*/
|
|
718
886
|
function FormRadioItem({ value, label, description, disabled }) {
|
|
719
|
-
const
|
|
887
|
+
const { id: fieldId } = useFieldContext$1();
|
|
888
|
+
const radioId = `${fieldId}-radio-${value}`;
|
|
720
889
|
return /* @__PURE__ */ jsxs("div", {
|
|
721
890
|
className: "flex items-start space-x-2",
|
|
722
891
|
children: [/* @__PURE__ */ jsx(RadioGroupItem, {
|
|
@@ -766,9 +935,13 @@ function FormRoot({ schema, children, onSubmit, action, method = "POST", formCom
|
|
|
766
935
|
const adapter = useAdapter();
|
|
767
936
|
const [internalIsSubmitting, setInternalIsSubmitting] = React$1.useState(false);
|
|
768
937
|
const isSubmitting = externalIsSubmitting ?? internalIsSubmitting;
|
|
938
|
+
const [isSubmitted, setIsSubmitted] = React$1.useState(false);
|
|
939
|
+
const [submitCount, setSubmitCount] = React$1.useState(0);
|
|
769
940
|
const formRef = React$1.useRef(null);
|
|
770
941
|
const wrappedOnSubmit = React$1.useCallback(async (data) => {
|
|
771
942
|
setInternalIsSubmitting(true);
|
|
943
|
+
setIsSubmitted(true);
|
|
944
|
+
setSubmitCount((prev) => prev + 1);
|
|
772
945
|
try {
|
|
773
946
|
await onSubmit?.(data);
|
|
774
947
|
telemetry?.onSuccess?.({
|
|
@@ -807,22 +980,47 @@ function FormRoot({ schema, children, onSubmit, action, method = "POST", formCom
|
|
|
807
980
|
onSubmit: onSubmit ? wrappedOnSubmit : void 0,
|
|
808
981
|
formRef
|
|
809
982
|
});
|
|
983
|
+
const { formState } = instance;
|
|
810
984
|
const contextValue = React$1.useMemo(() => ({
|
|
811
985
|
form: instance,
|
|
812
986
|
fields: instance.fields,
|
|
813
987
|
isSubmitting,
|
|
988
|
+
isDirty: formState.isDirty,
|
|
989
|
+
isValid: formState.isValid,
|
|
990
|
+
isSubmitted,
|
|
991
|
+
submitCount,
|
|
992
|
+
dirtyFields: formState.dirtyFields,
|
|
993
|
+
touchedFields: formState.touchedFields,
|
|
814
994
|
submit: () => formRef.current?.requestSubmit(),
|
|
815
995
|
reset: () => instance.reset(),
|
|
816
996
|
formId: instance.id
|
|
817
|
-
}), [
|
|
997
|
+
}), [
|
|
998
|
+
instance,
|
|
999
|
+
isSubmitting,
|
|
1000
|
+
formState,
|
|
1001
|
+
isSubmitted,
|
|
1002
|
+
submitCount
|
|
1003
|
+
]);
|
|
818
1004
|
const isRenderFunction = typeof children === "function";
|
|
819
|
-
const renderProps = {
|
|
1005
|
+
const renderProps = React$1.useMemo(() => ({
|
|
820
1006
|
form: instance,
|
|
821
1007
|
fields: instance.fields,
|
|
822
1008
|
isSubmitting,
|
|
1009
|
+
isDirty: formState.isDirty,
|
|
1010
|
+
isValid: formState.isValid,
|
|
1011
|
+
isSubmitted,
|
|
1012
|
+
submitCount,
|
|
1013
|
+
dirtyFields: formState.dirtyFields,
|
|
1014
|
+
touchedFields: formState.touchedFields,
|
|
823
1015
|
submit: () => formRef.current?.requestSubmit(),
|
|
824
1016
|
reset: () => instance.reset()
|
|
825
|
-
}
|
|
1017
|
+
}), [
|
|
1018
|
+
instance,
|
|
1019
|
+
isSubmitting,
|
|
1020
|
+
formState,
|
|
1021
|
+
isSubmitted,
|
|
1022
|
+
submitCount
|
|
1023
|
+
]);
|
|
826
1024
|
const renderChildren = () => {
|
|
827
1025
|
if (isRenderFunction) return children(renderProps);
|
|
828
1026
|
return children;
|
|
@@ -1002,6 +1200,73 @@ function FormTextarea({ ref, className, disabled, rows = 3, ...props }) {
|
|
|
1002
1200
|
}
|
|
1003
1201
|
FormTextarea.displayName = "Form.Textarea";
|
|
1004
1202
|
//#endregion
|
|
1203
|
+
//#region src/components/features/form/components/form-time-picker.tsx
|
|
1204
|
+
function FormTimePicker({ min, max, step, placeholder, disabled, className }) {
|
|
1205
|
+
const { id, errors, disabled: fieldDisabled, fieldState } = useFieldContext$1();
|
|
1206
|
+
const isDisabled = disabled ?? fieldDisabled;
|
|
1207
|
+
const hasErrors = errors && errors.length > 0;
|
|
1208
|
+
return /* @__PURE__ */ jsx(TimePicker, {
|
|
1209
|
+
id,
|
|
1210
|
+
value: fieldState?.value ?? "",
|
|
1211
|
+
onChange: React$1.useCallback((value) => {
|
|
1212
|
+
fieldState?.change(value || void 0);
|
|
1213
|
+
}, [fieldState]),
|
|
1214
|
+
min,
|
|
1215
|
+
max,
|
|
1216
|
+
step,
|
|
1217
|
+
placeholder,
|
|
1218
|
+
disabled: isDisabled,
|
|
1219
|
+
className: cn(className),
|
|
1220
|
+
"aria-invalid": hasErrors || void 0,
|
|
1221
|
+
"aria-describedby": hasErrors ? `${id}-error` : void 0
|
|
1222
|
+
});
|
|
1223
|
+
}
|
|
1224
|
+
FormTimePicker.displayName = "Form.TimePicker";
|
|
1225
|
+
//#endregion
|
|
1226
|
+
//#region src/components/features/form/components/form-transfer.tsx
|
|
1227
|
+
/**
|
|
1228
|
+
* Form.Transfer - Transfer list component for selecting multiple items
|
|
1229
|
+
*
|
|
1230
|
+
* Automatically wired to the parent Form.Field context.
|
|
1231
|
+
* Displays minItems/maxItems constraints when provided.
|
|
1232
|
+
*
|
|
1233
|
+
* @example
|
|
1234
|
+
* ```tsx
|
|
1235
|
+
* <Form.Field name="teams" label="Select Teams">
|
|
1236
|
+
* <Form.Transfer
|
|
1237
|
+
* items={teams}
|
|
1238
|
+
* itemKey="id"
|
|
1239
|
+
* itemLabel="name"
|
|
1240
|
+
* minItems={2}
|
|
1241
|
+
* maxItems={5}
|
|
1242
|
+
* />
|
|
1243
|
+
* </Form.Field>
|
|
1244
|
+
* ```
|
|
1245
|
+
*/
|
|
1246
|
+
function FormTransfer({ disabled, minItems, maxItems, ...props }) {
|
|
1247
|
+
const { id, errors, disabled: fieldDisabled, fieldState } = useFieldContext$1();
|
|
1248
|
+
const isDisabled = disabled ?? fieldDisabled;
|
|
1249
|
+
const hasErrors = errors && errors.length > 0;
|
|
1250
|
+
const value = Array.isArray(fieldState?.value) ? fieldState.value : [];
|
|
1251
|
+
const handleChange = React$1.useCallback((newValue) => {
|
|
1252
|
+
fieldState?.change(newValue);
|
|
1253
|
+
}, [fieldState]);
|
|
1254
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
|
|
1255
|
+
"aria-invalid": hasErrors || void 0,
|
|
1256
|
+
"aria-describedby": hasErrors ? `${id}-error` : void 0,
|
|
1257
|
+
children: /* @__PURE__ */ jsx(Transfer, {
|
|
1258
|
+
...props,
|
|
1259
|
+
value,
|
|
1260
|
+
onChange: handleChange,
|
|
1261
|
+
disabled: isDisabled
|
|
1262
|
+
})
|
|
1263
|
+
}), (minItems != null || maxItems != null) && /* @__PURE__ */ jsx("p", {
|
|
1264
|
+
className: "text-sm text-muted-foreground mt-2",
|
|
1265
|
+
children: minItems != null && maxItems != null ? `Select between ${minItems} and ${maxItems} items` : minItems != null ? `Select at least ${minItems} items` : `Select up to ${maxItems} items`
|
|
1266
|
+
})] });
|
|
1267
|
+
}
|
|
1268
|
+
FormTransfer.displayName = "Form.Transfer";
|
|
1269
|
+
//#endregion
|
|
1005
1270
|
//#region src/components/features/form/hooks/use-watch.ts
|
|
1006
1271
|
/**
|
|
1007
1272
|
* Hook to watch a field's value reactively.
|
|
@@ -1078,520 +1343,6 @@ function FormWhen({ field, is, isNot, in: inArray, notIn, children }) {
|
|
|
1078
1343
|
}
|
|
1079
1344
|
FormWhen.displayName = "Form.When";
|
|
1080
1345
|
//#endregion
|
|
1081
|
-
//#region src/components/features/form/components/stepper/form-stepper.tsx
|
|
1082
|
-
const FormStepperContext = React$1.createContext(null);
|
|
1083
|
-
function useFormStepperContext() {
|
|
1084
|
-
const context = React$1.use(FormStepperContext);
|
|
1085
|
-
if (!context) throw new Error("useFormStepperContext must be used within a Form.Stepper component");
|
|
1086
|
-
return context;
|
|
1087
|
-
}
|
|
1088
|
-
/**
|
|
1089
|
-
* Recursively unwrap ZodIntersection (from .and()) to extract the base ZodObject.
|
|
1090
|
-
*
|
|
1091
|
-
* Zod v4 schema types use `def.type` as a string discriminant:
|
|
1092
|
-
* - "intersection" (from .and()): merge left + right base objects
|
|
1093
|
-
* - "object": return directly
|
|
1094
|
-
*
|
|
1095
|
-
* Note: In Zod v4, .superRefine() and .refine() return `this` (no wrapper),
|
|
1096
|
-
* so only ZodIntersection needs unwrapping.
|
|
1097
|
-
*/
|
|
1098
|
-
function getBaseObject(schema) {
|
|
1099
|
-
if (schema.def.type === "intersection") {
|
|
1100
|
-
const intersectionDef = schema.def;
|
|
1101
|
-
const left = getBaseObject(intersectionDef.left);
|
|
1102
|
-
const right = getBaseObject(intersectionDef.right);
|
|
1103
|
-
return left.merge(right);
|
|
1104
|
-
}
|
|
1105
|
-
if (schema.def.type !== "object") {
|
|
1106
|
-
console.warn(`mergeSchemas: expected ZodObject or ZodIntersection but got "${schema.def.type}". Falling back to empty object.`);
|
|
1107
|
-
return z.object({});
|
|
1108
|
-
}
|
|
1109
|
-
return schema;
|
|
1110
|
-
}
|
|
1111
|
-
/**
|
|
1112
|
-
* Merge multiple zod schemas into one ZodObject for HTML constraint generation.
|
|
1113
|
-
* Handles ZodIntersection (.and()) by unwrapping to base ZodObject shapes.
|
|
1114
|
-
* Per-step validation still uses the original schemas with all refinements intact.
|
|
1115
|
-
*/
|
|
1116
|
-
function mergeSchemas(steps) {
|
|
1117
|
-
if (steps.length === 0) throw new Error("Form.Stepper requires at least one step");
|
|
1118
|
-
return steps.reduce((acc, step, index) => {
|
|
1119
|
-
const base = getBaseObject(step.schema);
|
|
1120
|
-
if (index === 0) return base;
|
|
1121
|
-
return acc.merge(base);
|
|
1122
|
-
}, {});
|
|
1123
|
-
}
|
|
1124
|
-
/**
|
|
1125
|
-
* Convert StepConfig[] to Stepperize step format
|
|
1126
|
-
*/
|
|
1127
|
-
function toStepperizeSteps(steps) {
|
|
1128
|
-
return steps.map((step) => ({
|
|
1129
|
-
id: step.id,
|
|
1130
|
-
label: step.label,
|
|
1131
|
-
description: step.description
|
|
1132
|
-
}));
|
|
1133
|
-
}
|
|
1134
|
-
/**
|
|
1135
|
-
* Form.Stepper - Multi-step form container
|
|
1136
|
-
*
|
|
1137
|
-
* Uses Stepperize internally for step navigation and a single Conform form
|
|
1138
|
-
* instance for all steps. Schemas are auto-merged for unified validation.
|
|
1139
|
-
*
|
|
1140
|
-
* @example
|
|
1141
|
-
* ```tsx
|
|
1142
|
-
* const steps = [
|
|
1143
|
-
* { id: 'account', label: 'Account', schema: accountSchema },
|
|
1144
|
-
* { id: 'profile', label: 'Profile', schema: profileSchema },
|
|
1145
|
-
* ];
|
|
1146
|
-
*
|
|
1147
|
-
* <Form.Stepper steps={steps} onComplete={handleComplete}>
|
|
1148
|
-
* <Form.StepperNavigation />
|
|
1149
|
-
*
|
|
1150
|
-
* <Form.Step id="account">
|
|
1151
|
-
* <Form.Field name="email" label="Email" required>
|
|
1152
|
-
* <Form.Input type="email" />
|
|
1153
|
-
* </Form.Field>
|
|
1154
|
-
* </Form.Step>
|
|
1155
|
-
*
|
|
1156
|
-
* <Form.Step id="profile">
|
|
1157
|
-
* <Form.Field name="name" label="Full Name" required>
|
|
1158
|
-
* <Form.Input />
|
|
1159
|
-
* </Form.Field>
|
|
1160
|
-
* </Form.Step>
|
|
1161
|
-
*
|
|
1162
|
-
* <Form.StepperControls />
|
|
1163
|
-
* </Form.Stepper>
|
|
1164
|
-
* ```
|
|
1165
|
-
*/
|
|
1166
|
-
function FormStepper({ steps, children, onComplete, onStepChange, initialStep, className, defaultValues, id, formComponent }) {
|
|
1167
|
-
const stepperDef = React$1.useMemo(() => {
|
|
1168
|
-
return defineStepper(...toStepperizeSteps(steps));
|
|
1169
|
-
}, [steps]);
|
|
1170
|
-
const initialStepIndex = React$1.useMemo(() => {
|
|
1171
|
-
if (!initialStep) return void 0;
|
|
1172
|
-
const index = steps.findIndex((s) => s.id === initialStep);
|
|
1173
|
-
return index >= 0 ? steps[index].id : void 0;
|
|
1174
|
-
}, [initialStep, steps]);
|
|
1175
|
-
const { Stepper } = stepperDef;
|
|
1176
|
-
const providerProps = initialStepIndex ? { initialStep: initialStepIndex } : {};
|
|
1177
|
-
return /* @__PURE__ */ jsx(Stepper.Provider, {
|
|
1178
|
-
...providerProps,
|
|
1179
|
-
children: /* @__PURE__ */ jsx(FormStepperContent, {
|
|
1180
|
-
steps,
|
|
1181
|
-
stepperDef,
|
|
1182
|
-
onComplete,
|
|
1183
|
-
onStepChange,
|
|
1184
|
-
className,
|
|
1185
|
-
defaultValues,
|
|
1186
|
-
id,
|
|
1187
|
-
formComponent,
|
|
1188
|
-
children
|
|
1189
|
-
})
|
|
1190
|
-
});
|
|
1191
|
-
}
|
|
1192
|
-
FormStepper.displayName = "Form.Stepper";
|
|
1193
|
-
function FormStepperContent({ steps, stepperDef, children, onComplete, onStepChange, className, defaultValues, id, formComponent }) {
|
|
1194
|
-
const { useStepper } = stepperDef;
|
|
1195
|
-
const stepper = useStepper();
|
|
1196
|
-
return /* @__PURE__ */ jsx(StepForm, {
|
|
1197
|
-
steps,
|
|
1198
|
-
stepper,
|
|
1199
|
-
currentStepConfig: React$1.useMemo(() => steps.find((s) => s.id === stepper.state.current.data.id) ?? steps[0], [steps, stepper.state.current.data.id]),
|
|
1200
|
-
combinedSchema: React$1.useMemo(() => mergeSchemas(steps), [steps]),
|
|
1201
|
-
storedValues: React$1.useMemo(() => {
|
|
1202
|
-
const allMetadata = steps.reduce((acc, step) => ({
|
|
1203
|
-
...acc,
|
|
1204
|
-
...stepper.metadata.get(step.id) || {}
|
|
1205
|
-
}), {});
|
|
1206
|
-
return {
|
|
1207
|
-
...defaultValues,
|
|
1208
|
-
...allMetadata
|
|
1209
|
-
};
|
|
1210
|
-
}, [
|
|
1211
|
-
steps,
|
|
1212
|
-
stepper,
|
|
1213
|
-
defaultValues,
|
|
1214
|
-
stepper.state.current.data.id
|
|
1215
|
-
]),
|
|
1216
|
-
onComplete,
|
|
1217
|
-
onStepChange,
|
|
1218
|
-
className,
|
|
1219
|
-
id,
|
|
1220
|
-
formComponent,
|
|
1221
|
-
children
|
|
1222
|
-
}, stepper.state.current.data.id);
|
|
1223
|
-
}
|
|
1224
|
-
function StepForm({ steps, stepper, currentStepConfig, combinedSchema: _combinedSchema, storedValues, children, onComplete, onStepChange, className, id, formComponent: FormComp = "form" }) {
|
|
1225
|
-
const adapter = useAdapter();
|
|
1226
|
-
const [isSubmitting, setIsSubmitting] = React$1.useState(false);
|
|
1227
|
-
const formRef = React$1.useRef(null);
|
|
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");
|
|
1251
|
-
}
|
|
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
|
|
1266
|
-
});
|
|
1267
|
-
const next = React$1.useCallback(() => {
|
|
1268
|
-
formRef.current?.requestSubmit();
|
|
1269
|
-
}, []);
|
|
1270
|
-
const prev = React$1.useCallback(() => {
|
|
1271
|
-
const currentValues = instance.getValues();
|
|
1272
|
-
if (Object.keys(currentValues).length > 0) stepper.metadata.set(stepper.state.current.data.id, currentValues);
|
|
1273
|
-
const prevStepId = stepper.lookup.getPrev(stepper.state.current.data.id)?.id;
|
|
1274
|
-
if (prevStepId) {
|
|
1275
|
-
stepper.navigation.goTo(prevStepId);
|
|
1276
|
-
onStepChange?.(prevStepId, "prev");
|
|
1277
|
-
}
|
|
1278
|
-
}, [
|
|
1279
|
-
instance,
|
|
1280
|
-
stepper,
|
|
1281
|
-
onStepChange
|
|
1282
|
-
]);
|
|
1283
|
-
const goTo = React$1.useCallback((stepId) => {
|
|
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);
|
|
1287
|
-
stepper.navigation.goTo(stepId);
|
|
1288
|
-
onStepChange?.(stepId, "prev");
|
|
1289
|
-
}
|
|
1290
|
-
}, [
|
|
1291
|
-
instance,
|
|
1292
|
-
stepper,
|
|
1293
|
-
currentIndex,
|
|
1294
|
-
onStepChange
|
|
1295
|
-
]);
|
|
1296
|
-
const getStepData = React$1.useCallback((stepId) => stepper.metadata.get(stepId), [stepper]);
|
|
1297
|
-
const getAllStepData = React$1.useCallback(() => {
|
|
1298
|
-
return steps.reduce((acc, step) => ({
|
|
1299
|
-
...acc,
|
|
1300
|
-
...stepper.metadata.get(step.id) || {}
|
|
1301
|
-
}), {});
|
|
1302
|
-
}, [steps, stepper]);
|
|
1303
|
-
const stepperContextValue = React$1.useMemo(() => ({
|
|
1304
|
-
steps,
|
|
1305
|
-
current: currentStepConfig,
|
|
1306
|
-
currentIndex,
|
|
1307
|
-
next,
|
|
1308
|
-
prev,
|
|
1309
|
-
goTo,
|
|
1310
|
-
isFirst: stepper.state.isFirst,
|
|
1311
|
-
isLast: stepper.state.isLast,
|
|
1312
|
-
getStepData,
|
|
1313
|
-
getAllStepData,
|
|
1314
|
-
utils: { getIndex: (stepId) => stepper.lookup.getIndex(stepId) }
|
|
1315
|
-
}), [
|
|
1316
|
-
steps,
|
|
1317
|
-
currentStepConfig,
|
|
1318
|
-
currentIndex,
|
|
1319
|
-
stepper,
|
|
1320
|
-
next,
|
|
1321
|
-
prev,
|
|
1322
|
-
goTo,
|
|
1323
|
-
getStepData,
|
|
1324
|
-
getAllStepData
|
|
1325
|
-
]);
|
|
1326
|
-
const contextValue = React$1.useMemo(() => ({
|
|
1327
|
-
form: instance,
|
|
1328
|
-
fields: instance.fields,
|
|
1329
|
-
isSubmitting,
|
|
1330
|
-
submit: () => formRef.current?.requestSubmit(),
|
|
1331
|
-
reset: () => instance.reset(),
|
|
1332
|
-
formId: instance.id
|
|
1333
|
-
}), [instance, isSubmitting]);
|
|
1334
|
-
const renderProps = {
|
|
1335
|
-
steps,
|
|
1336
|
-
current: currentStepConfig,
|
|
1337
|
-
currentIndex,
|
|
1338
|
-
next,
|
|
1339
|
-
prev,
|
|
1340
|
-
goTo,
|
|
1341
|
-
isFirst: stepper.state.isFirst,
|
|
1342
|
-
isLast: stepper.state.isLast,
|
|
1343
|
-
getStepData,
|
|
1344
|
-
getAllStepData
|
|
1345
|
-
};
|
|
1346
|
-
const resolvedChildren = typeof children === "function" ? children(renderProps) : children;
|
|
1347
|
-
return /* @__PURE__ */ jsx(FormStepperContext, {
|
|
1348
|
-
value: stepperContextValue,
|
|
1349
|
-
children: /* @__PURE__ */ jsx(FormProvider, {
|
|
1350
|
-
value: contextValue,
|
|
1351
|
-
children: /* @__PURE__ */ jsx(adapter.FormProvider, {
|
|
1352
|
-
instance,
|
|
1353
|
-
children: /* @__PURE__ */ jsx(FormComp, {
|
|
1354
|
-
ref: formRef,
|
|
1355
|
-
...instance.formProps,
|
|
1356
|
-
className: cn("space-y-6", className),
|
|
1357
|
-
autoComplete: "off",
|
|
1358
|
-
noValidate: true,
|
|
1359
|
-
onSubmit: (e) => {
|
|
1360
|
-
e.stopPropagation();
|
|
1361
|
-
const adapterSubmit = instance.formProps.onSubmit;
|
|
1362
|
-
adapterSubmit?.(e);
|
|
1363
|
-
},
|
|
1364
|
-
children: resolvedChildren
|
|
1365
|
-
})
|
|
1366
|
-
})
|
|
1367
|
-
})
|
|
1368
|
-
});
|
|
1369
|
-
}
|
|
1370
|
-
//#endregion
|
|
1371
|
-
//#region src/components/features/form/components/stepper/form-step.tsx
|
|
1372
|
-
/**
|
|
1373
|
-
* Form.Step - Individual step content container
|
|
1374
|
-
*
|
|
1375
|
-
* Only renders its children when the step is active.
|
|
1376
|
-
* Works with the single-form architecture - fields remain registered
|
|
1377
|
-
* even when unmounted, preserving their values.
|
|
1378
|
-
*
|
|
1379
|
-
* @example
|
|
1380
|
-
* ```tsx
|
|
1381
|
-
* <Form.Step id="account">
|
|
1382
|
-
* <Form.Field name="email" label="Email" required>
|
|
1383
|
-
* <Form.Input type="email" />
|
|
1384
|
-
* </Form.Field>
|
|
1385
|
-
* </Form.Step>
|
|
1386
|
-
* ```
|
|
1387
|
-
*/
|
|
1388
|
-
function FormStep({ id, children }) {
|
|
1389
|
-
const { current } = useFormStepperContext();
|
|
1390
|
-
if (current.id !== id) return null;
|
|
1391
|
-
return /* @__PURE__ */ jsx(Fragment$1, { children });
|
|
1392
|
-
}
|
|
1393
|
-
FormStep.displayName = "Form.Step";
|
|
1394
|
-
//#endregion
|
|
1395
|
-
//#region src/components/features/form/components/stepper/stepper-controls.tsx
|
|
1396
|
-
/**
|
|
1397
|
-
* Form.StepperControls - Navigation buttons (Previous/Next/Submit)
|
|
1398
|
-
*
|
|
1399
|
-
* Provides Previous and Next/Submit buttons for navigating between steps.
|
|
1400
|
-
* The Next button triggers form validation before advancing.
|
|
1401
|
-
* The Previous button navigates back without validation.
|
|
1402
|
-
*
|
|
1403
|
-
* @example
|
|
1404
|
-
* ```tsx
|
|
1405
|
-
* <Form.StepperControls
|
|
1406
|
-
* prevLabel={(isFirst) => isFirst ? 'Cancel' : 'Previous'}
|
|
1407
|
-
* nextLabel={(isLast) => isLast ? 'Submit' : 'Next'}
|
|
1408
|
-
* loadingText="Creating..."
|
|
1409
|
-
* onCancel={() => setOpen(false)}
|
|
1410
|
-
* />
|
|
1411
|
-
* ```
|
|
1412
|
-
*
|
|
1413
|
-
* @example With external loading state
|
|
1414
|
-
* ```tsx
|
|
1415
|
-
* <Form.StepperControls
|
|
1416
|
-
* loading={fetcher.state === 'submitting'}
|
|
1417
|
-
* disabled={!isValid}
|
|
1418
|
-
* loadingText="Saving..."
|
|
1419
|
-
* />
|
|
1420
|
-
* ```
|
|
1421
|
-
*/
|
|
1422
|
-
function StepperControls({ prevLabel = "Previous", nextLabel = (isLast) => isLast ? "Submit" : "Next", loadingText = "Submitting...", showPrev = true, loading, disabled, onPrev, onCancel, className }) {
|
|
1423
|
-
const { prev, isFirst, isLast } = useFormStepperContext();
|
|
1424
|
-
const { isSubmitting: formIsSubmitting } = useFormContext$1();
|
|
1425
|
-
const isLoading = loading ?? formIsSubmitting;
|
|
1426
|
-
const isDisabled = disabled ?? false;
|
|
1427
|
-
const getPrevLabel = () => {
|
|
1428
|
-
if (typeof prevLabel === "function") return prevLabel(isFirst);
|
|
1429
|
-
return prevLabel;
|
|
1430
|
-
};
|
|
1431
|
-
const getNextLabel = () => {
|
|
1432
|
-
if (typeof nextLabel === "function") return nextLabel(isLast);
|
|
1433
|
-
return nextLabel;
|
|
1434
|
-
};
|
|
1435
|
-
const handlePrev = () => {
|
|
1436
|
-
if (isFirst && onCancel) onCancel();
|
|
1437
|
-
else {
|
|
1438
|
-
onPrev?.();
|
|
1439
|
-
prev();
|
|
1440
|
-
}
|
|
1441
|
-
};
|
|
1442
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
1443
|
-
className: cn("flex items-center justify-between gap-3", className),
|
|
1444
|
-
children: [/* @__PURE__ */ jsx("div", { children: showPrev && /* @__PURE__ */ jsx(Button, {
|
|
1445
|
-
htmlType: "button",
|
|
1446
|
-
type: "quaternary",
|
|
1447
|
-
theme: "outline",
|
|
1448
|
-
size: "small",
|
|
1449
|
-
onClick: handlePrev,
|
|
1450
|
-
disabled: isLoading || isDisabled,
|
|
1451
|
-
children: getPrevLabel()
|
|
1452
|
-
}) }), /* @__PURE__ */ jsx(Button, {
|
|
1453
|
-
htmlType: "submit",
|
|
1454
|
-
type: "primary",
|
|
1455
|
-
size: "small",
|
|
1456
|
-
loading: isLoading,
|
|
1457
|
-
disabled: isLoading || isDisabled,
|
|
1458
|
-
children: isLoading && isLast ? loadingText : getNextLabel()
|
|
1459
|
-
})]
|
|
1460
|
-
});
|
|
1461
|
-
}
|
|
1462
|
-
StepperControls.displayName = "Form.StepperControls";
|
|
1463
|
-
//#endregion
|
|
1464
|
-
//#region src/components/features/form/components/stepper/stepper-navigation.tsx
|
|
1465
|
-
/**
|
|
1466
|
-
* Form.StepperNavigation - Step indicators/progress
|
|
1467
|
-
*
|
|
1468
|
-
* Displays visual step indicators showing current progress through the form.
|
|
1469
|
-
* Supports horizontal and vertical variants with optional label orientation.
|
|
1470
|
-
*
|
|
1471
|
-
* @example
|
|
1472
|
-
* ```tsx
|
|
1473
|
-
* <Form.StepperNavigation variant="horizontal" labelOrientation="vertical" />
|
|
1474
|
-
* ```
|
|
1475
|
-
*/
|
|
1476
|
-
function StepperNavigation({ variant = "horizontal", labelOrientation = "vertical", className }) {
|
|
1477
|
-
const { steps, currentIndex } = useFormStepperContext();
|
|
1478
|
-
if (variant === "horizontal" && labelOrientation === "vertical") return /* @__PURE__ */ jsx("nav", {
|
|
1479
|
-
"aria-label": "Form steps",
|
|
1480
|
-
className: cn("flex flex-row items-start justify-between", className),
|
|
1481
|
-
children: steps.map((step, index) => {
|
|
1482
|
-
const isActive = index === currentIndex;
|
|
1483
|
-
const isCompleted = index < currentIndex;
|
|
1484
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
1485
|
-
className: "relative flex flex-1 flex-col items-center",
|
|
1486
|
-
children: [
|
|
1487
|
-
!(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" }),
|
|
1488
|
-
/* @__PURE__ */ jsx("div", {
|
|
1489
|
-
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"),
|
|
1490
|
-
"aria-current": isActive ? "step" : void 0,
|
|
1491
|
-
children: isCompleted ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-tertiary h-4 w-4" }) : index + 1
|
|
1492
|
-
}),
|
|
1493
|
-
/* @__PURE__ */ jsxs("div", {
|
|
1494
|
-
className: "mt-1",
|
|
1495
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
1496
|
-
className: cn("text-xs font-medium", isActive && "text-foreground", isCompleted && "text-stepper-label", !isActive && !isCompleted && "text-stepper-label"),
|
|
1497
|
-
children: step.label
|
|
1498
|
-
}), step.description && /* @__PURE__ */ jsx("p", {
|
|
1499
|
-
className: "text-muted-foreground mt-0.5 text-xs",
|
|
1500
|
-
children: step.description
|
|
1501
|
-
})]
|
|
1502
|
-
})
|
|
1503
|
-
]
|
|
1504
|
-
}, step.id);
|
|
1505
|
-
})
|
|
1506
|
-
});
|
|
1507
|
-
if (variant === "horizontal") return /* @__PURE__ */ jsx("nav", {
|
|
1508
|
-
"aria-label": "Form steps",
|
|
1509
|
-
className: cn("flex flex-row items-center", className),
|
|
1510
|
-
children: steps.map((step, index) => {
|
|
1511
|
-
const isActive = index === currentIndex;
|
|
1512
|
-
const isCompleted = index < currentIndex;
|
|
1513
|
-
const isLast = index === steps.length - 1;
|
|
1514
|
-
return /* @__PURE__ */ jsxs(React$1.Fragment, { children: [/* @__PURE__ */ jsxs("div", {
|
|
1515
|
-
className: "flex items-center",
|
|
1516
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
1517
|
-
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"),
|
|
1518
|
-
"aria-current": isActive ? "step" : void 0,
|
|
1519
|
-
children: isCompleted ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-tertiary size-4" }) : index + 1
|
|
1520
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
1521
|
-
className: "ml-2",
|
|
1522
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
1523
|
-
className: cn("text-sm font-medium", isActive && "text-foreground", isCompleted && "text-stepper-label", !isActive && !isCompleted && "text-stepper-label"),
|
|
1524
|
-
children: step.label
|
|
1525
|
-
})
|
|
1526
|
-
})]
|
|
1527
|
-
}), !isLast && /* @__PURE__ */ jsx("div", { className: "bg-stepper-line mx-4 h-0.5 min-w-8 flex-1" })] }, step.id);
|
|
1528
|
-
})
|
|
1529
|
-
});
|
|
1530
|
-
return /* @__PURE__ */ jsx("nav", {
|
|
1531
|
-
"aria-label": "Form steps",
|
|
1532
|
-
className: cn("flex flex-col", className),
|
|
1533
|
-
children: steps.map((step, index) => {
|
|
1534
|
-
const isActive = index === currentIndex;
|
|
1535
|
-
const isCompleted = index < currentIndex;
|
|
1536
|
-
const isLast = index === steps.length - 1;
|
|
1537
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
1538
|
-
className: "flex flex-row",
|
|
1539
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
1540
|
-
className: "flex flex-col items-center",
|
|
1541
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
1542
|
-
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"),
|
|
1543
|
-
"aria-current": isActive ? "step" : void 0,
|
|
1544
|
-
children: isCompleted ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-tertiary size-4" }) : index + 1
|
|
1545
|
-
}), !isLast && /* @__PURE__ */ jsx("div", { className: "bg-stepper-line my-1 min-h-8 w-0.5 flex-1" })]
|
|
1546
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
1547
|
-
className: "ml-3 pb-8",
|
|
1548
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
1549
|
-
className: cn("text-sm font-medium", isActive && "text-foreground", isCompleted && "text-stepper-label", !isActive && !isCompleted && "text-stepper-label"),
|
|
1550
|
-
children: step.label
|
|
1551
|
-
}), step.description && /* @__PURE__ */ jsx("p", {
|
|
1552
|
-
className: "text-muted-foreground mt-0.5 text-xs",
|
|
1553
|
-
children: step.description
|
|
1554
|
-
})]
|
|
1555
|
-
})]
|
|
1556
|
-
}, step.id);
|
|
1557
|
-
})
|
|
1558
|
-
});
|
|
1559
|
-
}
|
|
1560
|
-
StepperNavigation.displayName = "Form.StepperNavigation";
|
|
1561
|
-
//#endregion
|
|
1562
|
-
//#region src/components/features/form/components/form-input-group.tsx
|
|
1563
|
-
/**
|
|
1564
|
-
* Form.InputGroup - Input with leading/trailing addons
|
|
1565
|
-
*
|
|
1566
|
-
* Automatically wired to the parent Form.Field context.
|
|
1567
|
-
*
|
|
1568
|
-
* @example
|
|
1569
|
-
* ```tsx
|
|
1570
|
-
* <Form.Field name="website" label="Website" required>
|
|
1571
|
-
* <Form.InputGroup leading="https://" placeholder="example.com" />
|
|
1572
|
-
* </Form.Field>
|
|
1573
|
-
* ```
|
|
1574
|
-
*/
|
|
1575
|
-
function FormInputGroup({ ref, className, disabled, ...props }) {
|
|
1576
|
-
const { id, errors, disabled: fieldDisabled, fieldState } = useFieldContext$1();
|
|
1577
|
-
const isDisabled = disabled ?? fieldDisabled;
|
|
1578
|
-
const hasErrors = errors && errors.length > 0;
|
|
1579
|
-
return /* @__PURE__ */ jsx(InputWithAddons, {
|
|
1580
|
-
...props,
|
|
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),
|
|
1588
|
-
disabled: isDisabled,
|
|
1589
|
-
"aria-invalid": hasErrors || void 0,
|
|
1590
|
-
"aria-describedby": hasErrors ? `${id}-error` : void 0
|
|
1591
|
-
});
|
|
1592
|
-
}
|
|
1593
|
-
FormInputGroup.displayName = "Form.InputGroup";
|
|
1594
|
-
//#endregion
|
|
1595
1346
|
//#region src/components/features/form/hooks/use-field.ts
|
|
1596
1347
|
/**
|
|
1597
1348
|
* Hook to access and control a specific field.
|
|
@@ -1682,48 +1433,36 @@ function useFormContext() {
|
|
|
1682
1433
|
return useFormContext$1();
|
|
1683
1434
|
}
|
|
1684
1435
|
//#endregion
|
|
1685
|
-
//#region src/components/features/form/hooks/use-
|
|
1436
|
+
//#region src/components/features/form/hooks/use-form-state.ts
|
|
1686
1437
|
/**
|
|
1687
|
-
* Hook to access
|
|
1688
|
-
* Must be used within a Form.Stepper component
|
|
1438
|
+
* Hook to access form-level state (dirty, valid, submitted, etc.)
|
|
1689
1439
|
*
|
|
1690
1440
|
* @example
|
|
1691
1441
|
* ```tsx
|
|
1692
|
-
* function
|
|
1693
|
-
* const {
|
|
1694
|
-
* current,
|
|
1695
|
-
* currentIndex,
|
|
1696
|
-
* steps,
|
|
1697
|
-
* next,
|
|
1698
|
-
* prev,
|
|
1699
|
-
* goTo,
|
|
1700
|
-
* isFirst,
|
|
1701
|
-
* isLast,
|
|
1702
|
-
* } = useStepper();
|
|
1442
|
+
* function SaveButton() {
|
|
1443
|
+
* const { isDirty, isSubmitting, isValid } = useFormState()
|
|
1703
1444
|
*
|
|
1704
1445
|
* return (
|
|
1705
|
-
* <
|
|
1706
|
-
*
|
|
1707
|
-
*
|
|
1708
|
-
*
|
|
1709
|
-
*
|
|
1710
|
-
*
|
|
1446
|
+
* <button
|
|
1447
|
+
* type="submit"
|
|
1448
|
+
* disabled={!isDirty || isSubmitting || !isValid}
|
|
1449
|
+
* >
|
|
1450
|
+
* Save Changes
|
|
1451
|
+
* </button>
|
|
1452
|
+
* )
|
|
1711
1453
|
* }
|
|
1712
1454
|
* ```
|
|
1713
1455
|
*/
|
|
1714
|
-
function
|
|
1715
|
-
const
|
|
1456
|
+
function useFormState() {
|
|
1457
|
+
const ctx = useFormContext$1();
|
|
1716
1458
|
return {
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
isLast: context.isLast,
|
|
1725
|
-
getStepData: context.getStepData,
|
|
1726
|
-
getAllStepData: context.getAllStepData
|
|
1459
|
+
isDirty: ctx.isDirty,
|
|
1460
|
+
isValid: ctx.isValid,
|
|
1461
|
+
isSubmitting: ctx.isSubmitting,
|
|
1462
|
+
isSubmitted: ctx.isSubmitted,
|
|
1463
|
+
submitCount: ctx.submitCount,
|
|
1464
|
+
dirtyFields: ctx.dirtyFields,
|
|
1465
|
+
touchedFields: ctx.touchedFields
|
|
1727
1466
|
};
|
|
1728
1467
|
}
|
|
1729
1468
|
//#endregion
|
|
@@ -1774,19 +1513,34 @@ function useStepper() {
|
|
|
1774
1513
|
* }
|
|
1775
1514
|
* ```
|
|
1776
1515
|
*
|
|
1777
|
-
* @example Multi-Step Form
|
|
1516
|
+
* @example Multi-Step Form (separate import)
|
|
1778
1517
|
* ```tsx
|
|
1518
|
+
* import { FormStepper, FormStep, StepperNavigation, StepperControls } from '@datum-cloud/datum-ui/form/stepper';
|
|
1519
|
+
*
|
|
1779
1520
|
* const steps = [
|
|
1780
1521
|
* { id: 'account', label: 'Account', schema: accountSchema },
|
|
1781
1522
|
* { id: 'profile', label: 'Profile', schema: profileSchema },
|
|
1782
1523
|
* ];
|
|
1783
1524
|
*
|
|
1784
|
-
* <
|
|
1785
|
-
* <
|
|
1786
|
-
* <
|
|
1787
|
-
* <
|
|
1788
|
-
* <
|
|
1789
|
-
* </
|
|
1525
|
+
* <FormStepper steps={steps} onComplete={handleComplete}>
|
|
1526
|
+
* <StepperNavigation />
|
|
1527
|
+
* <FormStep id="account">...</FormStep>
|
|
1528
|
+
* <FormStep id="profile">...</FormStep>
|
|
1529
|
+
* <StepperControls />
|
|
1530
|
+
* </FormStepper>
|
|
1531
|
+
* ```
|
|
1532
|
+
*
|
|
1533
|
+
* @example Form State
|
|
1534
|
+
* ```tsx
|
|
1535
|
+
* <Form.Root schema={schema} onSubmit={handleSubmit}>
|
|
1536
|
+
* {({ isDirty, isValid, isSubmitted, submitCount }) => (
|
|
1537
|
+
* <>
|
|
1538
|
+
* <Form.Field name="name"><Form.Input /></Form.Field>
|
|
1539
|
+
* <Form.Submit disabled={!isDirty || !isValid}>Save</Form.Submit>
|
|
1540
|
+
* {isSubmitted && <p>Submitted {submitCount} time(s)</p>}
|
|
1541
|
+
* </>
|
|
1542
|
+
* )}
|
|
1543
|
+
* </Form.Root>
|
|
1790
1544
|
* ```
|
|
1791
1545
|
*
|
|
1792
1546
|
* @example Conditional Fields
|
|
@@ -1818,13 +1572,15 @@ function useStepper() {
|
|
|
1818
1572
|
* - Form.When - Conditional rendering
|
|
1819
1573
|
* - Form.FieldArray - Dynamic array of fields
|
|
1820
1574
|
* - Form.Custom - Escape hatch for custom implementations
|
|
1821
|
-
* - Form.Stepper, Form.Step, Form.StepperNavigation, Form.StepperControls
|
|
1822
1575
|
* - Form.Dialog - Form rendered inside a Dialog
|
|
1823
1576
|
* - Form.Submit, Form.Button, Form.Error, Form.Description
|
|
1824
1577
|
*
|
|
1578
|
+
* Stepper (separate import):
|
|
1579
|
+
* - `@datum-cloud/datum-ui/form/stepper` provides FormStepper, FormStep, StepperNavigation, StepperControls, useStepper
|
|
1580
|
+
*
|
|
1825
1581
|
* Hooks:
|
|
1826
|
-
* - Form.useFormContext, Form.useFieldContext, Form.useField
|
|
1827
|
-
* - Form.useWatch, Form.useWatchAll
|
|
1582
|
+
* - Form.useFormContext, Form.useFormState, Form.useFieldContext, Form.useField
|
|
1583
|
+
* - Form.useWatch, Form.useWatchAll
|
|
1828
1584
|
*/
|
|
1829
1585
|
const Form = {
|
|
1830
1586
|
Root: FormRoot,
|
|
@@ -1843,21 +1599,23 @@ const Form = {
|
|
|
1843
1599
|
RadioItem: FormRadioItem,
|
|
1844
1600
|
CopyBox: FormCopyBox,
|
|
1845
1601
|
Autocomplete: FormAutocomplete,
|
|
1602
|
+
Autosearch: FormAutosearch,
|
|
1603
|
+
Combobox: FormCombobox,
|
|
1846
1604
|
InputGroup: FormInputGroup,
|
|
1605
|
+
DatePicker: FormDatePicker,
|
|
1606
|
+
DateTimePicker: FormDateTimePicker,
|
|
1607
|
+
TimePicker: FormTimePicker,
|
|
1608
|
+
Transfer: FormTransfer,
|
|
1847
1609
|
When: FormWhen,
|
|
1848
1610
|
FieldArray: FormFieldArray,
|
|
1849
1611
|
Custom: FormCustom,
|
|
1850
|
-
Stepper: FormStepper,
|
|
1851
|
-
Step: FormStep,
|
|
1852
|
-
StepperNavigation,
|
|
1853
|
-
StepperControls,
|
|
1854
1612
|
Dialog: FormDialog,
|
|
1855
1613
|
useFormContext,
|
|
1614
|
+
useFormState,
|
|
1856
1615
|
useFieldContext,
|
|
1857
1616
|
useField,
|
|
1858
1617
|
useWatch,
|
|
1859
|
-
useWatchAll
|
|
1860
|
-
useStepper
|
|
1618
|
+
useWatchAll
|
|
1861
1619
|
};
|
|
1862
1620
|
//#endregion
|
|
1863
|
-
export {
|
|
1621
|
+
export { FormCheckbox as A, FormDialog as C, FormCustom as D, FormDatePicker as E, FormAutosearch as M, FormAutocomplete as N, FormCopyBox as O, FormError as S, FormDateTimePicker as T, FormRadioGroup as _, useField as a, FormFieldArray as b, useWatchAll as c, FormTextarea as d, FormSwitch as f, FormRoot as g, FormSelectItem as h, useFieldContext as i, FormButton as j, FormCombobox as k, FormTransfer as l, FormSelect as m, useFormState as n, FormWhen as o, FormSubmit as p, useFormContext as r, useWatch as s, Form as t, FormTimePicker as u, FormRadioItem as v, FormDescription as w, FormField as x, FormInput as y };
|