@tanstack/form-core 0.3.5 → 0.3.7
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/legacy/FieldApi.cjs +3 -0
- package/build/legacy/FieldApi.cjs.map +1 -1
- package/build/legacy/FieldApi.d.cts +1 -1
- package/build/legacy/FieldApi.d.ts +1 -1
- package/build/legacy/FieldApi.js +3 -0
- package/build/legacy/FieldApi.js.map +1 -1
- package/build/legacy/FormApi.cjs.map +1 -1
- package/build/legacy/FormApi.js.map +1 -1
- package/build/legacy/index.d.cts +32 -42
- package/build/legacy/index.d.ts +32 -42
- package/build/modern/FieldApi.cjs +3 -0
- package/build/modern/FieldApi.cjs.map +1 -1
- package/build/modern/FieldApi.d.cts +1 -1
- package/build/modern/FieldApi.d.ts +1 -1
- package/build/modern/FieldApi.js +3 -0
- package/build/modern/FieldApi.js.map +1 -1
- package/build/modern/FormApi.cjs.map +1 -1
- package/build/modern/FormApi.js.map +1 -1
- package/build/modern/index.d.cts +32 -42
- package/build/modern/index.d.ts +32 -42
- package/package.json +1 -1
- package/src/FieldApi.ts +38 -62
- package/src/FormApi.ts +1 -1
- package/src/tests/FieldApi.spec.ts +16 -0
package/build/modern/index.d.cts
CHANGED
|
@@ -19,7 +19,7 @@ type FormOptions<TData> = {
|
|
|
19
19
|
onSubmitInvalid?: (values: TData, formApi: FormApi<TData>) => void;
|
|
20
20
|
};
|
|
21
21
|
type FieldInfo<TFormData> = {
|
|
22
|
-
instances: Record<string, FieldApi<
|
|
22
|
+
instances: Record<string, FieldApi<TFormData, any, any>>;
|
|
23
23
|
} & ValidationMeta;
|
|
24
24
|
type ValidationMeta = {
|
|
25
25
|
validationCount?: number;
|
|
@@ -82,9 +82,9 @@ declare class FormApi<TFormData> {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
type ValidationCause = 'change' | 'blur' | 'submit' | 'mount';
|
|
85
|
-
type ValidateFn<
|
|
86
|
-
type ValidateAsyncFn<
|
|
87
|
-
interface FieldOptions<
|
|
85
|
+
type ValidateFn<TParentData, TName extends DeepKeys<TParentData>, TData> = (value: TData, fieldApi: FieldApi<TParentData, TName>) => ValidationError;
|
|
86
|
+
type ValidateAsyncFn<TParentData, TName extends DeepKeys<TParentData>, TData> = (value: TData, fieldApi: FieldApi<TParentData, TName>) => ValidationError | Promise<ValidationError>;
|
|
87
|
+
interface FieldOptions<TParentData,
|
|
88
88
|
/**
|
|
89
89
|
* This allows us to restrict the name to only be a valid field name while
|
|
90
90
|
* also assigning it to a generic
|
|
@@ -93,32 +93,23 @@ TName extends DeepKeys<TParentData>,
|
|
|
93
93
|
/**
|
|
94
94
|
* If TData is unknown, we can use the TName generic to determine the type
|
|
95
95
|
*/
|
|
96
|
-
|
|
96
|
+
TData = DeepValue<TParentData, TName>> {
|
|
97
97
|
name: DeepKeys<TParentData>;
|
|
98
|
-
index?:
|
|
99
|
-
defaultValue?:
|
|
98
|
+
index?: TData extends any[] ? number : never;
|
|
99
|
+
defaultValue?: TData;
|
|
100
100
|
asyncDebounceMs?: number;
|
|
101
101
|
asyncAlways?: boolean;
|
|
102
|
-
onMount?: (formApi: FieldApi<
|
|
103
|
-
onChange?: ValidateFn<
|
|
104
|
-
onChangeAsync?: ValidateAsyncFn<
|
|
102
|
+
onMount?: (formApi: FieldApi<TParentData, TName>) => void;
|
|
103
|
+
onChange?: ValidateFn<TParentData, TName, TData>;
|
|
104
|
+
onChangeAsync?: ValidateAsyncFn<TParentData, TName, TData>;
|
|
105
105
|
onChangeAsyncDebounceMs?: number;
|
|
106
|
-
onBlur?: ValidateFn<
|
|
107
|
-
onBlurAsync?: ValidateAsyncFn<
|
|
106
|
+
onBlur?: ValidateFn<TParentData, TName, TData>;
|
|
107
|
+
onBlurAsync?: ValidateAsyncFn<TParentData, TName, TData>;
|
|
108
108
|
onBlurAsyncDebounceMs?: number;
|
|
109
|
-
onSubmitAsync?: ValidateAsyncFn<
|
|
109
|
+
onSubmitAsync?: ValidateAsyncFn<TParentData, TName, TData>;
|
|
110
110
|
defaultMeta?: Partial<FieldMeta>;
|
|
111
111
|
}
|
|
112
|
-
interface FieldApiOptions<TData, TParentData,
|
|
113
|
-
/**
|
|
114
|
-
* This allows us to restrict the name to only be a valid field name while
|
|
115
|
-
* also assigning it to a generic
|
|
116
|
-
*/
|
|
117
|
-
TName extends DeepKeys<TParentData>,
|
|
118
|
-
/**
|
|
119
|
-
* If TData is unknown, we can use the TName generic to determine the type
|
|
120
|
-
*/
|
|
121
|
-
TResolvedData extends ResolveData<TData, TParentData, TName> = ResolveData<TData, TParentData, TName>> extends FieldOptions<TData, TParentData, TName, TResolvedData> {
|
|
112
|
+
interface FieldApiOptions<TParentData, TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>> extends FieldOptions<TParentData, TName, TData> {
|
|
122
113
|
form: FormApi<TParentData>;
|
|
123
114
|
}
|
|
124
115
|
type FieldMeta = {
|
|
@@ -132,24 +123,23 @@ type FieldState<TData> = {
|
|
|
132
123
|
value: TData;
|
|
133
124
|
meta: FieldMeta;
|
|
134
125
|
};
|
|
135
|
-
type ResolveData<TData, TParentData, TName> = unknown extends TData ? DeepValue<TParentData, TName> : TData;
|
|
136
126
|
type ResolveName<TParentData> = unknown extends TParentData ? string : DeepKeys<TParentData>;
|
|
137
|
-
declare class FieldApi<
|
|
127
|
+
declare class FieldApi<TParentData, TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>> {
|
|
138
128
|
#private;
|
|
139
129
|
uid: number;
|
|
140
|
-
form: FieldApiOptions<
|
|
130
|
+
form: FieldApiOptions<TParentData, TName, TData>['form'];
|
|
141
131
|
name: DeepKeys<TParentData>;
|
|
142
|
-
options: FieldApiOptions<
|
|
143
|
-
store: Store<FieldState<
|
|
144
|
-
state: FieldState<
|
|
145
|
-
prevState: FieldState<
|
|
146
|
-
constructor(opts: FieldApiOptions<
|
|
132
|
+
options: FieldApiOptions<TParentData, TName>;
|
|
133
|
+
store: Store<FieldState<TData>>;
|
|
134
|
+
state: FieldState<TData>;
|
|
135
|
+
prevState: FieldState<TData>;
|
|
136
|
+
constructor(opts: FieldApiOptions<TParentData, TName, TData> & {
|
|
147
137
|
form: FormApi<TParentData>;
|
|
148
138
|
});
|
|
149
139
|
mount: () => () => void;
|
|
150
|
-
update: (opts: FieldApiOptions<
|
|
151
|
-
getValue: () =>
|
|
152
|
-
setValue: (updater: Updater<
|
|
140
|
+
update: (opts: FieldApiOptions<TParentData, TName, TData>) => void;
|
|
141
|
+
getValue: () => TData;
|
|
142
|
+
setValue: (updater: Updater<TData>, options?: {
|
|
153
143
|
touch?: boolean;
|
|
154
144
|
notify?: boolean;
|
|
155
145
|
}) => void;
|
|
@@ -157,17 +147,17 @@ declare class FieldApi<TData, TParentData, TName extends DeepKeys<TParentData>,
|
|
|
157
147
|
getMeta: () => FieldMeta;
|
|
158
148
|
setMeta: (updater: Updater<FieldMeta>) => void;
|
|
159
149
|
getInfo: () => FieldInfo<TParentData>;
|
|
160
|
-
pushValue: (value:
|
|
161
|
-
insertValue: (index: number, value:
|
|
150
|
+
pushValue: (value: TData extends any[] ? TData[number] : never) => void;
|
|
151
|
+
insertValue: (index: number, value: TData extends any[] ? TData[number] : never) => void;
|
|
162
152
|
removeValue: (index: number) => void;
|
|
163
153
|
swapValues: (aIndex: number, bIndex: number) => void;
|
|
164
|
-
getSubField: <
|
|
165
|
-
validateSync: (value:
|
|
154
|
+
getSubField: <TSubName extends DeepKeys<TData>, TSubData = DeepValue<TData, TSubName>>(name: TSubName) => FieldApi<TData, TSubName, TSubData>;
|
|
155
|
+
validateSync: (value: TData | undefined, cause: ValidationCause) => void;
|
|
166
156
|
cancelValidateAsync: () => void;
|
|
167
|
-
validateAsync: (value:
|
|
168
|
-
validate: (cause: ValidationCause, value?:
|
|
169
|
-
handleChange: (updater: Updater<
|
|
157
|
+
validateAsync: (value: TData | undefined, cause: ValidationCause) => Promise<ValidationError[]>;
|
|
158
|
+
validate: (cause: ValidationCause, value?: TData) => ValidationError[] | Promise<ValidationError[]>;
|
|
159
|
+
handleChange: (updater: Updater<TData>) => void;
|
|
170
160
|
handleBlur: () => void;
|
|
171
161
|
}
|
|
172
162
|
|
|
173
|
-
export { DeepKeys, DeepValue, FieldApi, FieldApiOptions, FieldInfo, FieldMeta, FieldOptions, FieldState, FormApi, FormOptions, FormState,
|
|
163
|
+
export { DeepKeys, DeepValue, FieldApi, FieldApiOptions, FieldInfo, FieldMeta, FieldOptions, FieldState, FormApi, FormOptions, FormState, ResolveName, Updater, ValidationCause, ValidationError, ValidationErrorMap, ValidationErrorMapKeys, ValidationMeta };
|
package/build/modern/index.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ type FormOptions<TData> = {
|
|
|
19
19
|
onSubmitInvalid?: (values: TData, formApi: FormApi<TData>) => void;
|
|
20
20
|
};
|
|
21
21
|
type FieldInfo<TFormData> = {
|
|
22
|
-
instances: Record<string, FieldApi<
|
|
22
|
+
instances: Record<string, FieldApi<TFormData, any, any>>;
|
|
23
23
|
} & ValidationMeta;
|
|
24
24
|
type ValidationMeta = {
|
|
25
25
|
validationCount?: number;
|
|
@@ -82,9 +82,9 @@ declare class FormApi<TFormData> {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
type ValidationCause = 'change' | 'blur' | 'submit' | 'mount';
|
|
85
|
-
type ValidateFn<
|
|
86
|
-
type ValidateAsyncFn<
|
|
87
|
-
interface FieldOptions<
|
|
85
|
+
type ValidateFn<TParentData, TName extends DeepKeys<TParentData>, TData> = (value: TData, fieldApi: FieldApi<TParentData, TName>) => ValidationError;
|
|
86
|
+
type ValidateAsyncFn<TParentData, TName extends DeepKeys<TParentData>, TData> = (value: TData, fieldApi: FieldApi<TParentData, TName>) => ValidationError | Promise<ValidationError>;
|
|
87
|
+
interface FieldOptions<TParentData,
|
|
88
88
|
/**
|
|
89
89
|
* This allows us to restrict the name to only be a valid field name while
|
|
90
90
|
* also assigning it to a generic
|
|
@@ -93,32 +93,23 @@ TName extends DeepKeys<TParentData>,
|
|
|
93
93
|
/**
|
|
94
94
|
* If TData is unknown, we can use the TName generic to determine the type
|
|
95
95
|
*/
|
|
96
|
-
|
|
96
|
+
TData = DeepValue<TParentData, TName>> {
|
|
97
97
|
name: DeepKeys<TParentData>;
|
|
98
|
-
index?:
|
|
99
|
-
defaultValue?:
|
|
98
|
+
index?: TData extends any[] ? number : never;
|
|
99
|
+
defaultValue?: TData;
|
|
100
100
|
asyncDebounceMs?: number;
|
|
101
101
|
asyncAlways?: boolean;
|
|
102
|
-
onMount?: (formApi: FieldApi<
|
|
103
|
-
onChange?: ValidateFn<
|
|
104
|
-
onChangeAsync?: ValidateAsyncFn<
|
|
102
|
+
onMount?: (formApi: FieldApi<TParentData, TName>) => void;
|
|
103
|
+
onChange?: ValidateFn<TParentData, TName, TData>;
|
|
104
|
+
onChangeAsync?: ValidateAsyncFn<TParentData, TName, TData>;
|
|
105
105
|
onChangeAsyncDebounceMs?: number;
|
|
106
|
-
onBlur?: ValidateFn<
|
|
107
|
-
onBlurAsync?: ValidateAsyncFn<
|
|
106
|
+
onBlur?: ValidateFn<TParentData, TName, TData>;
|
|
107
|
+
onBlurAsync?: ValidateAsyncFn<TParentData, TName, TData>;
|
|
108
108
|
onBlurAsyncDebounceMs?: number;
|
|
109
|
-
onSubmitAsync?: ValidateAsyncFn<
|
|
109
|
+
onSubmitAsync?: ValidateAsyncFn<TParentData, TName, TData>;
|
|
110
110
|
defaultMeta?: Partial<FieldMeta>;
|
|
111
111
|
}
|
|
112
|
-
interface FieldApiOptions<TData, TParentData,
|
|
113
|
-
/**
|
|
114
|
-
* This allows us to restrict the name to only be a valid field name while
|
|
115
|
-
* also assigning it to a generic
|
|
116
|
-
*/
|
|
117
|
-
TName extends DeepKeys<TParentData>,
|
|
118
|
-
/**
|
|
119
|
-
* If TData is unknown, we can use the TName generic to determine the type
|
|
120
|
-
*/
|
|
121
|
-
TResolvedData extends ResolveData<TData, TParentData, TName> = ResolveData<TData, TParentData, TName>> extends FieldOptions<TData, TParentData, TName, TResolvedData> {
|
|
112
|
+
interface FieldApiOptions<TParentData, TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>> extends FieldOptions<TParentData, TName, TData> {
|
|
122
113
|
form: FormApi<TParentData>;
|
|
123
114
|
}
|
|
124
115
|
type FieldMeta = {
|
|
@@ -132,24 +123,23 @@ type FieldState<TData> = {
|
|
|
132
123
|
value: TData;
|
|
133
124
|
meta: FieldMeta;
|
|
134
125
|
};
|
|
135
|
-
type ResolveData<TData, TParentData, TName> = unknown extends TData ? DeepValue<TParentData, TName> : TData;
|
|
136
126
|
type ResolveName<TParentData> = unknown extends TParentData ? string : DeepKeys<TParentData>;
|
|
137
|
-
declare class FieldApi<
|
|
127
|
+
declare class FieldApi<TParentData, TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>> {
|
|
138
128
|
#private;
|
|
139
129
|
uid: number;
|
|
140
|
-
form: FieldApiOptions<
|
|
130
|
+
form: FieldApiOptions<TParentData, TName, TData>['form'];
|
|
141
131
|
name: DeepKeys<TParentData>;
|
|
142
|
-
options: FieldApiOptions<
|
|
143
|
-
store: Store<FieldState<
|
|
144
|
-
state: FieldState<
|
|
145
|
-
prevState: FieldState<
|
|
146
|
-
constructor(opts: FieldApiOptions<
|
|
132
|
+
options: FieldApiOptions<TParentData, TName>;
|
|
133
|
+
store: Store<FieldState<TData>>;
|
|
134
|
+
state: FieldState<TData>;
|
|
135
|
+
prevState: FieldState<TData>;
|
|
136
|
+
constructor(opts: FieldApiOptions<TParentData, TName, TData> & {
|
|
147
137
|
form: FormApi<TParentData>;
|
|
148
138
|
});
|
|
149
139
|
mount: () => () => void;
|
|
150
|
-
update: (opts: FieldApiOptions<
|
|
151
|
-
getValue: () =>
|
|
152
|
-
setValue: (updater: Updater<
|
|
140
|
+
update: (opts: FieldApiOptions<TParentData, TName, TData>) => void;
|
|
141
|
+
getValue: () => TData;
|
|
142
|
+
setValue: (updater: Updater<TData>, options?: {
|
|
153
143
|
touch?: boolean;
|
|
154
144
|
notify?: boolean;
|
|
155
145
|
}) => void;
|
|
@@ -157,17 +147,17 @@ declare class FieldApi<TData, TParentData, TName extends DeepKeys<TParentData>,
|
|
|
157
147
|
getMeta: () => FieldMeta;
|
|
158
148
|
setMeta: (updater: Updater<FieldMeta>) => void;
|
|
159
149
|
getInfo: () => FieldInfo<TParentData>;
|
|
160
|
-
pushValue: (value:
|
|
161
|
-
insertValue: (index: number, value:
|
|
150
|
+
pushValue: (value: TData extends any[] ? TData[number] : never) => void;
|
|
151
|
+
insertValue: (index: number, value: TData extends any[] ? TData[number] : never) => void;
|
|
162
152
|
removeValue: (index: number) => void;
|
|
163
153
|
swapValues: (aIndex: number, bIndex: number) => void;
|
|
164
|
-
getSubField: <
|
|
165
|
-
validateSync: (value:
|
|
154
|
+
getSubField: <TSubName extends DeepKeys<TData>, TSubData = DeepValue<TData, TSubName>>(name: TSubName) => FieldApi<TData, TSubName, TSubData>;
|
|
155
|
+
validateSync: (value: TData | undefined, cause: ValidationCause) => void;
|
|
166
156
|
cancelValidateAsync: () => void;
|
|
167
|
-
validateAsync: (value:
|
|
168
|
-
validate: (cause: ValidationCause, value?:
|
|
169
|
-
handleChange: (updater: Updater<
|
|
157
|
+
validateAsync: (value: TData | undefined, cause: ValidationCause) => Promise<ValidationError[]>;
|
|
158
|
+
validate: (cause: ValidationCause, value?: TData) => ValidationError[] | Promise<ValidationError[]>;
|
|
159
|
+
handleChange: (updater: Updater<TData>) => void;
|
|
170
160
|
handleBlur: () => void;
|
|
171
161
|
}
|
|
172
162
|
|
|
173
|
-
export { DeepKeys, DeepValue, FieldApi, FieldApiOptions, FieldInfo, FieldMeta, FieldOptions, FieldState, FormApi, FormOptions, FormState,
|
|
163
|
+
export { DeepKeys, DeepValue, FieldApi, FieldApiOptions, FieldInfo, FieldMeta, FieldOptions, FieldState, FormApi, FormOptions, FormState, ResolveName, Updater, ValidationCause, ValidationError, ValidationErrorMap, ValidationErrorMapKeys, ValidationMeta };
|
package/package.json
CHANGED
package/src/FieldApi.ts
CHANGED
|
@@ -4,22 +4,21 @@ import { Store } from '@tanstack/store'
|
|
|
4
4
|
|
|
5
5
|
export type ValidationCause = 'change' | 'blur' | 'submit' | 'mount'
|
|
6
6
|
|
|
7
|
-
type ValidateFn<
|
|
7
|
+
type ValidateFn<TParentData, TName extends DeepKeys<TParentData>, TData> = (
|
|
8
8
|
value: TData,
|
|
9
|
-
fieldApi: FieldApi<
|
|
9
|
+
fieldApi: FieldApi<TParentData, TName>,
|
|
10
10
|
) => ValidationError
|
|
11
11
|
|
|
12
12
|
type ValidateAsyncFn<
|
|
13
|
-
TData,
|
|
14
13
|
TParentData,
|
|
15
14
|
TName extends DeepKeys<TParentData>,
|
|
15
|
+
TData,
|
|
16
16
|
> = (
|
|
17
17
|
value: TData,
|
|
18
|
-
fieldApi: FieldApi<
|
|
18
|
+
fieldApi: FieldApi<TParentData, TName>,
|
|
19
19
|
) => ValidationError | Promise<ValidationError>
|
|
20
20
|
|
|
21
21
|
export interface FieldOptions<
|
|
22
|
-
TData,
|
|
23
22
|
TParentData,
|
|
24
23
|
/**
|
|
25
24
|
* This allows us to restrict the name to only be a valid field name while
|
|
@@ -29,41 +28,29 @@ export interface FieldOptions<
|
|
|
29
28
|
/**
|
|
30
29
|
* If TData is unknown, we can use the TName generic to determine the type
|
|
31
30
|
*/
|
|
32
|
-
|
|
31
|
+
TData = DeepValue<TParentData, TName>,
|
|
33
32
|
> {
|
|
34
33
|
name: DeepKeys<TParentData>
|
|
35
|
-
index?:
|
|
36
|
-
defaultValue?:
|
|
34
|
+
index?: TData extends any[] ? number : never
|
|
35
|
+
defaultValue?: TData
|
|
37
36
|
asyncDebounceMs?: number
|
|
38
37
|
asyncAlways?: boolean
|
|
39
|
-
onMount?: (formApi: FieldApi<
|
|
40
|
-
onChange?: ValidateFn<
|
|
41
|
-
onChangeAsync?: ValidateAsyncFn<
|
|
38
|
+
onMount?: (formApi: FieldApi<TParentData, TName>) => void
|
|
39
|
+
onChange?: ValidateFn<TParentData, TName, TData>
|
|
40
|
+
onChangeAsync?: ValidateAsyncFn<TParentData, TName, TData>
|
|
42
41
|
onChangeAsyncDebounceMs?: number
|
|
43
|
-
onBlur?: ValidateFn<
|
|
44
|
-
onBlurAsync?: ValidateAsyncFn<
|
|
42
|
+
onBlur?: ValidateFn<TParentData, TName, TData>
|
|
43
|
+
onBlurAsync?: ValidateAsyncFn<TParentData, TName, TData>
|
|
45
44
|
onBlurAsyncDebounceMs?: number
|
|
46
|
-
onSubmitAsync?: ValidateAsyncFn<
|
|
45
|
+
onSubmitAsync?: ValidateAsyncFn<TParentData, TName, TData>
|
|
47
46
|
defaultMeta?: Partial<FieldMeta>
|
|
48
47
|
}
|
|
49
48
|
|
|
50
49
|
export interface FieldApiOptions<
|
|
51
|
-
TData,
|
|
52
50
|
TParentData,
|
|
53
|
-
/**
|
|
54
|
-
* This allows us to restrict the name to only be a valid field name while
|
|
55
|
-
* also assigning it to a generic
|
|
56
|
-
*/
|
|
57
51
|
TName extends DeepKeys<TParentData>,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
*/
|
|
61
|
-
TResolvedData extends ResolveData<TData, TParentData, TName> = ResolveData<
|
|
62
|
-
TData,
|
|
63
|
-
TParentData,
|
|
64
|
-
TName
|
|
65
|
-
>,
|
|
66
|
-
> extends FieldOptions<TData, TParentData, TName, TResolvedData> {
|
|
52
|
+
TData = DeepValue<TParentData, TName>,
|
|
53
|
+
> extends FieldOptions<TParentData, TName, TData> {
|
|
67
54
|
form: FormApi<TParentData>
|
|
68
55
|
}
|
|
69
56
|
|
|
@@ -82,34 +69,25 @@ export type FieldState<TData> = {
|
|
|
82
69
|
meta: FieldMeta
|
|
83
70
|
}
|
|
84
71
|
|
|
85
|
-
export type ResolveData<TData, TParentData, TName> = unknown extends TData
|
|
86
|
-
? DeepValue<TParentData, TName>
|
|
87
|
-
: TData
|
|
88
|
-
|
|
89
72
|
export type ResolveName<TParentData> = unknown extends TParentData
|
|
90
73
|
? string
|
|
91
74
|
: DeepKeys<TParentData>
|
|
92
75
|
|
|
93
76
|
export class FieldApi<
|
|
94
|
-
TData,
|
|
95
77
|
TParentData,
|
|
96
78
|
TName extends DeepKeys<TParentData>,
|
|
97
|
-
|
|
98
|
-
TData,
|
|
99
|
-
TParentData,
|
|
100
|
-
TName
|
|
101
|
-
>,
|
|
79
|
+
TData = DeepValue<TParentData, TName>,
|
|
102
80
|
> {
|
|
103
81
|
uid: number
|
|
104
|
-
form: FieldApiOptions<
|
|
82
|
+
form: FieldApiOptions<TParentData, TName, TData>['form']
|
|
105
83
|
name!: DeepKeys<TParentData>
|
|
106
|
-
options: FieldApiOptions<
|
|
107
|
-
store!: Store<FieldState<
|
|
108
|
-
state!: FieldState<
|
|
109
|
-
prevState!: FieldState<
|
|
84
|
+
options: FieldApiOptions<TParentData, TName> = {} as any
|
|
85
|
+
store!: Store<FieldState<TData>>
|
|
86
|
+
state!: FieldState<TData>
|
|
87
|
+
prevState!: FieldState<TData>
|
|
110
88
|
|
|
111
89
|
constructor(
|
|
112
|
-
opts: FieldApiOptions<
|
|
90
|
+
opts: FieldApiOptions<TParentData, TName, TData> & {
|
|
113
91
|
form: FormApi<TParentData>
|
|
114
92
|
},
|
|
115
93
|
) {
|
|
@@ -123,7 +101,11 @@ export class FieldApi<
|
|
|
123
101
|
|
|
124
102
|
this.name = opts.name as any
|
|
125
103
|
|
|
126
|
-
|
|
104
|
+
if (opts.defaultValue !== undefined) {
|
|
105
|
+
this.form.setFieldValue(this.name, opts.defaultValue as never)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
this.store = new Store<FieldState<TData>>(
|
|
127
109
|
{
|
|
128
110
|
value: this.getValue(),
|
|
129
111
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
@@ -190,7 +172,7 @@ export class FieldApi<
|
|
|
190
172
|
}
|
|
191
173
|
}
|
|
192
174
|
|
|
193
|
-
update = (opts: FieldApiOptions<
|
|
175
|
+
update = (opts: FieldApiOptions<TParentData, TName, TData>) => {
|
|
194
176
|
// Default Value
|
|
195
177
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
196
178
|
if (this.state.value === undefined) {
|
|
@@ -212,12 +194,12 @@ export class FieldApi<
|
|
|
212
194
|
this.options = opts as never
|
|
213
195
|
}
|
|
214
196
|
|
|
215
|
-
getValue = ():
|
|
197
|
+
getValue = (): TData => {
|
|
216
198
|
return this.form.getFieldValue(this.name) as any
|
|
217
199
|
}
|
|
218
200
|
|
|
219
201
|
setValue = (
|
|
220
|
-
updater: Updater<
|
|
202
|
+
updater: Updater<TData>,
|
|
221
203
|
options?: { touch?: boolean; notify?: boolean },
|
|
222
204
|
) => {
|
|
223
205
|
this.form.setFieldValue(this.name, updater as never, options)
|
|
@@ -241,13 +223,12 @@ export class FieldApi<
|
|
|
241
223
|
|
|
242
224
|
getInfo = () => this.form.getFieldInfo(this.name)
|
|
243
225
|
|
|
244
|
-
pushValue = (
|
|
245
|
-
value
|
|
246
|
-
) => this.form.pushFieldValue(this.name, value as any)
|
|
226
|
+
pushValue = (value: TData extends any[] ? TData[number] : never) =>
|
|
227
|
+
this.form.pushFieldValue(this.name, value as any)
|
|
247
228
|
|
|
248
229
|
insertValue = (
|
|
249
230
|
index: number,
|
|
250
|
-
value:
|
|
231
|
+
value: TData extends any[] ? TData[number] : never,
|
|
251
232
|
) => this.form.insertFieldValue(this.name, index, value as any)
|
|
252
233
|
|
|
253
234
|
removeValue = (index: number) => this.form.removeFieldValue(this.name, index)
|
|
@@ -256,16 +237,11 @@ export class FieldApi<
|
|
|
256
237
|
this.form.swapFieldValues(this.name, aIndex, bIndex)
|
|
257
238
|
|
|
258
239
|
getSubField = <
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
TSubResolvedData extends ResolveData<
|
|
262
|
-
DeepValue<TResolvedData, TSubName>,
|
|
263
|
-
TResolvedData,
|
|
264
|
-
TSubName
|
|
265
|
-
>,
|
|
240
|
+
TSubName extends DeepKeys<TData>,
|
|
241
|
+
TSubData = DeepValue<TData, TSubName>,
|
|
266
242
|
>(
|
|
267
243
|
name: TSubName,
|
|
268
|
-
): FieldApi<
|
|
244
|
+
): FieldApi<TData, TSubName, TSubData> =>
|
|
269
245
|
new FieldApi({
|
|
270
246
|
name: `${this.name}.${name}` as never,
|
|
271
247
|
form: this.form,
|
|
@@ -398,7 +374,7 @@ export class FieldApi<
|
|
|
398
374
|
|
|
399
375
|
validate = (
|
|
400
376
|
cause: ValidationCause,
|
|
401
|
-
value?:
|
|
377
|
+
value?: TData,
|
|
402
378
|
): ValidationError[] | Promise<ValidationError[]> => {
|
|
403
379
|
// If the field is pristine and validatePristine is false, do not validate
|
|
404
380
|
if (!this.state.meta.isTouched) return []
|
|
@@ -416,7 +392,7 @@ export class FieldApi<
|
|
|
416
392
|
return this.validateAsync(value, cause)
|
|
417
393
|
}
|
|
418
394
|
|
|
419
|
-
handleChange = (updater: Updater<
|
|
395
|
+
handleChange = (updater: Updater<TData>) => {
|
|
420
396
|
this.setValue(updater, { touch: true })
|
|
421
397
|
}
|
|
422
398
|
|
package/src/FormApi.ts
CHANGED
|
@@ -31,7 +31,7 @@ export type FormOptions<TData> = {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export type FieldInfo<TFormData> = {
|
|
34
|
-
instances: Record<string, FieldApi<
|
|
34
|
+
instances: Record<string, FieldApi<TFormData, any, any>>
|
|
35
35
|
} & ValidationMeta
|
|
36
36
|
|
|
37
37
|
export type ValidationMeta = {
|
|
@@ -20,6 +20,22 @@ describe('field api', () => {
|
|
|
20
20
|
expect(field.getValue()).toBe('test')
|
|
21
21
|
})
|
|
22
22
|
|
|
23
|
+
it('should use field default value first', () => {
|
|
24
|
+
const form = new FormApi({
|
|
25
|
+
defaultValues: {
|
|
26
|
+
name: 'test',
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const field = new FieldApi({
|
|
31
|
+
form,
|
|
32
|
+
defaultValue: 'other',
|
|
33
|
+
name: 'name',
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
expect(field.getValue()).toBe('other')
|
|
37
|
+
})
|
|
38
|
+
|
|
23
39
|
it('should get default meta', () => {
|
|
24
40
|
const form = new FormApi()
|
|
25
41
|
const field = new FieldApi({
|