@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 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 _qwik_dev_core_internal3 from "@qwik.dev/core/internal";
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 validateOn?: ValidationMode | undefined;
88
- readonly revalidateOn?: Exclude<ValidationMode, "initial"> | undefined;
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
- validateOn: ValidationMode;
94
- revalidateOn: Exclude<ValidationMode, "initial">;
95
- validate: QRL<(input: unknown) => Promise<v.SafeParseResult<TSchema>>>;
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: _qwik_dev_core_internal3.PublicProps<FieldProps<TSchema, TFieldPath>>, key: string | null, flags: number, dev?: _qwik_dev_core_internal3.DevJSX) => JSXOutput;
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: _qwik_dev_core_internal3.PublicProps<FieldArrayProps<TSchema, TFieldArrayPath>>, key: string | null, flags: number, dev?: _qwik_dev_core_internal3.DevJSX) => JSXOutput;
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: _qwik_dev_core_internal3.PublicProps<FormProps<TSchema>>, key: string | null, flags: number, dev?: _qwik_dev_core_internal3.DevJSX) => JSXOutput;
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 };
@@ -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, validate$1) {
327
+ function createFormStore(config, parse) {
327
328
  const store = {};
328
329
  initializeFieldStore(store, config.schema, config.initialInput, []);
329
- store.validateOn = config.validateOn ?? "submit";
330
- store.revalidateOn = config.revalidateOn ?? "input";
331
- store.validate = validate$1;
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.validate(untrack(() => getFieldInput(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.validateOn === "initial" || (internalFormStore.validateOn === "submit" ? untrack(() => internalFormStore.isSubmitted.value) : untrack(() => getFieldBool(internalFieldStore, "errors"))) ? internalFormStore.revalidateOn : internalFormStore.validateOn)) validateFormInput(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.validateOn === "initial") validateFormInput(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
- const nextValue = getElementInput(element, internalFieldStore.value);
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 validateOn = config.validateOn;
655
+ const validate$1 = config.validate;
640
656
  useTask$(async () => {
641
- if (validateOn === "initial") await validateFormInput(form[INTERNAL]);
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$: async (event) => {
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.1.1",
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
- "modular",
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
- "fmt": "prettier --write .",
44
- "fmt.check": "prettier --check .",
45
- "lint": "eslint \"src/**/*.ts*\"",
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": {