@formisch/solid 0.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/index.js ADDED
@@ -0,0 +1,696 @@
1
+ import * as v from 'valibot';
2
+ import { untrack, batch, createUniqueId, createMemo, onCleanup, splitProps, createSignal as createSignal$1 } from 'solid-js';
3
+ import { memo, template, use, spread, mergeProps } from 'solid-js/web';
4
+
5
+ // ../../packages/core/dist/index.solid.js
6
+ var framework = "solid";
7
+ function createSignal(initialValue) {
8
+ const [getSignal, setSignal] = createSignal$1(initialValue);
9
+ return {
10
+ get value() {
11
+ return getSignal();
12
+ },
13
+ set value(nextValue) {
14
+ setSignal(() => nextValue);
15
+ }
16
+ };
17
+ }
18
+ function initializeFieldStore(internalFieldStore, schema, initialInput, path) {
19
+ if (framework === "qwik" && schema.type === "lazy" || schema.type === "object_with_rest" || schema.type === "record" || schema.type === "tuple_with_rest" || schema.type === "promise") throw new Error(`"${schema.type}" schema is not supported`);
20
+ else if (schema.type === "lazy") initializeFieldStore(internalFieldStore, schema.getter(void 0), initialInput, path);
21
+ else if (schema.type === "exact_optional" || schema.type === "non_nullable" || schema.type === "non_nullish" || schema.type === "non_optional" || schema.type === "nullable" || schema.type === "nullish" || schema.type === "optional" || schema.type === "undefinedable") initializeFieldStore(internalFieldStore, schema.wrapped, initialInput ?? v.getDefault(schema), path);
22
+ else if (schema.type === "intersect" || schema.type === "union" || schema.type === "variant") for (const schemaOption of schema.options) initializeFieldStore(internalFieldStore, schemaOption, initialInput, path);
23
+ else {
24
+ internalFieldStore.schema = schema;
25
+ internalFieldStore.name = JSON.stringify(path);
26
+ internalFieldStore.elements = [];
27
+ internalFieldStore.errors = createSignal(null);
28
+ if (schema.type === "array" || schema.type === "loose_tuple" || schema.type === "strict_tuple" || schema.type === "tuple") {
29
+ if (internalFieldStore.kind && internalFieldStore.kind !== "array") throw new Error(`Store initialized as "${internalFieldStore.kind}" cannot be reinitialized as "array"`);
30
+ internalFieldStore.kind = "array";
31
+ if (internalFieldStore.kind === "array") {
32
+ internalFieldStore.children ??= [];
33
+ if (schema.type === "array") {
34
+ if (initialInput) for (let index = 0; index < initialInput.length; index++) {
35
+ internalFieldStore.children[index] = {};
36
+ path.push(index);
37
+ initializeFieldStore(internalFieldStore.children[index], schema.item, initialInput[index], path);
38
+ path.pop();
39
+ }
40
+ } else for (let index = 0; index < schema.items; index++) {
41
+ internalFieldStore.children[index] = {};
42
+ path.push(index);
43
+ initializeFieldStore(internalFieldStore.children[index], schema.items[index], initialInput && initialInput[index], path);
44
+ path.pop();
45
+ }
46
+ const initialItems = internalFieldStore.children.map(createUniqueId);
47
+ internalFieldStore.initialItems = createSignal(initialItems);
48
+ internalFieldStore.startItems = createSignal(initialItems);
49
+ internalFieldStore.items = createSignal(initialItems);
50
+ internalFieldStore.isTouched = createSignal(false);
51
+ internalFieldStore.isDirty = createSignal(false);
52
+ }
53
+ } else if (schema.type === "loose_object" || schema.type === "object" || schema.type === "strict_object") {
54
+ if (internalFieldStore.kind && internalFieldStore.kind !== "object") throw new Error(`Store initialized as "${internalFieldStore.kind}" cannot be reinitialized as "object"`);
55
+ internalFieldStore.kind = "object";
56
+ if (internalFieldStore.kind === "object") {
57
+ internalFieldStore.children ??= {};
58
+ for (const key in schema.entries) {
59
+ internalFieldStore.children[key] = {};
60
+ path.push(key);
61
+ initializeFieldStore(internalFieldStore.children[key], schema.entries[key], initialInput && initialInput[key], path);
62
+ path.pop();
63
+ }
64
+ }
65
+ } else {
66
+ internalFieldStore.kind = "value";
67
+ if (internalFieldStore.kind === "value") {
68
+ internalFieldStore.initialInput = createSignal(initialInput);
69
+ internalFieldStore.startInput = createSignal(initialInput);
70
+ internalFieldStore.input = createSignal(initialInput);
71
+ internalFieldStore.isTouched = createSignal(false);
72
+ internalFieldStore.isDirty = createSignal(false);
73
+ }
74
+ }
75
+ }
76
+ }
77
+ function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
78
+ batch(() => {
79
+ untrack(() => {
80
+ if (fromInternalFieldStore.kind === "array" && toInternalFieldStore.kind === "array") {
81
+ const fromItems = fromInternalFieldStore.items.value;
82
+ toInternalFieldStore.isTouched.value = fromInternalFieldStore.isTouched.value;
83
+ toInternalFieldStore.isDirty.value = fromInternalFieldStore.isDirty.value;
84
+ toInternalFieldStore.startItems.value = fromInternalFieldStore.startItems.value;
85
+ toInternalFieldStore.items.value = fromItems;
86
+ let path;
87
+ for (let index = 0; index < fromItems.length; index++) {
88
+ if (!toInternalFieldStore.children[index]) {
89
+ path ??= JSON.parse(toInternalFieldStore.name);
90
+ toInternalFieldStore.children[index] = {};
91
+ path.push(index);
92
+ initializeFieldStore(toInternalFieldStore.children[index], toInternalFieldStore.schema.item, void 0, path);
93
+ path.pop();
94
+ }
95
+ copyItemState(fromInternalFieldStore.children[index], toInternalFieldStore.children[index]);
96
+ }
97
+ } else if (fromInternalFieldStore.kind === "object" && toInternalFieldStore.kind === "object") for (const key in fromInternalFieldStore.children) copyItemState(fromInternalFieldStore.children[key], toInternalFieldStore.children[key]);
98
+ else if (fromInternalFieldStore.kind === "value" && toInternalFieldStore.kind === "value") {
99
+ toInternalFieldStore.isTouched.value = fromInternalFieldStore.isTouched.value;
100
+ toInternalFieldStore.isDirty.value = fromInternalFieldStore.isDirty.value;
101
+ toInternalFieldStore.startInput.value = fromInternalFieldStore.startInput.value;
102
+ toInternalFieldStore.input.value = fromInternalFieldStore.input.value;
103
+ }
104
+ });
105
+ });
106
+ }
107
+ function resetItemState(internalFieldStore, initialInput) {
108
+ batch(() => {
109
+ if (internalFieldStore.kind === "array") {
110
+ internalFieldStore.isTouched.value = false;
111
+ internalFieldStore.isDirty.value = false;
112
+ if (initialInput) {
113
+ const newItems = initialInput.map(createUniqueId);
114
+ internalFieldStore.startItems.value = newItems;
115
+ internalFieldStore.items.value = newItems;
116
+ for (let index = 0; index < initialInput.length; index++) if (internalFieldStore.children[index]) resetItemState(internalFieldStore.children[index], initialInput[index]);
117
+ } else {
118
+ internalFieldStore.startItems.value = [];
119
+ internalFieldStore.items.value = [];
120
+ }
121
+ } else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) resetItemState(internalFieldStore.children[key], initialInput?.[key]);
122
+ else {
123
+ internalFieldStore.isTouched.value = false;
124
+ internalFieldStore.isDirty.value = false;
125
+ internalFieldStore.startInput.value = initialInput;
126
+ internalFieldStore.input.value = initialInput;
127
+ }
128
+ });
129
+ }
130
+ function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
131
+ batch(() => {
132
+ untrack(() => {
133
+ if (firstInternalFieldStore.kind === "array" && secondInternalFieldStore.kind === "array") {
134
+ const firstItems = firstInternalFieldStore.items.value;
135
+ const secondItems = secondInternalFieldStore.items.value;
136
+ const tempIsTouched = firstInternalFieldStore.isTouched.value;
137
+ firstInternalFieldStore.isTouched.value = secondInternalFieldStore.isTouched.value;
138
+ secondInternalFieldStore.isTouched.value = tempIsTouched;
139
+ const tempIsDirty = firstInternalFieldStore.isDirty.value;
140
+ firstInternalFieldStore.isDirty.value = secondInternalFieldStore.isDirty.value;
141
+ secondInternalFieldStore.isDirty.value = tempIsDirty;
142
+ const tempStartItems = firstInternalFieldStore.startItems.value;
143
+ firstInternalFieldStore.startItems.value = secondInternalFieldStore.startItems.value;
144
+ secondInternalFieldStore.startItems.value = tempStartItems;
145
+ firstInternalFieldStore.items.value = secondItems;
146
+ secondInternalFieldStore.items.value = firstItems;
147
+ const maxLength = Math.max(firstItems.length, secondItems.length);
148
+ let firstPath;
149
+ let secondPath;
150
+ for (let index = 0; index < maxLength; index++) {
151
+ if (!firstInternalFieldStore.children[index]) {
152
+ firstPath ??= JSON.parse(firstInternalFieldStore.name);
153
+ firstInternalFieldStore.children[index] = {};
154
+ firstPath.push(index);
155
+ initializeFieldStore(firstInternalFieldStore.children[index], firstInternalFieldStore.schema.item, void 0, firstPath);
156
+ firstPath.pop();
157
+ }
158
+ if (!secondInternalFieldStore.children[index]) {
159
+ secondPath ??= JSON.parse(secondInternalFieldStore.name);
160
+ secondInternalFieldStore.children[index] = {};
161
+ secondPath.push(index);
162
+ initializeFieldStore(secondInternalFieldStore.children[index], secondInternalFieldStore.schema.item, void 0, secondPath);
163
+ secondPath.pop();
164
+ }
165
+ swapItemState(firstInternalFieldStore.children[index], secondInternalFieldStore.children[index]);
166
+ }
167
+ } else if (firstInternalFieldStore.kind === "object" && secondInternalFieldStore.kind === "object") for (const key in firstInternalFieldStore.children) swapItemState(firstInternalFieldStore.children[key], secondInternalFieldStore.children[key]);
168
+ else if (firstInternalFieldStore.kind === "value" && secondInternalFieldStore.kind === "value") {
169
+ const tempIsTouched = firstInternalFieldStore.isTouched.value;
170
+ firstInternalFieldStore.isTouched.value = secondInternalFieldStore.isTouched.value;
171
+ secondInternalFieldStore.isTouched.value = tempIsTouched;
172
+ const tempIsDirty = firstInternalFieldStore.isDirty.value;
173
+ firstInternalFieldStore.isDirty.value = secondInternalFieldStore.isDirty.value;
174
+ secondInternalFieldStore.isDirty.value = tempIsDirty;
175
+ const tempStartInput = firstInternalFieldStore.startInput.value;
176
+ firstInternalFieldStore.startInput.value = secondInternalFieldStore.startInput.value;
177
+ secondInternalFieldStore.startInput.value = tempStartInput;
178
+ const tempInput = firstInternalFieldStore.input.value;
179
+ firstInternalFieldStore.input.value = secondInternalFieldStore.input.value;
180
+ secondInternalFieldStore.input.value = tempInput;
181
+ }
182
+ });
183
+ });
184
+ }
185
+ function getFieldInput(internalFieldStore) {
186
+ if (internalFieldStore.kind === "array") {
187
+ const value = [];
188
+ for (let index = 0; index < internalFieldStore.items.value.length; index++) value[index] = getFieldInput(internalFieldStore.children[index]);
189
+ return value;
190
+ }
191
+ if (internalFieldStore.kind === "object") {
192
+ const value = {};
193
+ for (const key in internalFieldStore.children) value[key] = getFieldInput(internalFieldStore.children[key]);
194
+ return value;
195
+ }
196
+ return internalFieldStore.input.value;
197
+ }
198
+ function getElementInput(element, internalFieldStore) {
199
+ if (element.options && element.multiple) return [...element.options].filter((option) => option.selected && !option.disabled).map((option) => option.value);
200
+ if (element.type === "checkbox") {
201
+ const options = document.getElementsByName(element.name);
202
+ if (options.length > 1) return [...options].filter((option) => option.checked).map((option) => option.value);
203
+ return element.checked;
204
+ }
205
+ if (element.type === "radio") {
206
+ const prevValue = untrack(() => getFieldInput(internalFieldStore));
207
+ if (element.checked) return [...prevValue, element.value];
208
+ return prevValue.filter((value) => value !== element.value);
209
+ }
210
+ if (element.type === "file") {
211
+ if (element.multiple) return [...element.files];
212
+ return element.files[0];
213
+ }
214
+ return element.value;
215
+ }
216
+ function getFieldBool(internalFieldStore, type) {
217
+ if (internalFieldStore.kind === "array") {
218
+ if (internalFieldStore[type].value) return true;
219
+ for (let index = 0; index < internalFieldStore.items.value.length; index++) if (getFieldBool(internalFieldStore.children[index], type)) return true;
220
+ return false;
221
+ }
222
+ if (internalFieldStore.kind == "object") {
223
+ if (type === "errors" && internalFieldStore[type].value) return true;
224
+ for (const key in internalFieldStore.children) if (getFieldBool(internalFieldStore.children[key], type)) return true;
225
+ return false;
226
+ }
227
+ return !!internalFieldStore[type].value;
228
+ }
229
+ function getFieldStore(internalFormStore, path) {
230
+ let internalFieldStore = internalFormStore;
231
+ for (const key of path) internalFieldStore = internalFieldStore.children[key];
232
+ return internalFieldStore;
233
+ }
234
+ function setFieldBool(internalFieldStore, type, bool) {
235
+ batch(() => {
236
+ if (internalFieldStore.kind === "array") {
237
+ internalFieldStore[type].value = bool;
238
+ for (let index = 0; index < untrack(() => internalFieldStore.items.value).length; index++) setFieldBool(internalFieldStore.children[index], type, bool);
239
+ } else if (internalFieldStore.kind == "object") for (const key in internalFieldStore.children) setFieldBool(internalFieldStore.children[key], type, bool);
240
+ else internalFieldStore[type].value = bool;
241
+ });
242
+ }
243
+ function setFieldInput(internalFieldStore, input) {
244
+ batch(() => {
245
+ if (internalFieldStore.kind === "array") {
246
+ const items = untrack(() => internalFieldStore.items.value);
247
+ if (input.length < items.length) internalFieldStore.items.value = items.slice(0, input.length);
248
+ else if (input.length > items.length) {
249
+ if (input.length > internalFieldStore.children.length) {
250
+ const path = JSON.parse(internalFieldStore.name);
251
+ for (let index = internalFieldStore.children.length; index < input.length; index++) {
252
+ internalFieldStore.children[index] = {};
253
+ path.push(index);
254
+ initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, input[index], path);
255
+ path.pop();
256
+ }
257
+ }
258
+ internalFieldStore.items.value = [...items, ...input.slice(items.length).map(createUniqueId)];
259
+ }
260
+ for (let index = 0; index < items.length; index++) setFieldInput(internalFieldStore.children[index], input[index]);
261
+ internalFieldStore.isDirty.value = untrack(() => internalFieldStore.startItems.value).length !== items.length;
262
+ } else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) setFieldInput(internalFieldStore.children[key], input[key]);
263
+ else {
264
+ internalFieldStore.input.value = input;
265
+ const startInput = untrack(() => internalFieldStore.startInput.value);
266
+ internalFieldStore.isDirty.value = startInput !== input && (startInput !== void 0 || input !== "" && !Number.isNaN(input));
267
+ }
268
+ });
269
+ }
270
+ function setInitialFieldInput(internalFieldStore, initialInput) {
271
+ batch(() => {
272
+ if (internalFieldStore.kind === "array") {
273
+ if (initialInput.length > internalFieldStore.children.length) {
274
+ const path = JSON.parse(internalFieldStore.name);
275
+ for (let index = internalFieldStore.children.length; index < initialInput.length; index++) {
276
+ internalFieldStore.children[index] = {};
277
+ path.push(index);
278
+ initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, initialInput[index], path);
279
+ path.pop();
280
+ }
281
+ }
282
+ internalFieldStore.initialItems.value = initialInput.map(createUniqueId);
283
+ for (let index = 0; index < internalFieldStore.children.length; index++) setInitialFieldInput(internalFieldStore.children[index], initialInput?.[index]);
284
+ } else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) setInitialFieldInput(internalFieldStore.children[key], initialInput?.[key]);
285
+ else internalFieldStore.initialInput.value = initialInput;
286
+ });
287
+ }
288
+ function walkFieldStore(internalFieldStore, callback) {
289
+ callback(internalFieldStore);
290
+ if (internalFieldStore.kind === "array") for (let index = 0; index < untrack(() => internalFieldStore.items.value).length; index++) walkFieldStore(internalFieldStore.children[index], callback);
291
+ else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) walkFieldStore(internalFieldStore.children[key], callback);
292
+ }
293
+ function createFormStore(config, validate2) {
294
+ const store = {};
295
+ initializeFieldStore(store, config.schema, config.initialInput, []);
296
+ store.validateOn = config.validateOn ?? "submit";
297
+ store.revalidateOn = config.revalidateOn ?? "input";
298
+ store.validate = validate2;
299
+ store.isSubmitting = createSignal(false);
300
+ store.isSubmitted = createSignal(false);
301
+ store.isValidating = createSignal(false);
302
+ return store;
303
+ }
304
+ async function validateFormInput(internalFormStore, config) {
305
+ internalFormStore.validators++;
306
+ internalFormStore.isValidating.value = true;
307
+ const result = await internalFormStore.validate(untrack(() => getFieldInput(internalFormStore)));
308
+ let rootErrors;
309
+ let nestedErrors;
310
+ if (result.issues) {
311
+ nestedErrors = {};
312
+ for (const issue of result.issues) if (issue.path) {
313
+ const path = [];
314
+ for (const pathItem of issue.path) {
315
+ const key = pathItem.key;
316
+ const keyType = typeof key;
317
+ const itemType = pathItem.type;
318
+ if (keyType !== "string" && keyType !== "number" || itemType === "map" || itemType === "set") break;
319
+ path.push(key);
320
+ }
321
+ const name = JSON.stringify(path);
322
+ const fieldErrors = nestedErrors[name];
323
+ if (fieldErrors) fieldErrors.push(issue.message);
324
+ else nestedErrors[name] = [issue.message];
325
+ } else if (rootErrors) rootErrors.push(issue.message);
326
+ else rootErrors = [issue.message];
327
+ }
328
+ let shouldFocus = config?.shouldFocus ?? false;
329
+ batch(() => {
330
+ walkFieldStore(internalFormStore, (internalFieldStore) => {
331
+ if (internalFieldStore.name === "[]") internalFieldStore.errors.value = rootErrors ?? null;
332
+ else {
333
+ const fieldErrors = nestedErrors?.[internalFieldStore.name] ?? null;
334
+ internalFieldStore.errors.value = fieldErrors;
335
+ if (shouldFocus && fieldErrors) {
336
+ internalFieldStore.elements[0]?.focus();
337
+ shouldFocus = false;
338
+ }
339
+ }
340
+ });
341
+ internalFormStore.validators--;
342
+ internalFormStore.isValidating.value = internalFormStore.validators > 0;
343
+ });
344
+ return result;
345
+ }
346
+ function validateIfRequired(internalFormStore, internalFieldStore, validationModes) {
347
+ if (validationModes === (internalFormStore.validateOn === "initial" || (internalFormStore.validateOn === "submit" ? untrack(() => internalFormStore.isSubmitted.value) : untrack(() => getFieldBool(internalFieldStore, "errors"))) ? internalFormStore.revalidateOn : internalFormStore.validateOn)) validateFormInput(internalFormStore);
348
+ }
349
+ var INTERNAL = "~internal";
350
+
351
+ // ../../packages/methods/dist/index.solid.js
352
+ function focus(config) {
353
+ getFieldStore(config.form[INTERNAL], config.path).elements[0]?.focus();
354
+ }
355
+ function getAllErrors(form) {
356
+ let allErrors = null;
357
+ walkFieldStore(form[INTERNAL], (internalFieldStore) => {
358
+ const errors = internalFieldStore.errors.value;
359
+ if (errors) if (allErrors) allErrors.push(...errors);
360
+ else allErrors = [...errors];
361
+ });
362
+ return allErrors;
363
+ }
364
+ function getErrors(form, config) {
365
+ return (config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]).errors.value;
366
+ }
367
+ function getInput(form, config) {
368
+ return getFieldInput(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]);
369
+ }
370
+ function insert(form, config) {
371
+ const internalFormStore = form[INTERNAL];
372
+ const internalArrayStore = getFieldStore(internalFormStore, config.path);
373
+ const items = untrack(() => internalArrayStore.items.value);
374
+ const insertIndex = config.at === void 0 ? items.length : config.at;
375
+ if (insertIndex >= 0 && insertIndex <= items.length) batch(() => {
376
+ const newItems = [...items];
377
+ newItems.splice(insertIndex, 0, createUniqueId());
378
+ internalArrayStore.items.value = newItems;
379
+ for (let index = items.length; index > insertIndex; index--) copyItemState(internalArrayStore.children[index - 1], internalArrayStore.children[index]);
380
+ if (!internalArrayStore.children[insertIndex]) {
381
+ const path = JSON.parse(internalArrayStore.name);
382
+ internalArrayStore.children[insertIndex] = {};
383
+ path.push(insertIndex);
384
+ initializeFieldStore(internalArrayStore.children[insertIndex], internalArrayStore.schema.item, config.initialInput, path);
385
+ } else resetItemState(internalArrayStore.children[insertIndex], config.initialInput);
386
+ internalArrayStore.isTouched.value = true;
387
+ internalArrayStore.isDirty.value = true;
388
+ validateIfRequired(internalFormStore, internalArrayStore, "input");
389
+ });
390
+ }
391
+ function move(form, config) {
392
+ const internalFormStore = form[INTERNAL];
393
+ const internalArrayStore = getFieldStore(internalFormStore, config.path);
394
+ const items = untrack(() => internalArrayStore.items.value);
395
+ if (config.from >= 0 && config.from <= items.length - 1 && config.to >= 0 && config.to <= items.length - 1 && config.from !== config.to) batch(() => {
396
+ const newItems = [...items];
397
+ newItems.splice(config.to, 0, newItems.splice(config.from, 1)[0]);
398
+ internalArrayStore.items.value = newItems;
399
+ const tempInternalFieldStore = {};
400
+ initializeFieldStore(tempInternalFieldStore, internalArrayStore.schema.item, void 0, []);
401
+ copyItemState(internalArrayStore.children[config.from < config.to ? config.from : config.to], tempInternalFieldStore);
402
+ if (config.from < config.to) for (let index = config.from; index < config.to; index++) copyItemState(internalArrayStore.children[index + 1], internalArrayStore.children[index]);
403
+ else for (let index = config.from; index > config.to; index--) copyItemState(internalArrayStore.children[index - 1], internalArrayStore.children[index]);
404
+ copyItemState(tempInternalFieldStore, internalArrayStore.children[config.from < config.to ? config.to : config.from]);
405
+ internalArrayStore.isTouched.value = true;
406
+ internalArrayStore.isDirty.value = internalArrayStore.startItems.value.join() !== newItems.join();
407
+ validateIfRequired(internalFormStore, internalArrayStore, "input");
408
+ });
409
+ }
410
+ function remove(form, config) {
411
+ const internalFormStore = form[INTERNAL];
412
+ const internalArrayStore = getFieldStore(internalFormStore, config.path);
413
+ const items = untrack(() => internalArrayStore.items.value);
414
+ if (config.at >= 0 && config.at <= items.length - 1) batch(() => {
415
+ const newItems = [...items];
416
+ newItems.splice(config.at, 1);
417
+ internalArrayStore.items.value = newItems;
418
+ for (let index = config.at; index < items.length - 1; index++) copyItemState(internalArrayStore.children[index + 1], internalArrayStore.children[index]);
419
+ internalArrayStore.isTouched.value = true;
420
+ internalArrayStore.isDirty.value = internalArrayStore.startItems.value.join() !== newItems.join();
421
+ validateIfRequired(internalFormStore, internalArrayStore, "input");
422
+ });
423
+ }
424
+ function replace(form, config) {
425
+ const internalFormStore = form[INTERNAL];
426
+ const internalArrayStore = getFieldStore(internalFormStore, config.path);
427
+ const items = untrack(() => internalArrayStore.items.value);
428
+ if (config.at >= 0 && config.at <= items.length - 1) batch(() => {
429
+ const newItems = [...items];
430
+ newItems[config.at] = createUniqueId();
431
+ internalArrayStore.items.value = newItems;
432
+ resetItemState(internalArrayStore.children[config.at], config.initialInput);
433
+ internalArrayStore.isTouched.value = true;
434
+ internalArrayStore.isDirty.value = true;
435
+ validateIfRequired(internalFormStore, internalArrayStore, "input");
436
+ });
437
+ }
438
+ function reset(form, config) {
439
+ batch(() => {
440
+ untrack(() => {
441
+ const internalFormStore = form[INTERNAL];
442
+ const internalFieldStore = config?.path ? getFieldStore(internalFormStore, config.path) : internalFormStore;
443
+ if (config?.initialInput) setInitialFieldInput(internalFieldStore, config.initialInput);
444
+ walkFieldStore(internalFieldStore, (internalFieldStore$1) => {
445
+ if (!config?.keepErrors) internalFieldStore$1.errors.value = null;
446
+ if (internalFieldStore$1.kind === "array") {
447
+ internalFieldStore$1.startItems.value = internalFieldStore$1.initialItems.value;
448
+ if (!config?.keepInput || internalFieldStore$1.startItems.value.length === internalFieldStore$1.items.value.length) internalFieldStore$1.items.value = internalFieldStore$1.initialItems.value;
449
+ if (!config?.keepTouched) internalFieldStore$1.isTouched.value = false;
450
+ internalFieldStore$1.isDirty.value = internalFieldStore$1.startItems.value !== internalFieldStore$1.items.value;
451
+ } else if (internalFieldStore$1.kind === "value") {
452
+ internalFieldStore$1.startInput.value = internalFieldStore$1.initialInput.value;
453
+ if (!config?.keepInput) internalFieldStore$1.input.value = internalFieldStore$1.initialInput.value;
454
+ if (!config?.keepTouched) internalFieldStore$1.isTouched.value = false;
455
+ internalFieldStore$1.isDirty.value = internalFieldStore$1.startInput.value !== internalFieldStore$1.input.value;
456
+ for (const element of internalFieldStore$1.elements) if (element.type === "file") element.value = "";
457
+ }
458
+ });
459
+ if (!config?.path) {
460
+ if (!config?.keepSubmitted) internalFormStore.isSubmitted.value = false;
461
+ if (internalFormStore.validateOn === "initial") validateFormInput(internalFormStore);
462
+ }
463
+ });
464
+ });
465
+ }
466
+ function setErrors(form, config) {
467
+ (config.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]).errors.value = config.errors;
468
+ }
469
+ function setInput(form, config) {
470
+ batch(() => {
471
+ const internalFormStore = form[INTERNAL];
472
+ const internalFieldStore = config.path ? getFieldStore(internalFormStore, config.path) : internalFormStore;
473
+ setFieldBool(internalFieldStore, "isTouched", true);
474
+ setFieldInput(internalFieldStore, config.input);
475
+ validateIfRequired(internalFormStore, internalFieldStore, "input");
476
+ });
477
+ }
478
+ function submit(form) {
479
+ form[INTERNAL].element?.requestSubmit();
480
+ }
481
+ function swap(form, config) {
482
+ const internalFormStore = form[INTERNAL];
483
+ const internalArrayStore = getFieldStore(internalFormStore, config.path);
484
+ const items = untrack(() => internalArrayStore.items.value);
485
+ if (config.at >= 0 && config.at <= items.length - 1 && config.and >= 0 && config.and <= items.length - 1 && config.at !== config.and) batch(() => {
486
+ const newItems = [...items];
487
+ const tempItemId = newItems[config.at];
488
+ newItems[config.at] = newItems[config.and];
489
+ newItems[config.and] = tempItemId;
490
+ internalArrayStore.items.value = newItems;
491
+ swapItemState(internalArrayStore.children[config.at], internalArrayStore.children[config.and]);
492
+ internalArrayStore.isTouched.value = true;
493
+ internalArrayStore.isDirty.value = internalArrayStore.startItems.value.join() !== newItems.join();
494
+ validateIfRequired(internalFormStore, internalArrayStore, "input");
495
+ });
496
+ }
497
+ function validate(form, config) {
498
+ return validateFormInput(form[INTERNAL], config);
499
+ }
500
+ function createForm(config) {
501
+ const internalFormStore = createFormStore(
502
+ config,
503
+ async (input) => v.safeParseAsync(config.schema, input)
504
+ );
505
+ const form = {
506
+ [INTERNAL]: internalFormStore,
507
+ get isSubmitting() {
508
+ return internalFormStore.isSubmitting.value;
509
+ },
510
+ get isSubmitted() {
511
+ return internalFormStore.isSubmitted.value;
512
+ },
513
+ get isValidating() {
514
+ return internalFormStore.isValidating.value;
515
+ },
516
+ get isTouched() {
517
+ return getFieldBool(internalFormStore, "isTouched");
518
+ },
519
+ get isDirty() {
520
+ return getFieldBool(internalFormStore, "isDirty");
521
+ },
522
+ get isValid() {
523
+ return !getFieldBool(internalFormStore, "errors");
524
+ },
525
+ get errors() {
526
+ return internalFormStore.errors.value;
527
+ }
528
+ };
529
+ if (config.validateOn === "initial") {
530
+ validateFormInput(form[INTERNAL]);
531
+ }
532
+ return form;
533
+ }
534
+
535
+ // src/utils/unwrap/unwrap.ts
536
+ function unwrap(value) {
537
+ if (typeof value === "function") {
538
+ return value();
539
+ }
540
+ return value;
541
+ }
542
+
543
+ // src/primitives/useField/useField.ts
544
+ function useField(form, config) {
545
+ const getInternalFormStore = createMemo(() => unwrap(form)[INTERNAL]);
546
+ const getInternalFieldStore = createMemo(
547
+ () => getFieldStore(getInternalFormStore(), unwrap(config).path)
548
+ );
549
+ return {
550
+ get path() {
551
+ return unwrap(config).path;
552
+ },
553
+ get input() {
554
+ return getFieldInput(getInternalFieldStore());
555
+ },
556
+ get errors() {
557
+ return getInternalFieldStore().errors.value;
558
+ },
559
+ get isTouched() {
560
+ return getFieldBool(getInternalFieldStore(), "isTouched");
561
+ },
562
+ get isDirty() {
563
+ return getFieldBool(getInternalFieldStore(), "isDirty");
564
+ },
565
+ get isValid() {
566
+ return !getFieldBool(getInternalFieldStore(), "errors");
567
+ },
568
+ props: {
569
+ get name() {
570
+ return getInternalFieldStore().name;
571
+ },
572
+ // eslint-disable-next-line solid/reactivity
573
+ autofocus: !!getInternalFieldStore().errors.value,
574
+ ref: (element) => {
575
+ const internalFieldStore = getInternalFieldStore();
576
+ internalFieldStore.elements.push(element);
577
+ onCleanup(() => {
578
+ internalFieldStore.elements = internalFieldStore.elements.filter(
579
+ (el) => el !== element
580
+ );
581
+ });
582
+ },
583
+ onFocus() {
584
+ setFieldBool(getInternalFieldStore(), "isTouched", true);
585
+ validateIfRequired(
586
+ getInternalFormStore(),
587
+ getInternalFieldStore(),
588
+ "touch"
589
+ );
590
+ },
591
+ onInput(event) {
592
+ const internalFieldStore = getInternalFieldStore();
593
+ const nextValue = getElementInput(
594
+ event.currentTarget,
595
+ internalFieldStore
596
+ );
597
+ setFieldInput(internalFieldStore, nextValue);
598
+ validateIfRequired(getInternalFormStore(), internalFieldStore, "input");
599
+ },
600
+ onChange() {
601
+ validateIfRequired(
602
+ getInternalFormStore(),
603
+ getInternalFieldStore(),
604
+ "change"
605
+ );
606
+ },
607
+ onBlur() {
608
+ validateIfRequired(
609
+ getInternalFormStore(),
610
+ getInternalFieldStore(),
611
+ "blur"
612
+ );
613
+ }
614
+ }
615
+ };
616
+ }
617
+ function useFieldArray(form, config) {
618
+ const getInternalFieldStore = createMemo(
619
+ () => getFieldStore(
620
+ unwrap(form)[INTERNAL],
621
+ unwrap(config).path
622
+ )
623
+ );
624
+ return {
625
+ get path() {
626
+ return unwrap(config).path;
627
+ },
628
+ get items() {
629
+ return getInternalFieldStore().items.value;
630
+ },
631
+ get errors() {
632
+ return getInternalFieldStore().errors.value;
633
+ },
634
+ get isTouched() {
635
+ return getFieldBool(getInternalFieldStore(), "isTouched");
636
+ },
637
+ get isDirty() {
638
+ return getFieldBool(getInternalFieldStore(), "isDirty");
639
+ },
640
+ get isValid() {
641
+ return !getFieldBool(getInternalFieldStore(), "errors");
642
+ }
643
+ };
644
+ }
645
+
646
+ // src/components/Field/Field.tsx
647
+ function Field(props) {
648
+ const field = useField(() => props.of, {
649
+ get path() {
650
+ return props.path;
651
+ }
652
+ });
653
+ return memo(() => props.render(field));
654
+ }
655
+ function FieldArray(props) {
656
+ const field = useFieldArray(() => props.of, {
657
+ get path() {
658
+ return props.path;
659
+ }
660
+ });
661
+ return memo(() => props.render(field));
662
+ }
663
+ var _tmpl$ = /* @__PURE__ */ template(`<form>`);
664
+ function Form(props) {
665
+ const [, other] = splitProps(props, ["of", "onSubmit"]);
666
+ return (() => {
667
+ var _el$ = _tmpl$();
668
+ use((element) => {
669
+ props.of[INTERNAL].element = element;
670
+ }, _el$);
671
+ spread(_el$, mergeProps(other, {
672
+ "novalidate": true,
673
+ "onSubmit": async (event) => {
674
+ event.preventDefault();
675
+ const internalFormStore = props.of[INTERNAL];
676
+ internalFormStore.isSubmitted.value = true;
677
+ internalFormStore.isSubmitting.value = true;
678
+ try {
679
+ const result = await validateFormInput(internalFormStore, {
680
+ shouldFocus: true
681
+ });
682
+ if (result.success) {
683
+ await props.onSubmit(result.output, event);
684
+ }
685
+ } catch (error) {
686
+ internalFormStore.errors.value = [error instanceof Error ? error.message : "An unknown error has occurred."];
687
+ } finally {
688
+ internalFormStore.isSubmitting.value = false;
689
+ }
690
+ }
691
+ }), false, false);
692
+ return _el$;
693
+ })();
694
+ }
695
+
696
+ export { Field, FieldArray, Form, createForm, focus, getAllErrors, getErrors, getInput, insert, move, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, validate };