solid-hook-form 2.0.0 → 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 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>;
@@ -46,10 +46,9 @@ type Control<F extends FormValues> = {
46
46
  register: Register<F>;
47
47
  };
48
48
  type UseControllerArg<F extends FormValues> = {
49
- control: Control<F>;
49
+ control?: Control<F>;
50
50
  name: Path<F>;
51
51
  rules?: Rules<F>;
52
- render(arg: UseControllerReturn<F>): JSXElement;
53
52
  };
54
53
  type UseControllerReturn<F extends FormValues> = {
55
54
  field: RegisterReturn<F> & {
@@ -60,22 +59,31 @@ type UseControllerReturn<F extends FormValues> = {
60
59
  };
61
60
  };
62
61
  type ControllerProps<F extends FormValues> = {
63
- control: Control<F>;
62
+ control?: Control<F>;
64
63
  name: Path<F>;
65
64
  rules?: Rules<F>;
66
65
  render(arg: UseControllerReturn<F>): JSXElement;
67
66
  };
68
67
 
69
- type TouchedFields<F extends FormValues = FormValues> = Partial<Record<Path<F>, boolean>>;
70
-
71
68
  type DirtyFields<F extends FormValues = FormValues> = Partial<Record<Path<F>, boolean>>;
72
69
 
70
+ type TouchedFields<F extends FormValues = FormValues> = Partial<Record<Path<F>, boolean>>;
71
+
73
72
  type FormValues = Record<string, any>;
74
73
  type GetValues<F extends FormValues> = {
75
74
  (): F;
76
75
  <N extends FieldPath<F>>(name: N): FieldPathValue<F, N>;
77
76
  };
78
- type SetValue<F extends FormValues> = (name: Path<F>, value: FieldPathValue<F, Path<F>>) => void;
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;
79
87
  type SubmitHandler<F extends FormValues> = (values: F) => void;
80
88
  type SubmitErrorHandler<F extends FormValues> = (errors: FieldErrors<F>) => void;
81
89
  type HandleSubmit<F extends FormValues> = (onSubmit: SubmitHandler<F>, onError?: SubmitErrorHandler<F>) => (event: SubmitEvent) => void;
@@ -105,6 +113,7 @@ type CreateFormReturn<F extends FormValues = FormValues> = {
105
113
  setValue: SetValue<F>;
106
114
  handleSubmit: HandleSubmit<F>;
107
115
  reset: Reset<F>;
116
+ trigger: Trigger<F>;
108
117
  };
109
118
  type CreateForm = <F extends FormValues>(arg: CreateFormArg<F>) => CreateFormReturn<F>;
110
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/get_value.ts
5
- var getFieldValue = (event) => {
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 = (val) => val === void 0;
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/logic/validate.ts
64
- var getRuleValue = (rule) => {
65
- if (rule instanceof RegExp) {
66
- return rule;
67
- }
68
- if (typeof rule === "string" || typeof rule === "number") {
69
- return rule;
70
- }
71
- return rule.value;
72
- };
73
- var getRuleMessage = (rule) => {
74
- if (typeof rule === "string") {
75
- return rule;
76
- }
77
- if (typeof rule.message === "string") {
78
- return rule.message;
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
- var validate = (values, name, rules = {}) => {
83
- const value = get(values, name);
84
- if (rules.required && !value) {
85
- return { type: "required", message: getRuleMessage(rules.required) };
86
- }
87
- if (rules.min && Number(value) < Number(getRuleValue(rules.min))) {
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
- if (typeof message === "string") {
108
- return { type: "validate", message };
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, reconcile, produce } from "solid-js/store";
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/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
- }
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/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;
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
- return {
200
- fields,
201
- getField,
202
- setField
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.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",