@zeno-lib/forms 0.0.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +23 -11
- package/src/addons/validation-spinner.tsx +3 -4
- package/src/create-form.tsx +59 -0
- package/src/create-zeno-form.tsx +531 -0
- package/src/fields/checkbox-field.tsx +15 -12
- package/src/fields/checkbox-group-field.tsx +160 -0
- package/src/fields/combobox-field.tsx +13 -14
- package/src/fields/date-picker-field.tsx +18 -15
- package/src/fields/index.ts +5 -0
- package/src/fields/input-field.tsx +12 -13
- package/src/fields/money-field.tsx +123 -0
- package/src/fields/multi-select-field.tsx +193 -0
- package/src/fields/number-field.tsx +1 -2
- package/src/fields/otp-field.tsx +15 -12
- package/src/fields/percentage-field.tsx +73 -0
- package/src/fields/radio-group-field.tsx +12 -13
- package/src/fields/reset-button.tsx +2 -3
- package/src/fields/select-field.tsx +12 -13
- package/src/fields/slider-field.tsx +11 -12
- package/src/fields/submit-button.tsx +3 -4
- package/src/fields/switch-field.tsx +15 -12
- package/src/fields/textarea-field.tsx +12 -13
- package/src/fields/year-field.tsx +56 -0
- package/src/form-dialog.test.tsx +161 -0
- package/src/form-dialog.tsx +253 -0
- package/src/form-element.tsx +51 -0
- package/src/formatted-number-fields.test.tsx +236 -0
- package/src/index.ts +27 -0
- package/src/lib/action-result.ts +61 -0
- package/src/lib/apply-validation-error.test.ts +16 -6
- package/src/lib/apply-validation-error.ts +38 -6
- package/src/lib/formatted-number.test.ts +157 -0
- package/src/lib/formatted-number.ts +307 -0
- package/src/lib/required-indicator.tsx +1 -1
- package/src/lib/schema-defaults.test.ts +1 -2
- package/src/lib/schema-required.test.ts +98 -6
- package/src/lib/schema-required.ts +126 -22
- package/src/lib/submit-action.test-d.ts +83 -0
- package/src/lib/submit-action.ts +178 -0
- package/src/lib/use-form-dialog.ts +184 -0
- package/src/lib/use-formatted-number.ts +235 -0
- package/src/lib/use-is-invalid.ts +4 -4
- package/src/lib/use-rebased-default-values.ts +42 -0
- package/src/lib/use-unsaved-changes-warning.ts +3 -3
- package/src/lib/validation-error.test.ts +1 -1
- package/src/lib/validation-logic.test.ts +1 -1
- package/src/lib/validation-modes.test-d.ts +1 -1
- package/src/lib/validation-modes.test.ts +12 -2
- package/src/lib/validation-modes.ts +3 -1
- package/src/multi-value-fields.test.tsx +116 -0
- package/src/submit-action.test.tsx +421 -0
- package/src/use-app-fields.test-d.ts +8 -25
- package/src/use-app-fields.test.tsx +8 -32
- package/src/use-form.cascade.test.tsx +4 -6
- package/src/use-form.focus-invalid.test.tsx +198 -0
- package/src/use-form.reset-defaults.test.tsx +125 -0
- package/src/use-form.test-d.ts +2 -3
- package/src/use-form.test.tsx +12 -14
- package/src/use-form.unsaved-warning.test.tsx +4 -13
- package/src/use-form.validation-modes.test.tsx +10 -8
- package/src/form.tsx +0 -105
- package/src/use-app-fields.tsx +0 -272
- package/src/use-form.tsx +0 -450
package/src/use-form.tsx
DELETED
|
@@ -1,450 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import type {
|
|
4
|
-
AnyFormApi,
|
|
5
|
-
FormAsyncValidateOrFn,
|
|
6
|
-
FormOptions,
|
|
7
|
-
FormValidateOrFn,
|
|
8
|
-
} from "@tanstack/react-form"
|
|
9
|
-
import { useMemo } from "react"
|
|
10
|
-
|
|
11
|
-
import { ResetButton } from "./fields/reset-button"
|
|
12
|
-
import { SubmitButton } from "./fields/submit-button"
|
|
13
|
-
import { useAppForm } from "./form"
|
|
14
|
-
import { applyValidationError } from "./lib/apply-validation-error"
|
|
15
|
-
import { deepMergeDefaults, extractZodDefaults } from "./lib/schema-defaults"
|
|
16
|
-
import { getRequiredPaths } from "./lib/schema-required"
|
|
17
|
-
import { useUnsavedChangesWarning } from "./lib/use-unsaved-changes-warning"
|
|
18
|
-
import { ValidationError } from "./lib/validation-error"
|
|
19
|
-
import { blurThenChangeLogic } from "./lib/validation-logic"
|
|
20
|
-
import {
|
|
21
|
-
DEFAULT_VALIDATION_MODE,
|
|
22
|
-
setFormZenoState,
|
|
23
|
-
type ValidationMode,
|
|
24
|
-
} from "./lib/validation-modes"
|
|
25
|
-
import { useAppFields } from "./use-app-fields"
|
|
26
|
-
|
|
27
|
-
// Structural shape of a Standard Schema (Zod, Valibot, ArkType, …). Avoids a
|
|
28
|
-
// direct dependency on `@standard-schema/spec`; runtime validation goes
|
|
29
|
-
// through TanStack Form's standard-schema integration unchanged.
|
|
30
|
-
type StandardSchema<T> = {
|
|
31
|
-
readonly "~standard": {
|
|
32
|
-
readonly validate: (value: unknown) => unknown
|
|
33
|
-
readonly types?: { readonly input: T; readonly output: T }
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Recursive partial that preserves arrays, dates, and other structural types
|
|
38
|
-
// as atomic — only plain object keys become optional. Used to relax
|
|
39
|
-
// `defaultValues` so users can omit fields covered by the schema's
|
|
40
|
-
// `.default(...)` values or by the string/array auto-fill (see
|
|
41
|
-
// `lib/schema-defaults.ts`). `value` on submit is still typed as the full
|
|
42
|
-
// `TFormData` because TanStack's runtime state assertion is unchanged.
|
|
43
|
-
type PartialFormData<T> = T extends readonly unknown[]
|
|
44
|
-
? T
|
|
45
|
-
: T extends Date | RegExp | ((...args: never[]) => unknown)
|
|
46
|
-
? T
|
|
47
|
-
: T extends object
|
|
48
|
-
? { [K in keyof T]?: PartialFormData<T[K]> }
|
|
49
|
-
: T
|
|
50
|
-
|
|
51
|
-
type ZenoFormExtras<TFormData> = {
|
|
52
|
-
/**
|
|
53
|
-
* If `true`, shipped fields skip rendering their inline `<FieldError>`
|
|
54
|
-
* message. Use it when you collect errors in a single summary somewhere
|
|
55
|
-
* else (e.g. above the submit button). The fields still flip
|
|
56
|
-
* `data-invalid` and `aria-invalid`, so invalid styling is preserved.
|
|
57
|
-
*/
|
|
58
|
-
hideFieldErrors?: boolean
|
|
59
|
-
/**
|
|
60
|
-
* Show a `*` next to the label of every field the schema treats as
|
|
61
|
-
* required. Defaults to `true`. Set to `false` to opt out form-wide.
|
|
62
|
-
*
|
|
63
|
-
* Required-ness is detected by probing the schema with an empty object;
|
|
64
|
-
* fields wrapped in `.optional()`, `.nullable()`, or `.default(…)` are
|
|
65
|
-
* treated as not required. Async schemas can't be probed and produce no
|
|
66
|
-
* indicators. Pass `required` directly on a field to override the
|
|
67
|
-
* schema-derived value.
|
|
68
|
-
*/
|
|
69
|
-
requiredIndicator?: boolean
|
|
70
|
-
/**
|
|
71
|
-
* Warn the user before they navigate away with unsaved changes. Two
|
|
72
|
-
* trigger modes:
|
|
73
|
-
*
|
|
74
|
-
* - `"if-changed"` (recommended) — warn while current values differ
|
|
75
|
-
* from defaults (`!state.isDefaultValue`). Clears if the user
|
|
76
|
-
* restores the original values, or after `formApi.reset(value)` is
|
|
77
|
-
* called post-submit to rebase defaults.
|
|
78
|
-
* - `"if-touched"` — warn after the user has edited any field, even
|
|
79
|
-
* if they reverted (`state.isDirty`, sticky once edited).
|
|
80
|
-
*
|
|
81
|
-
* Pass `true` as shorthand for `"if-changed"`. The warning never fires
|
|
82
|
-
* while the form is mid-submit. Covers full-page navigation only — for
|
|
83
|
-
* client-side route changes, read the relevant state flag from the
|
|
84
|
-
* form yourself and prompt before pushing the next route.
|
|
85
|
-
*/
|
|
86
|
-
unsavedChangesWarning?: boolean | "if-changed" | "if-touched"
|
|
87
|
-
/**
|
|
88
|
-
* Initial values for the form fields. Relaxed to a deep partial so you can
|
|
89
|
-
* omit fields whose defaults come from the schema — `.default(...)` values
|
|
90
|
-
* flow through, and `z.string()` / `z.array(...)` without a default
|
|
91
|
-
* initialise to `""` / `[]` to keep inputs controlled. See `lib/schema-defaults.ts`.
|
|
92
|
-
*
|
|
93
|
-
* Numbers, booleans, dates, and other domain-loaded types still need an
|
|
94
|
-
* explicit value here when the schema doesn't provide one.
|
|
95
|
-
*/
|
|
96
|
-
defaultValues?: PartialFormData<TFormData>
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Schema path — `schema` drives validation. `validators` (if present) is a
|
|
100
|
-
// `ValidationMode` string that selects *when* the schema fires; the matching
|
|
101
|
-
// `validationLogic` is wired internally, so it must not be supplied by the
|
|
102
|
-
// caller. To take manual control of `validators` / `validationLogic`, omit
|
|
103
|
-
// `schema` and use the manual path instead.
|
|
104
|
-
type SchemaPathExtras<TFormData> = {
|
|
105
|
-
/**
|
|
106
|
-
* A standard schema (Zod, Valibot, ArkType, …) describing the form data.
|
|
107
|
-
* Drives validation, default values, the `*` required indicator, and the
|
|
108
|
-
* `TFormData` type. Pair with `validators` (a `ValidationMode` string)
|
|
109
|
-
* to control timing.
|
|
110
|
-
*/
|
|
111
|
-
schema: StandardSchema<TFormData>
|
|
112
|
-
/**
|
|
113
|
-
* When the schema runs and when errors are displayed.
|
|
114
|
-
*
|
|
115
|
-
* - `'blur-then-change'` (default) — schema runs on blur, then on every
|
|
116
|
-
* change for fields that have already been blurred. Errors appear after
|
|
117
|
-
* first blur. Calm typing, live corrections.
|
|
118
|
-
* - `'change'` — schema runs on every keystroke. Errors appear as soon as
|
|
119
|
-
* the user starts typing.
|
|
120
|
-
* - `'blur'` — schema runs only on blur. Errors appear after blur, but
|
|
121
|
-
* do not update until the next blur.
|
|
122
|
-
* - `'submit'` — schema runs only on submit. No errors before submit.
|
|
123
|
-
*/
|
|
124
|
-
validators?: ValidationMode
|
|
125
|
-
/**
|
|
126
|
-
* Not accepted on the schema path — the mode chosen via `validators`
|
|
127
|
-
* selects the logic internally. Omit `schema` to supply your own.
|
|
128
|
-
*/
|
|
129
|
-
validationLogic?: never
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Manual path — no schema. `validators` and `validationLogic` keep their
|
|
133
|
-
// native TanStack Form types unchanged.
|
|
134
|
-
type ManualPathExtras = {
|
|
135
|
-
schema?: never
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
type SchemaFormOptions<
|
|
139
|
-
TFormData,
|
|
140
|
-
TOnMount extends undefined | FormValidateOrFn<TFormData>,
|
|
141
|
-
TOnChange extends undefined | FormValidateOrFn<TFormData>,
|
|
142
|
-
TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
143
|
-
TOnBlur extends undefined | FormValidateOrFn<TFormData>,
|
|
144
|
-
TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
145
|
-
TOnSubmit extends undefined | FormValidateOrFn<TFormData>,
|
|
146
|
-
TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
147
|
-
TOnDynamic extends undefined | FormValidateOrFn<TFormData>,
|
|
148
|
-
TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
149
|
-
TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
150
|
-
TSubmitMeta,
|
|
151
|
-
> = Omit<
|
|
152
|
-
FormOptions<
|
|
153
|
-
TFormData,
|
|
154
|
-
TOnMount,
|
|
155
|
-
TOnChange,
|
|
156
|
-
TOnChangeAsync,
|
|
157
|
-
TOnBlur,
|
|
158
|
-
TOnBlurAsync,
|
|
159
|
-
TOnSubmit,
|
|
160
|
-
TOnSubmitAsync,
|
|
161
|
-
TOnDynamic,
|
|
162
|
-
TOnDynamicAsync,
|
|
163
|
-
TOnServer,
|
|
164
|
-
TSubmitMeta
|
|
165
|
-
>,
|
|
166
|
-
"defaultValues" | "validators" | "validationLogic"
|
|
167
|
-
> &
|
|
168
|
-
SchemaPathExtras<TFormData> &
|
|
169
|
-
ZenoFormExtras<TFormData>
|
|
170
|
-
|
|
171
|
-
type ManualFormOptions<
|
|
172
|
-
TFormData,
|
|
173
|
-
TOnMount extends undefined | FormValidateOrFn<TFormData>,
|
|
174
|
-
TOnChange extends undefined | FormValidateOrFn<TFormData>,
|
|
175
|
-
TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
176
|
-
TOnBlur extends undefined | FormValidateOrFn<TFormData>,
|
|
177
|
-
TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
178
|
-
TOnSubmit extends undefined | FormValidateOrFn<TFormData>,
|
|
179
|
-
TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
180
|
-
TOnDynamic extends undefined | FormValidateOrFn<TFormData>,
|
|
181
|
-
TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
182
|
-
TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
183
|
-
TSubmitMeta,
|
|
184
|
-
> = Omit<
|
|
185
|
-
FormOptions<
|
|
186
|
-
TFormData,
|
|
187
|
-
TOnMount,
|
|
188
|
-
TOnChange,
|
|
189
|
-
TOnChangeAsync,
|
|
190
|
-
TOnBlur,
|
|
191
|
-
TOnBlurAsync,
|
|
192
|
-
TOnSubmit,
|
|
193
|
-
TOnSubmitAsync,
|
|
194
|
-
TOnDynamic,
|
|
195
|
-
TOnDynamicAsync,
|
|
196
|
-
TOnServer,
|
|
197
|
-
TSubmitMeta
|
|
198
|
-
>,
|
|
199
|
-
"defaultValues"
|
|
200
|
-
> &
|
|
201
|
-
ManualPathExtras &
|
|
202
|
-
ZenoFormExtras<TFormData>
|
|
203
|
-
|
|
204
|
-
type UseFormOptions<
|
|
205
|
-
TFormData,
|
|
206
|
-
TOnMount extends undefined | FormValidateOrFn<TFormData>,
|
|
207
|
-
TOnChange extends undefined | FormValidateOrFn<TFormData>,
|
|
208
|
-
TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
209
|
-
TOnBlur extends undefined | FormValidateOrFn<TFormData>,
|
|
210
|
-
TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
211
|
-
TOnSubmit extends undefined | FormValidateOrFn<TFormData>,
|
|
212
|
-
TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
213
|
-
TOnDynamic extends undefined | FormValidateOrFn<TFormData>,
|
|
214
|
-
TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
215
|
-
TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
216
|
-
TSubmitMeta,
|
|
217
|
-
> =
|
|
218
|
-
| SchemaFormOptions<
|
|
219
|
-
TFormData,
|
|
220
|
-
TOnMount,
|
|
221
|
-
TOnChange,
|
|
222
|
-
TOnChangeAsync,
|
|
223
|
-
TOnBlur,
|
|
224
|
-
TOnBlurAsync,
|
|
225
|
-
TOnSubmit,
|
|
226
|
-
TOnSubmitAsync,
|
|
227
|
-
TOnDynamic,
|
|
228
|
-
TOnDynamicAsync,
|
|
229
|
-
TOnServer,
|
|
230
|
-
TSubmitMeta
|
|
231
|
-
>
|
|
232
|
-
| ManualFormOptions<
|
|
233
|
-
TFormData,
|
|
234
|
-
TOnMount,
|
|
235
|
-
TOnChange,
|
|
236
|
-
TOnChangeAsync,
|
|
237
|
-
TOnBlur,
|
|
238
|
-
TOnBlurAsync,
|
|
239
|
-
TOnSubmit,
|
|
240
|
-
TOnSubmitAsync,
|
|
241
|
-
TOnDynamic,
|
|
242
|
-
TOnDynamicAsync,
|
|
243
|
-
TOnServer,
|
|
244
|
-
TSubmitMeta
|
|
245
|
-
>
|
|
246
|
-
|
|
247
|
-
function buildValidatorsFromSchema<TFormData>(
|
|
248
|
-
schema: StandardSchema<TFormData>,
|
|
249
|
-
mode: ValidationMode
|
|
250
|
-
) {
|
|
251
|
-
switch (mode) {
|
|
252
|
-
case "change":
|
|
253
|
-
case "blur-then-change":
|
|
254
|
-
return { onChange: schema }
|
|
255
|
-
case "blur":
|
|
256
|
-
return { onBlur: schema }
|
|
257
|
-
case "submit":
|
|
258
|
-
return { onSubmit: schema }
|
|
259
|
-
default:
|
|
260
|
-
return { onChange: schema }
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
function useForm<
|
|
265
|
-
TFormData,
|
|
266
|
-
TOnMount extends undefined | FormValidateOrFn<TFormData> = undefined,
|
|
267
|
-
TOnChange extends undefined | FormValidateOrFn<TFormData> = undefined,
|
|
268
|
-
TOnChangeAsync extends
|
|
269
|
-
| undefined
|
|
270
|
-
| FormAsyncValidateOrFn<TFormData> = undefined,
|
|
271
|
-
TOnBlur extends undefined | FormValidateOrFn<TFormData> = undefined,
|
|
272
|
-
TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData> = undefined,
|
|
273
|
-
TOnSubmit extends undefined | FormValidateOrFn<TFormData> = undefined,
|
|
274
|
-
TOnSubmitAsync extends
|
|
275
|
-
| undefined
|
|
276
|
-
| FormAsyncValidateOrFn<TFormData> = undefined,
|
|
277
|
-
TOnDynamic extends undefined | FormValidateOrFn<TFormData> = undefined,
|
|
278
|
-
TOnDynamicAsync extends
|
|
279
|
-
| undefined
|
|
280
|
-
| FormAsyncValidateOrFn<TFormData> = undefined,
|
|
281
|
-
TOnServer extends undefined | FormAsyncValidateOrFn<TFormData> = undefined,
|
|
282
|
-
TSubmitMeta = never,
|
|
283
|
-
>(
|
|
284
|
-
options: UseFormOptions<
|
|
285
|
-
TFormData,
|
|
286
|
-
TOnMount,
|
|
287
|
-
TOnChange,
|
|
288
|
-
TOnChangeAsync,
|
|
289
|
-
TOnBlur,
|
|
290
|
-
TOnBlurAsync,
|
|
291
|
-
TOnSubmit,
|
|
292
|
-
TOnSubmitAsync,
|
|
293
|
-
TOnDynamic,
|
|
294
|
-
TOnDynamicAsync,
|
|
295
|
-
TOnServer,
|
|
296
|
-
TSubmitMeta
|
|
297
|
-
>
|
|
298
|
-
) {
|
|
299
|
-
type NativeFormOptions = FormOptions<
|
|
300
|
-
TFormData,
|
|
301
|
-
TOnMount,
|
|
302
|
-
TOnChange,
|
|
303
|
-
TOnChangeAsync,
|
|
304
|
-
TOnBlur,
|
|
305
|
-
TOnBlurAsync,
|
|
306
|
-
TOnSubmit,
|
|
307
|
-
TOnSubmitAsync,
|
|
308
|
-
TOnDynamic,
|
|
309
|
-
TOnDynamicAsync,
|
|
310
|
-
TOnServer,
|
|
311
|
-
TSubmitMeta
|
|
312
|
-
>
|
|
313
|
-
type NativeValidators = NativeFormOptions["validators"]
|
|
314
|
-
type NativeValidationLogic = NativeFormOptions["validationLogic"]
|
|
315
|
-
|
|
316
|
-
// Loosen the union for a single destructure. We narrow on `schema` below.
|
|
317
|
-
const {
|
|
318
|
-
schema,
|
|
319
|
-
validators: validatorsInput,
|
|
320
|
-
validationLogic: userValidationLogic,
|
|
321
|
-
hideFieldErrors = false,
|
|
322
|
-
requiredIndicator = true,
|
|
323
|
-
unsavedChangesWarning = false,
|
|
324
|
-
defaultValues: userDefaultValues,
|
|
325
|
-
onSubmit: userOnSubmit,
|
|
326
|
-
...rest
|
|
327
|
-
} = options as Omit<NativeFormOptions, "defaultValues"> & {
|
|
328
|
-
schema?: StandardSchema<TFormData>
|
|
329
|
-
validators?: ValidationMode | NativeValidators
|
|
330
|
-
validationLogic?: NativeValidationLogic
|
|
331
|
-
defaultValues?: PartialFormData<TFormData>
|
|
332
|
-
hideFieldErrors?: boolean
|
|
333
|
-
requiredIndicator?: boolean
|
|
334
|
-
unsavedChangesWarning?: boolean | "if-changed" | "if-touched"
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
let schemaMode: ValidationMode | undefined
|
|
338
|
-
let resolvedValidators: NativeValidators | undefined
|
|
339
|
-
let resolvedValidationLogic: NativeValidationLogic | undefined
|
|
340
|
-
|
|
341
|
-
if (schema === undefined) {
|
|
342
|
-
schemaMode = undefined
|
|
343
|
-
resolvedValidators =
|
|
344
|
-
typeof validatorsInput === "object" && validatorsInput !== null
|
|
345
|
-
? (validatorsInput as NativeValidators)
|
|
346
|
-
: undefined
|
|
347
|
-
resolvedValidationLogic = userValidationLogic
|
|
348
|
-
} else {
|
|
349
|
-
const mode: ValidationMode =
|
|
350
|
-
typeof validatorsInput === "string"
|
|
351
|
-
? (validatorsInput as ValidationMode)
|
|
352
|
-
: DEFAULT_VALIDATION_MODE
|
|
353
|
-
schemaMode = mode
|
|
354
|
-
resolvedValidators = buildValidatorsFromSchema(
|
|
355
|
-
schema,
|
|
356
|
-
mode
|
|
357
|
-
) as unknown as NativeValidators
|
|
358
|
-
resolvedValidationLogic =
|
|
359
|
-
mode === "blur-then-change"
|
|
360
|
-
? (blurThenChangeLogic as unknown as NativeValidationLogic)
|
|
361
|
-
: undefined
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
const wrappedOnSubmit = userOnSubmit
|
|
365
|
-
? ((async (props: { formApi: AnyFormApi; value: TFormData }) => {
|
|
366
|
-
try {
|
|
367
|
-
await (
|
|
368
|
-
userOnSubmit as unknown as (
|
|
369
|
-
p: typeof props
|
|
370
|
-
) => unknown | Promise<unknown>
|
|
371
|
-
)(props)
|
|
372
|
-
} catch (error) {
|
|
373
|
-
if (error instanceof ValidationError) {
|
|
374
|
-
applyValidationError(props.formApi, error)
|
|
375
|
-
return
|
|
376
|
-
}
|
|
377
|
-
throw error
|
|
378
|
-
}
|
|
379
|
-
}) as typeof userOnSubmit)
|
|
380
|
-
: undefined
|
|
381
|
-
|
|
382
|
-
const requiredFields = useMemo(
|
|
383
|
-
() =>
|
|
384
|
-
schema && requiredIndicator
|
|
385
|
-
? getRequiredPaths(schema as Parameters<typeof getRequiredPaths>[0])
|
|
386
|
-
: new Set<string>(),
|
|
387
|
-
[schema, requiredIndicator]
|
|
388
|
-
)
|
|
389
|
-
|
|
390
|
-
const schemaDefaults = useMemo(
|
|
391
|
-
() =>
|
|
392
|
-
schema
|
|
393
|
-
? extractZodDefaults(schema as Parameters<typeof extractZodDefaults>[0])
|
|
394
|
-
: undefined,
|
|
395
|
-
[schema]
|
|
396
|
-
)
|
|
397
|
-
|
|
398
|
-
const mergedDefaultValues = useMemo(
|
|
399
|
-
() =>
|
|
400
|
-
schemaDefaults
|
|
401
|
-
? (deepMergeDefaults(
|
|
402
|
-
schemaDefaults,
|
|
403
|
-
userDefaultValues as Record<string, unknown> | undefined
|
|
404
|
-
) as typeof userDefaultValues)
|
|
405
|
-
: userDefaultValues,
|
|
406
|
-
[schemaDefaults, userDefaultValues]
|
|
407
|
-
)
|
|
408
|
-
|
|
409
|
-
const form = useAppForm<
|
|
410
|
-
TFormData,
|
|
411
|
-
TOnMount,
|
|
412
|
-
TOnChange,
|
|
413
|
-
TOnChangeAsync,
|
|
414
|
-
TOnBlur,
|
|
415
|
-
TOnBlurAsync,
|
|
416
|
-
TOnSubmit,
|
|
417
|
-
TOnSubmitAsync,
|
|
418
|
-
TOnDynamic,
|
|
419
|
-
TOnDynamicAsync,
|
|
420
|
-
TOnServer,
|
|
421
|
-
TSubmitMeta
|
|
422
|
-
>({
|
|
423
|
-
...rest,
|
|
424
|
-
...(mergedDefaultValues === undefined
|
|
425
|
-
? {}
|
|
426
|
-
: { defaultValues: mergedDefaultValues }),
|
|
427
|
-
...(wrappedOnSubmit ? { onSubmit: wrappedOnSubmit } : {}),
|
|
428
|
-
...(resolvedValidators ? { validators: resolvedValidators } : {}),
|
|
429
|
-
...(resolvedValidationLogic
|
|
430
|
-
? { validationLogic: resolvedValidationLogic }
|
|
431
|
-
: {}),
|
|
432
|
-
} as NativeFormOptions)
|
|
433
|
-
|
|
434
|
-
setFormZenoState(form, {
|
|
435
|
-
hideFieldErrors,
|
|
436
|
-
requiredFields,
|
|
437
|
-
requiredIndicator,
|
|
438
|
-
...(schemaMode === undefined ? {} : { validation: schemaMode }),
|
|
439
|
-
})
|
|
440
|
-
|
|
441
|
-
useUnsavedChangesWarning(form, unsavedChangesWarning)
|
|
442
|
-
|
|
443
|
-
const fields = useAppFields(form)
|
|
444
|
-
return useMemo(
|
|
445
|
-
() => Object.assign(form, fields, { ResetButton, SubmitButton }),
|
|
446
|
-
[form, fields]
|
|
447
|
-
)
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
export { useForm }
|