@tanstack/form-core 0.3.1 → 0.3.3

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 (52) hide show
  1. package/build/legacy/FieldApi.cjs +285 -0
  2. package/build/legacy/FieldApi.cjs.map +1 -0
  3. package/build/legacy/FieldApi.d.cts +3 -0
  4. package/build/legacy/FieldApi.d.ts +3 -0
  5. package/build/legacy/FieldApi.js +252 -0
  6. package/build/legacy/FieldApi.js.map +1 -0
  7. package/build/legacy/FormApi.cjs +257 -0
  8. package/build/legacy/FormApi.cjs.map +1 -0
  9. package/build/legacy/FormApi.d.cts +3 -0
  10. package/build/legacy/FormApi.d.ts +3 -0
  11. package/build/legacy/FormApi.js +234 -0
  12. package/build/legacy/FormApi.js.map +1 -0
  13. package/build/legacy/chunk-4QZDOMDG.js +19 -0
  14. package/build/legacy/chunk-4QZDOMDG.js.map +1 -0
  15. package/build/legacy/index.cjs +29 -0
  16. package/build/legacy/index.cjs.map +1 -0
  17. package/build/legacy/index.d.cts +172 -0
  18. package/build/legacy/index.d.ts +172 -0
  19. package/build/legacy/index.js +5 -0
  20. package/build/legacy/index.js.map +1 -0
  21. package/build/legacy/utils.cjs +103 -0
  22. package/build/legacy/utils.cjs.map +1 -0
  23. package/build/legacy/utils.d.cts +33 -0
  24. package/build/legacy/utils.d.ts +33 -0
  25. package/build/legacy/utils.js +77 -0
  26. package/build/legacy/utils.js.map +1 -0
  27. package/build/modern/FieldApi.cjs +267 -0
  28. package/build/modern/FieldApi.cjs.map +1 -0
  29. package/build/modern/FieldApi.d.cts +3 -0
  30. package/build/modern/FieldApi.d.ts +3 -0
  31. package/build/modern/FieldApi.js +242 -0
  32. package/build/modern/FieldApi.js.map +1 -0
  33. package/build/modern/FormApi.cjs +251 -0
  34. package/build/modern/FormApi.cjs.map +1 -0
  35. package/build/modern/FormApi.d.cts +3 -0
  36. package/build/modern/FormApi.d.ts +3 -0
  37. package/build/modern/FormApi.js +226 -0
  38. package/build/modern/FormApi.js.map +1 -0
  39. package/build/modern/index.cjs +29 -0
  40. package/build/modern/index.cjs.map +1 -0
  41. package/build/modern/index.d.cts +172 -0
  42. package/build/modern/index.d.ts +172 -0
  43. package/build/modern/index.js +5 -0
  44. package/build/modern/index.js.map +1 -0
  45. package/build/modern/utils.cjs +103 -0
  46. package/build/modern/utils.cjs.map +1 -0
  47. package/build/modern/utils.d.cts +33 -0
  48. package/build/modern/utils.d.ts +33 -0
  49. package/build/modern/utils.js +75 -0
  50. package/build/modern/utils.js.map +1 -0
  51. package/package.json +1 -1
  52. package/src/FieldApi.ts +62 -48
package/src/FieldApi.ts CHANGED
@@ -43,10 +43,19 @@ export interface FieldOptions<
43
43
  defaultMeta?: Partial<FieldMeta>
44
44
  }
45
45
 
46
- export type FieldApiOptions<TData, TFormData> = FieldOptions<
47
- TData,
48
- TFormData
49
- > & {
46
+ export interface FieldApiOptions<
47
+ _TData,
48
+ TFormData,
49
+ /**
50
+ * This allows us to restrict the name to only be a valid field name while
51
+ * also assigning it to a generic
52
+ */
53
+ TName = unknown extends TFormData ? string : DeepKeys<TFormData>,
54
+ /**
55
+ * If TData is unknown, we can use the TName generic to determine the type
56
+ */
57
+ TData = unknown extends _TData ? DeepValue<TFormData, TName> : _TData,
58
+ > extends FieldOptions<_TData, TFormData, TName, TData> {
50
59
  form: FormApi<TFormData>
51
60
  }
52
61
 
@@ -65,35 +74,45 @@ export type FieldState<TData> = {
65
74
  meta: FieldMeta
66
75
  }
67
76
 
68
- /**
69
- * TData may not be known at the time of FieldApi construction, so we need to
70
- * use a conditional type to determine if TData is known or not.
71
- *
72
- * If TData is not known, we use the TFormData type to determine the type of
73
- * the field value based on the field name.
74
- */
75
- type GetTData<Name, TData, TFormData> = unknown extends TData
76
- ? DeepValue<TFormData, Name>
77
- : TData
78
-
79
- export class FieldApi<TData, TFormData> {
77
+ type GetTData<
78
+ TData,
79
+ TFormData,
80
+ Opts extends FieldApiOptions<TData, TFormData>,
81
+ > = Opts extends FieldApiOptions<
82
+ infer _TData,
83
+ infer _TFormData,
84
+ infer _TName,
85
+ infer RealTData
86
+ >
87
+ ? RealTData
88
+ : never
89
+
90
+ export class FieldApi<
91
+ _TData,
92
+ TFormData,
93
+ Opts extends FieldApiOptions<_TData, TFormData> = FieldApiOptions<
94
+ _TData,
95
+ TFormData
96
+ >,
97
+ TData extends GetTData<_TData, TFormData, Opts> = GetTData<
98
+ _TData,
99
+ TFormData,
100
+ Opts
101
+ >,
102
+ > {
80
103
  uid: number
81
- form: FormApi<TFormData>
104
+ form: Opts['form']
82
105
  name!: DeepKeys<TFormData>
83
- /**
84
- * This is a hack that allows us to use `GetTData` without calling it everywhere
85
- *
86
- * Unfortunately this hack appears to be needed alongside the `TName` hack
87
- * further up in this file. This properly types all of the internal methods,
88
- * while the `TName` hack types the options properly
89
- */
90
- _tdata!: GetTData<typeof this.name, TData, TFormData>
91
- store!: Store<FieldState<typeof this._tdata>>
92
- state!: FieldState<typeof this._tdata>
93
- prevState!: FieldState<typeof this._tdata>
94
- options: FieldOptions<typeof this._tdata, TFormData> = {} as any
95
-
96
- constructor(opts: FieldApiOptions<TData, TFormData>) {
106
+ options: Opts = {} as any
107
+ store!: Store<FieldState<TData>>
108
+ state!: FieldState<TData>
109
+ prevState!: FieldState<TData>
110
+
111
+ constructor(
112
+ opts: Opts & {
113
+ form: FormApi<TFormData>
114
+ },
115
+ ) {
97
116
  this.form = opts.form
98
117
  this.uid = uid++
99
118
  // Support field prefixing from FieldScope
@@ -104,7 +123,7 @@ export class FieldApi<TData, TFormData> {
104
123
 
105
124
  this.name = opts.name as any
106
125
 
107
- this.store = new Store<FieldState<typeof this._tdata>>(
126
+ this.store = new Store<FieldState<TData>>(
108
127
  {
109
128
  value: this.getValue(),
110
129
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
@@ -138,7 +157,7 @@ export class FieldApi<TData, TFormData> {
138
157
 
139
158
  mount = () => {
140
159
  const info = this.getInfo()
141
- info.instances[this.uid] = this
160
+ info.instances[this.uid] = this as never
142
161
 
143
162
  const unsubscribe = this.form.store.subscribe(() => {
144
163
  this.store.batch(() => {
@@ -167,7 +186,7 @@ export class FieldApi<TData, TFormData> {
167
186
  }
168
187
  }
169
188
 
170
- update = (opts: FieldApiOptions<typeof this._tdata, TFormData>) => {
189
+ update = (opts: FieldApiOptions<TData, TFormData>) => {
171
190
  // Default Value
172
191
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
173
192
  if (this.state.value === undefined) {
@@ -189,12 +208,12 @@ export class FieldApi<TData, TFormData> {
189
208
  this.options = opts as never
190
209
  }
191
210
 
192
- getValue = (): typeof this._tdata => {
211
+ getValue = (): TData => {
193
212
  return this.form.getFieldValue(this.name)
194
213
  }
195
214
 
196
215
  setValue = (
197
- updater: Updater<typeof this._tdata>,
216
+ updater: Updater<TData>,
198
217
  options?: { touch?: boolean; notify?: boolean },
199
218
  ) => {
200
219
  this.form.setFieldValue(this.name, updater as never, options)
@@ -218,17 +237,12 @@ export class FieldApi<TData, TFormData> {
218
237
 
219
238
  getInfo = () => this.form.getFieldInfo(this.name)
220
239
 
221
- pushValue = (
222
- value: typeof this._tdata extends any[]
223
- ? (typeof this._tdata)[number]
224
- : never,
225
- ) => this.form.pushFieldValue(this.name, value as any)
240
+ pushValue = (value: TData extends any[] ? TData[number] : never) =>
241
+ this.form.pushFieldValue(this.name, value as any)
226
242
 
227
243
  insertValue = (
228
244
  index: number,
229
- value: typeof this._tdata extends any[]
230
- ? (typeof this._tdata)[number]
231
- : never,
245
+ value: TData extends any[] ? TData[number] : never,
232
246
  ) => this.form.insertFieldValue(this.name, index, value as any)
233
247
 
234
248
  removeValue = (index: number) => this.form.removeFieldValue(this.name, index)
@@ -236,8 +250,8 @@ export class FieldApi<TData, TFormData> {
236
250
  swapValues = (aIndex: number, bIndex: number) =>
237
251
  this.form.swapFieldValues(this.name, aIndex, bIndex)
238
252
 
239
- getSubField = <TName extends DeepKeys<typeof this._tdata>>(name: TName) =>
240
- new FieldApi<DeepValue<typeof this._tdata, TName>, TFormData>({
253
+ getSubField = <TName extends DeepKeys<TData>>(name: TName) =>
254
+ new FieldApi<DeepValue<TData, TName>, TFormData>({
241
255
  name: `${this.name}.${name}` as never,
242
256
  form: this.form,
243
257
  })
@@ -371,7 +385,7 @@ export class FieldApi<TData, TFormData> {
371
385
 
372
386
  validate = (
373
387
  cause: ValidationCause,
374
- value?: typeof this._tdata,
388
+ value?: TData,
375
389
  ): ValidationError[] | Promise<ValidationError[]> => {
376
390
  // If the field is pristine and validatePristine is false, do not validate
377
391
  if (!this.state.meta.isTouched) return []
@@ -389,7 +403,7 @@ export class FieldApi<TData, TFormData> {
389
403
  return this.validateAsync(value, cause)
390
404
  }
391
405
 
392
- handleChange = (updater: Updater<typeof this._tdata>) => {
406
+ handleChange = (updater: Updater<TData>) => {
393
407
  this.setValue(updater, { touch: true })
394
408
  }
395
409