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 +47 -7
- package/dist/logic/get_value.d.ts +3 -0
- package/dist/logic/set_value.d.ts +3 -0
- package/dist/logic/validate.d.ts +5 -0
- package/dist/main.js +171 -127
- package/dist/main.umd.cjs +1 -1
- package/dist/types/array.d.ts +0 -20
- package/dist/types/errors.d.ts +3 -1
- package/dist/types/event.d.ts +4 -0
- package/dist/types/path.d.ts +12 -14
- package/dist/types/utils.d.ts +4 -23
- package/dist/types/validate.d.ts +20 -0
- package/dist/use_form.d.ts +6 -7
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -1,13 +1,53 @@
|
|
|
1
|
-
#
|
|
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
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
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,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
|
|
2
|
-
equals:
|
|
1
|
+
const Q = (t, e) => t === e, N = {
|
|
2
|
+
equals: Q
|
|
3
3
|
};
|
|
4
|
-
let
|
|
5
|
-
const
|
|
6
|
-
var
|
|
7
|
-
let
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
const
|
|
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:
|
|
15
|
-
}, r = (
|
|
16
|
-
return [
|
|
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
|
|
19
|
-
if (
|
|
20
|
-
const
|
|
21
|
-
|
|
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
|
-
|
|
25
|
+
a = e;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
function
|
|
28
|
+
function J() {
|
|
29
29
|
if (this.sources && this.state)
|
|
30
|
-
if (this.state ===
|
|
30
|
+
if (this.state === m) R(this);
|
|
31
31
|
else {
|
|
32
|
-
const t =
|
|
33
|
-
|
|
32
|
+
const t = l;
|
|
33
|
+
l = null, L(() => x(this)), l = t;
|
|
34
34
|
}
|
|
35
|
-
if (
|
|
35
|
+
if (a) {
|
|
36
36
|
const t = this.observers ? this.observers.length : 0;
|
|
37
|
-
|
|
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
|
|
41
|
+
function U(t, e, s) {
|
|
42
42
|
let r = t.value;
|
|
43
|
-
return (!t.comparator || !t.comparator(r,
|
|
44
|
-
for (let
|
|
45
|
-
const
|
|
46
|
-
f &&
|
|
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 (
|
|
49
|
-
throw
|
|
50
|
-
})),
|
|
48
|
+
if (l.length > 1e6)
|
|
49
|
+
throw l = [], new Error();
|
|
50
|
+
})), e;
|
|
51
51
|
}
|
|
52
|
-
function
|
|
52
|
+
function R(t) {
|
|
53
53
|
if (!t.fn) return;
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
54
|
+
S(t);
|
|
55
|
+
const e = E;
|
|
56
|
+
K(
|
|
57
57
|
t,
|
|
58
58
|
t.value,
|
|
59
|
-
|
|
59
|
+
e
|
|
60
60
|
);
|
|
61
61
|
}
|
|
62
|
-
function
|
|
62
|
+
function K(t, e, s) {
|
|
63
63
|
let r;
|
|
64
|
-
const
|
|
65
|
-
|
|
64
|
+
const n = y, u = a;
|
|
65
|
+
a = y = t;
|
|
66
66
|
try {
|
|
67
|
-
r = t.fn(
|
|
67
|
+
r = t.fn(e);
|
|
68
68
|
} catch (f) {
|
|
69
|
-
return t.pure && (t.state =
|
|
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
|
-
|
|
71
|
+
a = u, y = n;
|
|
72
72
|
}
|
|
73
|
-
(!t.updatedAt || t.updatedAt <=
|
|
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
|
|
75
|
+
function T(t) {
|
|
76
76
|
if (t.state === 0) return;
|
|
77
|
-
if (t.state === w) return
|
|
78
|
-
if (t.suspense &&
|
|
79
|
-
const
|
|
80
|
-
for (; (t = t.owner) && (!t.updatedAt || t.updatedAt <
|
|
81
|
-
t.state &&
|
|
82
|
-
for (let
|
|
83
|
-
if (t = s
|
|
84
|
-
|
|
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 =
|
|
87
|
-
|
|
86
|
+
const r = l;
|
|
87
|
+
l = null, L(() => x(t, e[0])), l = r;
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
-
function
|
|
91
|
-
if (
|
|
92
|
-
let
|
|
93
|
-
|
|
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
|
|
96
|
+
return W(s), r;
|
|
97
97
|
} catch (r) {
|
|
98
|
-
|
|
98
|
+
s || (h = null), l = null, _(r);
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
|
-
function
|
|
102
|
-
if (
|
|
103
|
-
const
|
|
104
|
-
h = null,
|
|
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
|
|
107
|
+
for (let e = 0; e < t.length; e++) T(t[e]);
|
|
108
108
|
}
|
|
109
|
-
function
|
|
109
|
+
function x(t, e) {
|
|
110
110
|
t.state = 0;
|
|
111
|
-
for (let
|
|
112
|
-
const r = t.sources[
|
|
111
|
+
for (let s = 0; s < t.sources.length; s += 1) {
|
|
112
|
+
const r = t.sources[s];
|
|
113
113
|
if (r.sources) {
|
|
114
|
-
const
|
|
115
|
-
|
|
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
|
|
120
|
-
for (let
|
|
121
|
-
const
|
|
122
|
-
|
|
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
|
|
126
|
-
let
|
|
125
|
+
function S(t) {
|
|
126
|
+
let e;
|
|
127
127
|
if (t.sources)
|
|
128
128
|
for (; t.sources.length; ) {
|
|
129
|
-
const
|
|
130
|
-
if (
|
|
131
|
-
const
|
|
132
|
-
r <
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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
|
|
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
|
|
155
|
-
throw
|
|
154
|
+
function _(t, e = y) {
|
|
155
|
+
throw X(t);
|
|
156
156
|
}
|
|
157
|
-
const
|
|
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:
|
|
194
|
+
mode: e = "onInput"
|
|
160
195
|
}) => {
|
|
161
|
-
const
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
const
|
|
165
|
-
return
|
|
166
|
-
})
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
-
},
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
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(
|
|
184
|
-
if (
|
|
185
|
-
const p =
|
|
186
|
-
|
|
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: (
|
|
190
|
-
|
|
229
|
+
ref: (o) => {
|
|
230
|
+
s[i] || (s[i] = o, o && F(o, n()[i]));
|
|
191
231
|
}
|
|
192
|
-
}),
|
|
232
|
+
}), C = (i) => i ? n()[i] : n();
|
|
193
233
|
return {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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: (
|
|
204
|
-
|
|
244
|
+
onSubmit: (i) => (c) => {
|
|
245
|
+
c.preventDefault(), M(), I() && i(C());
|
|
205
246
|
},
|
|
206
|
-
reset: (
|
|
207
|
-
|
|
247
|
+
reset: (i) => {
|
|
248
|
+
u(() => ({
|
|
249
|
+
...t,
|
|
250
|
+
...i
|
|
251
|
+
})), V({}), q(!0);
|
|
208
252
|
}
|
|
209
253
|
};
|
|
210
254
|
};
|
|
211
255
|
export {
|
|
212
|
-
|
|
256
|
+
st as useForm
|
|
213
257
|
};
|
package/dist/main.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(g,
|
|
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"})});
|
package/dist/types/array.d.ts
CHANGED
|
@@ -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;
|
package/dist/types/errors.d.ts
CHANGED
|
@@ -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;
|
package/dist/types/path.d.ts
CHANGED
|
@@ -1,18 +1,6 @@
|
|
|
1
1
|
import { ArrayKey, IsTuple, TupleKeys } from './array';
|
|
2
|
-
import {
|
|
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 {};
|
package/dist/types/utils.d.ts
CHANGED
|
@@ -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
|
+
};
|
package/dist/use_form.d.ts
CHANGED
|
@@ -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:
|
|
18
|
+
onChange(event: ChangeEvent): void;
|
|
20
19
|
ref: (ref: HTMLInputElement | null) => void;
|
|
21
20
|
};
|
|
22
|
-
getValues: (name?: Path<T>) =>
|
|
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.
|
|
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",
|