solid-hook-form 2.0.1 → 2.2.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/dist/main.d.ts +23 -10
- package/dist/main.js +197 -168
- package/dist/main.jsx +206 -177
- package/package.json +4 -2
package/dist/main.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as solid_js from 'solid-js';
|
|
2
|
-
import { Accessor, JSXElement, ParentProps } from 'solid-js';
|
|
3
1
|
import { FieldPath, FieldPathValue, Path, LiteralUnion, Resolver } from 'react-hook-form';
|
|
4
2
|
export { Path } from 'react-hook-form';
|
|
3
|
+
import * as solid_js from 'solid-js';
|
|
4
|
+
import { Accessor, JSXElement, ParentProps } from 'solid-js';
|
|
5
5
|
|
|
6
6
|
type ValidateResult = Message | boolean | undefined;
|
|
7
7
|
type Validate<V, F> = (value: V, formValues: F) => ValidateResult | Promise<ValidateResult>;
|
|
@@ -65,24 +65,36 @@ type ControllerProps<F extends FormValues> = {
|
|
|
65
65
|
render(arg: UseControllerReturn<F>): JSXElement;
|
|
66
66
|
};
|
|
67
67
|
|
|
68
|
-
type TouchedFields<F extends FormValues = FormValues> = Partial<Record<Path<F>, boolean>>;
|
|
69
|
-
|
|
70
68
|
type DirtyFields<F extends FormValues = FormValues> = Partial<Record<Path<F>, boolean>>;
|
|
71
69
|
|
|
70
|
+
type ResetOptions = {
|
|
71
|
+
keepErrors?: boolean;
|
|
72
|
+
keepValues?: boolean;
|
|
73
|
+
keepTouched?: boolean;
|
|
74
|
+
keepDirty?: boolean;
|
|
75
|
+
};
|
|
76
|
+
type Reset<F extends FormValues> = (values?: Partial<F>, options?: ResetOptions) => void;
|
|
77
|
+
|
|
78
|
+
type TouchedFields<F extends FormValues = FormValues> = Partial<Record<Path<F>, boolean>>;
|
|
79
|
+
|
|
72
80
|
type FormValues = Record<string, any>;
|
|
73
81
|
type GetValues<F extends FormValues> = {
|
|
74
82
|
(): F;
|
|
75
83
|
<N extends FieldPath<F>>(name: N): FieldPathValue<F, N>;
|
|
76
84
|
};
|
|
77
|
-
type
|
|
85
|
+
type SetValueOptions = {
|
|
86
|
+
shouldValidate?: boolean;
|
|
87
|
+
shouldDirty?: boolean;
|
|
88
|
+
shouldTouch?: boolean;
|
|
89
|
+
};
|
|
90
|
+
type SetValue<F extends FormValues> = (name: Path<F>, value: FieldPathValue<F, Path<F>>, options?: SetValueOptions) => void;
|
|
91
|
+
type TriggerOptions = {
|
|
92
|
+
shouldFocus?: boolean;
|
|
93
|
+
};
|
|
94
|
+
type Trigger<F extends FormValues> = (name?: Path<F> | Path<F>[], options?: TriggerOptions) => void;
|
|
78
95
|
type SubmitHandler<F extends FormValues> = (values: F) => void;
|
|
79
96
|
type SubmitErrorHandler<F extends FormValues> = (errors: FieldErrors<F>) => void;
|
|
80
97
|
type HandleSubmit<F extends FormValues> = (onSubmit: SubmitHandler<F>, onError?: SubmitErrorHandler<F>) => (event: SubmitEvent) => void;
|
|
81
|
-
type ResetOptions = {
|
|
82
|
-
keepTouched?: boolean;
|
|
83
|
-
keepDirty?: boolean;
|
|
84
|
-
};
|
|
85
|
-
type Reset<F extends FormValues> = (newDefaultValues?: Partial<F>, options?: ResetOptions) => void;
|
|
86
98
|
type CreateFormArg<F extends FormValues> = {
|
|
87
99
|
defaultValues: F;
|
|
88
100
|
mode?: "onChange" | "onSubmit" | "onBlur";
|
|
@@ -104,6 +116,7 @@ type CreateFormReturn<F extends FormValues = FormValues> = {
|
|
|
104
116
|
setValue: SetValue<F>;
|
|
105
117
|
handleSubmit: HandleSubmit<F>;
|
|
106
118
|
reset: Reset<F>;
|
|
119
|
+
trigger: Trigger<F>;
|
|
107
120
|
};
|
|
108
121
|
type CreateForm = <F extends FormValues>(arg: CreateFormArg<F>) => CreateFormReturn<F>;
|
|
109
122
|
|
package/dist/main.js
CHANGED
|
@@ -4,6 +4,174 @@ import { memo, createComponent } from 'solid-js/web';
|
|
|
4
4
|
|
|
5
5
|
// src/create_form.ts
|
|
6
6
|
|
|
7
|
+
// src/utils/get.ts
|
|
8
|
+
var isDateObject = (value) => value instanceof Date;
|
|
9
|
+
var isNullOrUndefined = (value) => value == null;
|
|
10
|
+
var isObjectType = (value) => typeof value === "object";
|
|
11
|
+
var isObject = (value) => !isNullOrUndefined(value) && !Array.isArray(value) && isObjectType(value) && !isDateObject(value);
|
|
12
|
+
var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
|
|
13
|
+
var isUndefined = (value) => value === void 0;
|
|
14
|
+
var get = (object, path, defaultValue) => {
|
|
15
|
+
if (!path || !isObject(object)) {
|
|
16
|
+
return defaultValue;
|
|
17
|
+
}
|
|
18
|
+
const result = compact(path.split(/[,[\].]+?/)).reduce(
|
|
19
|
+
(result2, key) => isNullOrUndefined(result2) ? result2 : result2[key],
|
|
20
|
+
object
|
|
21
|
+
);
|
|
22
|
+
return isUndefined(result) || result === object ? isUndefined(object[path]) ? defaultValue : object[path] : result;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// src/utils/set.ts
|
|
26
|
+
var isKey = (value) => /^\w*$/.test(value);
|
|
27
|
+
var stringToPath = (input) => compact(input.replace(/["|']|\]/g, "").split(/\.|\[/));
|
|
28
|
+
var set = (object, path, value) => {
|
|
29
|
+
let index = -1;
|
|
30
|
+
const tempPath = isKey(path) ? [path] : stringToPath(path);
|
|
31
|
+
const length = tempPath.length;
|
|
32
|
+
const lastIndex = length - 1;
|
|
33
|
+
while (++index < length) {
|
|
34
|
+
const key = tempPath[index];
|
|
35
|
+
let newValue = value;
|
|
36
|
+
if (index !== lastIndex) {
|
|
37
|
+
const objValue = object[key];
|
|
38
|
+
newValue = isObject(objValue) || Array.isArray(objValue) ? objValue : !Number.isNaN(+tempPath[index + 1]) ? [] : {};
|
|
39
|
+
}
|
|
40
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
object[key] = newValue;
|
|
44
|
+
object = object[key];
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// src/logic/create_dirty_fields.ts
|
|
49
|
+
var isSomeFieldDirty = (value) => {
|
|
50
|
+
return Object.values(value).some((value2) => {
|
|
51
|
+
if (typeof value2 === "object") {
|
|
52
|
+
return isSomeFieldDirty(value2);
|
|
53
|
+
}
|
|
54
|
+
return value2;
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
var createDirtyFields = (defaultValues) => {
|
|
58
|
+
const [dirtyFields, setDirtyFields] = createSignal({});
|
|
59
|
+
const isDirty = createMemo(() => {
|
|
60
|
+
return isSomeFieldDirty(dirtyFields());
|
|
61
|
+
});
|
|
62
|
+
const checkDirty = (name, value) => {
|
|
63
|
+
const defaultValue = get(defaultValues, name);
|
|
64
|
+
const isDirty2 = value !== defaultValue;
|
|
65
|
+
setDirtyFields((prev) => {
|
|
66
|
+
const newState = { ...prev };
|
|
67
|
+
set(newState, name, isDirty2);
|
|
68
|
+
return newState;
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
const resetDirty = (keepDirty) => {
|
|
72
|
+
if (keepDirty) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
setDirtyFields({});
|
|
76
|
+
};
|
|
77
|
+
return { dirtyFields, isDirty, checkDirty, resetDirty };
|
|
78
|
+
};
|
|
79
|
+
var createErrors = () => {
|
|
80
|
+
const [errors, setErrors] = createStore({});
|
|
81
|
+
const getError = (name) => {
|
|
82
|
+
return errors[name];
|
|
83
|
+
};
|
|
84
|
+
const appendError = (name, error) => {
|
|
85
|
+
setErrors(
|
|
86
|
+
produce((prevState) => {
|
|
87
|
+
prevState[name] = error;
|
|
88
|
+
})
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
const removeError = (name) => {
|
|
92
|
+
setErrors(
|
|
93
|
+
produce((prevState) => {
|
|
94
|
+
delete prevState[name];
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
};
|
|
98
|
+
const resetErrors = (keepErrors) => {
|
|
99
|
+
if (keepErrors) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
setErrors(reconcile({}));
|
|
103
|
+
};
|
|
104
|
+
return {
|
|
105
|
+
errors,
|
|
106
|
+
appendError,
|
|
107
|
+
removeError,
|
|
108
|
+
resetErrors,
|
|
109
|
+
getError
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// src/logic/create_fields.ts
|
|
114
|
+
var createFields = () => {
|
|
115
|
+
const fields = {};
|
|
116
|
+
const getField = (name) => {
|
|
117
|
+
return fields[name];
|
|
118
|
+
};
|
|
119
|
+
const setField = (name, element) => {
|
|
120
|
+
fields[name] = element;
|
|
121
|
+
};
|
|
122
|
+
return {
|
|
123
|
+
fields,
|
|
124
|
+
getField,
|
|
125
|
+
setField
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// src/logic/create_rules.ts
|
|
130
|
+
var createRules = () => {
|
|
131
|
+
const rules = {};
|
|
132
|
+
const addRule = (name, options) => {
|
|
133
|
+
rules[name] = {
|
|
134
|
+
required: options.required,
|
|
135
|
+
min: options.min,
|
|
136
|
+
max: options.max,
|
|
137
|
+
minLength: options.minLength,
|
|
138
|
+
maxLength: options.maxLength,
|
|
139
|
+
pattern: options.pattern,
|
|
140
|
+
valueAsNumber: options.valueAsNumber,
|
|
141
|
+
validate: options.validate
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
const getRule = (name) => {
|
|
145
|
+
return rules[name];
|
|
146
|
+
};
|
|
147
|
+
return { rules, addRule, getRule };
|
|
148
|
+
};
|
|
149
|
+
var createTouchedFields = () => {
|
|
150
|
+
const [touchedFields, setTouchedFields] = createSignal({});
|
|
151
|
+
const addTouched = (name) => {
|
|
152
|
+
setTouchedFields((prev) => {
|
|
153
|
+
const newState = { ...prev };
|
|
154
|
+
set(newState, name, true);
|
|
155
|
+
return newState;
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
const resetTouched = (keepTouched) => {
|
|
159
|
+
if (keepTouched) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
setTouchedFields({});
|
|
163
|
+
};
|
|
164
|
+
return { touchedFields, addTouched, resetTouched };
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// src/logic/format_value.ts
|
|
168
|
+
var formatValue = (value, rules) => {
|
|
169
|
+
if (rules.valueAsNumber) {
|
|
170
|
+
return Number(value);
|
|
171
|
+
}
|
|
172
|
+
return value;
|
|
173
|
+
};
|
|
174
|
+
|
|
7
175
|
// src/logic/get_value.ts
|
|
8
176
|
var getFieldValue = (event) => {
|
|
9
177
|
const isEvent = event instanceof Event;
|
|
@@ -45,24 +213,6 @@ var setFieldValue = (field, value) => {
|
|
|
45
213
|
field.value = value;
|
|
46
214
|
};
|
|
47
215
|
|
|
48
|
-
// src/utils/get.ts
|
|
49
|
-
var isDateObject = (value) => value instanceof Date;
|
|
50
|
-
var isNullOrUndefined = (value) => value == null;
|
|
51
|
-
var isObjectType = (value) => typeof value === "object";
|
|
52
|
-
var isObject = (value) => !isNullOrUndefined(value) && !Array.isArray(value) && isObjectType(value) && !isDateObject(value);
|
|
53
|
-
var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
|
|
54
|
-
var isUndefined = (val) => val === void 0;
|
|
55
|
-
var get = (object, path, defaultValue) => {
|
|
56
|
-
if (!path || !isObject(object)) {
|
|
57
|
-
return defaultValue;
|
|
58
|
-
}
|
|
59
|
-
const result = compact(path.split(/[,[\].]+?/)).reduce(
|
|
60
|
-
(result2, key) => isNullOrUndefined(result2) ? result2 : result2[key],
|
|
61
|
-
object
|
|
62
|
-
);
|
|
63
|
-
return isUndefined(result) || result === object ? isUndefined(object[path]) ? defaultValue : object[path] : result;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
216
|
// src/logic/validate.ts
|
|
67
217
|
var getRuleValue = (rule) => {
|
|
68
218
|
if (rule instanceof RegExp) {
|
|
@@ -112,104 +262,6 @@ var validate = (values, name, rules = {}) => {
|
|
|
112
262
|
}
|
|
113
263
|
}
|
|
114
264
|
};
|
|
115
|
-
var createErrors = () => {
|
|
116
|
-
const [errors, setErrors] = createStore({});
|
|
117
|
-
const getError = (name) => {
|
|
118
|
-
return errors[name];
|
|
119
|
-
};
|
|
120
|
-
const appendError = (name, error) => {
|
|
121
|
-
setErrors(
|
|
122
|
-
produce((prevState) => {
|
|
123
|
-
prevState[name] = error;
|
|
124
|
-
})
|
|
125
|
-
);
|
|
126
|
-
};
|
|
127
|
-
const removeError = (name) => {
|
|
128
|
-
setErrors(
|
|
129
|
-
produce((prevState) => {
|
|
130
|
-
delete prevState[name];
|
|
131
|
-
})
|
|
132
|
-
);
|
|
133
|
-
};
|
|
134
|
-
const resetErrors = () => {
|
|
135
|
-
setErrors(reconcile({}));
|
|
136
|
-
};
|
|
137
|
-
return {
|
|
138
|
-
errors,
|
|
139
|
-
appendError,
|
|
140
|
-
removeError,
|
|
141
|
-
resetErrors,
|
|
142
|
-
getError
|
|
143
|
-
};
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
// src/utils/set.ts
|
|
147
|
-
var isKey = (value) => /^\w*$/.test(value);
|
|
148
|
-
var stringToPath = (input) => compact(input.replace(/["|']|\]/g, "").split(/\.|\[/));
|
|
149
|
-
var set = (object, path, value) => {
|
|
150
|
-
let index = -1;
|
|
151
|
-
const tempPath = isKey(path) ? [path] : stringToPath(path);
|
|
152
|
-
const length = tempPath.length;
|
|
153
|
-
const lastIndex = length - 1;
|
|
154
|
-
while (++index < length) {
|
|
155
|
-
const key = tempPath[index];
|
|
156
|
-
let newValue = value;
|
|
157
|
-
if (index !== lastIndex) {
|
|
158
|
-
const objValue = object[key];
|
|
159
|
-
newValue = isObject(objValue) || Array.isArray(objValue) ? objValue : !isNaN(+tempPath[index + 1]) ? [] : {};
|
|
160
|
-
}
|
|
161
|
-
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
object[key] = newValue;
|
|
165
|
-
object = object[key];
|
|
166
|
-
}
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
// src/logic/create_rules.ts
|
|
170
|
-
var createRules = () => {
|
|
171
|
-
const rules = {};
|
|
172
|
-
const addRule = (name, options) => {
|
|
173
|
-
rules[name] = {
|
|
174
|
-
required: options.required,
|
|
175
|
-
min: options.min,
|
|
176
|
-
max: options.max,
|
|
177
|
-
minLength: options.minLength,
|
|
178
|
-
maxLength: options.maxLength,
|
|
179
|
-
pattern: options.pattern,
|
|
180
|
-
valueAsNumber: options.valueAsNumber,
|
|
181
|
-
validate: options.validate
|
|
182
|
-
};
|
|
183
|
-
};
|
|
184
|
-
const getRule = (name) => {
|
|
185
|
-
return rules[name];
|
|
186
|
-
};
|
|
187
|
-
return { rules, addRule, getRule };
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
// src/logic/create_fields.ts
|
|
191
|
-
var createFields = () => {
|
|
192
|
-
const fields = {};
|
|
193
|
-
const getField = (name) => {
|
|
194
|
-
return fields[name];
|
|
195
|
-
};
|
|
196
|
-
const setField = (name, element) => {
|
|
197
|
-
fields[name] = element;
|
|
198
|
-
};
|
|
199
|
-
return {
|
|
200
|
-
fields,
|
|
201
|
-
getField,
|
|
202
|
-
setField
|
|
203
|
-
};
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
// src/logic/format_value.ts
|
|
207
|
-
var formatValue = (value, rules) => {
|
|
208
|
-
if (rules.valueAsNumber) {
|
|
209
|
-
return Number(value);
|
|
210
|
-
}
|
|
211
|
-
return value;
|
|
212
|
-
};
|
|
213
265
|
|
|
214
266
|
// src/utils/resolver.ts
|
|
215
267
|
var getResolverFields = (fields) => {
|
|
@@ -221,53 +273,6 @@ var getResolverFields = (fields) => {
|
|
|
221
273
|
return acc;
|
|
222
274
|
}, {});
|
|
223
275
|
};
|
|
224
|
-
var createTouchedFields = () => {
|
|
225
|
-
const [touchedFields, setTouchedFields] = createSignal({});
|
|
226
|
-
const addTouched = (name) => {
|
|
227
|
-
setTouchedFields((prev) => {
|
|
228
|
-
const newState = { ...prev };
|
|
229
|
-
set(newState, name, true);
|
|
230
|
-
return newState;
|
|
231
|
-
});
|
|
232
|
-
};
|
|
233
|
-
const resetTouched = (keepTouched) => {
|
|
234
|
-
if (keepTouched) {
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
setTouchedFields({});
|
|
238
|
-
};
|
|
239
|
-
return { touchedFields, addTouched, resetTouched };
|
|
240
|
-
};
|
|
241
|
-
var isSomeFieldDirty = (value) => {
|
|
242
|
-
return Object.values(value).some((value2) => {
|
|
243
|
-
if (typeof value2 === "object") {
|
|
244
|
-
return isSomeFieldDirty(value2);
|
|
245
|
-
}
|
|
246
|
-
return value2;
|
|
247
|
-
});
|
|
248
|
-
};
|
|
249
|
-
var createDirtyFields = (defaultValues) => {
|
|
250
|
-
const [dirtyFields, setDirtyFields] = createSignal({});
|
|
251
|
-
const isDirty = createMemo(() => {
|
|
252
|
-
return isSomeFieldDirty(dirtyFields());
|
|
253
|
-
});
|
|
254
|
-
const checkDirty = (name, value) => {
|
|
255
|
-
const defaultValue = get(defaultValues, name);
|
|
256
|
-
const isDirty2 = value !== defaultValue;
|
|
257
|
-
setDirtyFields((prev) => {
|
|
258
|
-
const newState = { ...prev };
|
|
259
|
-
set(newState, name, isDirty2);
|
|
260
|
-
return newState;
|
|
261
|
-
});
|
|
262
|
-
};
|
|
263
|
-
const resetDirty = (keepDirty) => {
|
|
264
|
-
if (keepDirty) {
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
267
|
-
setDirtyFields({});
|
|
268
|
-
};
|
|
269
|
-
return { dirtyFields, isDirty, checkDirty, resetDirty };
|
|
270
|
-
};
|
|
271
276
|
|
|
272
277
|
// src/create_form.ts
|
|
273
278
|
var createForm = (arg) => {
|
|
@@ -392,7 +397,7 @@ var createForm = (arg) => {
|
|
|
392
397
|
}
|
|
393
398
|
return values();
|
|
394
399
|
};
|
|
395
|
-
const setValue = (name, value) => {
|
|
400
|
+
const setValue = (name, value, options = {}) => {
|
|
396
401
|
setValues((prev) => {
|
|
397
402
|
const newValues = { ...prev };
|
|
398
403
|
set(newValues, name, value);
|
|
@@ -400,6 +405,15 @@ var createForm = (arg) => {
|
|
|
400
405
|
});
|
|
401
406
|
const field = getField(name);
|
|
402
407
|
setFieldValue(field, value);
|
|
408
|
+
if (options.shouldValidate) {
|
|
409
|
+
validateField(name);
|
|
410
|
+
}
|
|
411
|
+
if (options.shouldDirty) {
|
|
412
|
+
checkDirty(name, value);
|
|
413
|
+
}
|
|
414
|
+
if (options.shouldTouch) {
|
|
415
|
+
addTouched(name);
|
|
416
|
+
}
|
|
403
417
|
};
|
|
404
418
|
const handleSubmit = (onSubmit, onError) => {
|
|
405
419
|
return async (event) => {
|
|
@@ -414,15 +428,29 @@ var createForm = (arg) => {
|
|
|
414
428
|
};
|
|
415
429
|
};
|
|
416
430
|
const reset = (values2, options = {}) => {
|
|
417
|
-
|
|
418
|
-
setValues(() => newValues);
|
|
419
|
-
resetErrors();
|
|
431
|
+
resetErrors(options.keepErrors);
|
|
420
432
|
resetTouched(options.keepTouched);
|
|
421
433
|
resetDirty(options.keepDirty);
|
|
434
|
+
if (options.keepValues) {
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
const newValues = values2 ? values2 : structuredClone(defaultValues);
|
|
438
|
+
setValues(() => newValues);
|
|
422
439
|
Object.entries(fields).forEach(([name, field]) => {
|
|
423
440
|
setFieldValue(field, get(newValues, name));
|
|
424
441
|
});
|
|
425
442
|
};
|
|
443
|
+
const trigger = async (name) => {
|
|
444
|
+
if (!name) {
|
|
445
|
+
await validateAllFields();
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
if (typeof name === "string") {
|
|
449
|
+
validateField(name);
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
name.forEach(validateField);
|
|
453
|
+
};
|
|
426
454
|
return {
|
|
427
455
|
control,
|
|
428
456
|
formState: {
|
|
@@ -438,7 +466,8 @@ var createForm = (arg) => {
|
|
|
438
466
|
getValues,
|
|
439
467
|
setValue,
|
|
440
468
|
handleSubmit,
|
|
441
|
-
reset
|
|
469
|
+
reset,
|
|
470
|
+
trigger
|
|
442
471
|
};
|
|
443
472
|
};
|
|
444
473
|
var FormContext = createContext();
|
package/dist/main.jsx
CHANGED
|
@@ -1,6 +1,183 @@
|
|
|
1
1
|
// src/create_form.ts
|
|
2
2
|
import { createMemo as createMemo2, createSignal as createSignal3 } from "solid-js";
|
|
3
3
|
|
|
4
|
+
// src/logic/create_dirty_fields.ts
|
|
5
|
+
import { createMemo, createSignal } from "solid-js";
|
|
6
|
+
|
|
7
|
+
// src/utils/get.ts
|
|
8
|
+
var isDateObject = (value) => value instanceof Date;
|
|
9
|
+
var isNullOrUndefined = (value) => value == null;
|
|
10
|
+
var isObjectType = (value) => typeof value === "object";
|
|
11
|
+
var isObject = (value) => !isNullOrUndefined(value) && !Array.isArray(value) && isObjectType(value) && !isDateObject(value);
|
|
12
|
+
var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
|
|
13
|
+
var isUndefined = (value) => value === void 0;
|
|
14
|
+
var get = (object, path, defaultValue) => {
|
|
15
|
+
if (!path || !isObject(object)) {
|
|
16
|
+
return defaultValue;
|
|
17
|
+
}
|
|
18
|
+
const result = compact(path.split(/[,[\].]+?/)).reduce(
|
|
19
|
+
(result2, key) => isNullOrUndefined(result2) ? result2 : result2[key],
|
|
20
|
+
object
|
|
21
|
+
);
|
|
22
|
+
return isUndefined(result) || result === object ? isUndefined(object[path]) ? defaultValue : object[path] : result;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// src/utils/set.ts
|
|
26
|
+
var isKey = (value) => /^\w*$/.test(value);
|
|
27
|
+
var stringToPath = (input) => compact(input.replace(/["|']|\]/g, "").split(/\.|\[/));
|
|
28
|
+
var set = (object, path, value) => {
|
|
29
|
+
let index = -1;
|
|
30
|
+
const tempPath = isKey(path) ? [path] : stringToPath(path);
|
|
31
|
+
const length = tempPath.length;
|
|
32
|
+
const lastIndex = length - 1;
|
|
33
|
+
while (++index < length) {
|
|
34
|
+
const key = tempPath[index];
|
|
35
|
+
let newValue = value;
|
|
36
|
+
if (index !== lastIndex) {
|
|
37
|
+
const objValue = object[key];
|
|
38
|
+
newValue = isObject(objValue) || Array.isArray(objValue) ? objValue : !Number.isNaN(+tempPath[index + 1]) ? [] : {};
|
|
39
|
+
}
|
|
40
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
object[key] = newValue;
|
|
44
|
+
object = object[key];
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// src/logic/create_dirty_fields.ts
|
|
49
|
+
var isSomeFieldDirty = (value) => {
|
|
50
|
+
return Object.values(value).some((value2) => {
|
|
51
|
+
if (typeof value2 === "object") {
|
|
52
|
+
return isSomeFieldDirty(value2);
|
|
53
|
+
}
|
|
54
|
+
return value2;
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
var createDirtyFields = (defaultValues) => {
|
|
58
|
+
const [dirtyFields, setDirtyFields] = createSignal({});
|
|
59
|
+
const isDirty = createMemo(() => {
|
|
60
|
+
return isSomeFieldDirty(dirtyFields());
|
|
61
|
+
});
|
|
62
|
+
const checkDirty = (name, value) => {
|
|
63
|
+
const defaultValue = get(defaultValues, name);
|
|
64
|
+
const isDirty2 = value !== defaultValue;
|
|
65
|
+
setDirtyFields((prev) => {
|
|
66
|
+
const newState = { ...prev };
|
|
67
|
+
set(newState, name, isDirty2);
|
|
68
|
+
return newState;
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
const resetDirty = (keepDirty) => {
|
|
72
|
+
if (keepDirty) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
setDirtyFields({});
|
|
76
|
+
};
|
|
77
|
+
return { dirtyFields, isDirty, checkDirty, resetDirty };
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// src/logic/create_errors.ts
|
|
81
|
+
import { createStore, produce, reconcile } from "solid-js/store";
|
|
82
|
+
var createErrors = () => {
|
|
83
|
+
const [errors, setErrors] = createStore({});
|
|
84
|
+
const getError = (name) => {
|
|
85
|
+
return errors[name];
|
|
86
|
+
};
|
|
87
|
+
const appendError = (name, error) => {
|
|
88
|
+
setErrors(
|
|
89
|
+
produce((prevState) => {
|
|
90
|
+
prevState[name] = error;
|
|
91
|
+
})
|
|
92
|
+
);
|
|
93
|
+
};
|
|
94
|
+
const removeError = (name) => {
|
|
95
|
+
setErrors(
|
|
96
|
+
produce((prevState) => {
|
|
97
|
+
delete prevState[name];
|
|
98
|
+
})
|
|
99
|
+
);
|
|
100
|
+
};
|
|
101
|
+
const resetErrors = (keepErrors) => {
|
|
102
|
+
if (keepErrors) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
setErrors(reconcile({}));
|
|
106
|
+
};
|
|
107
|
+
return {
|
|
108
|
+
errors,
|
|
109
|
+
appendError,
|
|
110
|
+
removeError,
|
|
111
|
+
resetErrors,
|
|
112
|
+
getError
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// src/logic/create_fields.ts
|
|
117
|
+
var createFields = () => {
|
|
118
|
+
const fields = {};
|
|
119
|
+
const getField = (name) => {
|
|
120
|
+
return fields[name];
|
|
121
|
+
};
|
|
122
|
+
const setField = (name, element) => {
|
|
123
|
+
fields[name] = element;
|
|
124
|
+
};
|
|
125
|
+
return {
|
|
126
|
+
fields,
|
|
127
|
+
getField,
|
|
128
|
+
setField
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// src/logic/create_rules.ts
|
|
133
|
+
var createRules = () => {
|
|
134
|
+
const rules = {};
|
|
135
|
+
const addRule = (name, options) => {
|
|
136
|
+
rules[name] = {
|
|
137
|
+
required: options.required,
|
|
138
|
+
min: options.min,
|
|
139
|
+
max: options.max,
|
|
140
|
+
minLength: options.minLength,
|
|
141
|
+
maxLength: options.maxLength,
|
|
142
|
+
pattern: options.pattern,
|
|
143
|
+
valueAsNumber: options.valueAsNumber,
|
|
144
|
+
validate: options.validate
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
const getRule = (name) => {
|
|
148
|
+
return rules[name];
|
|
149
|
+
};
|
|
150
|
+
return { rules, addRule, getRule };
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
// src/logic/create_touched_fields.ts
|
|
154
|
+
import { createSignal as createSignal2 } from "solid-js";
|
|
155
|
+
var createTouchedFields = () => {
|
|
156
|
+
const [touchedFields, setTouchedFields] = createSignal2({});
|
|
157
|
+
const addTouched = (name) => {
|
|
158
|
+
setTouchedFields((prev) => {
|
|
159
|
+
const newState = { ...prev };
|
|
160
|
+
set(newState, name, true);
|
|
161
|
+
return newState;
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
const resetTouched = (keepTouched) => {
|
|
165
|
+
if (keepTouched) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
setTouchedFields({});
|
|
169
|
+
};
|
|
170
|
+
return { touchedFields, addTouched, resetTouched };
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// src/logic/format_value.ts
|
|
174
|
+
var formatValue = (value, rules) => {
|
|
175
|
+
if (rules.valueAsNumber) {
|
|
176
|
+
return Number(value);
|
|
177
|
+
}
|
|
178
|
+
return value;
|
|
179
|
+
};
|
|
180
|
+
|
|
4
181
|
// src/logic/get_value.ts
|
|
5
182
|
var getFieldValue = (event) => {
|
|
6
183
|
const isEvent = event instanceof Event;
|
|
@@ -42,24 +219,6 @@ var setFieldValue = (field, value) => {
|
|
|
42
219
|
field.value = value;
|
|
43
220
|
};
|
|
44
221
|
|
|
45
|
-
// src/utils/get.ts
|
|
46
|
-
var isDateObject = (value) => value instanceof Date;
|
|
47
|
-
var isNullOrUndefined = (value) => value == null;
|
|
48
|
-
var isObjectType = (value) => typeof value === "object";
|
|
49
|
-
var isObject = (value) => !isNullOrUndefined(value) && !Array.isArray(value) && isObjectType(value) && !isDateObject(value);
|
|
50
|
-
var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
|
|
51
|
-
var isUndefined = (val) => val === void 0;
|
|
52
|
-
var get = (object, path, defaultValue) => {
|
|
53
|
-
if (!path || !isObject(object)) {
|
|
54
|
-
return defaultValue;
|
|
55
|
-
}
|
|
56
|
-
const result = compact(path.split(/[,[\].]+?/)).reduce(
|
|
57
|
-
(result2, key) => isNullOrUndefined(result2) ? result2 : result2[key],
|
|
58
|
-
object
|
|
59
|
-
);
|
|
60
|
-
return isUndefined(result) || result === object ? isUndefined(object[path]) ? defaultValue : object[path] : result;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
222
|
// src/logic/validate.ts
|
|
64
223
|
var getRuleValue = (rule) => {
|
|
65
224
|
if (rule instanceof RegExp) {
|
|
@@ -110,107 +269,6 @@ var validate = (values, name, rules = {}) => {
|
|
|
110
269
|
}
|
|
111
270
|
};
|
|
112
271
|
|
|
113
|
-
// src/logic/create_errors.ts
|
|
114
|
-
import { createStore, reconcile, produce } from "solid-js/store";
|
|
115
|
-
var createErrors = () => {
|
|
116
|
-
const [errors, setErrors] = createStore({});
|
|
117
|
-
const getError = (name) => {
|
|
118
|
-
return errors[name];
|
|
119
|
-
};
|
|
120
|
-
const appendError = (name, error) => {
|
|
121
|
-
setErrors(
|
|
122
|
-
produce((prevState) => {
|
|
123
|
-
prevState[name] = error;
|
|
124
|
-
})
|
|
125
|
-
);
|
|
126
|
-
};
|
|
127
|
-
const removeError = (name) => {
|
|
128
|
-
setErrors(
|
|
129
|
-
produce((prevState) => {
|
|
130
|
-
delete prevState[name];
|
|
131
|
-
})
|
|
132
|
-
);
|
|
133
|
-
};
|
|
134
|
-
const resetErrors = () => {
|
|
135
|
-
setErrors(reconcile({}));
|
|
136
|
-
};
|
|
137
|
-
return {
|
|
138
|
-
errors,
|
|
139
|
-
appendError,
|
|
140
|
-
removeError,
|
|
141
|
-
resetErrors,
|
|
142
|
-
getError
|
|
143
|
-
};
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
// src/utils/set.ts
|
|
147
|
-
var isKey = (value) => /^\w*$/.test(value);
|
|
148
|
-
var stringToPath = (input) => compact(input.replace(/["|']|\]/g, "").split(/\.|\[/));
|
|
149
|
-
var set = (object, path, value) => {
|
|
150
|
-
let index = -1;
|
|
151
|
-
const tempPath = isKey(path) ? [path] : stringToPath(path);
|
|
152
|
-
const length = tempPath.length;
|
|
153
|
-
const lastIndex = length - 1;
|
|
154
|
-
while (++index < length) {
|
|
155
|
-
const key = tempPath[index];
|
|
156
|
-
let newValue = value;
|
|
157
|
-
if (index !== lastIndex) {
|
|
158
|
-
const objValue = object[key];
|
|
159
|
-
newValue = isObject(objValue) || Array.isArray(objValue) ? objValue : !isNaN(+tempPath[index + 1]) ? [] : {};
|
|
160
|
-
}
|
|
161
|
-
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
object[key] = newValue;
|
|
165
|
-
object = object[key];
|
|
166
|
-
}
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
// src/logic/create_rules.ts
|
|
170
|
-
var createRules = () => {
|
|
171
|
-
const rules = {};
|
|
172
|
-
const addRule = (name, options) => {
|
|
173
|
-
rules[name] = {
|
|
174
|
-
required: options.required,
|
|
175
|
-
min: options.min,
|
|
176
|
-
max: options.max,
|
|
177
|
-
minLength: options.minLength,
|
|
178
|
-
maxLength: options.maxLength,
|
|
179
|
-
pattern: options.pattern,
|
|
180
|
-
valueAsNumber: options.valueAsNumber,
|
|
181
|
-
validate: options.validate
|
|
182
|
-
};
|
|
183
|
-
};
|
|
184
|
-
const getRule = (name) => {
|
|
185
|
-
return rules[name];
|
|
186
|
-
};
|
|
187
|
-
return { rules, addRule, getRule };
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
// src/logic/create_fields.ts
|
|
191
|
-
var createFields = () => {
|
|
192
|
-
const fields = {};
|
|
193
|
-
const getField = (name) => {
|
|
194
|
-
return fields[name];
|
|
195
|
-
};
|
|
196
|
-
const setField = (name, element) => {
|
|
197
|
-
fields[name] = element;
|
|
198
|
-
};
|
|
199
|
-
return {
|
|
200
|
-
fields,
|
|
201
|
-
getField,
|
|
202
|
-
setField
|
|
203
|
-
};
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
// src/logic/format_value.ts
|
|
207
|
-
var formatValue = (value, rules) => {
|
|
208
|
-
if (rules.valueAsNumber) {
|
|
209
|
-
return Number(value);
|
|
210
|
-
}
|
|
211
|
-
return value;
|
|
212
|
-
};
|
|
213
|
-
|
|
214
272
|
// src/utils/resolver.ts
|
|
215
273
|
var getResolverFields = (fields) => {
|
|
216
274
|
return Object.entries(fields).reduce((acc, [name, ref]) => {
|
|
@@ -222,59 +280,6 @@ var getResolverFields = (fields) => {
|
|
|
222
280
|
}, {});
|
|
223
281
|
};
|
|
224
282
|
|
|
225
|
-
// src/logic/create_touched_fields.ts
|
|
226
|
-
import { createSignal } from "solid-js";
|
|
227
|
-
var createTouchedFields = () => {
|
|
228
|
-
const [touchedFields, setTouchedFields] = createSignal({});
|
|
229
|
-
const addTouched = (name) => {
|
|
230
|
-
setTouchedFields((prev) => {
|
|
231
|
-
const newState = { ...prev };
|
|
232
|
-
set(newState, name, true);
|
|
233
|
-
return newState;
|
|
234
|
-
});
|
|
235
|
-
};
|
|
236
|
-
const resetTouched = (keepTouched) => {
|
|
237
|
-
if (keepTouched) {
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
setTouchedFields({});
|
|
241
|
-
};
|
|
242
|
-
return { touchedFields, addTouched, resetTouched };
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
// src/logic/create_dirty_fields.ts
|
|
246
|
-
import { createMemo, createSignal as createSignal2 } from "solid-js";
|
|
247
|
-
var isSomeFieldDirty = (value) => {
|
|
248
|
-
return Object.values(value).some((value2) => {
|
|
249
|
-
if (typeof value2 === "object") {
|
|
250
|
-
return isSomeFieldDirty(value2);
|
|
251
|
-
}
|
|
252
|
-
return value2;
|
|
253
|
-
});
|
|
254
|
-
};
|
|
255
|
-
var createDirtyFields = (defaultValues) => {
|
|
256
|
-
const [dirtyFields, setDirtyFields] = createSignal2({});
|
|
257
|
-
const isDirty = createMemo(() => {
|
|
258
|
-
return isSomeFieldDirty(dirtyFields());
|
|
259
|
-
});
|
|
260
|
-
const checkDirty = (name, value) => {
|
|
261
|
-
const defaultValue = get(defaultValues, name);
|
|
262
|
-
const isDirty2 = value !== defaultValue;
|
|
263
|
-
setDirtyFields((prev) => {
|
|
264
|
-
const newState = { ...prev };
|
|
265
|
-
set(newState, name, isDirty2);
|
|
266
|
-
return newState;
|
|
267
|
-
});
|
|
268
|
-
};
|
|
269
|
-
const resetDirty = (keepDirty) => {
|
|
270
|
-
if (keepDirty) {
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
setDirtyFields({});
|
|
274
|
-
};
|
|
275
|
-
return { dirtyFields, isDirty, checkDirty, resetDirty };
|
|
276
|
-
};
|
|
277
|
-
|
|
278
283
|
// src/create_form.ts
|
|
279
284
|
var createForm = (arg) => {
|
|
280
285
|
const { defaultValues, mode = "onChange", resolver } = arg;
|
|
@@ -398,7 +403,7 @@ var createForm = (arg) => {
|
|
|
398
403
|
}
|
|
399
404
|
return values();
|
|
400
405
|
};
|
|
401
|
-
const setValue = (name, value) => {
|
|
406
|
+
const setValue = (name, value, options = {}) => {
|
|
402
407
|
setValues((prev) => {
|
|
403
408
|
const newValues = { ...prev };
|
|
404
409
|
set(newValues, name, value);
|
|
@@ -406,6 +411,15 @@ var createForm = (arg) => {
|
|
|
406
411
|
});
|
|
407
412
|
const field = getField(name);
|
|
408
413
|
setFieldValue(field, value);
|
|
414
|
+
if (options.shouldValidate) {
|
|
415
|
+
validateField(name);
|
|
416
|
+
}
|
|
417
|
+
if (options.shouldDirty) {
|
|
418
|
+
checkDirty(name, value);
|
|
419
|
+
}
|
|
420
|
+
if (options.shouldTouch) {
|
|
421
|
+
addTouched(name);
|
|
422
|
+
}
|
|
409
423
|
};
|
|
410
424
|
const handleSubmit = (onSubmit, onError) => {
|
|
411
425
|
return async (event) => {
|
|
@@ -420,15 +434,29 @@ var createForm = (arg) => {
|
|
|
420
434
|
};
|
|
421
435
|
};
|
|
422
436
|
const reset = (values2, options = {}) => {
|
|
423
|
-
|
|
424
|
-
setValues(() => newValues);
|
|
425
|
-
resetErrors();
|
|
437
|
+
resetErrors(options.keepErrors);
|
|
426
438
|
resetTouched(options.keepTouched);
|
|
427
439
|
resetDirty(options.keepDirty);
|
|
440
|
+
if (options.keepValues) {
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
const newValues = values2 ? values2 : structuredClone(defaultValues);
|
|
444
|
+
setValues(() => newValues);
|
|
428
445
|
Object.entries(fields).forEach(([name, field]) => {
|
|
429
446
|
setFieldValue(field, get(newValues, name));
|
|
430
447
|
});
|
|
431
448
|
};
|
|
449
|
+
const trigger = async (name) => {
|
|
450
|
+
if (!name) {
|
|
451
|
+
await validateAllFields();
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
if (typeof name === "string") {
|
|
455
|
+
validateField(name);
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
name.forEach(validateField);
|
|
459
|
+
};
|
|
432
460
|
return {
|
|
433
461
|
control,
|
|
434
462
|
formState: {
|
|
@@ -444,7 +472,8 @@ var createForm = (arg) => {
|
|
|
444
472
|
getValues,
|
|
445
473
|
setValue,
|
|
446
474
|
handleSubmit,
|
|
447
|
-
reset
|
|
475
|
+
reset,
|
|
476
|
+
trigger
|
|
448
477
|
};
|
|
449
478
|
};
|
|
450
479
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "solid-hook-form",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/main.js",
|
|
6
6
|
"module": "./dist/main.js",
|
|
@@ -20,13 +20,15 @@
|
|
|
20
20
|
"solid-js": "^1.9.5"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
+
"@biomejs/biome": "2.3.8",
|
|
23
24
|
"esbuild-plugin-solid": "^0.6.0",
|
|
24
25
|
"react-hook-form": "^7.55.0",
|
|
25
26
|
"tsup": "^8.5.0",
|
|
26
27
|
"typescript": "~5.7.2"
|
|
27
28
|
},
|
|
28
29
|
"scripts": {
|
|
29
|
-
"build": "tsc && tsup"
|
|
30
|
+
"build": "tsc && tsup",
|
|
31
|
+
"lint": "npx @biomejs/biome lint"
|
|
30
32
|
},
|
|
31
33
|
"author": "thorn_pear",
|
|
32
34
|
"license": "ISC",
|