@websolutespa/bom-mixer-forms 1.8.1 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/index.d.ts +38 -43
- package/dist/index.js +69 -0
- package/dist/index.mjs +68 -0
- package/package.json +1 -1
- package/src/forms/form-abstract-collection.ts +10 -7
- package/src/forms/form-abstract.ts +2 -2
- package/src/forms/form-array.ts +6 -6
- package/src/forms/form-group.ts +4 -5
- package/src/forms/types.ts +7 -5
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useFormBuilder/useFormBuilder.ts +8 -2
- package/src/hooks/useFormSchema/useFormSchema.ts +105 -0
package/CHANGELOG.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -11,10 +11,10 @@ declare class EventEmitter {
|
|
|
11
11
|
once(event: string, listener: (...args: any[]) => any): void;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
declare class FormAbstractCollection<T extends FormControls> extends FormAbstract {
|
|
14
|
+
declare class FormAbstractCollection<U extends Record<string, FormValue> | FormValue[], T extends FormControls> extends FormAbstract<U> {
|
|
15
15
|
controls_: T;
|
|
16
16
|
constructor(controls: T, validators?: (FormValidator | FormValidator[]));
|
|
17
|
-
initControl_(controlOrValue: FormAbstract |
|
|
17
|
+
initControl_(controlOrValue: FormAbstract | FormValue, key: any): FormAbstract;
|
|
18
18
|
protected setInitialOptions(options?: FormOptions): void;
|
|
19
19
|
protected checkAsyncPropState_(key: keyof FormFlags, option?: FormActivator, root?: FormCollection): Promise<boolean>;
|
|
20
20
|
updateState_(): void;
|
|
@@ -34,7 +34,7 @@ declare class FormAbstractCollection<T extends FormControls> extends FormAbstrac
|
|
|
34
34
|
protected reduce_(callback: Function, result: any): any;
|
|
35
35
|
protected all_(key: (keyof FormAbstract), value: any): boolean;
|
|
36
36
|
protected any_(key: (keyof FormAbstract), value: any): boolean;
|
|
37
|
-
protected map_(): FormAbstract[];
|
|
37
|
+
protected map_(): FormAbstract<any>[];
|
|
38
38
|
get controls(): T;
|
|
39
39
|
set controls(controls: T);
|
|
40
40
|
set disabled(disabled: boolean);
|
|
@@ -42,12 +42,8 @@ declare class FormAbstractCollection<T extends FormControls> extends FormAbstrac
|
|
|
42
42
|
set hidden(hidden: boolean);
|
|
43
43
|
set submitted(submitted: boolean);
|
|
44
44
|
set touched(touched: boolean);
|
|
45
|
-
get value():
|
|
46
|
-
|
|
47
|
-
};
|
|
48
|
-
set value(value: {
|
|
49
|
-
[key: string]: FormValue;
|
|
50
|
-
});
|
|
45
|
+
get value(): U;
|
|
46
|
+
set value(value: U);
|
|
51
47
|
get errors(): {
|
|
52
48
|
[key: string]: any;
|
|
53
49
|
};
|
|
@@ -56,11 +52,11 @@ declare class FormAbstractCollection<T extends FormControls> extends FormAbstrac
|
|
|
56
52
|
});
|
|
57
53
|
}
|
|
58
54
|
|
|
59
|
-
declare class FormArray extends
|
|
60
|
-
constructor(controls?:
|
|
55
|
+
declare class FormArray<T extends FormValue[] = FormValue[]> extends FormAbstractCollection<T, FormArrayControls> {
|
|
56
|
+
constructor(controls?: FormArrayControls, validators?: FormValidator | FormValidator[], initialOptions?: FormOptions);
|
|
61
57
|
forEach_(callback: (control: FormAbstract, key: number) => any): void;
|
|
62
|
-
map_():
|
|
63
|
-
get value():
|
|
58
|
+
map_(): FormArrayControls;
|
|
59
|
+
get value(): T;
|
|
64
60
|
get length(): number;
|
|
65
61
|
protected init(control: FormAbstract, key: number): void;
|
|
66
62
|
set(control: FormAbstract, key: number): void;
|
|
@@ -69,25 +65,19 @@ declare class FormArray extends FormAbstractCollection<FormAbstract[]> {
|
|
|
69
65
|
insert(control: FormAbstract, key: number): void;
|
|
70
66
|
remove(control: FormAbstract): void;
|
|
71
67
|
removeKey(key: number): void;
|
|
72
|
-
at(key: number): FormAbstract
|
|
68
|
+
at(key: number): FormAbstract<any>;
|
|
73
69
|
}
|
|
74
|
-
declare function formArray(controls?:
|
|
70
|
+
declare function formArray(controls?: FormArrayControls, validators?: FormValidator | FormValidator[]): FormArray<any[]>;
|
|
75
71
|
|
|
76
72
|
declare class FormControl extends FormAbstract {
|
|
77
73
|
constructor(value?: FormValue, validators?: FormValidator | FormValidator[], initialOptions?: FormOptions);
|
|
78
74
|
}
|
|
79
75
|
declare function formControl(value?: FormValue, validators?: FormValidator | FormValidator[]): FormControl;
|
|
80
76
|
|
|
81
|
-
declare class FormGroup extends FormAbstractCollection<{
|
|
82
|
-
[
|
|
83
|
-
}> {
|
|
84
|
-
constructor(controls?: {
|
|
85
|
-
[key: string]: FormAbstract | any;
|
|
86
|
-
}, validators?: FormValidator | FormValidator[], initialOptions?: FormOptions);
|
|
77
|
+
declare class FormGroup<T extends Record<string, FormValue> = FormValue> extends FormAbstractCollection<T, FormGroupControls> {
|
|
78
|
+
constructor(controls?: FormGroupControls, validators?: FormValidator | FormValidator[], initialOptions?: FormOptions);
|
|
87
79
|
}
|
|
88
|
-
declare function formGroup(controls?:
|
|
89
|
-
[key: string]: FormAbstract | FormValue;
|
|
90
|
-
}, validators?: FormValidator | FormValidator[]): FormGroup;
|
|
80
|
+
declare function formGroup(controls?: FormGroupControls, validators?: FormValidator | FormValidator[]): FormGroup<any>;
|
|
91
81
|
|
|
92
82
|
type FormValue = any;
|
|
93
83
|
type FormValueGroup = {
|
|
@@ -121,10 +111,10 @@ type FormOptions = {
|
|
|
121
111
|
type ValidationError = {
|
|
122
112
|
[key: string]: any;
|
|
123
113
|
};
|
|
124
|
-
type
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
type FormCollection = FormAbstractCollection<FormControls>;
|
|
114
|
+
type FormGroupControls = Record<string, FormAbstract | FormValue>;
|
|
115
|
+
type FormArrayControls = FormAbstract[];
|
|
116
|
+
type FormControls = FormGroupControls | FormArrayControls;
|
|
117
|
+
type FormCollection = FormAbstractCollection<Record<string, any> | any[], FormControls>;
|
|
128
118
|
type FormActivator = boolean | ((value: FormValue, rootValue: FormValue, control?: FormAbstract, root?: FormCollection) => boolean | Promise<boolean>);
|
|
129
119
|
type FormValidator = (value: FormValue, rootValue: FormValue, control?: FormAbstract, root?: FormCollection) => null | ValidationError;
|
|
130
120
|
type FormAsyncValidator = (value: FormValue, rootValue: FormValue, control?: FormAbstract, root?: FormCollection) => Promise<null | ValidationError>;
|
|
@@ -144,9 +134,7 @@ type FormFlags = {
|
|
|
144
134
|
untouched: boolean;
|
|
145
135
|
unsubmitted: boolean;
|
|
146
136
|
};
|
|
147
|
-
type FormErrors =
|
|
148
|
-
[key: string]: any;
|
|
149
|
-
};
|
|
137
|
+
type FormErrors = Record<string, any>;
|
|
150
138
|
type FormValidationError = {
|
|
151
139
|
key: string;
|
|
152
140
|
value: FormValue;
|
|
@@ -176,18 +164,14 @@ type IFormBuilderControlSchema = {
|
|
|
176
164
|
children?: IFormBuilderSchema;
|
|
177
165
|
customData?: Record<string, any>;
|
|
178
166
|
};
|
|
179
|
-
type IFormBuilderGroupSchema =
|
|
180
|
-
[key: string]: IFormBuilderControlSchema;
|
|
181
|
-
};
|
|
167
|
+
type IFormBuilderGroupSchema = Record<string, IFormBuilderControlSchema>;
|
|
182
168
|
type IFormBuilderArraySchema = IFormBuilderControlSchema[];
|
|
183
|
-
type IFormBuilderGroupValues =
|
|
184
|
-
[key: string]: FormGroup | FormArray | FormControl;
|
|
185
|
-
};
|
|
169
|
+
type IFormBuilderGroupValues = Record<string, FormGroup | FormArray | FormControl>;
|
|
186
170
|
type IFormBuilderSchema = IFormBuilderGroupSchema | IFormBuilderArraySchema;
|
|
187
171
|
|
|
188
|
-
declare class FormAbstract extends EventEmitter {
|
|
172
|
+
declare class FormAbstract<T = any> extends EventEmitter {
|
|
189
173
|
errors_: ValidationError;
|
|
190
|
-
value_:
|
|
174
|
+
value_: T | null;
|
|
191
175
|
validators_: FormValidator[];
|
|
192
176
|
state_: FormFlags;
|
|
193
177
|
name?: string | number;
|
|
@@ -247,8 +231,8 @@ declare class FormAbstract extends EventEmitter {
|
|
|
247
231
|
get pristine(): boolean;
|
|
248
232
|
get untouched(): boolean;
|
|
249
233
|
get unsubmitted(): boolean;
|
|
250
|
-
get value():
|
|
251
|
-
set value(value:
|
|
234
|
+
get value(): T | null;
|
|
235
|
+
set value(value: T | null);
|
|
252
236
|
}
|
|
253
237
|
|
|
254
238
|
declare function validValue(value: FormValue): any;
|
|
@@ -317,6 +301,17 @@ declare function useControl<T>(control: FormAbstract): [FormState<T>, (value: T
|
|
|
317
301
|
|
|
318
302
|
declare function useForm<T, U extends (FormGroup | FormArray)>(factory: () => U, deps?: DependencyList): [FormState<T>, (value: any) => void, () => void, () => void, U];
|
|
319
303
|
|
|
320
|
-
|
|
304
|
+
/**
|
|
305
|
+
* @deprecated Since version 1.9.0. Will be deleted in version 1.10.0. Use useFormSchema instead.
|
|
306
|
+
*/
|
|
307
|
+
declare function useFormBuilder<T extends (Record<string, FormValue> | FormValue[]) = Record<string, FormValue>, U extends (T extends FormValue[] ? FormArray<T> : FormGroup<T>) = T extends FormValue[] ? FormArray<T> : FormGroup<T>>(schema: IFormBuilderSchema, deps?: DependencyList): [FormState<T>, (value: Partial<T>) => void, () => void, () => void, U];
|
|
308
|
+
|
|
309
|
+
declare function useFormSchema<T extends (Record<string, FormValue> | FormValue[]) = Record<string, FormValue>, U extends (T extends FormValue[] ? FormArray<T> : FormGroup<T>) = T extends FormValue[] ? FormArray<T> : FormGroup<T>>(schema: IFormBuilderSchema, deps?: DependencyList): {
|
|
310
|
+
state: FormState<T>;
|
|
311
|
+
setValue: (value: Partial<T>) => void;
|
|
312
|
+
setTouched: () => void;
|
|
313
|
+
reset: () => void;
|
|
314
|
+
form: U;
|
|
315
|
+
};
|
|
321
316
|
|
|
322
|
-
export { ControlType, EmailValidator, FormAbstract, FormAbstractCollection, FormActivator, FormArray, FormAsyncValidator, FormCollection, FormControl, FormControls, FormErrors, FormFlags, FormGroup, FormOptions, FormState, FormValidationError, FormValidationErrors, FormValidator, FormValue, FormValueArray, FormValueGroup, IControlParam, IFormBuilderArraySchema, IFormBuilderControlSchema, IFormBuilderGroupSchema, IFormBuilderGroupValues, IFormBuilderSchema, IFormOption, MatchValidator, MaxLengthValidator, MaxValidator, MinLengthValidator, MinValidator, NullValidator, PatternValidator, RequiredIfValidator, RequiredTrueValidator, RequiredValidator, ValidationError, formArray, formControl, formGroup, mapErrors_, stringToValue, useControl, useForm, useFormBuilder, validValue, valueToString };
|
|
317
|
+
export { ControlType, EmailValidator, FormAbstract, FormAbstractCollection, FormActivator, FormArray, FormArrayControls, FormAsyncValidator, FormCollection, FormControl, FormControls, FormErrors, FormFlags, FormGroup, FormGroupControls, FormOptions, FormState, FormValidationError, FormValidationErrors, FormValidator, FormValue, FormValueArray, FormValueGroup, IControlParam, IFormBuilderArraySchema, IFormBuilderControlSchema, IFormBuilderGroupSchema, IFormBuilderGroupValues, IFormBuilderSchema, IFormOption, MatchValidator, MaxLengthValidator, MaxValidator, MinLengthValidator, MinValidator, NullValidator, PatternValidator, RequiredIfValidator, RequiredTrueValidator, RequiredValidator, ValidationError, formArray, formControl, formGroup, mapErrors_, stringToValue, useControl, useForm, useFormBuilder, useFormSchema, validValue, valueToString };
|
package/dist/index.js
CHANGED
|
@@ -78,6 +78,7 @@ __export(src_exports, {
|
|
|
78
78
|
useControl: () => useControl,
|
|
79
79
|
useForm: () => useForm,
|
|
80
80
|
useFormBuilder: () => useFormBuilder,
|
|
81
|
+
useFormSchema: () => useFormSchema,
|
|
81
82
|
validValue: () => validValue,
|
|
82
83
|
valueToString: () => valueToString
|
|
83
84
|
});
|
|
@@ -1115,6 +1116,73 @@ function mapSchema_(schema) {
|
|
|
1115
1116
|
return mapControl_(schema);
|
|
1116
1117
|
}
|
|
1117
1118
|
}
|
|
1119
|
+
|
|
1120
|
+
// src/hooks/useFormSchema/useFormSchema.ts
|
|
1121
|
+
var import_react4 = require("react");
|
|
1122
|
+
function useFormSchema(schema, deps = []) {
|
|
1123
|
+
const form = (0, import_react4.useMemo)(() => {
|
|
1124
|
+
if (Array.isArray(schema)) {
|
|
1125
|
+
return mapArray_2(schema);
|
|
1126
|
+
} else {
|
|
1127
|
+
return mapGroup_2(schema);
|
|
1128
|
+
}
|
|
1129
|
+
}, deps);
|
|
1130
|
+
const setValue = (0, import_react4.useCallback)((value) => {
|
|
1131
|
+
form.patch(value);
|
|
1132
|
+
}, deps);
|
|
1133
|
+
const setTouched = (0, import_react4.useCallback)(() => {
|
|
1134
|
+
form.touched = true;
|
|
1135
|
+
}, deps);
|
|
1136
|
+
const reset = (0, import_react4.useCallback)(() => {
|
|
1137
|
+
form.reset();
|
|
1138
|
+
}, deps);
|
|
1139
|
+
const [state, setState] = (0, import_react4.useState)({
|
|
1140
|
+
value: form.value,
|
|
1141
|
+
flags: form.state,
|
|
1142
|
+
errors: mapErrors_(form.errors)
|
|
1143
|
+
});
|
|
1144
|
+
(0, import_react4.useEffect)(() => {
|
|
1145
|
+
const onChange = (value) => {
|
|
1146
|
+
const newState = { value, flags: form.state, errors: mapErrors_(form.errors) };
|
|
1147
|
+
};
|
|
1148
|
+
form.on("change", onChange);
|
|
1149
|
+
form.revalidate_();
|
|
1150
|
+
return () => form.off("change", onChange);
|
|
1151
|
+
}, deps);
|
|
1152
|
+
return {
|
|
1153
|
+
form,
|
|
1154
|
+
state,
|
|
1155
|
+
setTouched,
|
|
1156
|
+
setValue,
|
|
1157
|
+
reset
|
|
1158
|
+
};
|
|
1159
|
+
}
|
|
1160
|
+
function mapGroup_2(children, schema) {
|
|
1161
|
+
const controls = {};
|
|
1162
|
+
Object.keys(children).forEach((key) => {
|
|
1163
|
+
controls[key] = mapSchema_2(__spreadValues({ name: key }, children[key]));
|
|
1164
|
+
});
|
|
1165
|
+
const group = new FormGroup(controls, schema == null ? void 0 : schema.validators, schema);
|
|
1166
|
+
return group;
|
|
1167
|
+
}
|
|
1168
|
+
function mapArray_2(children, schema) {
|
|
1169
|
+
const controls = children.map((x) => mapSchema_2(x));
|
|
1170
|
+
const array = new FormArray(controls, schema == null ? void 0 : schema.validators, schema);
|
|
1171
|
+
return array;
|
|
1172
|
+
}
|
|
1173
|
+
function mapControl_2(schema) {
|
|
1174
|
+
return new FormControl(schema.value, schema.validators, schema);
|
|
1175
|
+
}
|
|
1176
|
+
function mapSchema_2(schema) {
|
|
1177
|
+
switch (schema.schema) {
|
|
1178
|
+
case "group":
|
|
1179
|
+
return mapGroup_2(schema.children || {}, schema);
|
|
1180
|
+
case "array":
|
|
1181
|
+
return mapArray_2(schema.children || [], schema);
|
|
1182
|
+
default:
|
|
1183
|
+
return mapControl_2(schema);
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1118
1186
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1119
1187
|
0 && (module.exports = {
|
|
1120
1188
|
EmailValidator,
|
|
@@ -1141,6 +1209,7 @@ function mapSchema_(schema) {
|
|
|
1141
1209
|
useControl,
|
|
1142
1210
|
useForm,
|
|
1143
1211
|
useFormBuilder,
|
|
1212
|
+
useFormSchema,
|
|
1144
1213
|
validValue,
|
|
1145
1214
|
valueToString
|
|
1146
1215
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1067,6 +1067,73 @@ function mapSchema_(schema) {
|
|
|
1067
1067
|
return mapControl_(schema);
|
|
1068
1068
|
}
|
|
1069
1069
|
}
|
|
1070
|
+
|
|
1071
|
+
// src/hooks/useFormSchema/useFormSchema.ts
|
|
1072
|
+
import { useCallback as useCallback4, useEffect as useEffect4, useMemo as useMemo3, useState as useState4 } from "react";
|
|
1073
|
+
function useFormSchema(schema, deps = []) {
|
|
1074
|
+
const form = useMemo3(() => {
|
|
1075
|
+
if (Array.isArray(schema)) {
|
|
1076
|
+
return mapArray_2(schema);
|
|
1077
|
+
} else {
|
|
1078
|
+
return mapGroup_2(schema);
|
|
1079
|
+
}
|
|
1080
|
+
}, deps);
|
|
1081
|
+
const setValue = useCallback4((value) => {
|
|
1082
|
+
form.patch(value);
|
|
1083
|
+
}, deps);
|
|
1084
|
+
const setTouched = useCallback4(() => {
|
|
1085
|
+
form.touched = true;
|
|
1086
|
+
}, deps);
|
|
1087
|
+
const reset = useCallback4(() => {
|
|
1088
|
+
form.reset();
|
|
1089
|
+
}, deps);
|
|
1090
|
+
const [state, setState] = useState4({
|
|
1091
|
+
value: form.value,
|
|
1092
|
+
flags: form.state,
|
|
1093
|
+
errors: mapErrors_(form.errors)
|
|
1094
|
+
});
|
|
1095
|
+
useEffect4(() => {
|
|
1096
|
+
const onChange = (value) => {
|
|
1097
|
+
const newState = { value, flags: form.state, errors: mapErrors_(form.errors) };
|
|
1098
|
+
};
|
|
1099
|
+
form.on("change", onChange);
|
|
1100
|
+
form.revalidate_();
|
|
1101
|
+
return () => form.off("change", onChange);
|
|
1102
|
+
}, deps);
|
|
1103
|
+
return {
|
|
1104
|
+
form,
|
|
1105
|
+
state,
|
|
1106
|
+
setTouched,
|
|
1107
|
+
setValue,
|
|
1108
|
+
reset
|
|
1109
|
+
};
|
|
1110
|
+
}
|
|
1111
|
+
function mapGroup_2(children, schema) {
|
|
1112
|
+
const controls = {};
|
|
1113
|
+
Object.keys(children).forEach((key) => {
|
|
1114
|
+
controls[key] = mapSchema_2(__spreadValues({ name: key }, children[key]));
|
|
1115
|
+
});
|
|
1116
|
+
const group = new FormGroup(controls, schema == null ? void 0 : schema.validators, schema);
|
|
1117
|
+
return group;
|
|
1118
|
+
}
|
|
1119
|
+
function mapArray_2(children, schema) {
|
|
1120
|
+
const controls = children.map((x) => mapSchema_2(x));
|
|
1121
|
+
const array = new FormArray(controls, schema == null ? void 0 : schema.validators, schema);
|
|
1122
|
+
return array;
|
|
1123
|
+
}
|
|
1124
|
+
function mapControl_2(schema) {
|
|
1125
|
+
return new FormControl(schema.value, schema.validators, schema);
|
|
1126
|
+
}
|
|
1127
|
+
function mapSchema_2(schema) {
|
|
1128
|
+
switch (schema.schema) {
|
|
1129
|
+
case "group":
|
|
1130
|
+
return mapGroup_2(schema.children || {}, schema);
|
|
1131
|
+
case "array":
|
|
1132
|
+
return mapArray_2(schema.children || [], schema);
|
|
1133
|
+
default:
|
|
1134
|
+
return mapControl_2(schema);
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1070
1137
|
export {
|
|
1071
1138
|
EmailValidator,
|
|
1072
1139
|
FormAbstract,
|
|
@@ -1092,6 +1159,7 @@ export {
|
|
|
1092
1159
|
useControl,
|
|
1093
1160
|
useForm,
|
|
1094
1161
|
useFormBuilder,
|
|
1162
|
+
useFormSchema,
|
|
1095
1163
|
validValue,
|
|
1096
1164
|
valueToString
|
|
1097
1165
|
};
|
package/package.json
CHANGED
|
@@ -3,7 +3,10 @@ import { FormAbstract } from './form-abstract';
|
|
|
3
3
|
import { FormControl } from './form-control';
|
|
4
4
|
import { FormActivator, FormCollection, FormControls, FormFlags, FormOptions, FormValidator, FormValue } from './types';
|
|
5
5
|
|
|
6
|
-
export class FormAbstractCollection<
|
|
6
|
+
export class FormAbstractCollection<
|
|
7
|
+
U extends Record<string, FormValue> | FormValue[],
|
|
8
|
+
T extends FormControls> extends FormAbstract<U
|
|
9
|
+
> {
|
|
7
10
|
|
|
8
11
|
controls_: T;
|
|
9
12
|
|
|
@@ -16,7 +19,7 @@ export class FormAbstractCollection<T extends FormControls> extends FormAbstract
|
|
|
16
19
|
});
|
|
17
20
|
}
|
|
18
21
|
|
|
19
|
-
initControl_(controlOrValue: FormAbstract |
|
|
22
|
+
initControl_(controlOrValue: FormAbstract | FormValue, key: any): FormAbstract {
|
|
20
23
|
const control = controlOrValue instanceof FormAbstract ? controlOrValue : new FormControl(controlOrValue);
|
|
21
24
|
control.name = key;
|
|
22
25
|
control.parent = this;
|
|
@@ -283,18 +286,18 @@ export class FormAbstractCollection<T extends FormControls> extends FormAbstract
|
|
|
283
286
|
});
|
|
284
287
|
}
|
|
285
288
|
|
|
286
|
-
get value():
|
|
287
|
-
return this.reduce_((result:
|
|
289
|
+
get value(): U {
|
|
290
|
+
return this.reduce_((result: U, control: FormAbstract, key: string) => {
|
|
288
291
|
if (control.enabled) {
|
|
289
|
-
result[key] = control.value;
|
|
292
|
+
result[key as keyof U] = control.value;
|
|
290
293
|
}
|
|
291
294
|
return result;
|
|
292
295
|
}, {});
|
|
293
296
|
}
|
|
294
297
|
|
|
295
|
-
set value(value:
|
|
298
|
+
set value(value: U) {
|
|
296
299
|
this.forEach_((control: FormAbstract, key: string) => {
|
|
297
|
-
control.value = value[key];
|
|
300
|
+
control.value = value[key as keyof U];
|
|
298
301
|
});
|
|
299
302
|
}
|
|
300
303
|
|
|
@@ -3,11 +3,11 @@ import { EventEmitter } from './event-emitter';
|
|
|
3
3
|
import { ControlType, FormActivator, FormCollection, FormFlags, FormOptions, FormValidator, FormValue, ValidationError } from './types';
|
|
4
4
|
import { validValue } from './utils';
|
|
5
5
|
|
|
6
|
-
export class FormAbstract extends EventEmitter {
|
|
6
|
+
export class FormAbstract<T = any> extends EventEmitter {
|
|
7
7
|
|
|
8
8
|
// callbacks_: Function[] = [];
|
|
9
9
|
errors_: ValidationError;
|
|
10
|
-
value_:
|
|
10
|
+
value_: T | null;
|
|
11
11
|
validators_: FormValidator[];
|
|
12
12
|
state_: FormFlags;
|
|
13
13
|
name?: string | number;
|
package/src/forms/form-array.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { FormAbstract } from './form-abstract';
|
|
2
2
|
import { FormAbstractCollection } from './form-abstract-collection';
|
|
3
|
-
import { FormOptions, FormValidator, FormValue } from './types';
|
|
3
|
+
import { FormArrayControls, FormOptions, FormValidator, FormValue } from './types';
|
|
4
4
|
|
|
5
|
-
export class FormArray extends
|
|
5
|
+
export class FormArray<T extends FormValue[] = FormValue[]> extends FormAbstractCollection<T, FormArrayControls> {
|
|
6
6
|
|
|
7
|
-
constructor(controls:
|
|
7
|
+
constructor(controls: FormArrayControls = [], validators?: FormValidator | FormValidator[], initialOptions?: FormOptions) {
|
|
8
8
|
super(controls, validators);
|
|
9
9
|
this.setInitialOptions(initialOptions);
|
|
10
10
|
// this.revalidate_();
|
|
@@ -18,8 +18,8 @@ export class FormArray extends FormAbstractCollection<FormAbstract[]> {
|
|
|
18
18
|
return this.controls;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
get value():
|
|
22
|
-
return this.reduce_((result:
|
|
21
|
+
get value(): T {
|
|
22
|
+
return this.reduce_((result: T, control: FormAbstract, key: number) => {
|
|
23
23
|
result[key] = control.value;
|
|
24
24
|
return result;
|
|
25
25
|
}, []); // init as array
|
|
@@ -73,6 +73,6 @@ export class FormArray extends FormAbstractCollection<FormAbstract[]> {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
export function formArray(controls:
|
|
76
|
+
export function formArray(controls: FormArrayControls = [], validators?: FormValidator | FormValidator[]) {
|
|
77
77
|
return new FormArray(controls, validators);
|
|
78
78
|
}
|
package/src/forms/form-group.ts
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { FormAbstract } from './form-abstract';
|
|
2
1
|
import { FormAbstractCollection } from './form-abstract-collection';
|
|
3
|
-
import { FormOptions, FormValidator, FormValue } from './types';
|
|
2
|
+
import { FormGroupControls, FormOptions, FormValidator, FormValue } from './types';
|
|
4
3
|
|
|
5
|
-
export class FormGroup extends
|
|
6
|
-
constructor(controls:
|
|
4
|
+
export class FormGroup<T extends Record<string, FormValue> = FormValue> extends FormAbstractCollection<T, FormGroupControls> {
|
|
5
|
+
constructor(controls: FormGroupControls = {}, validators?: FormValidator | FormValidator[], initialOptions?: FormOptions) {
|
|
7
6
|
super(controls, validators);
|
|
8
7
|
this.setInitialOptions(initialOptions);
|
|
9
8
|
// this.revalidate_();
|
|
10
9
|
}
|
|
11
10
|
}
|
|
12
11
|
|
|
13
|
-
export function formGroup(controls:
|
|
12
|
+
export function formGroup(controls: FormGroupControls = {}, validators?: FormValidator | FormValidator[]) {
|
|
14
13
|
return new FormGroup(controls, validators);
|
|
15
14
|
}
|
package/src/forms/types.ts
CHANGED
|
@@ -34,8 +34,10 @@ export type ValidationError = {
|
|
|
34
34
|
[key: string]: any
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
export type
|
|
38
|
-
export type
|
|
37
|
+
export type FormGroupControls = Record<string, FormAbstract | FormValue>;
|
|
38
|
+
export type FormArrayControls = FormAbstract[];
|
|
39
|
+
export type FormControls = FormGroupControls | FormArrayControls;
|
|
40
|
+
export type FormCollection = FormAbstractCollection<Record<string, any> | any[], FormControls>;
|
|
39
41
|
export type FormActivator = boolean | ((value: FormValue, rootValue: FormValue, control?: FormAbstract, root?: FormCollection) => boolean | Promise<boolean>);
|
|
40
42
|
export type FormValidator = (value: FormValue, rootValue: FormValue, control?: FormAbstract, root?: FormCollection) => null | ValidationError;
|
|
41
43
|
export type FormAsyncValidator = (value: FormValue, rootValue: FormValue, control?: FormAbstract, root?: FormCollection) => Promise<null | ValidationError>;
|
|
@@ -57,7 +59,7 @@ export type FormFlags = {
|
|
|
57
59
|
unsubmitted: boolean;
|
|
58
60
|
};
|
|
59
61
|
// export type FormFlags = { [key: string]: boolean };
|
|
60
|
-
export type FormErrors =
|
|
62
|
+
export type FormErrors = Record<string, any>;
|
|
61
63
|
export type FormValidationError = { key: string, value: FormValue };
|
|
62
64
|
export type FormValidationErrors = FormValidationError[];
|
|
63
65
|
|
|
@@ -86,7 +88,7 @@ export type IFormBuilderControlSchema = {
|
|
|
86
88
|
customData?: Record<string, any>;
|
|
87
89
|
};
|
|
88
90
|
|
|
89
|
-
export type IFormBuilderGroupSchema =
|
|
91
|
+
export type IFormBuilderGroupSchema = Record<string, IFormBuilderControlSchema>;
|
|
90
92
|
export type IFormBuilderArraySchema = IFormBuilderControlSchema[];
|
|
91
|
-
export type IFormBuilderGroupValues =
|
|
93
|
+
export type IFormBuilderGroupValues = Record<string, FormGroup | FormArray | FormControl>;
|
|
92
94
|
export type IFormBuilderSchema = IFormBuilderGroupSchema | IFormBuilderArraySchema;
|
package/src/hooks/index.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { DependencyList, useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import { FormArray, FormControl, FormGroup, FormState, mapErrors_ } from '../../forms';
|
|
3
|
-
import { IFormBuilderArraySchema, IFormBuilderControlSchema, IFormBuilderGroupSchema, IFormBuilderGroupValues, IFormBuilderSchema } from '../../forms/types';
|
|
3
|
+
import { FormValue, IFormBuilderArraySchema, IFormBuilderControlSchema, IFormBuilderGroupSchema, IFormBuilderGroupValues, IFormBuilderSchema } from '../../forms/types';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated Since version 1.9.0. Will be deleted in version 1.10.0. Use useFormSchema instead.
|
|
7
|
+
*/
|
|
8
|
+
export function useFormBuilder<
|
|
9
|
+
T extends (Record<string, FormValue> | FormValue[]) = Record<string, FormValue>,
|
|
10
|
+
U extends (T extends FormValue[] ? FormArray<T> : FormGroup<T>) = T extends FormValue[] ? FormArray<T> : FormGroup<T>
|
|
11
|
+
>(
|
|
6
12
|
schema: IFormBuilderSchema,
|
|
7
13
|
deps: DependencyList = []
|
|
8
14
|
): [FormState<T>, (value: Partial<T>) => void, () => void, () => void, U] {
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { DependencyList, useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
|
+
import { FormArray, FormControl, FormGroup, FormState, mapErrors_ } from '../../forms';
|
|
3
|
+
import { FormValue, IFormBuilderArraySchema, IFormBuilderControlSchema, IFormBuilderGroupSchema, IFormBuilderGroupValues, IFormBuilderSchema } from '../../forms/types';
|
|
4
|
+
|
|
5
|
+
export function useFormSchema<
|
|
6
|
+
T extends (Record<string, FormValue> | FormValue[]) = Record<string, FormValue>,
|
|
7
|
+
U extends (T extends FormValue[] ? FormArray<T> : FormGroup<T>) = T extends FormValue[] ? FormArray<T> : FormGroup<T>
|
|
8
|
+
>(
|
|
9
|
+
schema: IFormBuilderSchema,
|
|
10
|
+
deps: DependencyList = []
|
|
11
|
+
): {
|
|
12
|
+
state: FormState<T>,
|
|
13
|
+
setValue: (value: Partial<T>) => void,
|
|
14
|
+
setTouched: () => void,
|
|
15
|
+
reset: () => void,
|
|
16
|
+
form: U,
|
|
17
|
+
} {
|
|
18
|
+
const form: U = useMemo<U>(() => {
|
|
19
|
+
// console.log(' useFormSchema.rebuild', schema);
|
|
20
|
+
if (Array.isArray(schema)) {
|
|
21
|
+
return mapArray_(schema) as U;
|
|
22
|
+
} else {
|
|
23
|
+
return mapGroup_(schema) as U;
|
|
24
|
+
}
|
|
25
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
26
|
+
}, deps);
|
|
27
|
+
|
|
28
|
+
const setValue = useCallback((value: Partial<T>) => {
|
|
29
|
+
form.patch(value);
|
|
30
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
31
|
+
}, deps);
|
|
32
|
+
|
|
33
|
+
const setTouched = useCallback(() => {
|
|
34
|
+
form.touched = true;
|
|
35
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
36
|
+
}, deps);
|
|
37
|
+
|
|
38
|
+
const reset = useCallback(() => {
|
|
39
|
+
form.reset();
|
|
40
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
41
|
+
}, deps);
|
|
42
|
+
|
|
43
|
+
const [state, setState] = useState<FormState<T>>({
|
|
44
|
+
value: form.value as T,
|
|
45
|
+
flags: form.state,
|
|
46
|
+
errors: mapErrors_(form.errors),
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
const onChange = (value: T) => {
|
|
51
|
+
// console.log(' useFormSchema.onChange', value);
|
|
52
|
+
const newState = { value, flags: form.state, errors: mapErrors_(form.errors) };
|
|
53
|
+
// setState(newState);
|
|
54
|
+
};
|
|
55
|
+
form.on('change', onChange);
|
|
56
|
+
// form.validateAndChange_();
|
|
57
|
+
form.revalidate_();
|
|
58
|
+
// const value = form.value;
|
|
59
|
+
// form.reset();
|
|
60
|
+
// form.patch(value);
|
|
61
|
+
// console.log('subscribe');
|
|
62
|
+
return () => form.off('change', onChange);
|
|
63
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
64
|
+
}, deps);
|
|
65
|
+
|
|
66
|
+
// console.log(' useFormSchema', form.value);
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
form,
|
|
70
|
+
state,
|
|
71
|
+
setTouched,
|
|
72
|
+
setValue,
|
|
73
|
+
reset,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function mapGroup_(children: IFormBuilderGroupSchema, schema?: IFormBuilderControlSchema): FormGroup {
|
|
78
|
+
const controls: IFormBuilderGroupValues = {};
|
|
79
|
+
Object.keys(children).forEach(key => {
|
|
80
|
+
controls[key] = mapSchema_({ name: key, ...children[key] });
|
|
81
|
+
});
|
|
82
|
+
const group = new FormGroup(controls, schema?.validators, schema);
|
|
83
|
+
return group;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function mapArray_(children: IFormBuilderControlSchema[], schema?: IFormBuilderControlSchema): FormArray {
|
|
87
|
+
const controls = children.map(x => mapSchema_(x));
|
|
88
|
+
const array = new FormArray(controls, schema?.validators, schema);
|
|
89
|
+
return array;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function mapControl_(schema: IFormBuilderControlSchema): FormControl {
|
|
93
|
+
return new FormControl(schema.value, schema.validators, schema);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function mapSchema_(schema: IFormBuilderControlSchema): FormGroup | FormArray | FormControl {
|
|
97
|
+
switch (schema.schema) {
|
|
98
|
+
case 'group':
|
|
99
|
+
return mapGroup_(schema.children as IFormBuilderGroupSchema || {}, schema);
|
|
100
|
+
case 'array':
|
|
101
|
+
return mapArray_(schema.children as IFormBuilderArraySchema || [], schema);
|
|
102
|
+
default:
|
|
103
|
+
return mapControl_(schema);
|
|
104
|
+
}
|
|
105
|
+
}
|