@tanstack/form-core 1.14.0 → 1.15.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/src/types.ts CHANGED
@@ -1,4 +1,6 @@
1
- import type { DeepKeys } from './util-types'
1
+ import type { AnyFieldMeta, AnyFieldMetaBase } from './FieldApi'
2
+ import type { DeepKeys, DeepKeysOfType, DeepValue } from './util-types'
3
+ import type { Updater } from './utils'
2
4
 
3
5
  export type ValidationError = unknown
4
6
 
@@ -117,3 +119,152 @@ export interface UpdateMetaOptions {
117
119
  */
118
120
  dontUpdateMeta?: boolean
119
121
  }
122
+
123
+ /**
124
+ * @private
125
+ * A list of field manipulation methods that a form-like API must implement.
126
+ */
127
+ export interface FieldManipulator<TFormData, TSubmitMeta> {
128
+ /**
129
+ * Validates all fields using the correct handlers for a given validation cause.
130
+ */
131
+ validateAllFields: (cause: ValidationCause) => Promise<unknown[]>
132
+
133
+ /**
134
+ * Validates the children of a specified array in the form starting from a given index until the end using the correct handlers for a given validation type.
135
+ */
136
+ validateArrayFieldsStartingFrom: <
137
+ TField extends DeepKeysOfType<TFormData, any[]>,
138
+ >(
139
+ field: TField,
140
+ index: number,
141
+ cause: ValidationCause,
142
+ ) => Promise<unknown[]>
143
+
144
+ /**
145
+ * Validates a specified field in the form using the correct handlers for a given validation type.
146
+ */
147
+ validateField: <TField extends DeepKeys<TFormData>>(
148
+ field: TField,
149
+ cause: ValidationCause,
150
+ ) => unknown[] | Promise<unknown[]>
151
+
152
+ /**
153
+ * Handles the form submission, performs validation, and calls the appropriate onSubmit or onSubmitInvalid callbacks.
154
+ */
155
+ handleSubmit(): Promise<void>
156
+ handleSubmit(submitMeta: TSubmitMeta): Promise<void>
157
+
158
+ /**
159
+ * Gets the value of the specified field.
160
+ */
161
+ getFieldValue: <TField extends DeepKeys<TFormData>>(
162
+ field: TField,
163
+ ) => DeepValue<TFormData, TField>
164
+
165
+ /**
166
+ * Gets the metadata of the specified field.
167
+ */
168
+ getFieldMeta: <TField extends DeepKeys<TFormData>>(
169
+ field: TField,
170
+ ) => AnyFieldMeta | undefined
171
+
172
+ /**
173
+ * Updates the metadata of the specified field.
174
+ */
175
+ setFieldMeta: <TField extends DeepKeys<TFormData>>(
176
+ field: TField,
177
+ updater: Updater<AnyFieldMetaBase>,
178
+ ) => void
179
+
180
+ /**
181
+ * Sets the value of the specified field and optionally updates the touched state.
182
+ */
183
+ setFieldValue: <TField extends DeepKeys<TFormData>>(
184
+ field: TField,
185
+ updater: Updater<DeepValue<TFormData, TField>>,
186
+ opts?: UpdateMetaOptions,
187
+ ) => void
188
+
189
+ /**
190
+ * Delete the specified field. Also deletes all subfields if there are any.
191
+ */
192
+ deleteField: <TField extends DeepKeys<TFormData>>(field: TField) => void
193
+
194
+ /**
195
+ * Pushes a value into an array field.
196
+ */
197
+ pushFieldValue: <TField extends DeepKeysOfType<TFormData, any[]>>(
198
+ field: TField,
199
+ value: DeepValue<TFormData, TField> extends any[]
200
+ ? DeepValue<TFormData, TField>[number]
201
+ : never,
202
+ opts?: UpdateMetaOptions,
203
+ ) => void
204
+
205
+ /**
206
+ * Insert a value into an array field at the specified index.
207
+ */
208
+ insertFieldValue: <TField extends DeepKeysOfType<TFormData, any[]>>(
209
+ field: TField,
210
+ index: number,
211
+ value: DeepValue<TFormData, TField> extends any[]
212
+ ? DeepValue<TFormData, TField>[number]
213
+ : never,
214
+ opts?: UpdateMetaOptions,
215
+ ) => Promise<void>
216
+
217
+ /**
218
+ * Replaces a value into an array field at the specified index.
219
+ */
220
+ replaceFieldValue: <TField extends DeepKeysOfType<TFormData, any[]>>(
221
+ field: TField,
222
+ index: number,
223
+ value: DeepValue<TFormData, TField> extends any[]
224
+ ? DeepValue<TFormData, TField>[number]
225
+ : never,
226
+ opts?: UpdateMetaOptions,
227
+ ) => Promise<void>
228
+
229
+ /**
230
+ * Removes a value from an array field at the specified index.
231
+ */
232
+ removeFieldValue: <TField extends DeepKeysOfType<TFormData, any[]>>(
233
+ field: TField,
234
+ index: number,
235
+ opts?: UpdateMetaOptions,
236
+ ) => Promise<void>
237
+
238
+ /**
239
+ * Swaps the values at the specified indices within an array field.
240
+ */
241
+ swapFieldValues: <TField extends DeepKeysOfType<TFormData, any[]>>(
242
+ field: TField,
243
+ index1: number,
244
+ index2: number,
245
+ opts?: UpdateMetaOptions,
246
+ ) => void
247
+
248
+ /**
249
+ * Moves the value at the first specified index to the second specified index within an array field.
250
+ */
251
+ moveFieldValues: <TField extends DeepKeysOfType<TFormData, any[]>>(
252
+ field: TField,
253
+ index1: number,
254
+ index2: number,
255
+ opts?: UpdateMetaOptions,
256
+ ) => void
257
+
258
+ /**
259
+ * Clear all values within an array field.
260
+ */
261
+ clearFieldValues: <TField extends DeepKeysOfType<TFormData, any[]>>(
262
+ field: TField,
263
+ opts?: UpdateMetaOptions,
264
+ ) => void
265
+
266
+ /**
267
+ * Resets the field value and meta to default state
268
+ */
269
+ resetField: <TField extends DeepKeys<TFormData>>(field: TField) => void
270
+ }
package/src/util-types.ts CHANGED
@@ -177,3 +177,19 @@ export type DeepKeysOfType<TData, TValue> = Extract<
177
177
  DeepKeysAndValues<TData>,
178
178
  AnyDeepKeyAndValue<string, TValue>
179
179
  >['key']
180
+
181
+ /**
182
+ * Maps the deep keys of TFormData to the shallow keys of TFieldGroupData.
183
+ * Since using template strings as keys is impractical, it relies on shallow keys only.
184
+ */
185
+ export type FieldsMap<TFormData, TFieldGroupData> =
186
+ TFieldGroupData extends any[]
187
+ ? never
188
+ : string extends keyof TFieldGroupData
189
+ ? never
190
+ : {
191
+ [K in keyof TFieldGroupData]: DeepKeysOfType<
192
+ TFormData,
193
+ TFieldGroupData[K]
194
+ >
195
+ }
package/src/utils.ts CHANGED
@@ -171,14 +171,34 @@ export function makePathArray(str: string | Array<string | number>) {
171
171
  .replace(reMultipleDots, '.')
172
172
  .split('.')
173
173
  .map((d) => {
174
- if (d.indexOf(intPrefix) === 0) {
175
- return parseInt(d.substring(intPrefix.length), 10)
174
+ if (d.startsWith(intPrefix)) {
175
+ const numStr = d.substring(intPrefix.length)
176
+ const num = parseInt(numStr, 10)
177
+
178
+ if (String(num) === numStr) {
179
+ return num
180
+ }
181
+ return numStr
176
182
  }
177
183
  return d
178
184
  })
179
185
  )
180
186
  }
181
187
 
188
+ /**
189
+ * @private
190
+ */
191
+ export function concatenatePaths(path1: string, path2: string): string {
192
+ if (path1.length === 0) return path2
193
+ if (path2.length === 0) return path1
194
+
195
+ if (path2.startsWith('[')) {
196
+ return path1 + path2
197
+ }
198
+
199
+ return `${path1}.${path2}`
200
+ }
201
+
182
202
  /**
183
203
  * @private
184
204
  */
@@ -454,3 +474,13 @@ export const determineFieldLevelErrorSourceAndValue = ({
454
474
 
455
475
  return { newErrorValue: undefined, newSource: undefined }
456
476
  }
477
+
478
+ export function createFieldMap<T>(values: Readonly<T>): { [K in keyof T]: K } {
479
+ const output: { [K in keyof T]: K } = {} as any
480
+
481
+ for (const key in values) {
482
+ output[key] = key
483
+ }
484
+
485
+ return output
486
+ }