@tanstack/form-core 0.0.9 → 0.0.12

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 (79) hide show
  1. package/build/lib/FieldApi.cjs +307 -0
  2. package/build/lib/FieldApi.cjs.map +1 -0
  3. package/build/lib/FieldApi.d.ts +112 -0
  4. package/build/lib/FieldApi.d.ts.map +1 -0
  5. package/build/lib/FieldApi.js +305 -0
  6. package/build/lib/FieldApi.js.map +1 -0
  7. package/build/lib/FieldApi.legacy.cjs +307 -0
  8. package/build/lib/FieldApi.legacy.cjs.map +1 -0
  9. package/build/lib/FieldApi.legacy.js +305 -0
  10. package/build/lib/FieldApi.legacy.js.map +1 -0
  11. package/build/lib/FormApi.cjs +248 -0
  12. package/build/lib/FormApi.cjs.map +1 -0
  13. package/build/{types → lib}/FormApi.d.ts +16 -11
  14. package/build/lib/FormApi.d.ts.map +1 -0
  15. package/build/lib/FormApi.js +246 -0
  16. package/build/lib/FormApi.js.map +1 -0
  17. package/build/lib/FormApi.legacy.cjs +248 -0
  18. package/build/lib/FormApi.legacy.cjs.map +1 -0
  19. package/build/lib/FormApi.legacy.js +246 -0
  20. package/build/lib/FormApi.legacy.js.map +1 -0
  21. package/build/lib/_virtual/_rollupPluginBabelHelpers.cjs +65 -0
  22. package/build/lib/_virtual/_rollupPluginBabelHelpers.cjs.map +1 -0
  23. package/build/lib/_virtual/_rollupPluginBabelHelpers.js +56 -0
  24. package/build/{cjs → lib}/_virtual/_rollupPluginBabelHelpers.js.map +1 -1
  25. package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.cjs +65 -0
  26. package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.cjs.map +1 -0
  27. package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.js +56 -0
  28. package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.js.map +1 -0
  29. package/build/lib/index.cjs +14 -0
  30. package/build/lib/index.cjs.map +1 -0
  31. package/build/{types → lib}/index.d.ts +1 -0
  32. package/build/lib/index.d.ts.map +1 -0
  33. package/build/lib/index.js +4 -0
  34. package/build/{cjs → lib}/index.js.map +1 -1
  35. package/build/lib/index.legacy.cjs +14 -0
  36. package/build/lib/index.legacy.cjs.map +1 -0
  37. package/build/lib/index.legacy.js +4 -0
  38. package/build/lib/index.legacy.js.map +1 -0
  39. package/build/lib/tests/FieldApi.spec.d.ts +2 -0
  40. package/build/lib/tests/FieldApi.spec.d.ts.map +1 -0
  41. package/build/lib/tests/FieldApi.test-d.d.ts +2 -0
  42. package/build/lib/tests/FieldApi.test-d.d.ts.map +1 -0
  43. package/build/lib/tests/FormApi.spec.d.ts +2 -0
  44. package/build/lib/tests/FormApi.spec.d.ts.map +1 -0
  45. package/build/{cjs/utils.js → lib/utils.cjs} +18 -27
  46. package/build/lib/utils.cjs.map +1 -0
  47. package/build/{types → lib}/utils.d.ts +10 -0
  48. package/build/lib/utils.d.ts.map +1 -0
  49. package/build/lib/utils.js +77 -0
  50. package/build/lib/utils.js.map +1 -0
  51. package/build/lib/utils.legacy.cjs +81 -0
  52. package/build/lib/utils.legacy.cjs.map +1 -0
  53. package/build/lib/utils.legacy.js +77 -0
  54. package/build/lib/utils.legacy.js.map +1 -0
  55. package/package.json +23 -10
  56. package/src/FieldApi.ts +190 -138
  57. package/src/FormApi.ts +84 -118
  58. package/src/tests/FieldApi.spec.ts +143 -0
  59. package/src/tests/FieldApi.test-d.ts +41 -0
  60. package/src/tests/FormApi.spec.ts +216 -0
  61. package/src/utils.ts +10 -1
  62. package/build/cjs/FieldApi.js +0 -345
  63. package/build/cjs/FieldApi.js.map +0 -1
  64. package/build/cjs/FormApi.js +0 -317
  65. package/build/cjs/FormApi.js.map +0 -1
  66. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +0 -31
  67. package/build/cjs/index.js +0 -26
  68. package/build/cjs/utils.js.map +0 -1
  69. package/build/esm/index.js +0 -724
  70. package/build/esm/index.js.map +0 -1
  71. package/build/stats-html.html +0 -2689
  72. package/build/stats-react.json +0 -190
  73. package/build/types/FieldApi.d.ts +0 -79
  74. package/build/types/tests/test.test.d.ts +0 -0
  75. package/build/umd/index.development.js +0 -785
  76. package/build/umd/index.development.js.map +0 -1
  77. package/build/umd/index.production.js +0 -22
  78. package/build/umd/index.production.js.map +0 -1
  79. package/src/tests/test.test.tsx +0 -5
@@ -0,0 +1,216 @@
1
+ import { expect } from 'vitest'
2
+
3
+ import { FormApi } from '../FormApi'
4
+
5
+ describe('form api', () => {
6
+ it('should get default form state', () => {
7
+ const form = new FormApi()
8
+
9
+ expect(form.state).toEqual({
10
+ values: undefined,
11
+ fieldMeta: {},
12
+ canSubmit: true,
13
+ isFieldsValid: true,
14
+ isFieldsValidating: false,
15
+ isFormValid: true,
16
+ isFormValidating: false,
17
+ isSubmitted: false,
18
+ isSubmitting: false,
19
+ isTouched: false,
20
+ isValid: true,
21
+ isValidating: false,
22
+ submissionAttempts: 0,
23
+ formValidationCount: 0,
24
+ })
25
+ })
26
+
27
+ it('should get default form state when default values are passed', () => {
28
+ const form = new FormApi({
29
+ defaultValues: {
30
+ name: 'test',
31
+ },
32
+ })
33
+
34
+ expect(form.state).toEqual({
35
+ values: {
36
+ name: 'test',
37
+ },
38
+ fieldMeta: {},
39
+ canSubmit: true,
40
+ isFieldsValid: true,
41
+ isFieldsValidating: false,
42
+ isFormValid: true,
43
+ isFormValidating: false,
44
+ isSubmitted: false,
45
+ isSubmitting: false,
46
+ isTouched: false,
47
+ isValid: true,
48
+ isValidating: false,
49
+ submissionAttempts: 0,
50
+ formValidationCount: 0,
51
+ })
52
+ })
53
+
54
+ it('should get default form state when default state is passed', () => {
55
+ const form = new FormApi({
56
+ defaultState: {
57
+ submissionAttempts: 30,
58
+ },
59
+ })
60
+
61
+ expect(form.state).toEqual({
62
+ values: undefined,
63
+ fieldMeta: {},
64
+ canSubmit: true,
65
+ isFieldsValid: true,
66
+ isFieldsValidating: false,
67
+ isFormValid: true,
68
+ isFormValidating: false,
69
+ isSubmitted: false,
70
+ isSubmitting: false,
71
+ isTouched: false,
72
+ isValid: true,
73
+ isValidating: false,
74
+ submissionAttempts: 30,
75
+ formValidationCount: 0,
76
+ })
77
+ })
78
+
79
+ it('should handle updating form state', () => {
80
+ const form = new FormApi({
81
+ defaultValues: {
82
+ name: 'test',
83
+ },
84
+ })
85
+
86
+ form.update({
87
+ defaultValues: {
88
+ name: 'other',
89
+ },
90
+ defaultState: {
91
+ submissionAttempts: 300,
92
+ },
93
+ })
94
+
95
+ expect(form.state).toEqual({
96
+ values: {
97
+ name: 'other',
98
+ },
99
+ fieldMeta: {},
100
+ canSubmit: true,
101
+ isFieldsValid: true,
102
+ isFieldsValidating: false,
103
+ isFormValid: true,
104
+ isFormValidating: false,
105
+ isSubmitted: false,
106
+ isSubmitting: false,
107
+ isTouched: false,
108
+ isValid: true,
109
+ isValidating: false,
110
+ submissionAttempts: 300,
111
+ formValidationCount: 0,
112
+ })
113
+ })
114
+
115
+ it('should reset the form state properly', () => {
116
+ const form = new FormApi({
117
+ defaultValues: {
118
+ name: 'test',
119
+ },
120
+ })
121
+
122
+ form.pushFieldValue('name', 'other')
123
+ form.state.submissionAttempts = 300
124
+
125
+ form.reset()
126
+
127
+ expect(form.state).toEqual({
128
+ values: {
129
+ name: 'test',
130
+ },
131
+ fieldMeta: {},
132
+ canSubmit: true,
133
+ isFieldsValid: true,
134
+ isFieldsValidating: false,
135
+ isFormValid: true,
136
+ isFormValidating: false,
137
+ isSubmitted: false,
138
+ isSubmitting: false,
139
+ isTouched: false,
140
+ isValid: true,
141
+ isValidating: false,
142
+ submissionAttempts: 0,
143
+ formValidationCount: 0,
144
+ })
145
+ })
146
+
147
+ it("should get a field's value", () => {
148
+ const form = new FormApi({
149
+ defaultValues: {
150
+ name: 'test',
151
+ },
152
+ })
153
+
154
+ expect(form.getFieldValue('name')).toEqual('test')
155
+ })
156
+
157
+ it("should set a field's value", () => {
158
+ const form = new FormApi({
159
+ defaultValues: {
160
+ name: 'test',
161
+ },
162
+ })
163
+
164
+ form.setFieldValue('name', 'other')
165
+
166
+ expect(form.getFieldValue('name')).toEqual('other')
167
+ })
168
+
169
+ it("should push an array field's value", () => {
170
+ const form = new FormApi({
171
+ defaultValues: {
172
+ names: ['test'],
173
+ },
174
+ })
175
+
176
+ form.pushFieldValue('names', 'other')
177
+
178
+ expect(form.getFieldValue('names')).toStrictEqual(['test', 'other'])
179
+ })
180
+
181
+ it("should insert an array field's value", () => {
182
+ const form = new FormApi({
183
+ defaultValues: {
184
+ names: ['one', 'two', 'three'],
185
+ },
186
+ })
187
+
188
+ form.insertFieldValue('names', 1, 'other')
189
+
190
+ expect(form.getFieldValue('names')).toStrictEqual(['one', 'other', 'three'])
191
+ })
192
+
193
+ it("should remove an array field's value", () => {
194
+ const form = new FormApi({
195
+ defaultValues: {
196
+ names: ['one', 'two', 'three'],
197
+ },
198
+ })
199
+
200
+ form.removeFieldValue('names', 1)
201
+
202
+ expect(form.getFieldValue('names')).toStrictEqual(['one', 'three'])
203
+ })
204
+
205
+ it("should swap an array field's value", () => {
206
+ const form = new FormApi({
207
+ defaultValues: {
208
+ names: ['one', 'two', 'three'],
209
+ },
210
+ })
211
+
212
+ form.swapFieldValues('names', 1, 2)
213
+
214
+ expect(form.getFieldValue('names')).toStrictEqual(['one', 'three', 'two'])
215
+ })
216
+ })
package/src/utils.ts CHANGED
@@ -13,6 +13,9 @@ export function functionalUpdate<TInput, TOutput = TInput>(
13
13
  : updater
14
14
  }
15
15
 
16
+ /**
17
+ * Get a value from an object using a path, including dot notation.
18
+ */
16
19
  export function getBy(obj: any, path: any) {
17
20
  const pathArray = makePathArray(path)
18
21
  const pathObj = pathArray
@@ -24,6 +27,9 @@ export function getBy(obj: any, path: any) {
24
27
  }, obj)
25
28
  }
26
29
 
30
+ /**
31
+ * Set a value on an object using a path, including dot notation.
32
+ */
27
33
  export function setBy(obj: any, _path: any, updater: Updater<any>) {
28
34
  const path = makePathArray(_path)
29
35
 
@@ -75,7 +81,7 @@ const intReplace = `${intPrefix}$1`
75
81
 
76
82
  function makePathArray(str: string) {
77
83
  if (typeof str !== 'string') {
78
- throw new Error()
84
+ throw new Error('Path must be a string.')
79
85
  }
80
86
 
81
87
  return str
@@ -159,3 +165,6 @@ type NarrowRaw<A> =
159
165
  export type Narrow<A> = Try<A, [], NarrowRaw<A>>
160
166
 
161
167
  type Try<A1, A2, Catch = never> = A1 extends A2 ? A1 : Catch
168
+
169
+ // Hack to get TypeScript to show simplified types in error messages
170
+ export type Pretty<T> = { [K in keyof T]: T[K] } & {}
@@ -1,345 +0,0 @@
1
- /**
2
- * form-core
3
- *
4
- * Copyright (c) TanStack
5
- *
6
- * This source code is licensed under the MIT license found in the
7
- * LICENSE.md file in the root directory of this source tree.
8
- *
9
- * @license MIT
10
- */
11
- 'use strict';
12
-
13
- Object.defineProperty(exports, '__esModule', { value: true });
14
-
15
- var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
16
- var store = require('@tanstack/store');
17
-
18
- let uid = 0;
19
-
20
- var _updateStore = /*#__PURE__*/_rollupPluginBabelHelpers.classPrivateFieldLooseKey("updateStore");
21
-
22
- var _leaseValidateAsync = /*#__PURE__*/_rollupPluginBabelHelpers.classPrivateFieldLooseKey("leaseValidateAsync");
23
-
24
- class FieldApi {
25
- constructor(_opts) {
26
- var _this$getMeta;
27
-
28
- this.options = {};
29
-
30
- this.mount = () => {
31
- const info = this.getInfo();
32
- info.instances[this.uid] = this;
33
- const unsubscribe = this.form.store.subscribe(() => {
34
- _rollupPluginBabelHelpers.classPrivateFieldLooseBase(this, _updateStore)[_updateStore]();
35
- });
36
- return () => {
37
- unsubscribe();
38
- delete info.instances[this.uid];
39
-
40
- if (!Object.keys(info.instances).length) {
41
- delete this.form.fieldInfo[this.name];
42
- }
43
- };
44
- };
45
-
46
- Object.defineProperty(this, _updateStore, {
47
- writable: true,
48
- value: () => {
49
- this.store.batch(() => {
50
- const nextValue = this.getValue();
51
- const nextMeta = this.getMeta();
52
-
53
- if (nextValue !== this.state.value) {
54
- this.store.setState(prev => ({ ...prev,
55
- value: nextValue
56
- }));
57
- }
58
-
59
- if (nextMeta !== this.state.meta) {
60
- this.store.setState(prev => ({ ...prev,
61
- meta: nextMeta
62
- }));
63
- }
64
- });
65
- }
66
- });
67
-
68
- this.update = opts => {
69
- var _this$form$options$de, _this$form$options$de2, _this$form$options$de3, _this$form$options$de4;
70
-
71
- this.options = {
72
- validatePristine: (_this$form$options$de = this.form.options.defaultValidatePristine) != null ? _this$form$options$de : false,
73
- validateOn: (_this$form$options$de2 = this.form.options.defaultValidateOn) != null ? _this$form$options$de2 : 'change',
74
- validateAsyncOn: (_this$form$options$de3 = this.form.options.defaultValidateAsyncOn) != null ? _this$form$options$de3 : 'blur',
75
- validateAsyncDebounceMs: (_this$form$options$de4 = this.form.options.defaultValidateAsyncDebounceMs) != null ? _this$form$options$de4 : 0,
76
- ...opts
77
- }; // Default Value
78
-
79
- if (this.state.value === undefined && this.options.defaultValue !== undefined) {
80
- this.setValue(this.options.defaultValue);
81
- } // Default Meta
82
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
83
-
84
-
85
- if (this.getMeta() === undefined) {
86
- this.setMeta(this.state.meta);
87
- }
88
- };
89
-
90
- this.getValue = () => {
91
- return this.form.getFieldValue(this.name);
92
- };
93
-
94
- this.setValue = (updater, options) => this.form.setFieldValue(this.name, updater, options);
95
-
96
- this.getMeta = () => this.form.getFieldMeta(this.name);
97
-
98
- this.setMeta = updater => this.form.setFieldMeta(this.name, updater);
99
-
100
- this.getInfo = () => this.form.getFieldInfo(this.name);
101
-
102
- this.pushValue = value => this.form.pushFieldValue(this.name, value);
103
-
104
- this.insertValue = (index, value) => this.form.insertFieldValue(this.name, index, value);
105
-
106
- this.removeValue = index => this.form.removeFieldValue(this.name, index);
107
-
108
- this.swapValues = (aIndex, bIndex) => this.form.swapFieldValues(this.name, aIndex, bIndex);
109
-
110
- this.getSubField = name => new FieldApi({
111
- name: this.name + "." + name,
112
- form: this.form
113
- });
114
-
115
- this.validateSync = async (value = this.state.value) => {
116
- const {
117
- validate
118
- } = this.options;
119
-
120
- if (!validate) {
121
- return;
122
- } // Use the validationCount for all field instances to
123
- // track freshness of the validation
124
-
125
-
126
- const validationCount = (this.getInfo().validationCount || 0) + 1;
127
- this.getInfo().validationCount = validationCount;
128
- const error = normalizeError(validate(value, this));
129
-
130
- if (this.state.meta.error !== error) {
131
- this.setMeta(prev => ({ ...prev,
132
- error
133
- }));
134
- } // If a sync error is encountered, cancel any async validation
135
-
136
-
137
- if (this.state.meta.error) {
138
- this.cancelValidateAsync();
139
- }
140
- };
141
-
142
- Object.defineProperty(this, _leaseValidateAsync, {
143
- writable: true,
144
- value: () => {
145
- const count = (this.getInfo().validationAsyncCount || 0) + 1;
146
- this.getInfo().validationAsyncCount = count;
147
- return count;
148
- }
149
- });
150
-
151
- this.cancelValidateAsync = () => {
152
- // Lease a new validation count to ignore any pending validations
153
- _rollupPluginBabelHelpers.classPrivateFieldLooseBase(this, _leaseValidateAsync)[_leaseValidateAsync](); // Cancel any pending validation state
154
-
155
-
156
- this.setMeta(prev => ({ ...prev,
157
- isValidating: false
158
- }));
159
- };
160
-
161
- this.validateAsync = async (value = this.state.value) => {
162
- const {
163
- validateAsync,
164
- validateAsyncDebounceMs
165
- } = this.options;
166
-
167
- if (!validateAsync) {
168
- return;
169
- }
170
-
171
- if (this.state.meta.isValidating !== true) this.setMeta(prev => ({ ...prev,
172
- isValidating: true
173
- })); // Use the validationCount for all field instances to
174
- // track freshness of the validation
175
-
176
- const validationAsyncCount = _rollupPluginBabelHelpers.classPrivateFieldLooseBase(this, _leaseValidateAsync)[_leaseValidateAsync]();
177
-
178
- const checkLatest = () => validationAsyncCount === this.getInfo().validationAsyncCount;
179
-
180
- if (!this.getInfo().validationPromise) {
181
- this.getInfo().validationPromise = new Promise((resolve, reject) => {
182
- this.getInfo().validationResolve = resolve;
183
- this.getInfo().validationReject = reject;
184
- });
185
- }
186
-
187
- if (validateAsyncDebounceMs > 0) {
188
- await new Promise(r => setTimeout(r, validateAsyncDebounceMs));
189
- } // Only kick off validation if this validation is the latest attempt
190
-
191
-
192
- if (checkLatest()) {
193
- try {
194
- const rawError = await validateAsync(value, this);
195
-
196
- if (checkLatest()) {
197
- var _this$getInfo$validat, _this$getInfo;
198
-
199
- const error = normalizeError(rawError);
200
- this.setMeta(prev => ({ ...prev,
201
- isValidating: false,
202
- error
203
- }));
204
- (_this$getInfo$validat = (_this$getInfo = this.getInfo()).validationResolve) == null ? void 0 : _this$getInfo$validat.call(_this$getInfo, error);
205
- }
206
- } catch (error) {
207
- if (checkLatest()) {
208
- var _this$getInfo$validat2, _this$getInfo2;
209
-
210
- (_this$getInfo$validat2 = (_this$getInfo2 = this.getInfo()).validationReject) == null ? void 0 : _this$getInfo$validat2.call(_this$getInfo2, error);
211
- throw error;
212
- }
213
- } finally {
214
- if (checkLatest()) {
215
- this.setMeta(prev => ({ ...prev,
216
- isValidating: false
217
- }));
218
- delete this.getInfo().validationPromise;
219
- }
220
- }
221
- } // Always return the latest validation promise to the caller
222
-
223
-
224
- return this.getInfo().validationPromise;
225
- };
226
-
227
- this.shouldValidate = (isAsync, cause) => {
228
- const {
229
- validateOn,
230
- validateAsyncOn
231
- } = this.options;
232
- const level = getValidationCauseLevel(cause); // Must meet *at least* the validation level to validate,
233
- // e.g. if validateOn is 'change' and validateCause is 'blur',
234
- // the field will still validate
235
-
236
- return Object.keys(validateCauseLevels).some(d => isAsync ? validateAsyncOn : validateOn === d && level >= validateCauseLevels[d]);
237
- };
238
-
239
- this.validate = async (cause, value) => {
240
- // If the field is pristine and validatePristine is false, do not validate
241
- if (!this.options.validatePristine && !this.state.meta.isTouched) return; // Attempt to sync validate first
242
-
243
- if (this.shouldValidate(false, cause)) {
244
- this.validateSync(value);
245
- } // If there is an error, return it, do not attempt async validation
246
-
247
-
248
- if (this.state.meta.error) {
249
- return this.state.meta.error;
250
- } // No error? Attempt async validation
251
-
252
-
253
- if (this.shouldValidate(true, cause)) {
254
- return this.validateAsync(value);
255
- } // If there is no sync error or async validation attempt, there is no error
256
-
257
-
258
- return undefined;
259
- };
260
-
261
- this.getChangeProps = (props = {}) => {
262
- return { ...props,
263
- value: this.state.value,
264
- onChange: value => {
265
- this.setValue(value);
266
- props.onChange == null ? void 0 : props.onChange(value);
267
- },
268
- onBlur: e => {
269
- this.setMeta(prev => ({ ...prev,
270
- isTouched: true
271
- }));
272
- this.validate('blur');
273
- props.onBlur == null ? void 0 : props.onBlur(e);
274
- }
275
- };
276
- };
277
-
278
- this.getInputProps = (props = {}) => {
279
- return { ...props,
280
- value: String(this.state.value),
281
- onChange: e => {
282
- this.setValue(e.target.value);
283
- props.onChange == null ? void 0 : props.onChange(e.target.value);
284
- },
285
- onBlur: this.getChangeProps(props).onBlur
286
- };
287
- };
288
-
289
- this.form = _opts.form;
290
- this.uid = uid++; // Support field prefixing from FieldScope
291
- // let fieldPrefix = ''
292
- // if (this.form.fieldName) {
293
- // fieldPrefix = `${this.form.fieldName}.`
294
- // }
295
-
296
- this.name = _opts.name;
297
- this.store = new store.Store({
298
- value: this.getValue(),
299
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
300
- meta: (_this$getMeta = this.getMeta()) != null ? _this$getMeta : {
301
- isValidating: false,
302
- isTouched: false,
303
- ...this.options.defaultMeta
304
- }
305
- }, {
306
- onUpdate: next => {
307
- next.meta.touchedError = next.meta.isTouched ? next.meta.error : undefined; // Do not validate pristine fields
308
-
309
- const prevState = this.state;
310
- this.state = next;
311
-
312
- if (next.value !== prevState.value) {
313
- this.validate('change', next.value);
314
- }
315
- }
316
- });
317
- this.state = this.store.state;
318
- this.update(_opts);
319
- }
320
-
321
- }
322
- const validateCauseLevels = {
323
- change: 0,
324
- blur: 1,
325
- submit: 2
326
- };
327
-
328
- function getValidationCauseLevel(cause) {
329
- return !cause ? 3 : validateCauseLevels[cause];
330
- }
331
-
332
- function normalizeError(rawError) {
333
- if (rawError) {
334
- if (typeof rawError !== 'string') {
335
- return 'Invalid Form Values';
336
- }
337
-
338
- return rawError;
339
- }
340
-
341
- return undefined;
342
- }
343
-
344
- exports.FieldApi = FieldApi;
345
- //# sourceMappingURL=FieldApi.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FieldApi.js","sources":["../../src/FieldApi.ts"],"sourcesContent":["//\nimport type { DeepKeys, DeepValue, RequiredByKey, Updater } from './utils'\nimport type { FormApi, ValidationError } from './FormApi'\nimport { Store } from '@tanstack/store'\n\nexport type ValidationCause = 'change' | 'blur' | 'submit'\n\nexport interface FieldOptions<TData, TFormData> {\n name: unknown extends TFormData ? string : DeepKeys<TFormData>\n index?: TData extends any[] ? number : never\n defaultValue?: TData\n validate?: (\n value: TData,\n fieldApi: FieldApi<TData, TFormData>,\n ) => ValidationError\n validateAsync?: (\n value: TData,\n fieldApi: FieldApi<TData, TFormData>,\n ) => ValidationError | Promise<ValidationError>\n validatePristine?: boolean // Default: false\n validateOn?: ValidationCause // Default: 'change'\n validateAsyncOn?: ValidationCause // Default: 'blur'\n validateAsyncDebounceMs?: number\n defaultMeta?: Partial<FieldMeta>\n}\n\nexport type FieldApiOptions<TData, TFormData> = FieldOptions<\n TData,\n TFormData\n> & {\n form: FormApi<TFormData>\n}\n\nexport type FieldMeta = {\n isTouched: boolean\n touchedError?: ValidationError\n error?: ValidationError\n isValidating: boolean\n}\n\nexport type UserChangeProps<TData> = {\n onChange?: (updater: Updater<TData>) => void\n onBlur?: (event: any) => void\n}\n\nexport type UserInputProps = {\n onChange?: (event: any) => void\n onBlur?: (event: any) => void\n}\n\nexport type ChangeProps<TData> = {\n value: TData\n onChange: (updater: Updater<TData>) => void\n onBlur: (event: any) => void\n}\n\nexport type InputProps = {\n value: string\n onChange: (event: any) => void\n onBlur: (event: any) => void\n}\n\nlet uid = 0\n\nexport type FieldState<TData> = {\n value: TData\n meta: FieldMeta\n}\n\nexport class FieldApi<TData, TFormData> {\n uid: number\n form: FormApi<TFormData>\n name!: DeepKeys<TFormData>\n store!: Store<FieldState<TData>>\n state!: FieldState<TData>\n options: RequiredByKey<\n FieldOptions<TData, TFormData>,\n | 'validatePristine'\n | 'validateOn'\n | 'validateAsyncOn'\n | 'validateAsyncDebounceMs'\n > = {} as any\n\n constructor(opts: FieldApiOptions<TData, TFormData>) {\n this.form = opts.form\n this.uid = uid++\n // Support field prefixing from FieldScope\n // let fieldPrefix = ''\n // if (this.form.fieldName) {\n // fieldPrefix = `${this.form.fieldName}.`\n // }\n\n this.name = opts.name as any\n\n this.store = new Store<FieldState<TData>>(\n {\n value: this.getValue(),\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n meta: this.getMeta() ?? {\n isValidating: false,\n isTouched: false,\n ...this.options.defaultMeta,\n },\n },\n {\n onUpdate: (next) => {\n next.meta.touchedError = next.meta.isTouched\n ? next.meta.error\n : undefined\n\n // Do not validate pristine fields\n const prevState = this.state\n this.state = next\n if (next.value !== prevState.value) {\n this.validate('change', next.value)\n }\n },\n },\n )\n\n this.state = this.store.state\n this.update(opts)\n }\n\n mount = () => {\n const info = this.getInfo()\n info.instances[this.uid] = this\n\n const unsubscribe = this.form.store.subscribe(() => {\n this.#updateStore()\n })\n\n return () => {\n unsubscribe()\n delete info.instances[this.uid]\n if (!Object.keys(info.instances).length) {\n delete this.form.fieldInfo[this.name]\n }\n }\n }\n\n #updateStore = () => {\n this.store.batch(() => {\n const nextValue = this.getValue()\n const nextMeta = this.getMeta()\n\n if (nextValue !== this.state.value) {\n this.store.setState((prev) => ({ ...prev, value: nextValue }))\n }\n\n if (nextMeta !== this.state.meta) {\n this.store.setState((prev) => ({ ...prev, meta: nextMeta }))\n }\n })\n }\n\n update = (opts: FieldApiOptions<TData, TFormData>) => {\n this.options = {\n validatePristine: this.form.options.defaultValidatePristine ?? false,\n validateOn: this.form.options.defaultValidateOn ?? 'change',\n validateAsyncOn: this.form.options.defaultValidateAsyncOn ?? 'blur',\n validateAsyncDebounceMs:\n this.form.options.defaultValidateAsyncDebounceMs ?? 0,\n ...opts,\n }\n\n // Default Value\n if (\n this.state.value === undefined &&\n this.options.defaultValue !== undefined\n ) {\n this.setValue(this.options.defaultValue)\n }\n\n // Default Meta\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (this.getMeta() === undefined) {\n this.setMeta(this.state.meta)\n }\n }\n\n getValue = (): TData => {\n return this.form.getFieldValue(this.name)\n }\n setValue = (\n updater: Updater<TData>,\n options?: { touch?: boolean; notify?: boolean },\n ) => this.form.setFieldValue(this.name, updater as any, options)\n\n getMeta = (): FieldMeta => this.form.getFieldMeta(this.name)\n setMeta = (updater: Updater<FieldMeta>) =>\n this.form.setFieldMeta(this.name, updater)\n\n getInfo = () => this.form.getFieldInfo(this.name)\n\n pushValue = (value: TData extends any[] ? TData[number] : never) =>\n this.form.pushFieldValue(this.name, value as any)\n insertValue = (index: number, value: TData) =>\n this.form.insertFieldValue(this.name, index, value as any)\n removeValue = (index: number) => this.form.removeFieldValue(this.name, index)\n swapValues = (aIndex: number, bIndex: number) =>\n this.form.swapFieldValues(this.name, aIndex, bIndex)\n\n getSubField = <TName extends DeepKeys<TData>>(name: TName) =>\n new FieldApi<DeepValue<TData, TName>, TFormData>({\n name: `${this.name}.${name}` as any,\n form: this.form,\n })\n\n validateSync = async (value = this.state.value) => {\n const { validate } = this.options\n\n if (!validate) {\n return\n }\n\n // Use the validationCount for all field instances to\n // track freshness of the validation\n const validationCount = (this.getInfo().validationCount || 0) + 1\n this.getInfo().validationCount = validationCount\n const error = normalizeError(validate(value, this))\n\n if (this.state.meta.error !== error) {\n this.setMeta((prev) => ({\n ...prev,\n error,\n }))\n }\n\n // If a sync error is encountered, cancel any async validation\n if (this.state.meta.error) {\n this.cancelValidateAsync()\n }\n }\n\n #leaseValidateAsync = () => {\n const count = (this.getInfo().validationAsyncCount || 0) + 1\n this.getInfo().validationAsyncCount = count\n return count\n }\n\n cancelValidateAsync = () => {\n // Lease a new validation count to ignore any pending validations\n this.#leaseValidateAsync()\n // Cancel any pending validation state\n this.setMeta((prev) => ({\n ...prev,\n isValidating: false,\n }))\n }\n\n validateAsync = async (value = this.state.value) => {\n const { validateAsync, validateAsyncDebounceMs } = this.options\n\n if (!validateAsync) {\n return\n }\n\n if (this.state.meta.isValidating !== true)\n this.setMeta((prev) => ({ ...prev, isValidating: true }))\n\n // Use the validationCount for all field instances to\n // track freshness of the validation\n const validationAsyncCount = this.#leaseValidateAsync()\n\n const checkLatest = () =>\n validationAsyncCount === this.getInfo().validationAsyncCount\n\n if (!this.getInfo().validationPromise) {\n this.getInfo().validationPromise = new Promise((resolve, reject) => {\n this.getInfo().validationResolve = resolve\n this.getInfo().validationReject = reject\n })\n }\n\n if (validateAsyncDebounceMs > 0) {\n await new Promise((r) => setTimeout(r, validateAsyncDebounceMs))\n }\n\n // Only kick off validation if this validation is the latest attempt\n if (checkLatest()) {\n try {\n const rawError = await validateAsync(value, this)\n\n if (checkLatest()) {\n const error = normalizeError(rawError)\n this.setMeta((prev) => ({\n ...prev,\n isValidating: false,\n error,\n }))\n this.getInfo().validationResolve?.(error)\n }\n } catch (error) {\n if (checkLatest()) {\n this.getInfo().validationReject?.(error)\n throw error\n }\n } finally {\n if (checkLatest()) {\n this.setMeta((prev) => ({ ...prev, isValidating: false }))\n delete this.getInfo().validationPromise\n }\n }\n }\n\n // Always return the latest validation promise to the caller\n return this.getInfo().validationPromise\n }\n\n shouldValidate = (isAsync: boolean, cause?: ValidationCause) => {\n const { validateOn, validateAsyncOn } = this.options\n const level = getValidationCauseLevel(cause)\n\n // Must meet *at least* the validation level to validate,\n // e.g. if validateOn is 'change' and validateCause is 'blur',\n // the field will still validate\n return Object.keys(validateCauseLevels).some((d) =>\n isAsync\n ? validateAsyncOn\n : validateOn === d && level >= validateCauseLevels[d],\n )\n }\n\n validate = async (\n cause?: ValidationCause,\n value?: TData,\n ): Promise<ValidationError> => {\n // If the field is pristine and validatePristine is false, do not validate\n if (!this.options.validatePristine && !this.state.meta.isTouched) return\n\n // Attempt to sync validate first\n if (this.shouldValidate(false, cause)) {\n this.validateSync(value)\n }\n\n // If there is an error, return it, do not attempt async validation\n if (this.state.meta.error) {\n return this.state.meta.error\n }\n\n // No error? Attempt async validation\n if (this.shouldValidate(true, cause)) {\n return this.validateAsync(value)\n }\n\n // If there is no sync error or async validation attempt, there is no error\n return undefined\n }\n\n getChangeProps = <T extends UserChangeProps<any>>(\n props: T = {} as T,\n ): ChangeProps<TData> & Omit<T, keyof ChangeProps<TData>> => {\n return {\n ...props,\n value: this.state.value,\n onChange: (value) => {\n this.setValue(value)\n props.onChange?.(value)\n },\n onBlur: (e) => {\n this.setMeta((prev) => ({ ...prev, isTouched: true }))\n this.validate('blur')\n props.onBlur?.(e)\n },\n } as ChangeProps<TData> & Omit<T, keyof ChangeProps<TData>>\n }\n\n getInputProps = <T extends UserInputProps>(\n props: T = {} as T,\n ): InputProps & Omit<T, keyof InputProps> => {\n return {\n ...props,\n value: String(this.state.value),\n onChange: (e) => {\n this.setValue(e.target.value)\n props.onChange?.(e.target.value)\n },\n onBlur: this.getChangeProps(props).onBlur,\n }\n }\n}\n\nconst validateCauseLevels = {\n change: 0,\n blur: 1,\n submit: 2,\n}\n\nfunction getValidationCauseLevel(cause?: ValidationCause) {\n return !cause ? 3 : validateCauseLevels[cause]\n}\n\nfunction normalizeError(rawError?: ValidationError) {\n if (rawError) {\n if (typeof rawError !== 'string') {\n return 'Invalid Form Values'\n }\n\n return rawError\n }\n\n return undefined\n}\n"],"names":["uid","FieldApi","constructor","opts","options","mount","info","getInfo","instances","unsubscribe","form","store","subscribe","_classPrivateFieldLooseBase","Object","keys","length","fieldInfo","name","batch","nextValue","getValue","nextMeta","getMeta","state","value","setState","prev","meta","update","validatePristine","defaultValidatePristine","validateOn","defaultValidateOn","validateAsyncOn","defaultValidateAsyncOn","validateAsyncDebounceMs","defaultValidateAsyncDebounceMs","undefined","defaultValue","setValue","setMeta","getFieldValue","updater","setFieldValue","getFieldMeta","setFieldMeta","getFieldInfo","pushValue","pushFieldValue","insertValue","index","insertFieldValue","removeValue","removeFieldValue","swapValues","aIndex","bIndex","swapFieldValues","getSubField","validateSync","validate","validationCount","error","normalizeError","cancelValidateAsync","count","validationAsyncCount","isValidating","validateAsync","checkLatest","validationPromise","Promise","resolve","reject","validationResolve","validationReject","r","setTimeout","rawError","shouldValidate","isAsync","cause","level","getValidationCauseLevel","validateCauseLevels","some","d","isTouched","getChangeProps","props","onChange","onBlur","e","getInputProps","String","target","Store","defaultMeta","onUpdate","next","touchedError","prevState","change","blur","submit"],"mappings":"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"}