@jcoreio/zod-forms 2.0.0-beta.4 → 2.1.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/ConditionalValidator.d.ts.map +1 -1
- package/ConditionalValidator.js +4 -2
- package/ConditionalValidator.js.map +1 -1
- package/ConditionalValidator.mjs +3 -1
- package/ConditionalValidator.mjs.map +1 -1
- package/FieldPath.d.ts.map +1 -1
- package/FieldPath.js +1 -0
- package/FieldPath.js.map +1 -1
- package/FieldPath.mjs.map +1 -1
- package/FormState.d.ts +7 -4
- package/FormState.d.ts.map +1 -1
- package/FormState.js.map +1 -1
- package/FormState.mjs.map +1 -1
- package/actions/arrayActions.js.map +1 -1
- package/actions/arrayActions.mjs.map +1 -1
- package/actions/setSubmitStatus.d.ts +1 -1
- package/createFormMiddleware.js +3 -3
- package/createFormMiddleware.js.map +1 -1
- package/createFormMiddleware.mjs.map +1 -1
- package/createFormProvider.d.ts +9 -3
- package/createFormProvider.d.ts.map +1 -1
- package/createFormProvider.js +10 -3
- package/createFormProvider.js.map +1 -1
- package/createFormProvider.mjs +53 -44
- package/createFormProvider.mjs.map +1 -1
- package/createFormReducer.js +16 -16
- package/createFormReducer.js.map +1 -1
- package/createSelectFieldErrorMap.d.ts +3 -3
- package/createSelectFieldErrorMap.js.map +1 -1
- package/createSelectFieldErrorMap.mjs.map +1 -1
- package/createSelectFormStatus.d.ts +10 -10
- package/createSelectFormStatus.d.ts.map +1 -1
- package/createSelectFormStatus.js +2 -2
- package/createSelectFormStatus.js.map +1 -1
- package/createSelectFormStatus.mjs +1 -1
- package/createSelectFormStatus.mjs.map +1 -1
- package/createSelectFormValues.js.map +1 -1
- package/createZodForm.d.ts +10 -5
- package/createZodForm.d.ts.map +1 -1
- package/package.json +5 -4
- package/reducers/addHandlers.d.ts +2 -2
- package/reducers/addHandlers.d.ts.map +1 -1
- package/reducers/arrayMove.js.map +1 -1
- package/reducers/arrayMove.mjs.map +1 -1
- package/reducers/initialize.d.ts +4 -4
- package/reducers/initialize.d.ts.map +1 -1
- package/reducers/initialize.js.map +1 -1
- package/reducers/initialize.mjs.map +1 -1
- package/reducers/removeHandlers.d.ts +2 -2
- package/reducers/removeHandlers.d.ts.map +1 -1
- package/reducers/setMeta.d.ts.map +1 -1
- package/reducers/setMeta.js +4 -1
- package/reducers/setMeta.js.map +1 -1
- package/reducers/setMeta.mjs +4 -1
- package/reducers/setMeta.mjs.map +1 -1
- package/reducers/setParsedValue.d.ts +2 -2
- package/reducers/setParsedValue.d.ts.map +1 -1
- package/reducers/setParsedValue.js +1 -1
- package/reducers/setParsedValue.js.map +1 -1
- package/reducers/setParsedValue.mjs +1 -1
- package/reducers/setParsedValue.mjs.map +1 -1
- package/reducers/setSubmitStatus.d.ts +2 -2
- package/reducers/setSubmitStatus.d.ts.map +1 -1
- package/reducers/setValue.d.ts +1 -1
- package/reducers/setValue.d.ts.map +1 -1
- package/reducers/submitSucceeded.d.ts +1 -1
- package/reducers/submitSucceeded.d.ts.map +1 -1
- package/reducers/util/updateRawArray.js.map +1 -1
- package/reducers/util/updateRawArray.mjs.map +1 -1
- package/src/ConditionalValidator.ts +11 -12
- package/src/FieldPath.ts +34 -54
- package/src/FormState.ts +5 -4
- package/src/actions/arrayActions.ts +4 -4
- package/src/createFormMiddleware.ts +2 -2
- package/src/createFormProvider.tsx +14 -2
- package/src/createSelectFieldErrorMap.ts +12 -10
- package/src/createSelectFormStatus.ts +3 -1
- package/src/reducers/arrayMove.ts +2 -2
- package/src/reducers/initialize.ts +3 -3
- package/src/reducers/setMeta.ts +4 -1
- package/src/reducers/setParsedValue.ts +10 -9
- package/src/reducers/util/updateRawArray.ts +4 -4
- package/src/useArrayField.ts +39 -28
- package/src/useField.ts +92 -27
- package/src/useFormContext.ts +2 -2
- package/src/useFormDispatch.ts +3 -7
- package/src/useHtmlField.ts +47 -41
- package/src/useInitialize.ts +1 -1
- package/src/util/DeepPartial.ts +2 -3
- package/src/util/PathInType.ts +16 -16
- package/src/util/SchemaAt.ts +38 -49
- package/src/util/bindActionsToField.ts +6 -7
- package/src/util/parsePathstring.ts +47 -41
- package/src/util/pathstring.ts +9 -13
- package/src/util/set.ts +4 -1
- package/useArrayField.d.ts +2 -2
- package/useArrayField.d.ts.map +1 -1
- package/useArrayField.js +22 -8
- package/useArrayField.js.map +1 -1
- package/useArrayField.mjs +12 -2
- package/useArrayField.mjs.map +1 -1
- package/useField.d.ts +6 -3
- package/useField.d.ts.map +1 -1
- package/useField.js +55 -22
- package/useField.js.map +1 -1
- package/useField.mjs +34 -16
- package/useField.mjs.map +1 -1
- package/useFormContext.js.map +1 -1
- package/useFormContext.mjs.map +1 -1
- package/useFormDispatch.d.ts +1 -3
- package/useFormDispatch.d.ts.map +1 -1
- package/useFormDispatch.js.map +1 -1
- package/useFormDispatch.mjs.map +1 -1
- package/useFormStatus.d.ts +1 -1
- package/useHtmlField.d.ts +2 -1
- package/useHtmlField.d.ts.map +1 -1
- package/useHtmlField.js +35 -24
- package/useHtmlField.js.map +1 -1
- package/useHtmlField.mjs +36 -21
- package/useHtmlField.mjs.map +1 -1
- package/useInitialize.js.map +1 -1
- package/useInitialize.mjs.map +1 -1
- package/useSubmit.js.map +1 -1
- package/util/DeepPartial.d.ts.map +1 -1
- package/util/DeepPartial.js.map +1 -1
- package/util/DeepPartial.mjs.map +1 -1
- package/util/PathInType.d.ts +2 -1
- package/util/PathInType.d.ts.map +1 -1
- package/util/PathInType.js.map +1 -1
- package/util/PathInType.mjs.map +1 -1
- package/util/SchemaAt.d.ts +1 -1
- package/util/SchemaAt.d.ts.map +1 -1
- package/util/SchemaAt.js.map +1 -1
- package/util/SchemaAt.mjs.map +1 -1
- package/util/bindActionsToField.d.ts +1 -1
- package/util/bindActionsToField.d.ts.map +1 -1
- package/util/bindActionsToField.js.map +1 -1
- package/util/bindActionsToField.mjs.map +1 -1
- package/util/parsePathstring.d.ts +23 -6
- package/util/parsePathstring.d.ts.map +1 -1
- package/util/parsePathstring.js.map +1 -1
- package/util/parsePathstring.mjs.map +1 -1
- package/util/pathstring.d.ts +2 -8
- package/util/pathstring.d.ts.map +1 -1
- package/util/pathstring.js.map +1 -1
- package/util/pathstring.mjs.map +1 -1
- package/util/set.d.ts.map +1 -1
- package/util/set.js +1 -4
- package/util/set.js.map +1 -1
- package/util/set.mjs +1 -3
- package/util/set.mjs.map +1 -1
package/src/useField.ts
CHANGED
|
@@ -20,6 +20,8 @@ import { SchemaAt } from './util/SchemaAt'
|
|
|
20
20
|
import { maybeParse } from './util/maybeParse'
|
|
21
21
|
import { bindActionsToField } from './util/bindActionsToField'
|
|
22
22
|
import { DeepPartial } from './util/DeepPartial'
|
|
23
|
+
import { invert } from 'zod-invertible'
|
|
24
|
+
import { SelectFormValues } from './createSelectFormValues'
|
|
23
25
|
|
|
24
26
|
export type UseFieldProps<Field extends FieldPath> = FieldMeta &
|
|
25
27
|
ReturnType<
|
|
@@ -45,16 +47,25 @@ export type UseFieldProps<Field extends FieldPath> = FieldMeta &
|
|
|
45
47
|
|
|
46
48
|
export interface TypedUseField<T extends z.ZodTypeAny> {
|
|
47
49
|
<Field extends FieldPath>(field: Field): UseFieldProps<Field>
|
|
48
|
-
<Path extends PathInSchema<T>>(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
<Pathstring extends PathstringInSchema<T>>(
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
<Path extends PathInSchema<T>>(
|
|
51
|
+
path: Path
|
|
52
|
+
): UseFieldProps<FieldPath<SchemaAt<T, Path>>>
|
|
53
|
+
<Pathstring extends PathstringInSchema<T>>(
|
|
54
|
+
path: Pathstring
|
|
55
|
+
): UseFieldProps<FieldPath<SchemaAt<T, parsePathstring<Pathstring>>>>
|
|
54
56
|
}
|
|
55
57
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
export type UseFieldOptions = {
|
|
59
|
+
normalizeOnMount?: boolean
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function useFieldBase<
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
|
|
64
|
+
T extends z.ZodTypeAny,
|
|
65
|
+
Field extends FieldPath,
|
|
66
|
+
>(
|
|
67
|
+
field: Field,
|
|
68
|
+
{ normalizeOnMount = true }: UseFieldOptions = {}
|
|
58
69
|
): UseFieldProps<Field> {
|
|
59
70
|
type Schema = Field['schema']
|
|
60
71
|
|
|
@@ -66,6 +77,8 @@ function useFieldBase<T extends z.ZodTypeAny, Field extends FieldPath>(
|
|
|
66
77
|
selectFieldErrorMap,
|
|
67
78
|
} = useFormContext<T>()
|
|
68
79
|
|
|
80
|
+
type FormValues = ReturnType<SelectFormValues<T>>
|
|
81
|
+
|
|
69
82
|
const useFormSelector = untypedUseFormSelector as TypedUseFormSelector<T>
|
|
70
83
|
|
|
71
84
|
const valuesSelector = React.useMemo(
|
|
@@ -75,24 +88,42 @@ function useFieldBase<T extends z.ZodTypeAny, Field extends FieldPath>(
|
|
|
75
88
|
createSelector(
|
|
76
89
|
[
|
|
77
90
|
createStructuredSelector({
|
|
78
|
-
parsedValue: (
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
91
|
+
parsedValue: createSelector(
|
|
92
|
+
(state: FormValues) => state.parsedValues,
|
|
93
|
+
(parsedValues) =>
|
|
94
|
+
get(parsedValues, field.path) as z.output<Schema> | undefined
|
|
95
|
+
),
|
|
96
|
+
value: createSelector(
|
|
97
|
+
(state: FormValues) => state.values,
|
|
98
|
+
(values) =>
|
|
99
|
+
get(values, field.path) as
|
|
100
|
+
| DeepPartial<z.input<Schema>>
|
|
101
|
+
| undefined
|
|
102
|
+
),
|
|
103
|
+
initialParsedValue: createSelector(
|
|
104
|
+
(state: FormValues) => state.initialParsedValues,
|
|
105
|
+
(initialParsedValues) =>
|
|
106
|
+
get(initialParsedValues, field.path) as
|
|
107
|
+
| z.output<Schema>
|
|
108
|
+
| undefined
|
|
109
|
+
),
|
|
110
|
+
initialValue: createSelector(
|
|
111
|
+
(state: FormValues) => state.initialValues,
|
|
112
|
+
(initialValues) =>
|
|
113
|
+
get(initialValues, field.path) as
|
|
114
|
+
| DeepPartial<z.input<Schema>>
|
|
115
|
+
| undefined
|
|
116
|
+
),
|
|
87
117
|
}),
|
|
88
118
|
],
|
|
89
119
|
({
|
|
90
120
|
value,
|
|
91
|
-
parsedValue = maybeParse(field.schema, value),
|
|
121
|
+
parsedValue = maybeParse<Schema>(field.schema, value),
|
|
92
122
|
initialValue,
|
|
93
|
-
initialParsedValue = maybeParse(field.schema, initialValue),
|
|
123
|
+
initialParsedValue = maybeParse<Schema>(field.schema, initialValue),
|
|
94
124
|
}) => {
|
|
95
|
-
|
|
125
|
+
// console.error(new Error('selector'), { value, parsedValue })
|
|
126
|
+
const dirty = !isEqual(parsedValue, initialParsedValue)
|
|
96
127
|
const pristine = !dirty
|
|
97
128
|
return {
|
|
98
129
|
parsedValue,
|
|
@@ -115,18 +146,44 @@ function useFieldBase<T extends z.ZodTypeAny, Field extends FieldPath>(
|
|
|
115
146
|
)
|
|
116
147
|
const meta = useFormSelector((state) => state.fieldMeta[field.pathstring])
|
|
117
148
|
const submitFailed = useFormSelector((state) => state.submitFailed)
|
|
149
|
+
const initialized = useFormSelector((state) => state.initialized)
|
|
118
150
|
|
|
119
151
|
const boundActions = React.useMemo(
|
|
120
152
|
() => bindActionsToField({ setParsedValue, setValue, setMeta }, field),
|
|
121
153
|
[field.pathstring]
|
|
122
154
|
)
|
|
123
155
|
|
|
156
|
+
const info = React.useRef({ mounted: false, initialized })
|
|
157
|
+
|
|
158
|
+
let normalizedValue = parsedValues.value
|
|
159
|
+
if (
|
|
160
|
+
normalizeOnMount &&
|
|
161
|
+
(!info.current.mounted || (!info.current.initialized && initialized))
|
|
162
|
+
) {
|
|
163
|
+
const parsed = field.schema.safeParse(parsedValues.value)
|
|
164
|
+
const formatted =
|
|
165
|
+
parsed.success ? invert(field.schema).safeParse(parsed.data) : undefined
|
|
166
|
+
if (formatted?.success && formatted.data !== parsedValues.value) {
|
|
167
|
+
normalizedValue = formatted.data
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
info.current.mounted = true
|
|
171
|
+
info.current.initialized = initialized
|
|
172
|
+
|
|
173
|
+
React.useEffect(() => {
|
|
174
|
+
if (normalizeOnMount && !isEqual(normalizedValue, parsedValues.value)) {
|
|
175
|
+
boundActions.setValue(normalizedValue)
|
|
176
|
+
}
|
|
177
|
+
}, [])
|
|
178
|
+
|
|
124
179
|
return React.useMemo(
|
|
125
180
|
() => ({
|
|
126
181
|
...boundActions,
|
|
127
182
|
...parsedValues,
|
|
183
|
+
value: normalizedValue,
|
|
128
184
|
visited: meta?.visited || false,
|
|
129
185
|
touched: meta?.touched || submitFailed,
|
|
186
|
+
customMeta: meta?.customMeta,
|
|
130
187
|
error,
|
|
131
188
|
valid: !error,
|
|
132
189
|
invalid: Boolean(error),
|
|
@@ -136,29 +193,37 @@ function useFieldBase<T extends z.ZodTypeAny, Field extends FieldPath>(
|
|
|
136
193
|
}
|
|
137
194
|
|
|
138
195
|
export function useField<Field extends FieldPath>(
|
|
139
|
-
field: Field
|
|
196
|
+
field: Field,
|
|
197
|
+
options?: UseFieldOptions
|
|
140
198
|
): UseFieldProps<Field>
|
|
141
199
|
export function useField<
|
|
142
200
|
T extends z.ZodTypeAny = z.ZodBranded<
|
|
143
201
|
z.ZodNever,
|
|
144
202
|
'cast to TypedUseArray<T> to pass a path array'
|
|
145
203
|
>,
|
|
146
|
-
Path extends PathInSchema<T> = any
|
|
147
|
-
>(
|
|
204
|
+
Path extends PathInSchema<T> = any,
|
|
205
|
+
>(
|
|
206
|
+
field: Path,
|
|
207
|
+
options?: UseFieldOptions
|
|
208
|
+
): UseFieldProps<FieldPath<SchemaAt<T, Path>>>
|
|
148
209
|
export function useField<
|
|
149
210
|
T extends z.ZodTypeAny = z.ZodBranded<
|
|
150
211
|
z.ZodNever,
|
|
151
212
|
'cast to TypedUseArray<T> to pass a pathstring'
|
|
152
213
|
>,
|
|
153
|
-
Pathstring extends PathstringInSchema<T> = any
|
|
214
|
+
Pathstring extends PathstringInSchema<T> = any,
|
|
154
215
|
>(
|
|
155
|
-
field: Pathstring
|
|
216
|
+
field: Pathstring,
|
|
217
|
+
|
|
218
|
+
options?: UseFieldOptions
|
|
156
219
|
): UseFieldProps<FieldPath<SchemaAt<T, parsePathstring<Pathstring>>>>
|
|
157
220
|
export function useField<T extends z.ZodTypeAny>(
|
|
158
|
-
field: FieldPath | BasePath | string
|
|
221
|
+
field: FieldPath | BasePath | string,
|
|
222
|
+
options?: UseFieldOptions
|
|
159
223
|
): UseFieldProps<any> | { ERROR: string } {
|
|
160
224
|
const { root } = useFormContext<T>()
|
|
161
225
|
return useFieldBase(
|
|
162
|
-
field instanceof FieldPath ? field : root.get(field as any)
|
|
226
|
+
field instanceof FieldPath ? field : root.get(field as any),
|
|
227
|
+
options
|
|
163
228
|
)
|
|
164
229
|
}
|
package/src/useFormContext.ts
CHANGED
|
@@ -6,9 +6,9 @@ export function useFormContext<
|
|
|
6
6
|
T extends z.ZodTypeAny = z.ZodBranded<
|
|
7
7
|
z.ZodNever,
|
|
8
8
|
'you must pass a schema type'
|
|
9
|
-
|
|
9
|
+
>,
|
|
10
10
|
>(): FormContextProps<T> {
|
|
11
|
-
const props: FormContextProps<T> = React.useContext(FormContext) as any
|
|
11
|
+
const props: FormContextProps<T> | null = React.useContext(FormContext) as any
|
|
12
12
|
if (!props) {
|
|
13
13
|
throw new Error(`must be used inside a <FormProvider>`)
|
|
14
14
|
}
|
package/src/useFormDispatch.ts
CHANGED
|
@@ -4,13 +4,9 @@ import z from 'zod'
|
|
|
4
4
|
import { FormAction } from './FormAction'
|
|
5
5
|
import { Dispatch } from 'redux'
|
|
6
6
|
|
|
7
|
-
export const useFormDispatch = createDispatchHook(
|
|
8
|
-
FormStateContext
|
|
9
|
-
) as typeof useFormDispatchType
|
|
10
|
-
|
|
11
|
-
declare function useFormDispatchType<
|
|
7
|
+
export const useFormDispatch = createDispatchHook(FormStateContext) as <
|
|
12
8
|
T extends z.ZodTypeAny = z.ZodBranded<
|
|
13
9
|
z.ZodNever,
|
|
14
10
|
'you must pass a schema type'
|
|
15
|
-
|
|
16
|
-
>()
|
|
11
|
+
>,
|
|
12
|
+
>() => Dispatch<FormAction<T>>
|
package/src/useHtmlField.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { PathInSchema, PathstringInSchema } from './util/PathInSchema'
|
|
|
10
10
|
import { parsePathstring } from './util/parsePathstring'
|
|
11
11
|
import { SchemaAt } from './util/SchemaAt'
|
|
12
12
|
import { DeepPartial } from './util/DeepPartial'
|
|
13
|
+
import isEqual from 'fast-deep-equal'
|
|
13
14
|
|
|
14
15
|
export type HtmlFieldInputProps = {
|
|
15
16
|
name: string
|
|
@@ -26,10 +27,11 @@ export type ValidUseHtmlFieldProps<Field extends FieldPath> = {
|
|
|
26
27
|
meta: UseFieldProps<Field>
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
export type UseHtmlFieldProps<Field extends FieldPath> =
|
|
30
|
-
Field['schema']
|
|
31
|
-
|
|
32
|
-
?
|
|
30
|
+
export type UseHtmlFieldProps<Field extends FieldPath> =
|
|
31
|
+
z.input<Field['schema']> extends (
|
|
32
|
+
string | number | bigint | boolean | null | undefined
|
|
33
|
+
) ?
|
|
34
|
+
{
|
|
33
35
|
input: HtmlFieldInputProps
|
|
34
36
|
meta: UseFieldProps<Field>
|
|
35
37
|
}
|
|
@@ -39,14 +41,13 @@ export type UseHtmlFieldProps<Field extends FieldPath> = z.input<
|
|
|
39
41
|
|
|
40
42
|
export type UseHtmlFieldOptions<
|
|
41
43
|
Field,
|
|
42
|
-
Schema extends z.ZodTypeAny = Field extends FieldPath<infer S>
|
|
43
|
-
|
|
44
|
-
: z.ZodTypeAny
|
|
44
|
+
Schema extends z.ZodTypeAny = Field extends FieldPath<infer S> ? S
|
|
45
|
+
: z.ZodTypeAny,
|
|
45
46
|
> = {
|
|
46
47
|
field: Field
|
|
47
|
-
type: z.input<Schema> extends boolean | null | undefined
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
type: z.input<Schema> extends boolean | null | undefined ? 'checkbox'
|
|
49
|
+
: Exclude<HTMLInputTypeAttribute, 'checkbox'>
|
|
50
|
+
normalizeOnMount?: boolean
|
|
50
51
|
normalizeOnBlur?: boolean
|
|
51
52
|
}
|
|
52
53
|
|
|
@@ -62,11 +63,16 @@ export interface TypedUseHtmlField<T extends z.ZodTypeAny> {
|
|
|
62
63
|
): UseHtmlFieldProps<FieldPath<SchemaAt<T, parsePathstring<Path>>>>
|
|
63
64
|
}
|
|
64
65
|
|
|
66
|
+
const customMetaSchema = z.object({
|
|
67
|
+
value: z.unknown(),
|
|
68
|
+
stringValue: z.string(),
|
|
69
|
+
})
|
|
70
|
+
|
|
65
71
|
function useHtmlFieldBase<Field extends FieldPath>(
|
|
66
72
|
options: UseHtmlFieldOptions<Field, Field['schema']>
|
|
67
73
|
): UseHtmlFieldProps<Field> {
|
|
68
|
-
const { field, type, normalizeOnBlur = true } = options
|
|
69
|
-
const props = useField(field)
|
|
74
|
+
const { field, type, normalizeOnMount, normalizeOnBlur = true } = options
|
|
75
|
+
const props = useField(field, { normalizeOnMount })
|
|
70
76
|
const {
|
|
71
77
|
parsedValue,
|
|
72
78
|
value,
|
|
@@ -78,16 +84,16 @@ function useHtmlFieldBase<Field extends FieldPath>(
|
|
|
78
84
|
...meta
|
|
79
85
|
} = props
|
|
80
86
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
// tempValue is used for storing blank text when we've coerced the
|
|
84
|
-
// value to null or undefined, or storing numeric text when we've
|
|
85
|
-
// coerced the value to a number or bigint.
|
|
87
|
+
// we've coerced the value to null or undefined, or storing numeric
|
|
88
|
+
// text when we've coerced the value to a number or bigint.
|
|
86
89
|
// This way we can set a value that will parse better in the form
|
|
87
90
|
// state without interfering with the text the user is typing.
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
+
const customMeta = React.useMemo(() => {
|
|
92
|
+
const parsedCustomMeta = customMetaSchema.safeParse(meta.customMeta)
|
|
93
|
+
return parsedCustomMeta.success ? parsedCustomMeta.data : undefined
|
|
94
|
+
}, [meta.customMeta])
|
|
95
|
+
|
|
96
|
+
const { schema } = field
|
|
91
97
|
|
|
92
98
|
const tryNumber = React.useMemo(() => acceptsNumber(schema), [schema])
|
|
93
99
|
const tryBigint = React.useMemo(() => acceptsBigint(schema), [schema])
|
|
@@ -101,7 +107,7 @@ function useHtmlFieldBase<Field extends FieldPath>(
|
|
|
101
107
|
tryBigint,
|
|
102
108
|
})
|
|
103
109
|
if (typeof value === 'string' && typeof normalized !== 'string') {
|
|
104
|
-
|
|
110
|
+
setMeta({ customMeta: { stringValue: value, value: normalized } })
|
|
105
111
|
}
|
|
106
112
|
setValue(normalized)
|
|
107
113
|
},
|
|
@@ -114,21 +120,20 @@ function useHtmlFieldBase<Field extends FieldPath>(
|
|
|
114
120
|
|
|
115
121
|
const onBlur = React.useCallback(
|
|
116
122
|
(e: React.FocusEvent) => {
|
|
117
|
-
let value = normalizeValue(getValue(e), {
|
|
118
|
-
schema,
|
|
119
|
-
tryNumber,
|
|
120
|
-
tryBigint,
|
|
121
|
-
})
|
|
122
123
|
if (normalizeOnBlur) {
|
|
124
|
+
const value = normalizeValue(getValue(e), {
|
|
125
|
+
schema,
|
|
126
|
+
tryNumber,
|
|
127
|
+
tryBigint,
|
|
128
|
+
})
|
|
123
129
|
const parsed = field.schema.safeParse(value)
|
|
124
|
-
const formatted =
|
|
125
|
-
|
|
130
|
+
const formatted =
|
|
131
|
+
parsed.success ?
|
|
132
|
+
invert(field.schema).safeParse(parsed.data)
|
|
126
133
|
: undefined
|
|
127
|
-
|
|
128
|
-
setValue(value)
|
|
134
|
+
setValue(formatted?.success ? formatted.data : value)
|
|
129
135
|
}
|
|
130
|
-
|
|
131
|
-
setMeta({ visited: true, touched: true })
|
|
136
|
+
setMeta({ visited: true, touched: true, customMeta: undefined })
|
|
132
137
|
},
|
|
133
138
|
[getValue, setValue, schema]
|
|
134
139
|
)
|
|
@@ -139,11 +144,12 @@ function useHtmlFieldBase<Field extends FieldPath>(
|
|
|
139
144
|
name: field.pathstring,
|
|
140
145
|
type,
|
|
141
146
|
value:
|
|
142
|
-
typeof value === 'boolean'
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
+
typeof value === 'boolean' ? String(value)
|
|
148
|
+
: typeof value === 'string' ? value || customMeta?.stringValue || ''
|
|
149
|
+
: customMeta && isEqual(customMeta.value, value) ?
|
|
150
|
+
customMeta.stringValue
|
|
151
|
+
: value == null ? ''
|
|
152
|
+
: String(value) || '',
|
|
147
153
|
...(type === 'checkbox' && { checked: Boolean(value) }),
|
|
148
154
|
onChange,
|
|
149
155
|
onFocus,
|
|
@@ -160,7 +166,7 @@ function useHtmlFieldBase<Field extends FieldPath>(
|
|
|
160
166
|
setMeta,
|
|
161
167
|
},
|
|
162
168
|
}),
|
|
163
|
-
[props,
|
|
169
|
+
[props, customMeta, onChange]
|
|
164
170
|
) as any
|
|
165
171
|
}
|
|
166
172
|
|
|
@@ -181,7 +187,7 @@ function normalizeBlank(schema: z.ZodTypeAny): any {
|
|
|
181
187
|
function safeBigInt(value: string): bigint | undefined {
|
|
182
188
|
try {
|
|
183
189
|
return BigInt(value)
|
|
184
|
-
} catch
|
|
190
|
+
} catch {
|
|
185
191
|
return undefined
|
|
186
192
|
}
|
|
187
193
|
}
|
|
@@ -219,7 +225,7 @@ export function useHtmlField<
|
|
|
219
225
|
z.ZodNever,
|
|
220
226
|
'cast to TypedUseHtmlField<T> to pass a path array'
|
|
221
227
|
>,
|
|
222
|
-
Path extends PathInSchema<T> = any
|
|
228
|
+
Path extends PathInSchema<T> = any,
|
|
223
229
|
>(
|
|
224
230
|
options: UseHtmlFieldOptions<Path, SchemaAt<T, Path>>
|
|
225
231
|
): UseHtmlFieldProps<FieldPath<SchemaAt<T, Path>>>
|
|
@@ -228,7 +234,7 @@ export function useHtmlField<
|
|
|
228
234
|
z.ZodNever,
|
|
229
235
|
'cast to TypedUseHtmlField<T> to pass a pathstring'
|
|
230
236
|
>,
|
|
231
|
-
Path extends PathstringInSchema<T> = any
|
|
237
|
+
Path extends PathstringInSchema<T> = any,
|
|
232
238
|
>(
|
|
233
239
|
options: UseHtmlFieldOptions<Path, SchemaAt<T, parsePathstring<Path>>>
|
|
234
240
|
): UseHtmlFieldProps<FieldPath<SchemaAt<T, parsePathstring<Path>>>>
|
package/src/useInitialize.ts
CHANGED
package/src/util/DeepPartial.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
export type DeepPartial<T> =
|
|
2
|
-
? { [K in keyof T]?: DeepPartial<T[K]> }
|
|
3
|
-
: T
|
|
1
|
+
export type DeepPartial<T> =
|
|
2
|
+
T extends object | any[] ? { [K in keyof T]?: DeepPartial<T[K]> } : T
|
package/src/util/PathInType.ts
CHANGED
|
@@ -3,22 +3,22 @@ import { pathstring } from './pathstring'
|
|
|
3
3
|
|
|
4
4
|
export type PathInType<T> = [] | SubPathInType<T>
|
|
5
5
|
|
|
6
|
-
type SubPathInType<T> =
|
|
7
|
-
? BasePath
|
|
8
|
-
: T extends
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
: T extends readonly any[]
|
|
21
|
-
|
|
6
|
+
type SubPathInType<T> =
|
|
7
|
+
0 extends 1 & T ? BasePath
|
|
8
|
+
: T extends (
|
|
9
|
+
| string
|
|
10
|
+
| number
|
|
11
|
+
| boolean
|
|
12
|
+
| bigint
|
|
13
|
+
| symbol
|
|
14
|
+
| null
|
|
15
|
+
| undefined
|
|
16
|
+
| void
|
|
17
|
+
| ((...args: any[]) => any)
|
|
18
|
+
) ?
|
|
19
|
+
[]
|
|
20
|
+
: T extends readonly any[] ?
|
|
21
|
+
{ [K in keyof T & number]-?: [K, ...PathInType<T[K]>] }[keyof T & number]
|
|
22
22
|
: {
|
|
23
23
|
[K in keyof T]-?: K extends symbol ? never : [K, ...PathInType<T[K]>]
|
|
24
24
|
}[keyof T]
|
package/src/util/SchemaAt.ts
CHANGED
|
@@ -2,67 +2,56 @@ import z from 'zod'
|
|
|
2
2
|
|
|
3
3
|
type BasePath = (string | number)[]
|
|
4
4
|
|
|
5
|
-
export type SchemaAt<T extends z.ZodTypeAny, Path> =
|
|
6
|
-
? z.ZodTypeAny
|
|
7
|
-
: 0 extends 1 & T
|
|
8
|
-
? z.ZodTypeAny
|
|
9
|
-
:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
? SchemaAt<U, Path>
|
|
14
|
-
: T extends z.
|
|
15
|
-
? SchemaAt<U, Path>
|
|
16
|
-
: T extends z.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
? SchemaAt<
|
|
20
|
-
: T extends z.
|
|
21
|
-
? SchemaAt<U, Path>
|
|
22
|
-
: T extends z.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
? SchemaAt<Options[number], Path>
|
|
26
|
-
: T extends z.ZodDiscriminatedUnion<any, infer Options>
|
|
27
|
-
? SchemaAt<Options[number], Path>
|
|
28
|
-
: T extends z.ZodPipeline<infer In, any>
|
|
29
|
-
? SchemaAt<In, Path>
|
|
30
|
-
: T extends z.ZodEffects<infer U>
|
|
31
|
-
? SchemaAt<U, Path>
|
|
32
|
-
: T extends z.ZodReadonly<infer U>
|
|
33
|
-
? SchemaAt<U, Path>
|
|
34
|
-
: T extends z.ZodRecord<infer Key, infer Value>
|
|
35
|
-
? Head extends z.input<Key>
|
|
36
|
-
? SchemaAt<Value, Tail>
|
|
5
|
+
export type SchemaAt<T extends z.ZodTypeAny, Path> =
|
|
6
|
+
0 extends 1 & Path ? z.ZodTypeAny
|
|
7
|
+
: 0 extends 1 & T ? z.ZodTypeAny
|
|
8
|
+
: 0 extends 1 & z.input<T> ? z.ZodTypeAny
|
|
9
|
+
: Path extends [infer Head, ...infer Tail extends BasePath] ?
|
|
10
|
+
T extends z.ZodLazy<infer U> ? SchemaAt<U, Path>
|
|
11
|
+
: T extends z.ZodCatch<infer U> ? SchemaAt<U, Path>
|
|
12
|
+
: T extends z.ZodBranded<infer U, any> ? SchemaAt<U, Path>
|
|
13
|
+
: T extends z.ZodOptional<infer U> ? SchemaAt<U, Path>
|
|
14
|
+
: T extends z.ZodDefault<infer U> ? SchemaAt<U, Path>
|
|
15
|
+
: T extends z.ZodNullable<infer U> ? SchemaAt<U, Path>
|
|
16
|
+
: T extends z.ZodUnion<infer Options> ? SchemaAt<Options[number], Path>
|
|
17
|
+
: T extends z.ZodDiscriminatedUnion<any, infer Options> ?
|
|
18
|
+
SchemaAt<Options[number], Path>
|
|
19
|
+
: T extends z.ZodPipeline<infer In, any> ? SchemaAt<In, Path>
|
|
20
|
+
: T extends z.ZodEffects<infer U> ? SchemaAt<U, Path>
|
|
21
|
+
: T extends z.ZodReadonly<infer U> ? SchemaAt<U, Path>
|
|
22
|
+
: T extends z.ZodRecord<infer Key, infer Value> ?
|
|
23
|
+
Head extends z.input<Key> ?
|
|
24
|
+
SchemaAt<Value, Tail>
|
|
37
25
|
: never
|
|
38
|
-
: T extends z.ZodMap<infer Key, infer Value>
|
|
39
|
-
|
|
40
|
-
|
|
26
|
+
: T extends z.ZodMap<infer Key, infer Value> ?
|
|
27
|
+
Head extends z.input<Key> ?
|
|
28
|
+
SchemaAt<Value, Tail>
|
|
41
29
|
: never
|
|
42
|
-
: T extends
|
|
30
|
+
: T extends (
|
|
31
|
+
z.ZodObject<
|
|
43
32
|
infer Shape,
|
|
44
33
|
infer UnknownKeys,
|
|
45
34
|
infer Catchall extends z.ZodTypeAny
|
|
46
35
|
>
|
|
47
|
-
?
|
|
48
|
-
? SchemaAt<Shape[Head], Tail>
|
|
49
|
-
: UnknownKeys extends 'passthrough'
|
|
50
|
-
? SchemaAt<Catchall, Tail>
|
|
36
|
+
) ?
|
|
37
|
+
Head extends keyof Shape ? SchemaAt<Shape[Head], Tail>
|
|
38
|
+
: UnknownKeys extends 'passthrough' ? SchemaAt<Catchall, Tail>
|
|
51
39
|
: never
|
|
52
|
-
: T extends
|
|
40
|
+
: T extends (
|
|
41
|
+
z.ZodTuple<
|
|
53
42
|
infer Elements extends [z.ZodTypeAny, ...z.ZodTypeAny[]],
|
|
54
43
|
infer Rest
|
|
55
44
|
>
|
|
56
|
-
?
|
|
57
|
-
? SchemaAt<Elements[Head], Tail>
|
|
58
|
-
: Rest extends z.ZodTypeAny
|
|
59
|
-
|
|
60
|
-
|
|
45
|
+
) ?
|
|
46
|
+
Head extends number & keyof Elements ? SchemaAt<Elements[Head], Tail>
|
|
47
|
+
: Rest extends z.ZodTypeAny ?
|
|
48
|
+
Head extends number ?
|
|
49
|
+
SchemaAt<Rest, Tail>
|
|
61
50
|
: never
|
|
62
51
|
: never
|
|
63
|
-
: T extends z.ZodArray<infer Element>
|
|
64
|
-
|
|
65
|
-
|
|
52
|
+
: T extends z.ZodArray<infer Element> ?
|
|
53
|
+
Head extends number ?
|
|
54
|
+
SchemaAt<Element, Tail>
|
|
66
55
|
: never
|
|
67
56
|
: never
|
|
68
57
|
: T
|
|
@@ -4,22 +4,21 @@ export function bindActionsToField<
|
|
|
4
4
|
Field extends FieldPath,
|
|
5
5
|
Actions extends {
|
|
6
6
|
[K in string]: (field: Field, ...rest: any[]) => any
|
|
7
|
-
}
|
|
7
|
+
},
|
|
8
8
|
>(
|
|
9
9
|
actions: Actions,
|
|
10
10
|
field: Field
|
|
11
11
|
): {
|
|
12
12
|
[K in keyof Actions]: Actions[K] extends (
|
|
13
|
-
field: Field,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
: never
|
|
13
|
+
(field: Field, ...rest: infer Rest) => infer Return
|
|
14
|
+
) ?
|
|
15
|
+
(...rest: Rest) => Return
|
|
16
|
+
: never
|
|
18
17
|
} {
|
|
19
18
|
return Object.fromEntries(
|
|
20
19
|
Object.entries(actions).map(([key, action]: any) => [
|
|
21
20
|
key,
|
|
22
21
|
(...args: any[]) => action(field, ...args),
|
|
23
22
|
])
|
|
24
|
-
)
|
|
23
|
+
)
|
|
25
24
|
}
|