@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.
Files changed (151) hide show
  1. package/ConditionalValidator.d.ts.map +1 -1
  2. package/ConditionalValidator.js +4 -2
  3. package/ConditionalValidator.js.map +1 -1
  4. package/ConditionalValidator.mjs +3 -1
  5. package/ConditionalValidator.mjs.map +1 -1
  6. package/FieldPath.d.ts.map +1 -1
  7. package/FieldPath.js +1 -0
  8. package/FieldPath.js.map +1 -1
  9. package/FieldPath.mjs.map +1 -1
  10. package/FormState.d.ts +7 -4
  11. package/FormState.d.ts.map +1 -1
  12. package/FormState.js.map +1 -1
  13. package/FormState.mjs.map +1 -1
  14. package/actions/arrayActions.js.map +1 -1
  15. package/actions/arrayActions.mjs.map +1 -1
  16. package/actions/setSubmitStatus.d.ts +1 -1
  17. package/createFormMiddleware.js +3 -3
  18. package/createFormMiddleware.js.map +1 -1
  19. package/createFormMiddleware.mjs.map +1 -1
  20. package/createFormProvider.d.ts +9 -3
  21. package/createFormProvider.d.ts.map +1 -1
  22. package/createFormProvider.js +10 -3
  23. package/createFormProvider.js.map +1 -1
  24. package/createFormProvider.mjs +53 -44
  25. package/createFormProvider.mjs.map +1 -1
  26. package/createFormReducer.js +16 -16
  27. package/createFormReducer.js.map +1 -1
  28. package/createSelectFieldErrorMap.d.ts +3 -3
  29. package/createSelectFieldErrorMap.js.map +1 -1
  30. package/createSelectFieldErrorMap.mjs.map +1 -1
  31. package/createSelectFormStatus.d.ts +10 -10
  32. package/createSelectFormStatus.d.ts.map +1 -1
  33. package/createSelectFormStatus.js +2 -2
  34. package/createSelectFormStatus.js.map +1 -1
  35. package/createSelectFormStatus.mjs +1 -1
  36. package/createSelectFormStatus.mjs.map +1 -1
  37. package/createSelectFormValues.js.map +1 -1
  38. package/createZodForm.d.ts +10 -5
  39. package/createZodForm.d.ts.map +1 -1
  40. package/package.json +5 -4
  41. package/reducers/addHandlers.d.ts +2 -2
  42. package/reducers/addHandlers.d.ts.map +1 -1
  43. package/reducers/arrayMove.js.map +1 -1
  44. package/reducers/arrayMove.mjs.map +1 -1
  45. package/reducers/initialize.d.ts +4 -4
  46. package/reducers/initialize.d.ts.map +1 -1
  47. package/reducers/initialize.js.map +1 -1
  48. package/reducers/initialize.mjs.map +1 -1
  49. package/reducers/removeHandlers.d.ts +2 -2
  50. package/reducers/removeHandlers.d.ts.map +1 -1
  51. package/reducers/setMeta.d.ts.map +1 -1
  52. package/reducers/setMeta.js +4 -1
  53. package/reducers/setMeta.js.map +1 -1
  54. package/reducers/setMeta.mjs +4 -1
  55. package/reducers/setMeta.mjs.map +1 -1
  56. package/reducers/setParsedValue.d.ts +2 -2
  57. package/reducers/setParsedValue.d.ts.map +1 -1
  58. package/reducers/setParsedValue.js +1 -1
  59. package/reducers/setParsedValue.js.map +1 -1
  60. package/reducers/setParsedValue.mjs +1 -1
  61. package/reducers/setParsedValue.mjs.map +1 -1
  62. package/reducers/setSubmitStatus.d.ts +2 -2
  63. package/reducers/setSubmitStatus.d.ts.map +1 -1
  64. package/reducers/setValue.d.ts +1 -1
  65. package/reducers/setValue.d.ts.map +1 -1
  66. package/reducers/submitSucceeded.d.ts +1 -1
  67. package/reducers/submitSucceeded.d.ts.map +1 -1
  68. package/reducers/util/updateRawArray.js.map +1 -1
  69. package/reducers/util/updateRawArray.mjs.map +1 -1
  70. package/src/ConditionalValidator.ts +11 -12
  71. package/src/FieldPath.ts +34 -54
  72. package/src/FormState.ts +5 -4
  73. package/src/actions/arrayActions.ts +4 -4
  74. package/src/createFormMiddleware.ts +2 -2
  75. package/src/createFormProvider.tsx +14 -2
  76. package/src/createSelectFieldErrorMap.ts +12 -10
  77. package/src/createSelectFormStatus.ts +3 -1
  78. package/src/reducers/arrayMove.ts +2 -2
  79. package/src/reducers/initialize.ts +3 -3
  80. package/src/reducers/setMeta.ts +4 -1
  81. package/src/reducers/setParsedValue.ts +10 -9
  82. package/src/reducers/util/updateRawArray.ts +4 -4
  83. package/src/useArrayField.ts +39 -28
  84. package/src/useField.ts +92 -27
  85. package/src/useFormContext.ts +2 -2
  86. package/src/useFormDispatch.ts +3 -7
  87. package/src/useHtmlField.ts +47 -41
  88. package/src/useInitialize.ts +1 -1
  89. package/src/util/DeepPartial.ts +2 -3
  90. package/src/util/PathInType.ts +16 -16
  91. package/src/util/SchemaAt.ts +38 -49
  92. package/src/util/bindActionsToField.ts +6 -7
  93. package/src/util/parsePathstring.ts +47 -41
  94. package/src/util/pathstring.ts +9 -13
  95. package/src/util/set.ts +4 -1
  96. package/useArrayField.d.ts +2 -2
  97. package/useArrayField.d.ts.map +1 -1
  98. package/useArrayField.js +22 -8
  99. package/useArrayField.js.map +1 -1
  100. package/useArrayField.mjs +12 -2
  101. package/useArrayField.mjs.map +1 -1
  102. package/useField.d.ts +6 -3
  103. package/useField.d.ts.map +1 -1
  104. package/useField.js +55 -22
  105. package/useField.js.map +1 -1
  106. package/useField.mjs +34 -16
  107. package/useField.mjs.map +1 -1
  108. package/useFormContext.js.map +1 -1
  109. package/useFormContext.mjs.map +1 -1
  110. package/useFormDispatch.d.ts +1 -3
  111. package/useFormDispatch.d.ts.map +1 -1
  112. package/useFormDispatch.js.map +1 -1
  113. package/useFormDispatch.mjs.map +1 -1
  114. package/useFormStatus.d.ts +1 -1
  115. package/useHtmlField.d.ts +2 -1
  116. package/useHtmlField.d.ts.map +1 -1
  117. package/useHtmlField.js +35 -24
  118. package/useHtmlField.js.map +1 -1
  119. package/useHtmlField.mjs +36 -21
  120. package/useHtmlField.mjs.map +1 -1
  121. package/useInitialize.js.map +1 -1
  122. package/useInitialize.mjs.map +1 -1
  123. package/useSubmit.js.map +1 -1
  124. package/util/DeepPartial.d.ts.map +1 -1
  125. package/util/DeepPartial.js.map +1 -1
  126. package/util/DeepPartial.mjs.map +1 -1
  127. package/util/PathInType.d.ts +2 -1
  128. package/util/PathInType.d.ts.map +1 -1
  129. package/util/PathInType.js.map +1 -1
  130. package/util/PathInType.mjs.map +1 -1
  131. package/util/SchemaAt.d.ts +1 -1
  132. package/util/SchemaAt.d.ts.map +1 -1
  133. package/util/SchemaAt.js.map +1 -1
  134. package/util/SchemaAt.mjs.map +1 -1
  135. package/util/bindActionsToField.d.ts +1 -1
  136. package/util/bindActionsToField.d.ts.map +1 -1
  137. package/util/bindActionsToField.js.map +1 -1
  138. package/util/bindActionsToField.mjs.map +1 -1
  139. package/util/parsePathstring.d.ts +23 -6
  140. package/util/parsePathstring.d.ts.map +1 -1
  141. package/util/parsePathstring.js.map +1 -1
  142. package/util/parsePathstring.mjs.map +1 -1
  143. package/util/pathstring.d.ts +2 -8
  144. package/util/pathstring.d.ts.map +1 -1
  145. package/util/pathstring.js.map +1 -1
  146. package/util/pathstring.mjs.map +1 -1
  147. package/util/set.d.ts.map +1 -1
  148. package/util/set.js +1 -4
  149. package/util/set.js.map +1 -1
  150. package/util/set.mjs +1 -3
  151. package/util/set.mjs.map +1 -1
package/src/FieldPath.ts CHANGED
@@ -55,45 +55,31 @@ export class FieldPath<T extends z.ZodTypeAny = z.ZodTypeAny> {
55
55
 
56
56
  export type BasePath = (string | number)[]
57
57
 
58
- export type SubpathKey<T extends z.ZodTypeAny> = 0 extends 1 & T
59
- ? any
60
- : 0 extends 1 & z.input<T>
61
- ? any
62
- : T extends z.ZodObject<infer Shape, infer UnknownKeys>
63
- ? UnknownKeys extends 'passthrough'
64
- ? string
58
+ export type SubpathKey<T extends z.ZodTypeAny> =
59
+ 0 extends 1 & T ? any
60
+ : 0 extends 1 & z.input<T> ? any
61
+ : T extends z.ZodObject<infer Shape, infer UnknownKeys> ?
62
+ UnknownKeys extends 'passthrough' ?
63
+ string
65
64
  : keyof Shape
66
- : T extends z.ZodRecord<infer Key, any>
67
- ? z.input<Key>
68
- : T extends z.ZodMap<infer Key, any>
69
- ? z.input<Key>
70
- : T extends z.ZodArray<any>
71
- ? number
72
- : T extends z.ZodTuple<any, any>
73
- ? number
74
- : T extends z.ZodLazy<infer U>
75
- ? SubpathKey<U>
76
- : T extends z.ZodUnion<infer Options>
77
- ? SubpathKey<Options[number]>
78
- : T extends z.ZodDiscriminatedUnion<any, infer Options>
79
- ? SubpathKey<Options[number]>
80
- : T extends z.ZodOptional<infer U>
81
- ? SubpathKey<U>
82
- : T extends z.ZodNullable<infer U>
83
- ? SubpathKey<U>
84
- : T extends z.ZodDefault<infer U>
85
- ? SubpathKey<U>
86
- : T extends z.ZodCatch<infer U>
87
- ? SubpathKey<U>
88
- : T extends z.ZodEffects<infer U, any>
89
- ? SubpathKey<U>
90
- : T extends z.ZodBranded<infer U, any>
91
- ? SubpathKey<U>
65
+ : T extends z.ZodRecord<infer Key, any> ? z.input<Key>
66
+ : T extends z.ZodMap<infer Key, any> ? z.input<Key>
67
+ : T extends z.ZodArray<any> ? number
68
+ : T extends z.ZodTuple<any, any> ? number
69
+ : T extends z.ZodLazy<infer U> ? SubpathKey<U>
70
+ : T extends z.ZodUnion<infer Options> ? SubpathKey<Options[number]>
71
+ : T extends z.ZodDiscriminatedUnion<any, infer Options> ?
72
+ SubpathKey<Options[number]>
73
+ : T extends z.ZodOptional<infer U> ? SubpathKey<U>
74
+ : T extends z.ZodNullable<infer U> ? SubpathKey<U>
75
+ : T extends z.ZodDefault<infer U> ? SubpathKey<U>
76
+ : T extends z.ZodCatch<infer U> ? SubpathKey<U>
77
+ : T extends z.ZodEffects<infer U, any> ? SubpathKey<U>
78
+ : T extends z.ZodBranded<infer U, any> ? SubpathKey<U>
92
79
  : never
93
80
 
94
- export type AllPaths<T extends z.ZodTypeAny> = SubpathKey<T> extends never
95
- ? []
96
- : [] | ValuesOf<SubpathKeyMap<T>>
81
+ export type AllPaths<T extends z.ZodTypeAny> =
82
+ SubpathKey<T> extends never ? [] : [] | ValuesOf<SubpathKeyMap<T>>
97
83
 
98
84
  type ValuesOf<O> = O[keyof O]
99
85
 
@@ -117,8 +103,8 @@ function subschema(
117
103
  } = schema as z.AnyZodObject
118
104
  if (key in shape) return shape[key]
119
105
  if (unknownKeys === 'passthrough') {
120
- return catchall._def.typeName === z.ZodFirstPartyTypeKind.ZodNever
121
- ? z.unknown()
106
+ return catchall._def.typeName === z.ZodFirstPartyTypeKind.ZodNever ?
107
+ z.unknown()
122
108
  : catchall
123
109
  }
124
110
  break
@@ -129,11 +115,11 @@ function subschema(
129
115
  ).options
130
116
  .map((opt) => subschema(opt, key))
131
117
  .filter((opt): opt is z.ZodTypeAny => opt != null)
132
- return options.length > 1
133
- ? z.union(options as any)
134
- : options.length === 1
135
- ? options[0]
118
+ return (
119
+ options.length > 1 ? z.union(options as any)
120
+ : options.length === 1 ? options[0]
136
121
  : undefined
122
+ )
137
123
  }
138
124
  case 'ZodDiscriminatedUnion': {
139
125
  const discUnion = schema as z.ZodDiscriminatedUnion<
@@ -143,11 +129,11 @@ function subschema(
143
129
  const options = discUnion.options
144
130
  .map((opt) => subschema(opt, key))
145
131
  .filter((opt): opt is z.ZodTypeAny => opt != null)
146
- return options.length > 1
147
- ? z.union(options as any)
148
- : options.length === 1
149
- ? options[0]
132
+ return (
133
+ options.length > 1 ? z.union(options as any)
134
+ : options.length === 1 ? options[0]
150
135
  : undefined
136
+ )
151
137
  break
152
138
  }
153
139
  case 'ZodIntersection':
@@ -164,18 +150,12 @@ function subschema(
164
150
  break
165
151
  }
166
152
  case 'ZodRecord': {
167
- const { keySchema, valueSchema } = schema as z.ZodRecord<
168
- z.ZodTypeAny,
169
- z.ZodTypeAny
170
- >
153
+ const { keySchema, valueSchema } = schema as z.ZodRecord<z.ZodTypeAny>
171
154
  if (keySchema.safeParse(key).success) return valueSchema
172
155
  break
173
156
  }
174
157
  case 'ZodMap': {
175
- const { keySchema, valueSchema } = schema as z.ZodMap<
176
- z.ZodTypeAny,
177
- z.ZodTypeAny
178
- >
158
+ const { keySchema, valueSchema } = schema as z.ZodMap
179
159
  if (keySchema.safeParse(key).success) return valueSchema
180
160
  break
181
161
  }
package/src/FormState.ts CHANGED
@@ -4,6 +4,7 @@ import { DeepPartial } from './util/DeepPartial'
4
4
  export type FieldMeta = {
5
5
  touched: boolean
6
6
  visited: boolean
7
+ customMeta?: unknown
7
8
  }
8
9
 
9
10
  export type SubmitHandler<T extends z.ZodTypeAny> = (
@@ -14,14 +15,14 @@ export type SubmitHandler<T extends z.ZodTypeAny> = (
14
15
  }
15
16
  ) => void | Promise<void>
16
17
 
17
- export type SubmitSuccededHandler = () => void
18
+ export type SubmitSuccededHandler = () => void | Promise<void>
18
19
 
19
- export type SubmitFailedHandler = (error: Error) => void
20
+ export type SubmitFailedHandler = (error: unknown) => void | Promise<void>
20
21
 
21
22
  export type FormState<T extends z.ZodTypeAny> = {
22
23
  mounted: boolean
23
24
  initialized: boolean
24
- fieldMeta: Record<string, FieldMeta>
25
+ fieldMeta: { [K in string]?: FieldMeta }
25
26
  values?: DeepPartial<z.input<T>>
26
27
  parsedValues?: z.output<T>
27
28
  submittedParsedValues?: z.output<T>
@@ -36,5 +37,5 @@ export type FormState<T extends z.ZodTypeAny> = {
36
37
  submitting: boolean
37
38
  submitSucceeded: boolean
38
39
  submitFailed: boolean
39
- submitError?: Error
40
+ submitError?: unknown
40
41
  }
@@ -16,7 +16,7 @@ type ValueFor<Field extends ArrayFieldPath> = DeepPartial<
16
16
  >
17
17
 
18
18
  export type ArrayInsertParsedAction<
19
- Field extends ArrayFieldPath = ArrayFieldPath
19
+ Field extends ArrayFieldPath = ArrayFieldPath,
20
20
  > = ReturnType<typeof arrayInsertParsed<Field>>
21
21
 
22
22
  export function arrayInsertParsed<Field extends ArrayFieldPath>(
@@ -51,7 +51,7 @@ export function arrayPop(field: ArrayFieldPath) {
51
51
  }
52
52
 
53
53
  export type ArrayPushParsedAction<
54
- Field extends ArrayFieldPath = ArrayFieldPath
54
+ Field extends ArrayFieldPath = ArrayFieldPath,
55
55
  > = ReturnType<typeof arrayPushParsed<Field>>
56
56
 
57
57
  export function arrayPushParsed<Field extends ArrayFieldPath>(
@@ -90,7 +90,7 @@ export function arrayShift(field: ArrayFieldPath) {
90
90
  }
91
91
 
92
92
  export type ArraySpliceParsedAction<
93
- Field extends ArrayFieldPath = ArrayFieldPath
93
+ Field extends ArrayFieldPath = ArrayFieldPath,
94
94
  > = ReturnType<typeof arraySpliceParsed<Field>>
95
95
 
96
96
  export function arraySpliceParsed<Field extends ArrayFieldPath>(
@@ -137,7 +137,7 @@ export function arraySwap(
137
137
  }
138
138
 
139
139
  export type ArrayUnshiftParsedAction<
140
- Field extends ArrayFieldPath = ArrayFieldPath
140
+ Field extends ArrayFieldPath = ArrayFieldPath,
141
141
  > = ReturnType<typeof arrayUnshiftParsed<Field>>
142
142
 
143
143
  export function arrayUnshiftParsed<Field extends ArrayFieldPath>(
@@ -7,7 +7,7 @@ import { setSubmitStatus } from './actions/setSubmitStatus'
7
7
  import { submitSucceeded } from './actions/submitSucceeded'
8
8
 
9
9
  export function createFormMiddleware<T extends z.ZodTypeAny>(): Middleware<
10
- // eslint-disable-next-line @typescript-eslint/ban-types
10
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
11
11
  {},
12
12
  FormState<T>,
13
13
  Dispatch<FormAction<T>>
@@ -49,7 +49,7 @@ export function createFormMiddleware<T extends z.ZodTypeAny>(): Middleware<
49
49
  store.dispatch(submitSucceeded())
50
50
  for (const fn of onSubmitSucceeded) await fn()
51
51
  },
52
- async (error) => {
52
+ async (error: unknown) => {
53
53
  if (store.getState().submitPromise !== submitPromise) return
54
54
  store.dispatch(
55
55
  setSubmitStatus({
@@ -1,5 +1,10 @@
1
1
  import React from 'react'
2
- import { Store, applyMiddleware, bindActionCreators, createStore } from 'redux'
2
+ import {
3
+ Store,
4
+ applyMiddleware,
5
+ bindActionCreators,
6
+ legacy_createStore as createStore,
7
+ } from 'redux'
3
8
  import z from 'zod'
4
9
  import { setMounted } from './actions/setMounted'
5
10
  import { createFormReducer } from './createFormReducer'
@@ -18,6 +23,7 @@ import { setMeta } from './actions/setMeta'
18
23
  import { addHandlers } from './actions/addHandlers'
19
24
  import { removeHandlers } from './actions/removeHandlers'
20
25
  import { arrayActions } from './actions/arrayActions'
26
+ import PropTypes from 'prop-types'
21
27
 
22
28
  export const createFormProvider = <T extends z.ZodTypeAny>(
23
29
  props: Pick<
@@ -29,7 +35,7 @@ export const createFormProvider = <T extends z.ZodTypeAny>(
29
35
  | 'selectFieldErrorMap'
30
36
  | 'selectFormValues'
31
37
  >
32
- ) =>
38
+ ) => {
33
39
  function FormProvider({ children }: { children: React.ReactElement }) {
34
40
  const storeRef = React.useRef<Store<FormState<T>, FormAction<T>>>()
35
41
  if (!storeRef.current) {
@@ -55,6 +61,7 @@ export const createFormProvider = <T extends z.ZodTypeAny>(
55
61
  []
56
62
  )
57
63
  const getStatus = React.useCallback(
64
+ // eslint-disable-next-line react/prop-types
58
65
  () => props.selectFormStatus(store.getState()),
59
66
  []
60
67
  )
@@ -102,3 +109,8 @@ export const createFormProvider = <T extends z.ZodTypeAny>(
102
109
  </FormContext.Provider>
103
110
  )
104
111
  }
112
+ FormProvider.propTypes = {
113
+ children: PropTypes.node,
114
+ }
115
+ return FormProvider
116
+ }
@@ -14,12 +14,12 @@ export function createSelectFieldErrorMap() {
14
14
  (...errors: any[]): { [K in string]?: string } =>
15
15
  Object.fromEntries(
16
16
  errors.flatMap((e) =>
17
- isZodError(e)
18
- ? e.issues.map((issue) => [
19
- pathstring(issue.path),
20
- messageForIssue(issue),
21
- ])
22
- : []
17
+ isZodError(e) ?
18
+ e.issues.map((issue) => [
19
+ pathstring(issue.path),
20
+ messageForIssue(issue),
21
+ ])
22
+ : []
23
23
  )
24
24
  )
25
25
  )
@@ -34,14 +34,16 @@ function isZodError(error: any): error is z.ZodError {
34
34
  */
35
35
  function messageForIssue(issue: z.ZodIssue): string {
36
36
  if (issue.code === 'invalid_type') {
37
- return issue.received === 'null' || issue.received === 'undefined'
38
- ? // Without this, the error would say "Expected <type>, received null"
37
+ return (
38
+ issue.received === 'null' || issue.received === 'undefined' ?
39
+ // Without this, the error would say "Expected <type>, received null"
39
40
  // or "Invalid number" as below
40
41
  'Required'
41
- : issue.expected === 'number' || issue.expected === 'bigint'
42
- ? // Without this, invalid text input for z.number() would say "Expected number, received string"
42
+ : issue.expected === 'number' || issue.expected === 'bigint' ?
43
+ // Without this, invalid text input for z.number() would say "Expected number, received string"
43
44
  'Invalid number'
44
45
  : issue.message
46
+ )
45
47
  }
46
48
  return issue.message
47
49
  }
@@ -34,8 +34,10 @@ export function createSelectFormStatus() {
34
34
  ],
35
35
  isEqual
36
36
  ),
37
+ selectValidationError,
37
38
  ],
38
- (parsedPristine, pristine) => parsedPristine && pristine
39
+ (parsedPristine, pristine, validationError) =>
40
+ validationError ? pristine : parsedPristine
39
41
  )
40
42
 
41
43
  return createStructuredSelector({
@@ -20,8 +20,8 @@ export function arrayMoveReducer<T extends z.ZodTypeAny>(
20
20
  export function move<T>(array: T[], from: number, to: number): T[] {
21
21
  if (from < 0 || from >= array.length) throw new Error(`from out of range`)
22
22
  if (to < 0 || to >= array.length) throw new Error(`to out of range`)
23
- return from < to
24
- ? [
23
+ return from < to ?
24
+ [
25
25
  ...array.slice(0, from),
26
26
  ...array.slice(from + 1, to),
27
27
  array[from],
@@ -14,9 +14,9 @@ export const createInitializeReducer = <T extends z.ZodTypeAny>({
14
14
  try {
15
15
  const values =
16
16
  action.values ??
17
- (action.parsedValues
18
- ? inverseSchema.parse(action.parsedValues)
19
- : undefined)
17
+ (action.parsedValues ?
18
+ inverseSchema.parse(action.parsedValues)
19
+ : undefined)
20
20
  const parsedValues =
21
21
  action.parsedValues ??
22
22
  (action.values ? schema.parse(action.values) : undefined)
@@ -20,7 +20,10 @@ export function setMetaReducer<T extends z.ZodTypeAny>(
20
20
  ...state,
21
21
  fieldMeta: {
22
22
  ...state.fieldMeta,
23
- [field.pathstring]: { ...oldMeta, ...meta },
23
+ [field.pathstring]: {
24
+ ...(oldMeta || { touched: false, visited: false }),
25
+ ...meta,
26
+ },
24
27
  },
25
28
  }
26
29
  }
@@ -31,12 +31,13 @@ export const createSetParsedValueReducer = <T extends z.ZodTypeAny>({
31
31
  values: newValues,
32
32
  parsedValues: newParsedValues,
33
33
  }
34
- } catch (error) {
34
+ } catch {
35
35
  const newParsed = invert(action.field.schema).safeParse(
36
36
  action.parsedValue
37
37
  )
38
- const values = newParsed.success
39
- ? (set(
38
+ const values =
39
+ newParsed.success ?
40
+ (set(
40
41
  state.values,
41
42
  action.field.path,
42
43
  newParsed.data
@@ -46,14 +47,14 @@ export const createSetParsedValueReducer = <T extends z.ZodTypeAny>({
46
47
  const result = {
47
48
  ...state,
48
49
  submitError: undefined,
49
- validationError: !newParsed.success
50
- ? newParsed.error
51
- : newValidatedParsed.success
52
- ? undefined
50
+ validationError:
51
+ !newParsed.success ? newParsed.error
52
+ : newValidatedParsed.success ? undefined
53
53
  : newValidatedParsed.error,
54
54
  values,
55
- parsedValues: newValidatedParsed.success
56
- ? newValidatedParsed.data
55
+ parsedValues:
56
+ newValidatedParsed.success ?
57
+ newValidatedParsed.data
57
58
  : state.parsedValues,
58
59
  }
59
60
  return result
@@ -8,7 +8,7 @@ import { setValue } from '../../actions/setValue'
8
8
 
9
9
  export function updateRawArray<
10
10
  T extends z.ZodTypeAny,
11
- Field extends FieldPathForValue<any[]>
11
+ Field extends FieldPathForValue<any[]>,
12
12
  >(
13
13
  reducer: Reducer<FormState<T>, FormAction<T>>,
14
14
  state: FormState<T>,
@@ -19,7 +19,7 @@ export function updateRawArray<
19
19
  ) {
20
20
  const oldValue = get(state.values, field.path)
21
21
  const newValue = updater(oldValue as any)
22
- return newValue === oldValue
23
- ? state
24
- : reducer(state, setValue(field, newValue))
22
+ return newValue === oldValue ? state : (
23
+ reducer(state, setValue(field, newValue))
24
+ )
25
25
  }
@@ -20,36 +20,37 @@ import { setValue } from './actions/setValue'
20
20
  import { setMeta } from './actions/setMeta'
21
21
  import { FieldMeta } from './FormState'
22
22
  import { DeepPartial } from './util/DeepPartial'
23
+ import { maybeParse } from './util/maybeParse'
23
24
 
24
- export type UseArrayFieldProps<Field extends ArrayFieldPath = ArrayFieldPath> =
25
- NonNullable<z.input<Field['schema']>> extends any[]
26
- ? FieldMeta &
27
- ReturnType<
28
- typeof bindActionsToField<
29
- Field,
30
- arrayActions<Field> & {
31
- setParsedValue: typeof setParsedValue<Field>
32
- setValue: typeof setValue<Field>
33
- setMeta: typeof setMeta<Field>
34
- }
35
- >
36
- > & {
37
- elements: FieldPath<SchemaAt<Field['schema'], [number]>>[]
38
- error?: string
39
- dirty: boolean
40
- pristine: boolean
41
- valid: boolean
42
- invalid: boolean
43
- }
44
- : { ERROR: 'not an array field' }
25
+ export type UseArrayFieldProps<Field extends FieldPath> =
26
+ NonNullable<z.input<Field['schema']>> extends any[] ?
27
+ FieldMeta &
28
+ ReturnType<
29
+ typeof bindActionsToField<
30
+ Field,
31
+ arrayActions<Field> & {
32
+ setParsedValue: typeof setParsedValue<Field>
33
+ setValue: typeof setValue<Field>
34
+ setMeta: typeof setMeta<Field>
35
+ }
36
+ >
37
+ > & {
38
+ elements: FieldPath<SchemaAt<Field['schema'], [number]>>[]
39
+ error?: string
40
+ dirty: boolean
41
+ pristine: boolean
42
+ valid: boolean
43
+ invalid: boolean
44
+ }
45
+ : { ERROR: 'not an array field' }
45
46
 
46
47
  export interface TypedUseArrayField<T extends z.ZodTypeAny> {
47
48
  <Field extends FieldPathForValue<any[] | null | undefined>>(
48
49
  field: Field
49
50
  ): UseArrayFieldProps<Field>
50
- <Path extends PathInSchema<T>>(path: Path): UseArrayFieldProps<
51
- FieldPath<SchemaAt<T, Path>>
52
- >
51
+ <Path extends PathInSchema<T>>(
52
+ path: Path
53
+ ): UseArrayFieldProps<FieldPath<SchemaAt<T, Path>>>
53
54
  <Pathstring extends PathstringInSchema<T>>(
54
55
  path: Pathstring
55
56
  ): UseArrayFieldProps<FieldPath<SchemaAt<T, parsePathstring<Pathstring>>>>
@@ -78,16 +79,25 @@ function useArrayFieldBase<Field extends ArrayFieldPath>(
78
79
  createSelector(
79
80
  [
80
81
  createStructuredSelector({
82
+ parsedValue: ({ parsedValues }) =>
83
+ get(parsedValues, field.path) as z.output<T> | undefined,
81
84
  value: ({ values }) =>
82
85
  get(values, field.path) as DeepPartial<z.input<T>> | undefined,
86
+ initialParsedValue: ({ initialParsedValues }) =>
87
+ get(initialParsedValues, field.path) as z.output<T> | undefined,
83
88
  initialValue: ({ initialValues }) =>
84
89
  get(initialValues, field.path) as
85
90
  | DeepPartial<z.input<T>>
86
91
  | undefined,
87
92
  }),
88
93
  ],
89
- ({ value, initialValue }) => {
90
- const dirty = !isEqual(value, initialValue)
94
+ ({
95
+ value,
96
+ parsedValue = maybeParse(field.schema, value),
97
+ initialValue,
98
+ initialParsedValue = maybeParse(field.schema, initialValue),
99
+ }) => {
100
+ const dirty = !isEqual(parsedValue, initialParsedValue)
91
101
  const pristine = !dirty
92
102
  return {
93
103
  dirty,
@@ -135,6 +145,7 @@ function useArrayFieldBase<Field extends ArrayFieldPath>(
135
145
  ...boundActions,
136
146
  visited: meta?.visited || false,
137
147
  touched: meta?.touched || submitFailed,
148
+ customMeta: meta?.customMeta,
138
149
  error,
139
150
  elements,
140
151
  dirty,
@@ -154,14 +165,14 @@ export function useArrayField<
154
165
  z.ZodNever,
155
166
  'cast to TypedUseArrayField<T> to pass a path array'
156
167
  >,
157
- Path extends PathInSchema<T> = any
168
+ Path extends PathInSchema<T> = any,
158
169
  >(field: Path): UseArrayFieldProps<FieldPath<SchemaAt<T, Path>>>
159
170
  export function useArrayField<
160
171
  T extends z.ZodTypeAny = z.ZodBranded<
161
172
  z.ZodNever,
162
173
  'cast to TypedUseArrayField<T> to pass a pathstring'
163
174
  >,
164
- Pathstring extends PathstringInSchema<T> = any
175
+ Pathstring extends PathstringInSchema<T> = any,
165
176
  >(
166
177
  field: Pathstring
167
178
  ): UseArrayFieldProps<FieldPath<SchemaAt<T, parsePathstring<Pathstring>>>>