@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.
- package/build/lib/FieldApi.cjs +307 -0
- package/build/lib/FieldApi.cjs.map +1 -0
- package/build/lib/FieldApi.d.ts +112 -0
- package/build/lib/FieldApi.d.ts.map +1 -0
- package/build/lib/FieldApi.js +305 -0
- package/build/lib/FieldApi.js.map +1 -0
- package/build/lib/FieldApi.legacy.cjs +307 -0
- package/build/lib/FieldApi.legacy.cjs.map +1 -0
- package/build/lib/FieldApi.legacy.js +305 -0
- package/build/lib/FieldApi.legacy.js.map +1 -0
- package/build/lib/FormApi.cjs +248 -0
- package/build/lib/FormApi.cjs.map +1 -0
- package/build/{types → lib}/FormApi.d.ts +16 -11
- package/build/lib/FormApi.d.ts.map +1 -0
- package/build/lib/FormApi.js +246 -0
- package/build/lib/FormApi.js.map +1 -0
- package/build/lib/FormApi.legacy.cjs +248 -0
- package/build/lib/FormApi.legacy.cjs.map +1 -0
- package/build/lib/FormApi.legacy.js +246 -0
- package/build/lib/FormApi.legacy.js.map +1 -0
- package/build/lib/_virtual/_rollupPluginBabelHelpers.cjs +65 -0
- package/build/lib/_virtual/_rollupPluginBabelHelpers.cjs.map +1 -0
- package/build/lib/_virtual/_rollupPluginBabelHelpers.js +56 -0
- package/build/{cjs → lib}/_virtual/_rollupPluginBabelHelpers.js.map +1 -1
- package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.cjs +65 -0
- package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.cjs.map +1 -0
- package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.js +56 -0
- package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.js.map +1 -0
- package/build/lib/index.cjs +14 -0
- package/build/lib/index.cjs.map +1 -0
- package/build/{types → lib}/index.d.ts +1 -0
- package/build/lib/index.d.ts.map +1 -0
- package/build/lib/index.js +4 -0
- package/build/{cjs → lib}/index.js.map +1 -1
- package/build/lib/index.legacy.cjs +14 -0
- package/build/lib/index.legacy.cjs.map +1 -0
- package/build/lib/index.legacy.js +4 -0
- package/build/lib/index.legacy.js.map +1 -0
- package/build/lib/tests/FieldApi.spec.d.ts +2 -0
- package/build/lib/tests/FieldApi.spec.d.ts.map +1 -0
- package/build/lib/tests/FieldApi.test-d.d.ts +2 -0
- package/build/lib/tests/FieldApi.test-d.d.ts.map +1 -0
- package/build/lib/tests/FormApi.spec.d.ts +2 -0
- package/build/lib/tests/FormApi.spec.d.ts.map +1 -0
- package/build/{cjs/utils.js → lib/utils.cjs} +18 -27
- package/build/lib/utils.cjs.map +1 -0
- package/build/{types → lib}/utils.d.ts +10 -0
- package/build/lib/utils.d.ts.map +1 -0
- package/build/lib/utils.js +77 -0
- package/build/lib/utils.js.map +1 -0
- package/build/lib/utils.legacy.cjs +81 -0
- package/build/lib/utils.legacy.cjs.map +1 -0
- package/build/lib/utils.legacy.js +77 -0
- package/build/lib/utils.legacy.js.map +1 -0
- package/package.json +23 -10
- package/src/FieldApi.ts +190 -138
- package/src/FormApi.ts +84 -118
- package/src/tests/FieldApi.spec.ts +143 -0
- package/src/tests/FieldApi.test-d.ts +41 -0
- package/src/tests/FormApi.spec.ts +216 -0
- package/src/utils.ts +10 -1
- package/build/cjs/FieldApi.js +0 -345
- package/build/cjs/FieldApi.js.map +0 -1
- package/build/cjs/FormApi.js +0 -317
- package/build/cjs/FormApi.js.map +0 -1
- package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +0 -31
- package/build/cjs/index.js +0 -26
- package/build/cjs/utils.js.map +0 -1
- package/build/esm/index.js +0 -724
- package/build/esm/index.js.map +0 -1
- package/build/stats-html.html +0 -2689
- package/build/stats-react.json +0 -190
- package/build/types/FieldApi.d.ts +0 -79
- package/build/types/tests/test.test.d.ts +0 -0
- package/build/umd/index.development.js +0 -785
- package/build/umd/index.development.js.map +0 -1
- package/build/umd/index.production.js +0 -22
- package/build/umd/index.production.js.map +0 -1
- 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] } & {}
|
package/build/cjs/FieldApi.js
DELETED
|
@@ -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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"}
|