@formisch/qwik 0.1.1 → 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/dist/index.d.ts +13 -10
- package/dist/index.qwik.js +29 -25
- package/package.json +7 -9
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as v from "valibot";
|
|
2
2
|
import { JSXOutput, NoSerialize, PropsOf, QRL, ReadonlySignal } from "@qwik.dev/core";
|
|
3
|
-
import * as
|
|
3
|
+
import * as _qwik_dev_core_internal1 from "@qwik.dev/core/internal";
|
|
4
4
|
|
|
5
5
|
//#region ../../packages/core/dist/index.qwik.d.ts
|
|
6
6
|
//#region src/types/schema.d.ts
|
|
@@ -84,15 +84,15 @@ type SubmitHandler<TSchema extends Schema> = (output: v.InferOutput<TSchema>, ev
|
|
|
84
84
|
interface FormConfig<TSchema extends Schema = Schema> {
|
|
85
85
|
readonly schema: TSchema;
|
|
86
86
|
readonly initialInput?: DeepPartial<v.InferInput<TSchema>> | undefined;
|
|
87
|
-
readonly
|
|
88
|
-
readonly
|
|
87
|
+
readonly validate?: ValidationMode | undefined;
|
|
88
|
+
readonly revalidate?: Exclude<ValidationMode, "initial"> | undefined;
|
|
89
89
|
}
|
|
90
90
|
interface InternalFormStore<TSchema extends Schema = Schema> extends InternalObjectStore {
|
|
91
91
|
element?: HTMLFormElement;
|
|
92
92
|
validators: number;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
validate: ValidationMode;
|
|
94
|
+
revalidate: Exclude<ValidationMode, "initial">;
|
|
95
|
+
parse: QRL<(input: unknown) => Promise<v.SafeParseResult<TSchema>>>;
|
|
96
96
|
isSubmitting: Signal<boolean>;
|
|
97
97
|
isSubmitted: Signal<boolean>;
|
|
98
98
|
isValidating: Signal<boolean>;
|
|
@@ -199,6 +199,9 @@ interface GetFieldInputConfig<TSchema extends Schema, TFieldPath extends Require
|
|
|
199
199
|
declare function getInput<TSchema extends Schema>(form: BaseFormStore<TSchema>): PartialValues<v.InferInput<TSchema>>;
|
|
200
200
|
declare function getInput<TSchema extends Schema, TFieldPath extends RequiredPath | undefined = undefined>(form: BaseFormStore<TSchema>, config: TFieldPath extends RequiredPath ? GetFieldInputConfig<TSchema, TFieldPath> : GetFormInputConfig): PartialValues<TFieldPath extends RequiredPath ? PathValue<v.InferInput<TSchema>, TFieldPath> : v.InferInput<TSchema>>;
|
|
201
201
|
//#endregion
|
|
202
|
+
//#region src/handleSubmit/handleSubmit.d.ts
|
|
203
|
+
declare function handleSubmit<TSchema extends Schema>(form: BaseFormStore<TSchema>, handler: SubmitHandler<TSchema>): (event: SubmitEvent) => void;
|
|
204
|
+
//#endregion
|
|
202
205
|
//#region src/insert/insert.d.ts
|
|
203
206
|
interface InsertConfig<TSchema extends Schema, TFieldArrayPath extends RequiredPath> {
|
|
204
207
|
readonly path: ValidArrayPath<v.InferInput<TSchema>, TFieldArrayPath>;
|
|
@@ -350,7 +353,7 @@ interface FieldProps<TSchema extends Schema = Schema, TFieldPath extends Require
|
|
|
350
353
|
/**
|
|
351
354
|
* Headless form field that provides reactive properties and state.
|
|
352
355
|
*/
|
|
353
|
-
declare const Field: <TSchema extends Schema, TFieldPath extends RequiredPath>(props:
|
|
356
|
+
declare const Field: <TSchema extends Schema, TFieldPath extends RequiredPath>(props: _qwik_dev_core_internal1.PublicProps<FieldProps<TSchema, TFieldPath>>, key: string | null, flags: number, dev?: _qwik_dev_core_internal1.DevJSX) => JSXOutput;
|
|
354
357
|
//#endregion
|
|
355
358
|
//#region src/components/FieldArray/FieldArray.d.ts
|
|
356
359
|
/**
|
|
@@ -364,14 +367,14 @@ interface FieldArrayProps<TSchema extends Schema = Schema, TFieldArrayPath exten
|
|
|
364
367
|
/**
|
|
365
368
|
* Headless field array that provides reactive properties and state.
|
|
366
369
|
*/
|
|
367
|
-
declare const FieldArray: <TSchema extends Schema, TFieldArrayPath extends RequiredPath>(props:
|
|
370
|
+
declare const FieldArray: <TSchema extends Schema, TFieldArrayPath extends RequiredPath>(props: _qwik_dev_core_internal1.PublicProps<FieldArrayProps<TSchema, TFieldArrayPath>>, key: string | null, flags: number, dev?: _qwik_dev_core_internal1.DevJSX) => JSXOutput;
|
|
368
371
|
//#endregion
|
|
369
372
|
//#region src/components/Form/Form.d.ts
|
|
370
373
|
type FormProps<TSchema extends Schema = Schema> = Omit<PropsOf<'form'>, 'onSubmit$'> & {
|
|
371
374
|
of: FormStore<TSchema>;
|
|
372
375
|
onSubmit$: QRL<SubmitHandler<TSchema>>;
|
|
373
376
|
};
|
|
374
|
-
declare const Form: <TSchema extends Schema>(props:
|
|
377
|
+
declare const Form: <TSchema extends Schema>(props: _qwik_dev_core_internal1.PublicProps<FormProps<TSchema>>, key: string | null, flags: number, dev?: _qwik_dev_core_internal1.DevJSX) => JSXOutput;
|
|
375
378
|
//#endregion
|
|
376
379
|
//#region src/hooks/useField/useField.d.ts
|
|
377
380
|
interface UseFieldConfig<TSchema extends Schema = Schema, TFieldPath extends RequiredPath = RequiredPath> {
|
|
@@ -389,4 +392,4 @@ declare function useFieldArray<TSchema extends Schema, TFieldArrayPath extends R
|
|
|
389
392
|
declare function useFormQrl<TSchema extends Schema>(configQrl: QRL<FormConfig<TSchema>>): FormStore<TSchema>;
|
|
390
393
|
declare const useForm$: <TSchema extends Schema>(qrl: FormConfig<TSchema>) => FormStore<TSchema>;
|
|
391
394
|
//#endregion
|
|
392
|
-
export { Field, FieldArray, FieldArrayProps, FieldArrayStore, FieldElementProps, FieldProps, FieldStore, FocusFieldConfig, Form, FormProps, FormStore, GetFieldErrorsConfig, GetFieldInputConfig, GetFormErrorsConfig, GetFormInputConfig, InsertConfig, MoveConfig, RemoveConfig, ReplaceConfig, ResetFieldConfig, ResetFormConfig, SetFieldErrorsConfig, SetFieldInputConfig, SetFormErrorsConfig, SetFormInputConfig, SwapConfig, UseFieldArrayConfig, UseFieldConfig, ValidateFormConfig, focus, getAllErrors, getErrors, getInput, insert, move, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, useForm$, useFormQrl, validate };
|
|
395
|
+
export { Field, FieldArray, FieldArrayProps, FieldArrayStore, FieldElementProps, FieldProps, FieldStore, FocusFieldConfig, Form, FormProps, FormStore, GetFieldErrorsConfig, GetFieldInputConfig, GetFormErrorsConfig, GetFormInputConfig, InsertConfig, MoveConfig, RemoveConfig, ReplaceConfig, ResetFieldConfig, ResetFormConfig, SetFieldErrorsConfig, SetFieldInputConfig, SetFormErrorsConfig, SetFormInputConfig, type SubmitHandler, SwapConfig, UseFieldArrayConfig, UseFieldConfig, ValidateFormConfig, focus, getAllErrors, getErrors, getInput, handleSubmit, insert, move, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, useForm$, useFormQrl, validate };
|
package/dist/index.qwik.js
CHANGED
|
@@ -123,6 +123,7 @@ function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
|
|
|
123
123
|
*/
|
|
124
124
|
function resetItemState(internalFieldStore, initialInput) {
|
|
125
125
|
batch(() => {
|
|
126
|
+
internalFieldStore.errors.value = null;
|
|
126
127
|
if (internalFieldStore.kind === "array") {
|
|
127
128
|
internalFieldStore.isTouched.value = false;
|
|
128
129
|
internalFieldStore.isDirty.value = false;
|
|
@@ -323,12 +324,12 @@ function walkFieldStore(internalFieldStore, callback) {
|
|
|
323
324
|
if (internalFieldStore.kind === "array") for (let index = 0; index < untrack(() => internalFieldStore.items.value).length; index++) walkFieldStore(internalFieldStore.children[index], callback);
|
|
324
325
|
else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) walkFieldStore(internalFieldStore.children[key], callback);
|
|
325
326
|
}
|
|
326
|
-
function createFormStore(config,
|
|
327
|
+
function createFormStore(config, parse) {
|
|
327
328
|
const store = {};
|
|
328
329
|
initializeFieldStore(store, config.schema, config.initialInput, []);
|
|
329
|
-
store.
|
|
330
|
-
store.
|
|
331
|
-
store.
|
|
330
|
+
store.validate = config.validate ?? "submit";
|
|
331
|
+
store.revalidate = config.revalidate ?? "input";
|
|
332
|
+
store.parse = parse;
|
|
332
333
|
store.isSubmitting = createSignal(false);
|
|
333
334
|
store.isSubmitted = createSignal(false);
|
|
334
335
|
store.isValidating = createSignal(false);
|
|
@@ -337,7 +338,7 @@ function createFormStore(config, validate$1) {
|
|
|
337
338
|
async function validateFormInput(internalFormStore, config) {
|
|
338
339
|
internalFormStore.validators++;
|
|
339
340
|
internalFormStore.isValidating.value = true;
|
|
340
|
-
const result = await internalFormStore.
|
|
341
|
+
const result = await internalFormStore.parse(untrack(() => getFieldInput(internalFormStore)));
|
|
341
342
|
let rootErrors;
|
|
342
343
|
let nestedErrors;
|
|
343
344
|
if (result.issues) {
|
|
@@ -377,7 +378,7 @@ async function validateFormInput(internalFormStore, config) {
|
|
|
377
378
|
return result;
|
|
378
379
|
}
|
|
379
380
|
function validateIfRequired(internalFormStore, internalFieldStore, validationModes) {
|
|
380
|
-
if (validationModes === (internalFormStore.
|
|
381
|
+
if (validationModes === (internalFormStore.validate === "initial" || (internalFormStore.validate === "submit" ? untrack(() => internalFormStore.isSubmitted.value) : untrack(() => getFieldBool(internalFieldStore, "errors"))) ? internalFormStore.revalidate : internalFormStore.validate)) validateFormInput(internalFormStore);
|
|
381
382
|
}
|
|
382
383
|
const INTERNAL = "~internal";
|
|
383
384
|
|
|
@@ -401,6 +402,22 @@ function getErrors(form, config) {
|
|
|
401
402
|
function getInput(form, config) {
|
|
402
403
|
return getFieldInput(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]);
|
|
403
404
|
}
|
|
405
|
+
function handleSubmit(form, handler) {
|
|
406
|
+
return async (event) => {
|
|
407
|
+
event.preventDefault();
|
|
408
|
+
const internalFormStore = form[INTERNAL];
|
|
409
|
+
internalFormStore.isSubmitted.value = true;
|
|
410
|
+
internalFormStore.isSubmitting.value = true;
|
|
411
|
+
try {
|
|
412
|
+
const result = await validateFormInput(internalFormStore, { shouldFocus: true });
|
|
413
|
+
if (result.success) await handler(result.output, event);
|
|
414
|
+
} catch (error) {
|
|
415
|
+
internalFormStore.errors.value = [error instanceof Error ? error.message : "An unknown error has occurred."];
|
|
416
|
+
} finally {
|
|
417
|
+
internalFormStore.isSubmitting.value = false;
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
}
|
|
404
421
|
function insert(form, config) {
|
|
405
422
|
const internalFormStore = form[INTERNAL];
|
|
406
423
|
const internalArrayStore = getFieldStore(internalFormStore, config.path);
|
|
@@ -492,7 +509,7 @@ function reset(form, config) {
|
|
|
492
509
|
});
|
|
493
510
|
if (!config?.path) {
|
|
494
511
|
if (!config?.keepSubmitted) internalFormStore.isSubmitted.value = false;
|
|
495
|
-
if (internalFormStore.
|
|
512
|
+
if (internalFormStore.validate === "initial") validateFormInput(internalFormStore);
|
|
496
513
|
}
|
|
497
514
|
});
|
|
498
515
|
});
|
|
@@ -576,8 +593,7 @@ function useField(form, config) {
|
|
|
576
593
|
validateIfRequired(form[INTERNAL], internalFieldStore.value, "touch");
|
|
577
594
|
}),
|
|
578
595
|
onInput$: $((_, element) => {
|
|
579
|
-
|
|
580
|
-
setFieldInput(internalFieldStore.value, nextValue);
|
|
596
|
+
setFieldInput(internalFieldStore.value, getElementInput(element, internalFieldStore.value));
|
|
581
597
|
validateIfRequired(form[INTERNAL], internalFieldStore.value, "input");
|
|
582
598
|
}),
|
|
583
599
|
onChange$: $(() => {
|
|
@@ -636,9 +652,9 @@ function useFormQrl(configQrl) {
|
|
|
636
652
|
errors: internalFormStore.errors
|
|
637
653
|
};
|
|
638
654
|
});
|
|
639
|
-
const
|
|
655
|
+
const validate$1 = config.validate;
|
|
640
656
|
useTask$(async () => {
|
|
641
|
-
if (
|
|
657
|
+
if (validate$1 === "initial") await validateFormInput(form[INTERNAL]);
|
|
642
658
|
});
|
|
643
659
|
return form;
|
|
644
660
|
}
|
|
@@ -676,22 +692,10 @@ const Form = component$(({ of, onSubmit$,...other }) => {
|
|
|
676
692
|
ref: (element) => {
|
|
677
693
|
of[INTERNAL].element = element;
|
|
678
694
|
},
|
|
679
|
-
onSubmit$:
|
|
680
|
-
const internalFormStore = of[INTERNAL];
|
|
681
|
-
internalFormStore.isSubmitted.value = true;
|
|
682
|
-
internalFormStore.isSubmitting.value = true;
|
|
683
|
-
try {
|
|
684
|
-
const result = await validateFormInput(internalFormStore, { shouldFocus: true });
|
|
685
|
-
if (result.success) await onSubmit$(result.output, event);
|
|
686
|
-
} catch (error) {
|
|
687
|
-
internalFormStore.errors.value = [error instanceof Error ? error.message : "An unknown error has occurred."];
|
|
688
|
-
} finally {
|
|
689
|
-
internalFormStore.isSubmitting.value = false;
|
|
690
|
-
}
|
|
691
|
-
},
|
|
695
|
+
onSubmit$: (event) => handleSubmit(of, onSubmit$)(event),
|
|
692
696
|
children: /* @__PURE__ */ jsx(Slot, {})
|
|
693
697
|
});
|
|
694
698
|
});
|
|
695
699
|
|
|
696
700
|
//#endregion
|
|
697
|
-
export { Field, FieldArray, Form, focus, getAllErrors, getErrors, getInput, insert, move, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, useForm$, useFormQrl, validate };
|
|
701
|
+
export { Field, FieldArray, Form, focus, getAllErrors, getErrors, getInput, handleSubmit, insert, move, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, useForm$, useFormQrl, validate };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formisch/qwik",
|
|
3
3
|
"description": "The modular and type-safe form library for Qwik",
|
|
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
|
"qwik",
|
|
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.qwik.js",
|
|
@@ -40,9 +37,10 @@
|
|
|
40
37
|
},
|
|
41
38
|
"scripts": {
|
|
42
39
|
"build": "tsdown",
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
40
|
+
"lint": "eslint \"src/**/*.ts*\" && tsc --noEmit",
|
|
41
|
+
"lint.fix": "eslint \"src/**/*.ts*\" --fix",
|
|
42
|
+
"format": "prettier --write ./src",
|
|
43
|
+
"format.check": "prettier --check ./src",
|
|
46
44
|
"qwik": "qwik"
|
|
47
45
|
},
|
|
48
46
|
"devDependencies": {
|