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