@formisch/solid 0.1.0 → 0.2.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/README.md +7 -11
- package/dist/dev.js +76 -53
- package/dist/dev.jsx +84 -59
- package/dist/index.d.ts +363 -69
- package/dist/index.js +76 -53
- package/dist/index.jsx +84 -59
- package/package.json +5 -9
package/dist/index.js
CHANGED
|
@@ -106,6 +106,7 @@ function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
|
|
|
106
106
|
}
|
|
107
107
|
function resetItemState(internalFieldStore, initialInput) {
|
|
108
108
|
batch(() => {
|
|
109
|
+
internalFieldStore.errors.value = null;
|
|
109
110
|
if (internalFieldStore.kind === "array") {
|
|
110
111
|
internalFieldStore.isTouched.value = false;
|
|
111
112
|
internalFieldStore.isDirty.value = false;
|
|
@@ -290,12 +291,12 @@ function walkFieldStore(internalFieldStore, callback) {
|
|
|
290
291
|
if (internalFieldStore.kind === "array") for (let index = 0; index < untrack(() => internalFieldStore.items.value).length; index++) walkFieldStore(internalFieldStore.children[index], callback);
|
|
291
292
|
else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) walkFieldStore(internalFieldStore.children[key], callback);
|
|
292
293
|
}
|
|
293
|
-
function createFormStore(config,
|
|
294
|
+
function createFormStore(config, parse) {
|
|
294
295
|
const store = {};
|
|
295
296
|
initializeFieldStore(store, config.schema, config.initialInput, []);
|
|
296
|
-
store.
|
|
297
|
-
store.
|
|
298
|
-
store.
|
|
297
|
+
store.validate = config.validate ?? "submit";
|
|
298
|
+
store.revalidate = config.revalidate ?? "input";
|
|
299
|
+
store.parse = parse;
|
|
299
300
|
store.isSubmitting = createSignal(false);
|
|
300
301
|
store.isSubmitted = createSignal(false);
|
|
301
302
|
store.isValidating = createSignal(false);
|
|
@@ -304,7 +305,7 @@ function createFormStore(config, validate2) {
|
|
|
304
305
|
async function validateFormInput(internalFormStore, config) {
|
|
305
306
|
internalFormStore.validators++;
|
|
306
307
|
internalFormStore.isValidating.value = true;
|
|
307
|
-
const result = await internalFormStore.
|
|
308
|
+
const result = await internalFormStore.parse(untrack(() => getFieldInput(internalFormStore)));
|
|
308
309
|
let rootErrors;
|
|
309
310
|
let nestedErrors;
|
|
310
311
|
if (result.issues) {
|
|
@@ -344,7 +345,7 @@ async function validateFormInput(internalFormStore, config) {
|
|
|
344
345
|
return result;
|
|
345
346
|
}
|
|
346
347
|
function validateIfRequired(internalFormStore, internalFieldStore, validationModes) {
|
|
347
|
-
if (validationModes === (internalFormStore.
|
|
348
|
+
if (validationModes === (internalFormStore.validate === "initial" || (internalFormStore.validate === "submit" ? untrack(() => internalFormStore.isSubmitted.value) : untrack(() => getFieldBool(internalFieldStore, "errors"))) ? internalFormStore.revalidate : internalFormStore.validate)) validateFormInput(internalFormStore);
|
|
348
349
|
}
|
|
349
350
|
var INTERNAL = "~internal";
|
|
350
351
|
|
|
@@ -367,6 +368,22 @@ function getErrors(form, config) {
|
|
|
367
368
|
function getInput(form, config) {
|
|
368
369
|
return getFieldInput(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]);
|
|
369
370
|
}
|
|
371
|
+
function handleSubmit(form, handler) {
|
|
372
|
+
return async (event) => {
|
|
373
|
+
event.preventDefault();
|
|
374
|
+
const internalFormStore = form[INTERNAL];
|
|
375
|
+
internalFormStore.isSubmitted.value = true;
|
|
376
|
+
internalFormStore.isSubmitting.value = true;
|
|
377
|
+
try {
|
|
378
|
+
const result = await validateFormInput(internalFormStore, { shouldFocus: true });
|
|
379
|
+
if (result.success) await handler(result.output, event);
|
|
380
|
+
} catch (error) {
|
|
381
|
+
internalFormStore.errors.value = [error instanceof Error ? error.message : "An unknown error has occurred."];
|
|
382
|
+
} finally {
|
|
383
|
+
internalFormStore.isSubmitting.value = false;
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
}
|
|
370
387
|
function insert(form, config) {
|
|
371
388
|
const internalFormStore = form[INTERNAL];
|
|
372
389
|
const internalArrayStore = getFieldStore(internalFormStore, config.path);
|
|
@@ -458,7 +475,7 @@ function reset(form, config) {
|
|
|
458
475
|
});
|
|
459
476
|
if (!config?.path) {
|
|
460
477
|
if (!config?.keepSubmitted) internalFormStore.isSubmitted.value = false;
|
|
461
|
-
if (internalFormStore.
|
|
478
|
+
if (internalFormStore.validate === "initial") validateFormInput(internalFormStore);
|
|
462
479
|
}
|
|
463
480
|
});
|
|
464
481
|
});
|
|
@@ -502,6 +519,15 @@ function createForm(config) {
|
|
|
502
519
|
config,
|
|
503
520
|
async (input) => v.safeParseAsync(config.schema, input)
|
|
504
521
|
);
|
|
522
|
+
const getIsTouched = createMemo(
|
|
523
|
+
() => getFieldBool(internalFormStore, "isTouched")
|
|
524
|
+
);
|
|
525
|
+
const getIsDirty = createMemo(
|
|
526
|
+
() => getFieldBool(internalFormStore, "isDirty")
|
|
527
|
+
);
|
|
528
|
+
const getIsValid = createMemo(
|
|
529
|
+
() => !getFieldBool(internalFormStore, "errors")
|
|
530
|
+
);
|
|
505
531
|
const form = {
|
|
506
532
|
[INTERNAL]: internalFormStore,
|
|
507
533
|
get isSubmitting() {
|
|
@@ -514,19 +540,19 @@ function createForm(config) {
|
|
|
514
540
|
return internalFormStore.isValidating.value;
|
|
515
541
|
},
|
|
516
542
|
get isTouched() {
|
|
517
|
-
return
|
|
543
|
+
return getIsTouched();
|
|
518
544
|
},
|
|
519
545
|
get isDirty() {
|
|
520
|
-
return
|
|
546
|
+
return getIsDirty();
|
|
521
547
|
},
|
|
522
548
|
get isValid() {
|
|
523
|
-
return
|
|
549
|
+
return getIsValid();
|
|
524
550
|
},
|
|
525
551
|
get errors() {
|
|
526
552
|
return internalFormStore.errors.value;
|
|
527
553
|
}
|
|
528
554
|
};
|
|
529
|
-
if (config.
|
|
555
|
+
if (config.validate === "initial") {
|
|
530
556
|
validateFormInput(form[INTERNAL]);
|
|
531
557
|
}
|
|
532
558
|
return form;
|
|
@@ -546,24 +572,34 @@ function useField(form, config) {
|
|
|
546
572
|
const getInternalFieldStore = createMemo(
|
|
547
573
|
() => getFieldStore(getInternalFormStore(), unwrap(config).path)
|
|
548
574
|
);
|
|
575
|
+
const getInput2 = createMemo(() => getFieldInput(getInternalFieldStore()));
|
|
576
|
+
const getIsTouched = createMemo(
|
|
577
|
+
() => getFieldBool(getInternalFieldStore(), "isTouched")
|
|
578
|
+
);
|
|
579
|
+
const getIsDirty = createMemo(
|
|
580
|
+
() => getFieldBool(getInternalFieldStore(), "isDirty")
|
|
581
|
+
);
|
|
582
|
+
const getIsValid = createMemo(
|
|
583
|
+
() => !getFieldBool(getInternalFieldStore(), "errors")
|
|
584
|
+
);
|
|
549
585
|
return {
|
|
550
586
|
get path() {
|
|
551
587
|
return unwrap(config).path;
|
|
552
588
|
},
|
|
553
589
|
get input() {
|
|
554
|
-
return
|
|
590
|
+
return getInput2();
|
|
555
591
|
},
|
|
556
592
|
get errors() {
|
|
557
593
|
return getInternalFieldStore().errors.value;
|
|
558
594
|
},
|
|
559
595
|
get isTouched() {
|
|
560
|
-
return
|
|
596
|
+
return getIsTouched();
|
|
561
597
|
},
|
|
562
598
|
get isDirty() {
|
|
563
|
-
return
|
|
599
|
+
return getIsDirty();
|
|
564
600
|
},
|
|
565
601
|
get isValid() {
|
|
566
|
-
return
|
|
602
|
+
return getIsValid();
|
|
567
603
|
},
|
|
568
604
|
props: {
|
|
569
605
|
get name() {
|
|
@@ -590,11 +626,10 @@ function useField(form, config) {
|
|
|
590
626
|
},
|
|
591
627
|
onInput(event) {
|
|
592
628
|
const internalFieldStore = getInternalFieldStore();
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
internalFieldStore
|
|
629
|
+
setFieldInput(
|
|
630
|
+
internalFieldStore,
|
|
631
|
+
getElementInput(event.currentTarget, internalFieldStore)
|
|
596
632
|
);
|
|
597
|
-
setFieldInput(internalFieldStore, nextValue);
|
|
598
633
|
validateIfRequired(getInternalFormStore(), internalFieldStore, "input");
|
|
599
634
|
},
|
|
600
635
|
onChange() {
|
|
@@ -621,6 +656,15 @@ function useFieldArray(form, config) {
|
|
|
621
656
|
unwrap(config).path
|
|
622
657
|
)
|
|
623
658
|
);
|
|
659
|
+
const getIsTouched = createMemo(
|
|
660
|
+
() => getFieldBool(getInternalFieldStore(), "isTouched")
|
|
661
|
+
);
|
|
662
|
+
const getIsDirty = createMemo(
|
|
663
|
+
() => getFieldBool(getInternalFieldStore(), "isDirty")
|
|
664
|
+
);
|
|
665
|
+
const getIsValid = createMemo(
|
|
666
|
+
() => !getFieldBool(getInternalFieldStore(), "errors")
|
|
667
|
+
);
|
|
624
668
|
return {
|
|
625
669
|
get path() {
|
|
626
670
|
return unwrap(config).path;
|
|
@@ -632,33 +676,29 @@ function useFieldArray(form, config) {
|
|
|
632
676
|
return getInternalFieldStore().errors.value;
|
|
633
677
|
},
|
|
634
678
|
get isTouched() {
|
|
635
|
-
return
|
|
679
|
+
return getIsTouched();
|
|
636
680
|
},
|
|
637
681
|
get isDirty() {
|
|
638
|
-
return
|
|
682
|
+
return getIsDirty();
|
|
639
683
|
},
|
|
640
684
|
get isValid() {
|
|
641
|
-
return
|
|
685
|
+
return getIsValid();
|
|
642
686
|
}
|
|
643
687
|
};
|
|
644
688
|
}
|
|
645
689
|
|
|
646
690
|
// src/components/Field/Field.tsx
|
|
647
691
|
function Field(props) {
|
|
648
|
-
const field = useField(() => props.of, {
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
});
|
|
653
|
-
return memo(() => props.render(field));
|
|
692
|
+
const field = useField(() => props.of, () => ({
|
|
693
|
+
path: props.path
|
|
694
|
+
}));
|
|
695
|
+
return memo(() => props.children(field));
|
|
654
696
|
}
|
|
655
697
|
function FieldArray(props) {
|
|
656
|
-
const field = useFieldArray(() => props.of, {
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
});
|
|
661
|
-
return memo(() => props.render(field));
|
|
698
|
+
const field = useFieldArray(() => props.of, () => ({
|
|
699
|
+
path: props.path
|
|
700
|
+
}));
|
|
701
|
+
return memo(() => props.children(field));
|
|
662
702
|
}
|
|
663
703
|
var _tmpl$ = /* @__PURE__ */ template(`<form>`);
|
|
664
704
|
function Form(props) {
|
|
@@ -670,27 +710,10 @@ function Form(props) {
|
|
|
670
710
|
}, _el$);
|
|
671
711
|
spread(_el$, mergeProps(other, {
|
|
672
712
|
"novalidate": true,
|
|
673
|
-
"onSubmit":
|
|
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
|
-
}
|
|
713
|
+
"onSubmit": (event) => handleSubmit(props.of, props.onSubmit)(event)
|
|
691
714
|
}), false, false);
|
|
692
715
|
return _el$;
|
|
693
716
|
})();
|
|
694
717
|
}
|
|
695
718
|
|
|
696
|
-
export { Field, FieldArray, Form, createForm, focus, getAllErrors, getErrors, getInput, insert, move, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, validate };
|
|
719
|
+
export { Field, FieldArray, Form, createForm, focus, getAllErrors, getErrors, getInput, handleSubmit, insert, move, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, validate };
|
package/dist/index.jsx
CHANGED
|
@@ -104,6 +104,7 @@ function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
|
|
|
104
104
|
}
|
|
105
105
|
function resetItemState(internalFieldStore, initialInput) {
|
|
106
106
|
batch(() => {
|
|
107
|
+
internalFieldStore.errors.value = null;
|
|
107
108
|
if (internalFieldStore.kind === "array") {
|
|
108
109
|
internalFieldStore.isTouched.value = false;
|
|
109
110
|
internalFieldStore.isDirty.value = false;
|
|
@@ -288,12 +289,12 @@ function walkFieldStore(internalFieldStore, callback) {
|
|
|
288
289
|
if (internalFieldStore.kind === "array") for (let index = 0; index < untrack(() => internalFieldStore.items.value).length; index++) walkFieldStore(internalFieldStore.children[index], callback);
|
|
289
290
|
else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) walkFieldStore(internalFieldStore.children[key], callback);
|
|
290
291
|
}
|
|
291
|
-
function createFormStore(config,
|
|
292
|
+
function createFormStore(config, parse) {
|
|
292
293
|
const store = {};
|
|
293
294
|
initializeFieldStore(store, config.schema, config.initialInput, []);
|
|
294
|
-
store.
|
|
295
|
-
store.
|
|
296
|
-
store.
|
|
295
|
+
store.validate = config.validate ?? "submit";
|
|
296
|
+
store.revalidate = config.revalidate ?? "input";
|
|
297
|
+
store.parse = parse;
|
|
297
298
|
store.isSubmitting = createSignal(false);
|
|
298
299
|
store.isSubmitted = createSignal(false);
|
|
299
300
|
store.isValidating = createSignal(false);
|
|
@@ -302,7 +303,7 @@ function createFormStore(config, validate2) {
|
|
|
302
303
|
async function validateFormInput(internalFormStore, config) {
|
|
303
304
|
internalFormStore.validators++;
|
|
304
305
|
internalFormStore.isValidating.value = true;
|
|
305
|
-
const result = await internalFormStore.
|
|
306
|
+
const result = await internalFormStore.parse(untrack(() => getFieldInput(internalFormStore)));
|
|
306
307
|
let rootErrors;
|
|
307
308
|
let nestedErrors;
|
|
308
309
|
if (result.issues) {
|
|
@@ -342,7 +343,7 @@ async function validateFormInput(internalFormStore, config) {
|
|
|
342
343
|
return result;
|
|
343
344
|
}
|
|
344
345
|
function validateIfRequired(internalFormStore, internalFieldStore, validationModes) {
|
|
345
|
-
if (validationModes === (internalFormStore.
|
|
346
|
+
if (validationModes === (internalFormStore.validate === "initial" || (internalFormStore.validate === "submit" ? untrack(() => internalFormStore.isSubmitted.value) : untrack(() => getFieldBool(internalFieldStore, "errors"))) ? internalFormStore.revalidate : internalFormStore.validate)) validateFormInput(internalFormStore);
|
|
346
347
|
}
|
|
347
348
|
var INTERNAL = "~internal";
|
|
348
349
|
|
|
@@ -365,6 +366,22 @@ function getErrors(form, config) {
|
|
|
365
366
|
function getInput(form, config) {
|
|
366
367
|
return getFieldInput(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]);
|
|
367
368
|
}
|
|
369
|
+
function handleSubmit(form, handler) {
|
|
370
|
+
return async (event) => {
|
|
371
|
+
event.preventDefault();
|
|
372
|
+
const internalFormStore = form[INTERNAL];
|
|
373
|
+
internalFormStore.isSubmitted.value = true;
|
|
374
|
+
internalFormStore.isSubmitting.value = true;
|
|
375
|
+
try {
|
|
376
|
+
const result = await validateFormInput(internalFormStore, { shouldFocus: true });
|
|
377
|
+
if (result.success) await handler(result.output, event);
|
|
378
|
+
} catch (error) {
|
|
379
|
+
internalFormStore.errors.value = [error instanceof Error ? error.message : "An unknown error has occurred."];
|
|
380
|
+
} finally {
|
|
381
|
+
internalFormStore.isSubmitting.value = false;
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
}
|
|
368
385
|
function insert(form, config) {
|
|
369
386
|
const internalFormStore = form[INTERNAL];
|
|
370
387
|
const internalArrayStore = getFieldStore(internalFormStore, config.path);
|
|
@@ -456,7 +473,7 @@ function reset(form, config) {
|
|
|
456
473
|
});
|
|
457
474
|
if (!config?.path) {
|
|
458
475
|
if (!config?.keepSubmitted) internalFormStore.isSubmitted.value = false;
|
|
459
|
-
if (internalFormStore.
|
|
476
|
+
if (internalFormStore.validate === "initial") validateFormInput(internalFormStore);
|
|
460
477
|
}
|
|
461
478
|
});
|
|
462
479
|
});
|
|
@@ -497,12 +514,22 @@ function validate(form, config) {
|
|
|
497
514
|
}
|
|
498
515
|
|
|
499
516
|
// src/primitives/createForm/createForm.ts
|
|
517
|
+
import { createMemo } from "solid-js";
|
|
500
518
|
import * as v2 from "valibot";
|
|
501
519
|
function createForm(config) {
|
|
502
520
|
const internalFormStore = createFormStore(
|
|
503
521
|
config,
|
|
504
522
|
async (input) => v2.safeParseAsync(config.schema, input)
|
|
505
523
|
);
|
|
524
|
+
const getIsTouched = createMemo(
|
|
525
|
+
() => getFieldBool(internalFormStore, "isTouched")
|
|
526
|
+
);
|
|
527
|
+
const getIsDirty = createMemo(
|
|
528
|
+
() => getFieldBool(internalFormStore, "isDirty")
|
|
529
|
+
);
|
|
530
|
+
const getIsValid = createMemo(
|
|
531
|
+
() => !getFieldBool(internalFormStore, "errors")
|
|
532
|
+
);
|
|
506
533
|
const form = {
|
|
507
534
|
[INTERNAL]: internalFormStore,
|
|
508
535
|
get isSubmitting() {
|
|
@@ -515,26 +542,26 @@ function createForm(config) {
|
|
|
515
542
|
return internalFormStore.isValidating.value;
|
|
516
543
|
},
|
|
517
544
|
get isTouched() {
|
|
518
|
-
return
|
|
545
|
+
return getIsTouched();
|
|
519
546
|
},
|
|
520
547
|
get isDirty() {
|
|
521
|
-
return
|
|
548
|
+
return getIsDirty();
|
|
522
549
|
},
|
|
523
550
|
get isValid() {
|
|
524
|
-
return
|
|
551
|
+
return getIsValid();
|
|
525
552
|
},
|
|
526
553
|
get errors() {
|
|
527
554
|
return internalFormStore.errors.value;
|
|
528
555
|
}
|
|
529
556
|
};
|
|
530
|
-
if (config.
|
|
557
|
+
if (config.validate === "initial") {
|
|
531
558
|
validateFormInput(form[INTERNAL]);
|
|
532
559
|
}
|
|
533
560
|
return form;
|
|
534
561
|
}
|
|
535
562
|
|
|
536
563
|
// src/primitives/useField/useField.ts
|
|
537
|
-
import { createMemo, onCleanup } from "solid-js";
|
|
564
|
+
import { createMemo as createMemo2, onCleanup } from "solid-js";
|
|
538
565
|
|
|
539
566
|
// src/utils/unwrap/unwrap.ts
|
|
540
567
|
function unwrap(value) {
|
|
@@ -546,28 +573,38 @@ function unwrap(value) {
|
|
|
546
573
|
|
|
547
574
|
// src/primitives/useField/useField.ts
|
|
548
575
|
function useField(form, config) {
|
|
549
|
-
const getInternalFormStore =
|
|
550
|
-
const getInternalFieldStore =
|
|
576
|
+
const getInternalFormStore = createMemo2(() => unwrap(form)[INTERNAL]);
|
|
577
|
+
const getInternalFieldStore = createMemo2(
|
|
551
578
|
() => getFieldStore(getInternalFormStore(), unwrap(config).path)
|
|
552
579
|
);
|
|
580
|
+
const getInput2 = createMemo2(() => getFieldInput(getInternalFieldStore()));
|
|
581
|
+
const getIsTouched = createMemo2(
|
|
582
|
+
() => getFieldBool(getInternalFieldStore(), "isTouched")
|
|
583
|
+
);
|
|
584
|
+
const getIsDirty = createMemo2(
|
|
585
|
+
() => getFieldBool(getInternalFieldStore(), "isDirty")
|
|
586
|
+
);
|
|
587
|
+
const getIsValid = createMemo2(
|
|
588
|
+
() => !getFieldBool(getInternalFieldStore(), "errors")
|
|
589
|
+
);
|
|
553
590
|
return {
|
|
554
591
|
get path() {
|
|
555
592
|
return unwrap(config).path;
|
|
556
593
|
},
|
|
557
594
|
get input() {
|
|
558
|
-
return
|
|
595
|
+
return getInput2();
|
|
559
596
|
},
|
|
560
597
|
get errors() {
|
|
561
598
|
return getInternalFieldStore().errors.value;
|
|
562
599
|
},
|
|
563
600
|
get isTouched() {
|
|
564
|
-
return
|
|
601
|
+
return getIsTouched();
|
|
565
602
|
},
|
|
566
603
|
get isDirty() {
|
|
567
|
-
return
|
|
604
|
+
return getIsDirty();
|
|
568
605
|
},
|
|
569
606
|
get isValid() {
|
|
570
|
-
return
|
|
607
|
+
return getIsValid();
|
|
571
608
|
},
|
|
572
609
|
props: {
|
|
573
610
|
get name() {
|
|
@@ -594,11 +631,10 @@ function useField(form, config) {
|
|
|
594
631
|
},
|
|
595
632
|
onInput(event) {
|
|
596
633
|
const internalFieldStore = getInternalFieldStore();
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
internalFieldStore
|
|
634
|
+
setFieldInput(
|
|
635
|
+
internalFieldStore,
|
|
636
|
+
getElementInput(event.currentTarget, internalFieldStore)
|
|
600
637
|
);
|
|
601
|
-
setFieldInput(internalFieldStore, nextValue);
|
|
602
638
|
validateIfRequired(getInternalFormStore(), internalFieldStore, "input");
|
|
603
639
|
},
|
|
604
640
|
onChange() {
|
|
@@ -620,14 +656,23 @@ function useField(form, config) {
|
|
|
620
656
|
}
|
|
621
657
|
|
|
622
658
|
// src/primitives/useFieldArray/useFieldArray.ts
|
|
623
|
-
import { createMemo as
|
|
659
|
+
import { createMemo as createMemo3 } from "solid-js";
|
|
624
660
|
function useFieldArray(form, config) {
|
|
625
|
-
const getInternalFieldStore =
|
|
661
|
+
const getInternalFieldStore = createMemo3(
|
|
626
662
|
() => getFieldStore(
|
|
627
663
|
unwrap(form)[INTERNAL],
|
|
628
664
|
unwrap(config).path
|
|
629
665
|
)
|
|
630
666
|
);
|
|
667
|
+
const getIsTouched = createMemo3(
|
|
668
|
+
() => getFieldBool(getInternalFieldStore(), "isTouched")
|
|
669
|
+
);
|
|
670
|
+
const getIsDirty = createMemo3(
|
|
671
|
+
() => getFieldBool(getInternalFieldStore(), "isDirty")
|
|
672
|
+
);
|
|
673
|
+
const getIsValid = createMemo3(
|
|
674
|
+
() => !getFieldBool(getInternalFieldStore(), "errors")
|
|
675
|
+
);
|
|
631
676
|
return {
|
|
632
677
|
get path() {
|
|
633
678
|
return unwrap(config).path;
|
|
@@ -639,35 +684,33 @@ function useFieldArray(form, config) {
|
|
|
639
684
|
return getInternalFieldStore().errors.value;
|
|
640
685
|
},
|
|
641
686
|
get isTouched() {
|
|
642
|
-
return
|
|
687
|
+
return getIsTouched();
|
|
643
688
|
},
|
|
644
689
|
get isDirty() {
|
|
645
|
-
return
|
|
690
|
+
return getIsDirty();
|
|
646
691
|
},
|
|
647
692
|
get isValid() {
|
|
648
|
-
return
|
|
693
|
+
return getIsValid();
|
|
649
694
|
}
|
|
650
695
|
};
|
|
651
696
|
}
|
|
652
697
|
|
|
653
698
|
// src/components/Field/Field.tsx
|
|
654
699
|
function Field(props) {
|
|
655
|
-
const field = useField(
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
}
|
|
660
|
-
return <>{props.render(field)}</>;
|
|
700
|
+
const field = useField(
|
|
701
|
+
() => props.of,
|
|
702
|
+
() => ({ path: props.path })
|
|
703
|
+
);
|
|
704
|
+
return <>{props.children(field)}</>;
|
|
661
705
|
}
|
|
662
706
|
|
|
663
707
|
// src/components/FieldArray/FieldArray.tsx
|
|
664
708
|
function FieldArray(props) {
|
|
665
|
-
const field = useFieldArray(
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
}
|
|
670
|
-
return <>{props.render(field)}</>;
|
|
709
|
+
const field = useFieldArray(
|
|
710
|
+
() => props.of,
|
|
711
|
+
() => ({ path: props.path })
|
|
712
|
+
);
|
|
713
|
+
return <>{props.children(field)}</>;
|
|
671
714
|
}
|
|
672
715
|
|
|
673
716
|
// src/components/Form/Form.tsx
|
|
@@ -680,26 +723,7 @@ function Form(props) {
|
|
|
680
723
|
ref={(element) => {
|
|
681
724
|
props.of[INTERNAL].element = element;
|
|
682
725
|
}}
|
|
683
|
-
onSubmit={
|
|
684
|
-
event.preventDefault();
|
|
685
|
-
const internalFormStore = props.of[INTERNAL];
|
|
686
|
-
internalFormStore.isSubmitted.value = true;
|
|
687
|
-
internalFormStore.isSubmitting.value = true;
|
|
688
|
-
try {
|
|
689
|
-
const result = await validateFormInput(internalFormStore, {
|
|
690
|
-
shouldFocus: true
|
|
691
|
-
});
|
|
692
|
-
if (result.success) {
|
|
693
|
-
await props.onSubmit(result.output, event);
|
|
694
|
-
}
|
|
695
|
-
} catch (error) {
|
|
696
|
-
internalFormStore.errors.value = [
|
|
697
|
-
error instanceof Error ? error.message : "An unknown error has occurred."
|
|
698
|
-
];
|
|
699
|
-
} finally {
|
|
700
|
-
internalFormStore.isSubmitting.value = false;
|
|
701
|
-
}
|
|
702
|
-
}}
|
|
726
|
+
onSubmit={(event) => handleSubmit(props.of, props.onSubmit)(event)}
|
|
703
727
|
/>;
|
|
704
728
|
}
|
|
705
729
|
export {
|
|
@@ -711,6 +735,7 @@ export {
|
|
|
711
735
|
getAllErrors,
|
|
712
736
|
getErrors,
|
|
713
737
|
getInput,
|
|
738
|
+
handleSubmit,
|
|
714
739
|
insert,
|
|
715
740
|
move,
|
|
716
741
|
remove,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formisch/solid",
|
|
3
3
|
"description": "The modular and type-safe form library for SolidJS",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Fabian Hiller",
|
|
7
7
|
"homepage": "https://formisch.dev",
|
|
@@ -11,13 +11,10 @@
|
|
|
11
11
|
},
|
|
12
12
|
"keywords": [
|
|
13
13
|
"solidjs",
|
|
14
|
-
"
|
|
14
|
+
"form",
|
|
15
15
|
"typescript",
|
|
16
16
|
"schema",
|
|
17
|
-
"validation"
|
|
18
|
-
"parsing",
|
|
19
|
-
"bundle-size",
|
|
20
|
-
"type-safe"
|
|
17
|
+
"validation"
|
|
21
18
|
],
|
|
22
19
|
"type": "module",
|
|
23
20
|
"main": "./dist/index.js",
|
|
@@ -48,12 +45,11 @@
|
|
|
48
45
|
},
|
|
49
46
|
"scripts": {
|
|
50
47
|
"test": "vitest --typecheck",
|
|
51
|
-
"
|
|
52
|
-
"lint": "eslint \"src/**/*.ts*\" && tsc --noEmit && deno check ./src/index.ts",
|
|
48
|
+
"lint": "eslint \"src/**/*.ts*\" && tsc --noEmit",
|
|
53
49
|
"lint.fix": "eslint \"src/**/*.ts*\" --fix",
|
|
54
50
|
"format": "prettier --write ./src",
|
|
55
51
|
"format.check": "prettier --check ./src",
|
|
56
|
-
"build": "tsup"
|
|
52
|
+
"build": "tsup && tsdown"
|
|
57
53
|
},
|
|
58
54
|
"devDependencies": {
|
|
59
55
|
"@eslint/js": "^9.31.0",
|