solid-hook-form 1.0.0 → 1.1.1

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/README.md CHANGED
@@ -1,13 +1,53 @@
1
- # solid-hook-form
1
+ # Solid Hook Form
2
+
3
+ ## Playground
4
+
5
+ [<img width="1171" alt="Screenshot 2025-04-05 at 15 01 47" src="https://github.com/user-attachments/assets/072eb398-85fa-4240-b305-dcbbe9c0a9c8" />](https://solid-hook-form.vercel.app/)
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ npm install solid-hook-form
11
+ ```
12
+
13
+ ## Quickstart
2
14
 
3
15
  ```tsx
4
16
  import { useForm } from "solid-hook-form";
5
17
 
6
- const { errors, isValid, register } = useForm({
7
- defaultValues: {
8
- email: "",
9
- },
10
- });
18
+ const Form = () => {
19
+ const { errors, isValid, register, onSubmit } = useForm({
20
+ defaultValues: {
21
+ date: new Date().toISOString().split("T")[0],
22
+ email: "",
23
+ password: "",
24
+ age: 0,
25
+ remember: false,
26
+ },
27
+ });
11
28
 
12
- register("email", { required: true });
29
+ return (
30
+ <form onSubmit={onSubmit(handleSubmit)}>
31
+ <input type="date" {...register("date", { required: "Required" })} />;
32
+ <input
33
+ {...register("email", {
34
+ required: "Required",
35
+ pattern: {
36
+ value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
37
+ message: "Invalid email",
38
+ },
39
+ })}
40
+ />
41
+ <input
42
+ {...register("password", {
43
+ required: "Required",
44
+ minLength: { value: 8, message: "Min 8" },
45
+ })}
46
+ />
47
+ <input type="number" {...register("age", { min: 18, max: 100 })} />
48
+ <input type="checkbox" {...register("remember", { required: "Required" })} />
49
+ <button type="submit">Submit</button>
50
+ </form>
51
+ );
52
+ };
13
53
  ```
@@ -0,0 +1,3 @@
1
+ type GetValueStrategy = (element: HTMLInputElement) => any;
2
+ export declare const executeGetValueStrategy: GetValueStrategy;
3
+ export {};
@@ -0,0 +1,3 @@
1
+ type SetValueStrategy = (element: HTMLInputElement, value: any) => void;
2
+ export declare const executeSetValueStrategy: SetValueStrategy;
3
+ export {};
@@ -0,0 +1,5 @@
1
+ import { FieldError } from '../types/errors';
2
+ import { FormValues } from '../types/form';
3
+ import { Path } from '../types/path';
4
+ import { Rules } from '../types/validate';
5
+ export declare const validate: <F extends FormValues>(values: F, name: Path<F>, rules: Rules<F, Path<F>>) => FieldError | undefined;
package/dist/main.js CHANGED
@@ -1,213 +1,257 @@
1
- const _ = (t, s) => t === s, q = {
2
- equals: _
1
+ const Q = (t, e) => t === e, N = {
2
+ equals: Q
3
3
  };
4
- let G = j;
5
- const g = 1, w = 2;
6
- var b = null;
7
- let V = null, P = null, i = null, o = null, h = null, A = 0;
8
- function x(t, s) {
9
- s = s ? Object.assign({}, q, s) : q;
10
- const e = {
4
+ let z = j;
5
+ const m = 1, w = 2;
6
+ var y = null;
7
+ let A = null, B = null, a = null, l = null, h = null, E = 0;
8
+ function O(t, e) {
9
+ e = e ? Object.assign({}, N, e) : N;
10
+ const s = {
11
11
  value: t,
12
12
  observers: null,
13
13
  observerSlots: null,
14
- comparator: s.equals || void 0
15
- }, r = (u) => (typeof u == "function" && (u = u(e.value)), D(e, u));
16
- return [z.bind(e), r];
14
+ comparator: e.equals || void 0
15
+ }, r = (n) => (typeof n == "function" && (n = n(s.value)), U(s, n));
16
+ return [J.bind(s), r];
17
17
  }
18
- function Q(t) {
19
- if (i === null) return t();
20
- const s = i;
21
- i = null;
18
+ function H(t) {
19
+ if (a === null) return t();
20
+ const e = a;
21
+ a = null;
22
22
  try {
23
23
  return t();
24
24
  } finally {
25
- i = s;
25
+ a = e;
26
26
  }
27
27
  }
28
- function z() {
28
+ function J() {
29
29
  if (this.sources && this.state)
30
- if (this.state === g) F(this);
30
+ if (this.state === m) R(this);
31
31
  else {
32
- const t = o;
33
- o = null, O(() => S(this)), o = t;
32
+ const t = l;
33
+ l = null, L(() => x(this)), l = t;
34
34
  }
35
- if (i) {
35
+ if (a) {
36
36
  const t = this.observers ? this.observers.length : 0;
37
- i.sources ? (i.sources.push(this), i.sourceSlots.push(t)) : (i.sources = [this], i.sourceSlots = [t]), this.observers ? (this.observers.push(i), this.observerSlots.push(i.sources.length - 1)) : (this.observers = [i], this.observerSlots = [i.sources.length - 1]);
37
+ a.sources ? (a.sources.push(this), a.sourceSlots.push(t)) : (a.sources = [this], a.sourceSlots = [t]), this.observers ? (this.observers.push(a), this.observerSlots.push(a.sources.length - 1)) : (this.observers = [a], this.observerSlots = [a.sources.length - 1]);
38
38
  }
39
39
  return this.value;
40
40
  }
41
- function D(t, s, e) {
41
+ function U(t, e, s) {
42
42
  let r = t.value;
43
- return (!t.comparator || !t.comparator(r, s)) && (t.value = s, t.observers && t.observers.length && O(() => {
44
- for (let u = 0; u < t.observers.length; u += 1) {
45
- const l = t.observers[u], f = V && V.running;
46
- f && V.disposed.has(l), (f ? !l.tState : !l.state) && (l.pure ? o.push(l) : h.push(l), l.observers && T(l)), f || (l.state = g);
43
+ return (!t.comparator || !t.comparator(r, e)) && (t.value = e, t.observers && t.observers.length && L(() => {
44
+ for (let n = 0; n < t.observers.length; n += 1) {
45
+ const u = t.observers[n], f = A && A.running;
46
+ f && A.disposed.has(u), (f ? !u.tState : !u.state) && (u.pure ? l.push(u) : h.push(u), u.observers && G(u)), f || (u.state = m);
47
47
  }
48
- if (o.length > 1e6)
49
- throw o = [], new Error();
50
- })), s;
48
+ if (l.length > 1e6)
49
+ throw l = [], new Error();
50
+ })), e;
51
51
  }
52
- function F(t) {
52
+ function R(t) {
53
53
  if (!t.fn) return;
54
- E(t);
55
- const s = A;
56
- B(
54
+ S(t);
55
+ const e = E;
56
+ K(
57
57
  t,
58
58
  t.value,
59
- s
59
+ e
60
60
  );
61
61
  }
62
- function B(t, s, e) {
62
+ function K(t, e, s) {
63
63
  let r;
64
- const u = b, l = i;
65
- i = b = t;
64
+ const n = y, u = a;
65
+ a = y = t;
66
66
  try {
67
- r = t.fn(s);
67
+ r = t.fn(e);
68
68
  } catch (f) {
69
- return t.pure && (t.state = g, t.owned && t.owned.forEach(E), t.owned = null), t.updatedAt = e + 1, N(f);
69
+ return t.pure && (t.state = m, t.owned && t.owned.forEach(S), t.owned = null), t.updatedAt = s + 1, _(f);
70
70
  } finally {
71
- i = l, b = u;
71
+ a = u, y = n;
72
72
  }
73
- (!t.updatedAt || t.updatedAt <= e) && (t.updatedAt != null && "observers" in t ? D(t, r) : t.value = r, t.updatedAt = e);
73
+ (!t.updatedAt || t.updatedAt <= s) && (t.updatedAt != null && "observers" in t ? U(t, r) : t.value = r, t.updatedAt = s);
74
74
  }
75
- function U(t) {
75
+ function T(t) {
76
76
  if (t.state === 0) return;
77
- if (t.state === w) return S(t);
78
- if (t.suspense && Q(t.suspense.inFallback)) return t.suspense.effects.push(t);
79
- const s = [t];
80
- for (; (t = t.owner) && (!t.updatedAt || t.updatedAt < A); )
81
- t.state && s.push(t);
82
- for (let e = s.length - 1; e >= 0; e--)
83
- if (t = s[e], t.state === g)
84
- F(t);
77
+ if (t.state === w) return x(t);
78
+ if (t.suspense && H(t.suspense.inFallback)) return t.suspense.effects.push(t);
79
+ const e = [t];
80
+ for (; (t = t.owner) && (!t.updatedAt || t.updatedAt < E); )
81
+ t.state && e.push(t);
82
+ for (let s = e.length - 1; s >= 0; s--)
83
+ if (t = e[s], t.state === m)
84
+ R(t);
85
85
  else if (t.state === w) {
86
- const r = o;
87
- o = null, O(() => S(t, s[0])), o = r;
86
+ const r = l;
87
+ l = null, L(() => x(t, e[0])), l = r;
88
88
  }
89
89
  }
90
- function O(t, s) {
91
- if (o) return t();
92
- let e = !1;
93
- o = [], h ? e = !0 : h = [], A++;
90
+ function L(t, e) {
91
+ if (l) return t();
92
+ let s = !1;
93
+ l = [], h ? s = !0 : h = [], E++;
94
94
  try {
95
95
  const r = t();
96
- return H(e), r;
96
+ return W(s), r;
97
97
  } catch (r) {
98
- e || (h = null), o = null, N(r);
98
+ s || (h = null), l = null, _(r);
99
99
  }
100
100
  }
101
- function H(t) {
102
- if (o && (j(o), o = null), t) return;
103
- const s = h;
104
- h = null, s.length && O(() => G(s));
101
+ function W(t) {
102
+ if (l && (j(l), l = null), t) return;
103
+ const e = h;
104
+ h = null, e.length && L(() => z(e));
105
105
  }
106
106
  function j(t) {
107
- for (let s = 0; s < t.length; s++) U(t[s]);
107
+ for (let e = 0; e < t.length; e++) T(t[e]);
108
108
  }
109
- function S(t, s) {
109
+ function x(t, e) {
110
110
  t.state = 0;
111
- for (let e = 0; e < t.sources.length; e += 1) {
112
- const r = t.sources[e];
111
+ for (let s = 0; s < t.sources.length; s += 1) {
112
+ const r = t.sources[s];
113
113
  if (r.sources) {
114
- const u = r.state;
115
- u === g ? r !== s && (!r.updatedAt || r.updatedAt < A) && U(r) : u === w && S(r, s);
114
+ const n = r.state;
115
+ n === m ? r !== e && (!r.updatedAt || r.updatedAt < E) && T(r) : n === w && x(r, e);
116
116
  }
117
117
  }
118
118
  }
119
- function T(t) {
120
- for (let s = 0; s < t.observers.length; s += 1) {
121
- const e = t.observers[s];
122
- e.state || (e.state = w, e.pure ? o.push(e) : h.push(e), e.observers && T(e));
119
+ function G(t) {
120
+ for (let e = 0; e < t.observers.length; e += 1) {
121
+ const s = t.observers[e];
122
+ s.state || (s.state = w, s.pure ? l.push(s) : h.push(s), s.observers && G(s));
123
123
  }
124
124
  }
125
- function E(t) {
126
- let s;
125
+ function S(t) {
126
+ let e;
127
127
  if (t.sources)
128
128
  for (; t.sources.length; ) {
129
- const e = t.sources.pop(), r = t.sourceSlots.pop(), u = e.observers;
130
- if (u && u.length) {
131
- const l = u.pop(), f = e.observerSlots.pop();
132
- r < u.length && (l.sourceSlots[f] = r, u[r] = l, e.observerSlots[r] = f);
129
+ const s = t.sources.pop(), r = t.sourceSlots.pop(), n = s.observers;
130
+ if (n && n.length) {
131
+ const u = n.pop(), f = s.observerSlots.pop();
132
+ r < n.length && (u.sourceSlots[f] = r, n[r] = u, s.observerSlots[r] = f);
133
133
  }
134
134
  }
135
135
  if (t.tOwned) {
136
- for (s = t.tOwned.length - 1; s >= 0; s--) E(t.tOwned[s]);
136
+ for (e = t.tOwned.length - 1; e >= 0; e--) S(t.tOwned[e]);
137
137
  delete t.tOwned;
138
138
  }
139
139
  if (t.owned) {
140
- for (s = t.owned.length - 1; s >= 0; s--) E(t.owned[s]);
140
+ for (e = t.owned.length - 1; e >= 0; e--) S(t.owned[e]);
141
141
  t.owned = null;
142
142
  }
143
143
  if (t.cleanups) {
144
- for (s = t.cleanups.length - 1; s >= 0; s--) t.cleanups[s]();
144
+ for (e = t.cleanups.length - 1; e >= 0; e--) t.cleanups[e]();
145
145
  t.cleanups = null;
146
146
  }
147
147
  t.state = 0;
148
148
  }
149
- function J(t) {
149
+ function X(t) {
150
150
  return t instanceof Error ? t : new Error(typeof t == "string" ? t : "Unknown error", {
151
151
  cause: t
152
152
  });
153
153
  }
154
- function N(t, s = b) {
155
- throw J(t);
154
+ function _(t, e = y) {
155
+ throw X(t);
156
156
  }
157
- const X = ({
157
+ const d = {
158
+ text(t) {
159
+ return t.value;
160
+ },
161
+ checkbox(t) {
162
+ return t.checked;
163
+ }
164
+ }, Y = (t) => (d[t.type] || d.text)(t), D = {
165
+ text(t, e) {
166
+ t.value = e;
167
+ },
168
+ checkbox(t, e) {
169
+ t.checked = e;
170
+ }
171
+ }, F = (t, e) => (D[t.type] || D.text)(t, e), b = (t) => t instanceof RegExp || typeof t == "string" || typeof t == "number" ? t : t.value, v = (t) => typeof t == "string" ? t : typeof t.message == "string" ? t.message : "", Z = (t, e, s) => {
172
+ const r = t[e];
173
+ if (s.required && !r)
174
+ return { type: "required", message: v(s.required) };
175
+ if (s.min && Number(r) < Number(b(s.min)))
176
+ return { type: "min", message: v(s.min) };
177
+ if (s.max && Number(r) > Number(b(s.max)))
178
+ return { type: "max", message: v(s.max) };
179
+ if (s.minLength && r.length < b(s.minLength))
180
+ return { type: "minLength", message: v(s.minLength) };
181
+ if (s.maxLength && r.length > b(s.maxLength))
182
+ return { type: "maxLength", message: v(s.maxLength) };
183
+ if (s.pattern && !b(s.pattern).test(r))
184
+ return { type: "pattern", message: v(s.pattern) };
185
+ if (s.validate) {
186
+ const n = s.validate(r, t);
187
+ if (n === !1)
188
+ return { type: "validate" };
189
+ if (typeof n == "string")
190
+ return { type: "validate", message: n };
191
+ }
192
+ }, st = ({
158
193
  defaultValues: t,
159
- mode: s = "onInput"
194
+ mode: e = "onInput"
160
195
  }) => {
161
- const e = t, r = {}, u = {}, [l, f] = x({}), [k, C] = x(!0), y = (n) => {
162
- const a = r[n], c = u[n];
163
- c != null && c.required && !(a != null && a.value) ? f((p) => {
164
- const v = { message: "Required" };
165
- return { ...p, [n]: v };
166
- }) : f((p) => {
167
- const v = { ...p };
168
- return delete v[n], v;
169
- }), C(!Object.keys(l()).length);
170
- }, L = () => {
171
- Object.keys(e).forEach((n) => {
172
- y(n);
196
+ const s = {}, r = {}, [n, u] = O(t), [f, V] = O({}), [I, q] = O(!0), k = (i) => {
197
+ const c = r[i], o = Z(n(), i, c);
198
+ V(o ? (p) => ({ ...p, [i]: o }) : (p) => {
199
+ const g = { ...p };
200
+ return delete g[i], g;
201
+ }), q(!Object.keys(f()).length);
202
+ }, M = () => {
203
+ Object.keys(n()).forEach((i) => {
204
+ k(i);
173
205
  });
174
- }, R = (n, a) => (a && (u[n] = { required: a.required }), {
175
- name: n,
176
- value: e[n],
177
- onInput(c) {
178
- if (s === "onInput") {
179
- const p = c.target.value;
180
- e[n] = p, y(n);
206
+ }, P = (i, c) => (c && (r[i] = {
207
+ required: c.required,
208
+ min: c.min,
209
+ max: c.max,
210
+ minLength: c.minLength,
211
+ maxLength: c.maxLength,
212
+ pattern: c.pattern,
213
+ validate: c.validate
214
+ }), {
215
+ name: i,
216
+ // value: values()[name],
217
+ onInput(o) {
218
+ if (e === "onInput") {
219
+ const p = o.target.value;
220
+ u((g) => ({ ...g, [i]: p })), k(i);
181
221
  }
182
222
  },
183
- onChange(c) {
184
- if (s === "onChange") {
185
- const p = c.target.value;
186
- e[n] = p, y(n);
223
+ onChange(o) {
224
+ if (e === "onChange" || e === "onInput") {
225
+ const p = Y(o.target);
226
+ u((g) => ({ ...g, [i]: p })), k(i);
187
227
  }
188
228
  },
189
- ref: (c) => {
190
- r[n] || (r[n] = c, c && (c.value = e[n]));
229
+ ref: (o) => {
230
+ s[i] || (s[i] = o, o && F(o, n()[i]));
191
231
  }
192
- }), I = (n) => n ? e[n] : e;
232
+ }), C = (i) => i ? n()[i] : n();
193
233
  return {
194
- errors: l,
195
- isValid: k,
196
- register: R,
197
- getValues: I,
198
- setValue: (n, a) => {
199
- e[n] = a;
200
- const c = r[n];
201
- c && (c.value = a);
234
+ values: n,
235
+ errors: f,
236
+ isValid: I,
237
+ register: P,
238
+ getValues: C,
239
+ setValue: (i, c) => {
240
+ u((p) => ({ ...p, [i]: c }));
241
+ const o = s[i];
242
+ o && F(o, c);
202
243
  },
203
- onSubmit: (n) => (a) => {
204
- a.preventDefault(), L(), k() && n(I());
244
+ onSubmit: (i) => (c) => {
245
+ c.preventDefault(), M(), I() && i(C());
205
246
  },
206
- reset: (n) => {
207
- Object.assign(e, n || t), f({}), C(!0);
247
+ reset: (i) => {
248
+ u(() => ({
249
+ ...t,
250
+ ...i
251
+ })), V({}), q(!0);
208
252
  }
209
253
  };
210
254
  };
211
255
  export {
212
- X as useForm
256
+ st as useForm
213
257
  };
package/dist/main.umd.cjs CHANGED
@@ -1 +1 @@
1
- (function(g,v){typeof exports=="object"&&typeof module<"u"?v(exports):typeof define=="function"&&define.amd?define(["exports"],v):(g=typeof globalThis<"u"?globalThis:g||self,v(g["solid-hook-form"]={}))})(this,function(g){"use strict";const q={equals:(t,e)=>t===e};let L=j;const b=1,w=2;var S=null;let d=null,P=null,i=null,o=null,h=null,E=0;function C(t,e){e=e?Object.assign({},q,e):q;const s={value:t,observers:null,observerSlots:null,comparator:e.equals||void 0},r=u=>(typeof u=="function"&&(u=u(s.value)),F(s,u));return[_.bind(s),r]}function R(t){if(i===null)return t();const e=i;i=null;try{return t()}finally{i=e}}function _(){if(this.sources&&this.state)if(this.state===b)I(this);else{const t=o;o=null,y(()=>A(this)),o=t}if(i){const t=this.observers?this.observers.length:0;i.sources?(i.sources.push(this),i.sourceSlots.push(t)):(i.sources=[this],i.sourceSlots=[t]),this.observers?(this.observers.push(i),this.observerSlots.push(i.sources.length-1)):(this.observers=[i],this.observerSlots=[i.sources.length-1])}return this.value}function F(t,e,s){let r=t.value;return(!t.comparator||!t.comparator(r,e))&&(t.value=e,t.observers&&t.observers.length&&y(()=>{for(let u=0;u<t.observers.length;u+=1){const l=t.observers[u],f=d&&d.running;f&&d.disposed.has(l),(f?!l.tState:!l.state)&&(l.pure?o.push(l):h.push(l),l.observers&&x(l)),f||(l.state=b)}if(o.length>1e6)throw o=[],new Error})),e}function I(t){if(!t.fn)return;O(t);const e=E;G(t,t.value,e)}function G(t,e,s){let r;const u=S,l=i;i=S=t;try{r=t.fn(e)}catch(f){return t.pure&&(t.state=b,t.owned&&t.owned.forEach(O),t.owned=null),t.updatedAt=s+1,D(f)}finally{i=l,S=u}(!t.updatedAt||t.updatedAt<=s)&&(t.updatedAt!=null&&"observers"in t?F(t,r):t.value=r,t.updatedAt=s)}function T(t){if(t.state===0)return;if(t.state===w)return A(t);if(t.suspense&&R(t.suspense.inFallback))return t.suspense.effects.push(t);const e=[t];for(;(t=t.owner)&&(!t.updatedAt||t.updatedAt<E);)t.state&&e.push(t);for(let s=e.length-1;s>=0;s--)if(t=e[s],t.state===b)I(t);else if(t.state===w){const r=o;o=null,y(()=>A(t,e[0])),o=r}}function y(t,e){if(o)return t();let s=!1;o=[],h?s=!0:h=[],E++;try{const r=t();return M(s),r}catch(r){s||(h=null),o=null,D(r)}}function M(t){if(o&&(j(o),o=null),t)return;const e=h;h=null,e.length&&y(()=>L(e))}function j(t){for(let e=0;e<t.length;e++)T(t[e])}function A(t,e){t.state=0;for(let s=0;s<t.sources.length;s+=1){const r=t.sources[s];if(r.sources){const u=r.state;u===b?r!==e&&(!r.updatedAt||r.updatedAt<E)&&T(r):u===w&&A(r,e)}}}function x(t){for(let e=0;e<t.observers.length;e+=1){const s=t.observers[e];s.state||(s.state=w,s.pure?o.push(s):h.push(s),s.observers&&x(s))}}function O(t){let e;if(t.sources)for(;t.sources.length;){const s=t.sources.pop(),r=t.sourceSlots.pop(),u=s.observers;if(u&&u.length){const l=u.pop(),f=s.observerSlots.pop();r<u.length&&(l.sourceSlots[f]=r,u[r]=l,s.observerSlots[r]=f)}}if(t.tOwned){for(e=t.tOwned.length-1;e>=0;e--)O(t.tOwned[e]);delete t.tOwned}if(t.owned){for(e=t.owned.length-1;e>=0;e--)O(t.owned[e]);t.owned=null}if(t.cleanups){for(e=t.cleanups.length-1;e>=0;e--)t.cleanups[e]();t.cleanups=null}t.state=0}function Q(t){return t instanceof Error?t:new Error(typeof t=="string"?t:"Unknown error",{cause:t})}function D(t,e=S){throw Q(t)}const z=({defaultValues:t,mode:e="onInput"})=>{const s=t,r={},u={},[l,f]=C({}),[U,m]=C(!0),k=n=>{const a=r[n],c=u[n];c!=null&&c.required&&!(a!=null&&a.value)?f(p=>{const V={message:"Required"};return{...p,[n]:V}}):f(p=>{const V={...p};return delete V[n],V}),m(!Object.keys(l()).length)},B=()=>{Object.keys(s).forEach(n=>{k(n)})},H=(n,a)=>(a&&(u[n]={required:a.required}),{name:n,value:s[n],onInput(c){if(e==="onInput"){const p=c.target.value;s[n]=p,k(n)}},onChange(c){if(e==="onChange"){const p=c.target.value;s[n]=p,k(n)}},ref:c=>{r[n]||(r[n]=c,c&&(c.value=s[n]))}}),N=n=>n?s[n]:s;return{errors:l,isValid:U,register:H,getValues:N,setValue:(n,a)=>{s[n]=a;const c=r[n];c&&(c.value=a)},onSubmit:n=>a=>{a.preventDefault(),B(),U()&&n(N())},reset:n=>{Object.assign(s,n||t),f({}),m(!0)}}};g.useForm=z,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"})});
1
+ (function(g,x){typeof exports=="object"&&typeof module<"u"?x(exports):typeof define=="function"&&define.amd?define(["exports"],x):(g=typeof globalThis<"u"?globalThis:g||self,x(g["solid-hook-form"]={}))})(this,function(g){"use strict";const I={equals:(t,e)=>t===e};let Q=T;const m=1,S=2;var w=null;let k=null,z=null,a=null,l=null,h=null,d=0;function A(t,e){e=e?Object.assign({},I,e):I;const s={value:t,observers:null,observerSlots:null,comparator:e.equals||void 0},r=n=>(typeof n=="function"&&(n=n(s.value)),C(s,n));return[H.bind(s),r]}function B(t){if(a===null)return t();const e=a;a=null;try{return t()}finally{a=e}}function H(){if(this.sources&&this.state)if(this.state===m)F(this);else{const t=l;l=null,E(()=>L(this)),l=t}if(a){const t=this.observers?this.observers.length:0;a.sources?(a.sources.push(this),a.sourceSlots.push(t)):(a.sources=[this],a.sourceSlots=[t]),this.observers?(this.observers.push(a),this.observerSlots.push(a.sources.length-1)):(this.observers=[a],this.observerSlots=[a.sources.length-1])}return this.value}function C(t,e,s){let r=t.value;return(!t.comparator||!t.comparator(r,e))&&(t.value=e,t.observers&&t.observers.length&&E(()=>{for(let n=0;n<t.observers.length;n+=1){const u=t.observers[n],f=k&&k.running;f&&k.disposed.has(u),(f?!u.tState:!u.state)&&(u.pure?l.push(u):h.push(u),u.observers&&j(u)),f||(u.state=m)}if(l.length>1e6)throw l=[],new Error})),e}function F(t){if(!t.fn)return;V(t);const e=d;J(t,t.value,e)}function J(t,e,s){let r;const n=w,u=a;a=w=t;try{r=t.fn(e)}catch(f){return t.pure&&(t.state=m,t.owned&&t.owned.forEach(V),t.owned=null),t.updatedAt=s+1,D(f)}finally{a=u,w=n}(!t.updatedAt||t.updatedAt<=s)&&(t.updatedAt!=null&&"observers"in t?C(t,r):t.value=r,t.updatedAt=s)}function N(t){if(t.state===0)return;if(t.state===S)return L(t);if(t.suspense&&B(t.suspense.inFallback))return t.suspense.effects.push(t);const e=[t];for(;(t=t.owner)&&(!t.updatedAt||t.updatedAt<d);)t.state&&e.push(t);for(let s=e.length-1;s>=0;s--)if(t=e[s],t.state===m)F(t);else if(t.state===S){const r=l;l=null,E(()=>L(t,e[0])),l=r}}function E(t,e){if(l)return t();let s=!1;l=[],h?s=!0:h=[],d++;try{const r=t();return K(s),r}catch(r){s||(h=null),l=null,D(r)}}function K(t){if(l&&(T(l),l=null),t)return;const e=h;h=null,e.length&&E(()=>Q(e))}function T(t){for(let e=0;e<t.length;e++)N(t[e])}function L(t,e){t.state=0;for(let s=0;s<t.sources.length;s+=1){const r=t.sources[s];if(r.sources){const n=r.state;n===m?r!==e&&(!r.updatedAt||r.updatedAt<d)&&N(r):n===S&&L(r,e)}}}function j(t){for(let e=0;e<t.observers.length;e+=1){const s=t.observers[e];s.state||(s.state=S,s.pure?l.push(s):h.push(s),s.observers&&j(s))}}function V(t){let e;if(t.sources)for(;t.sources.length;){const s=t.sources.pop(),r=t.sourceSlots.pop(),n=s.observers;if(n&&n.length){const u=n.pop(),f=s.observerSlots.pop();r<n.length&&(u.sourceSlots[f]=r,n[r]=u,s.observerSlots[r]=f)}}if(t.tOwned){for(e=t.tOwned.length-1;e>=0;e--)V(t.tOwned[e]);delete t.tOwned}if(t.owned){for(e=t.owned.length-1;e>=0;e--)V(t.owned[e]);t.owned=null}if(t.cleanups){for(e=t.cleanups.length-1;e>=0;e--)t.cleanups[e]();t.cleanups=null}t.state=0}function W(t){return t instanceof Error?t:new Error(typeof t=="string"?t:"Unknown error",{cause:t})}function D(t,e=w){throw W(t)}const U={text(t){return t.value},checkbox(t){return t.checked}},X=t=>(U[t.type]||U.text)(t),R={text(t,e){t.value=e},checkbox(t,e){t.checked=e}},G=(t,e)=>(R[t.type]||R.text)(t,e),y=t=>t instanceof RegExp||typeof t=="string"||typeof t=="number"?t:t.value,b=t=>typeof t=="string"?t:typeof t.message=="string"?t.message:"",Y=(t,e,s)=>{const r=t[e];if(s.required&&!r)return{type:"required",message:b(s.required)};if(s.min&&Number(r)<Number(y(s.min)))return{type:"min",message:b(s.min)};if(s.max&&Number(r)>Number(y(s.max)))return{type:"max",message:b(s.max)};if(s.minLength&&r.length<y(s.minLength))return{type:"minLength",message:b(s.minLength)};if(s.maxLength&&r.length>y(s.maxLength))return{type:"maxLength",message:b(s.maxLength)};if(s.pattern&&!y(s.pattern).test(r))return{type:"pattern",message:b(s.pattern)};if(s.validate){const n=s.validate(r,t);if(n===!1)return{type:"validate"};if(typeof n=="string")return{type:"validate",message:n}}},Z=({defaultValues:t,mode:e="onInput"})=>{const s={},r={},[n,u]=A(t),[f,O]=A({}),[M,P]=A(!0),q=i=>{const o=r[i],c=Y(n(),i,o);O(c?p=>({...p,[i]:c}):p=>{const v={...p};return delete v[i],v}),P(!Object.keys(f()).length)},$=()=>{Object.keys(n()).forEach(i=>{q(i)})},tt=(i,o)=>(o&&(r[i]={required:o.required,min:o.min,max:o.max,minLength:o.minLength,maxLength:o.maxLength,pattern:o.pattern,validate:o.validate}),{name:i,onInput(c){if(e==="onInput"){const p=c.target.value;u(v=>({...v,[i]:p})),q(i)}},onChange(c){if(e==="onChange"||e==="onInput"){const p=X(c.target);u(v=>({...v,[i]:p})),q(i)}},ref:c=>{s[i]||(s[i]=c,c&&G(c,n()[i]))}}),_=i=>i?n()[i]:n();return{values:n,errors:f,isValid:M,register:tt,getValues:_,setValue:(i,o)=>{u(p=>({...p,[i]:o}));const c=s[i];c&&G(c,o)},onSubmit:i=>o=>{o.preventDefault(),$(),M()&&i(_())},reset:i=>{u(()=>({...t,...i})),O({}),P(!0)}}};g.useForm=Z,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"})});
@@ -1,23 +1,3 @@
1
- /**
2
- * Type which can be used to index an array or tuple type.
3
- */
4
1
  export type ArrayKey = number;
5
- /**
6
- * Type which given a tuple type returns its own keys, i.e. only its indices.
7
- * @typeParam T - tuple type
8
- * @example
9
- * ```
10
- * TupleKeys<[number, string]> = '0' | '1'
11
- * ```
12
- */
13
2
  export type TupleKeys<T extends ReadonlyArray<any>> = Exclude<keyof T, keyof any[]>;
14
- /**
15
- * Type to query whether an array type T is a tuple type.
16
- * @typeParam T - type which may be an array or tuple
17
- * @example
18
- * ```
19
- * IsTuple<[number]> = true
20
- * IsTuple<number[]> = false
21
- * ```
22
- */
23
3
  export type IsTuple<T extends ReadonlyArray<any>> = number extends T["length"] ? false : true;
@@ -1,6 +1,8 @@
1
1
  import { FormValues } from './form';
2
- import { BrowserNativeObject, IsAny, Merge } from './utils';
2
+ import { BrowserNativeObject, IsAny, LiteralUnion, Merge } from './utils';
3
+ import { Rules } from './validate';
3
4
  export type FieldError = {
5
+ type: LiteralUnion<keyof Rules, string>;
4
6
  message?: Message;
5
7
  };
6
8
  export type Message = string;
@@ -0,0 +1,4 @@
1
+ export type ChangeEvent = Event & {
2
+ target: HTMLInputElement;
3
+ };
4
+ export type StrategyKey = "text" | "checkbox";
@@ -1,18 +1,6 @@
1
1
  import { ArrayKey, IsTuple, TupleKeys } from './array';
2
- import { BrowserNativeObject, IsEqual, Primitive } from './utils';
3
- /**
4
- * Helper function to break apart T1 and check if any are equal to T2
5
- *
6
- * See {@link IsEqual}
7
- */
8
- type AnyIsEqual<T1, T2> = T1 extends T2 ? (IsEqual<T1, T2> extends true ? true : never) : never;
9
- /**
10
- * Helper type for recursively constructing paths through a type.
11
- * This actually constructs the strings and recurses into nested
12
- * object types.
13
- *
14
- * See {@link Path}
15
- */
2
+ import { FormValues } from './form';
3
+ import { BrowserNativeObject, IsAny, Primitive, AnyIsEqual } from './utils';
16
4
  type PathImpl<K extends string | number, V, TraversedTypes> = V extends Primitive | BrowserNativeObject ? `${K}` : true extends AnyIsEqual<TraversedTypes, V> ? `${K}` : `${K}` | `${K}.${PathInternal<V, TraversedTypes | V>}`;
17
5
  type PathInternal<T, TraversedTypes = T> = T extends ReadonlyArray<infer V> ? IsTuple<T> extends true ? {
18
6
  [K in TupleKeys<T>]-?: PathImpl<K & string, T[K], TraversedTypes>;
@@ -20,4 +8,14 @@ type PathInternal<T, TraversedTypes = T> = T extends ReadonlyArray<infer V> ? Is
20
8
  [K in keyof T]-?: PathImpl<K & string, T[K], TraversedTypes>;
21
9
  }[keyof T];
22
10
  export type Path<T> = T extends any ? PathInternal<T> : never;
11
+ export type FieldPath<F extends FormValues> = Path<F>;
12
+ type ArrayPathImpl<K extends string | number, V, TraversedTypes> = V extends Primitive | BrowserNativeObject ? IsAny<V> extends true ? string : never : V extends ReadonlyArray<infer U> ? U extends Primitive | BrowserNativeObject ? IsAny<V> extends true ? string : never : true extends AnyIsEqual<TraversedTypes, V> ? never : `${K}` | `${K}.${ArrayPathInternal<V, TraversedTypes | V>}` : true extends AnyIsEqual<TraversedTypes, V> ? never : `${K}.${ArrayPathInternal<V, TraversedTypes | V>}`;
13
+ type ArrayPathInternal<T, TraversedTypes = T> = T extends ReadonlyArray<infer V> ? IsTuple<T> extends true ? {
14
+ [K in TupleKeys<T>]-?: ArrayPathImpl<K & string, T[K], TraversedTypes>;
15
+ }[TupleKeys<T>] : ArrayPathImpl<ArrayKey, V, TraversedTypes> : {
16
+ [K in keyof T]-?: ArrayPathImpl<K & string, T[K], TraversedTypes>;
17
+ }[keyof T];
18
+ export type ArrayPath<T> = T extends any ? ArrayPathInternal<T> : never;
19
+ export type PathValue<T, P extends Path<T> | ArrayPath<T>> = T extends any ? P extends `${infer K}.${infer R}` ? K extends keyof T ? R extends Path<T[K]> ? PathValue<T[K], R> : never : K extends `${ArrayKey}` ? T extends ReadonlyArray<infer V> ? PathValue<V, R & Path<V>> : never : never : P extends keyof T ? T[P] : P extends `${ArrayKey}` ? T extends ReadonlyArray<infer V> ? V : never : never : never;
20
+ export type FieldPathValue<F extends FormValues, P extends FieldPath<F>> = PathValue<F, P>;
23
21
  export {};
@@ -1,30 +1,11 @@
1
1
  export type Primitive = null | undefined | string | number | boolean | symbol | bigint;
2
2
  export type BrowserNativeObject = Date | FileList | File;
3
- /**
4
- * Checks whether T1 can be exactly (mutually) assigned to T2
5
- * @typeParam T1 - type to check
6
- * @typeParam T2 - type to check against
7
- * ```
8
- * IsEqual<string, string> = true
9
- * IsEqual<'foo', 'foo'> = true
10
- * IsEqual<string, number> = false
11
- * IsEqual<string, number> = false
12
- * IsEqual<string, 'foo'> = false
13
- * IsEqual<'foo', string> = false
14
- * IsEqual<'foo' | 'bar', 'foo'> = boolean // 'foo' is assignable, but 'bar' is not (true | false) -> boolean
15
- * ```
16
- */
17
3
  export type IsEqual<T1, T2> = T1 extends T2 ? (<G>() => G extends T1 ? 1 : 2) extends <G>() => G extends T2 ? 1 : 2 ? true : false : false;
18
- /**
19
- * Checks whether the type is any
20
- * See {@link https://stackoverflow.com/a/49928360/3406963}
21
- * @typeParam T - type which may be any
22
- * ```
23
- * IsAny<any> = true
24
- * IsAny<string> = false
25
- * ```
26
- */
27
4
  export type IsAny<T> = 0 extends 1 & T ? true : false;
28
5
  export type Merge<A, B> = {
29
6
  [K in keyof A | keyof B]?: K extends keyof A & keyof B ? [A[K], B[K]] extends [object, object] ? Merge<A[K], B[K]> : A[K] | B[K] : K extends keyof A ? A[K] : K extends keyof B ? B[K] : never;
30
7
  };
8
+ export type AnyIsEqual<T1, T2> = T1 extends T2 ? IsEqual<T1, T2> extends true ? true : never : never;
9
+ export type LiteralUnion<T extends U, U extends Primitive> = T | (U & {
10
+ _?: never;
11
+ });
@@ -0,0 +1,20 @@
1
+ import { Message } from './errors';
2
+ import { FormValues } from './form';
3
+ import { FieldPath, FieldPathValue } from './path';
4
+ export type ValidateResult = Message | boolean | undefined;
5
+ export type Validate<V, F> = (value: V, formValues: F) => ValidateResult | Promise<ValidateResult>;
6
+ export type ValidationValue = boolean | number | string | RegExp;
7
+ export type ValidationRule<V extends ValidationValue = ValidationValue> = V | ValidationValueMessage<V>;
8
+ export type ValidationValueMessage<V extends ValidationValue = ValidationValue> = {
9
+ value: V;
10
+ message: Message;
11
+ };
12
+ export type Rules<F extends FormValues = FormValues, N extends FieldPath<F> = FieldPath<F>> = {
13
+ required?: Message | ValidationRule<boolean>;
14
+ min?: ValidationRule<number | string>;
15
+ max?: ValidationRule<number | string>;
16
+ maxLength?: ValidationRule<number>;
17
+ minLength?: ValidationRule<number>;
18
+ pattern?: ValidationRule<RegExp>;
19
+ validate?: Validate<FieldPathValue<F, N>, F>;
20
+ };
@@ -1,25 +1,24 @@
1
1
  import { FormValues } from './types/form';
2
2
  import { Path } from './types/path';
3
3
  import { FieldErrors } from './types/errors';
4
+ import { ChangeEvent } from './types/event';
5
+ import { Rules } from './types/validate';
4
6
  type UseFormArg<T extends FormValues> = {
5
7
  defaultValues: T;
6
8
  mode?: "onInput" | "onChange" | "onSubmit";
7
9
  };
8
10
  type SubmitCallback<T extends FormValues> = (values: T) => void;
9
- type Rules = {
10
- required: boolean;
11
- };
12
11
  export declare const useForm: <T extends FormValues>({ defaultValues, mode, }: UseFormArg<T>) => {
12
+ values: import('solid-js').Accessor<T>;
13
13
  errors: import('solid-js').Accessor<FieldErrors<T>>;
14
14
  isValid: import('solid-js').Accessor<boolean>;
15
- register: (name: Path<T>, options?: Rules) => {
15
+ register: (name: Path<T>, options?: Rules<T, Path<T>>) => {
16
16
  name: Path<T>;
17
- value: any;
18
17
  onInput(event: InputEvent): void;
19
- onChange(event: Event): void;
18
+ onChange(event: ChangeEvent): void;
20
19
  ref: (ref: HTMLInputElement | null) => void;
21
20
  };
22
- getValues: (name?: Path<T>) => any;
21
+ getValues: (name?: Path<T>) => T | T[Path<T>];
23
22
  setValue: (name: Path<T>, value: any) => void;
24
23
  onSubmit: (submit: SubmitCallback<T>) => (event: SubmitEvent) => void;
25
24
  reset: (newDefaultValues?: Partial<T>) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "solid-hook-form",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "type": "module",
5
5
  "main": "./dist/main.umd.cjs",
6
6
  "module": "./dist/main.js",
@@ -23,10 +23,13 @@
23
23
  "typescript": "~5.7.2",
24
24
  "vite": "^6.0.11",
25
25
  "vite-plugin-dts": "^4.5.0",
26
+ "vite-plugin-solid": "^2.11.6",
26
27
  "vitest": "^3.0.5"
27
28
  },
28
29
  "scripts": {
30
+ "start": "vite --config vite.demo",
29
31
  "build": "tsc && vite build",
32
+ "build:demo": "tsc && vite build --config vite.demo",
30
33
  "test": "vitest run"
31
34
  },
32
35
  "author": "thorn_pear",