From ab5153ac19703c11b107825208e33d04e01a9be2 Mon Sep 17 00:00:00 2001 From: SevicheCC <91365763+Sevichecc@users.noreply.github.com> Date: Thu, 7 Sep 2023 07:58:25 -0500 Subject: [PATCH] feat(Form): add valibot supprt (#615) Co-authored-by: Benjamin Canac --- .../content/examples/FormExampleValibot.vue | 42 ++++++++++++++ docs/content/3.forms/10.form.md | 57 ++++++++++++++++++- package.json | 3 +- pnpm-lock.yaml | 7 +++ src/runtime/components/forms/Form.vue | 25 +++++++- 5 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 docs/components/content/examples/FormExampleValibot.vue diff --git a/docs/components/content/examples/FormExampleValibot.vue b/docs/components/content/examples/FormExampleValibot.vue new file mode 100644 index 0000000000..0ff026824e --- /dev/null +++ b/docs/components/content/examples/FormExampleValibot.vue @@ -0,0 +1,42 @@ + + + diff --git a/docs/content/3.forms/10.form.md b/docs/content/3.forms/10.form.md index 2a0e122fa3..330f22c918 100644 --- a/docs/content/3.forms/10.form.md +++ b/docs/content/3.forms/10.form.md @@ -8,7 +8,7 @@ links: ## Usage -Use the Form component to validate form data using schema libraries such as [Yup](https://github.com/jquense/yup), [Zod](https://github.com/colinhacks/zod), [Joi](https://github.com/hapijs/joi) or your own validation logic. It works seamlessly with the FormGroup component to automatically display error messages around form elements. +Use the Form component to validate form data using schema libraries such as [Yup](https://github.com/jquense/yup), [Zod](https://github.com/colinhacks/zod), [Joi](https://github.com/hapijs/joi), [Valibot](https://valibot.dev/) or your own validation logic. It works seamlessly with the FormGroup component to automatically display error messages around form elements. The Form component requires the `validate` and `state` props for form validation. @@ -69,7 +69,7 @@ async function submit (event: FormSubmitEvent) { ## Schema -You can provide a schema from [Yup](#yup), [Zod](#zod) or [Joi](#joi) through the `schema` prop to validate the state. It's important to note that **none of these libraries are included** by default, so make sure to **install the one you need**. +You can provide a schema from [Yup](#yup), [Zod](#zod) or [Joi](#joi), [Valibot](#valibot) through the `schema` prop to validate the state. It's important to note that **none of these libraries are included** by default, so make sure to **install the one you need**. ### Yup @@ -232,6 +232,59 @@ async function submit (event: FormSubmitEvent) { ``` :: +### Valibot + +::component-example +#default +:form-example-valibot{class="space-y-4 w-60"} + +#code +```vue + + + +``` +:: + ## Other libraries For other validation libraries, you can define your own component with custom validation logic. diff --git a/package.json b/package.json index ddef5299a1..6825b673c2 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,8 @@ "unbuild": "^2.0.0", "vue-tsc": "^1.8.10", "yup": "^1.2.0", - "zod": "^3.22.2" + "zod": "^3.22.2", + "valibot": "^0.13.1" }, "pnpm": { "patchedDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 800d32f4c3..3babdb3f85 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -98,6 +98,9 @@ importers: unbuild: specifier: ^2.0.0 version: 2.0.0(typescript@5.2.2) + valibot: + specifier: ^0.13.1 + version: 0.13.1 vue-tsc: specifier: ^1.8.10 version: 1.8.10(typescript@5.2.2) @@ -12570,6 +12573,10 @@ packages: vue-screen-utils: 1.0.0-beta.13(vue@3.3.4) dev: true + /valibot@0.13.1: + resolution: {integrity: sha512-SG2W1RHqE2LShl3p6tyERt6I+G6PQa9ZFVfkyNKXz01HBzL+tBeH5kXw/5AQeAzPJSjI3djVGBl1CyozA1kyBQ==} + dev: true + /validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: diff --git a/src/runtime/components/forms/Form.vue b/src/runtime/components/forms/Form.vue index ed9be7d047..51c7c28a98 100644 --- a/src/runtime/components/forms/Form.vue +++ b/src/runtime/components/forms/Form.vue @@ -10,6 +10,8 @@ import { useEventBus } from '@vueuse/core' import type { ZodSchema } from 'zod' import type { ValidationError as JoiError, Schema as JoiSchema } from 'joi' import type { ObjectSchema as YupObjectSchema, ValidationError as YupError } from 'yup' +import type { ObjectSchema as ValibotObjectSchema } from 'valibot' +import { safeParseAsync } from 'valibot' import type { FormError, FormEvent, FormEventType, FormSubmitEvent, Form } from '../../types/form' export default defineComponent({ @@ -18,7 +20,8 @@ export default defineComponent({ type: Object as | PropType | PropType> - | PropType, + | PropType + | PropType>, default: undefined }, state: { @@ -61,6 +64,8 @@ export default defineComponent({ errs = errs.concat(await getYupErrors(props.state, props.schema)) } else if (isJoiSchema(props.schema)) { errs = errs.concat(await getJoiErrors(props.state, props.schema)) + } else if (isValibotSchema(props.schema)) { + errs = errs.concat(await getValibotError(props.state, props.schema)) } else { throw new Error('Form validation failed: Unsupported form schema') } @@ -204,4 +209,22 @@ async function getJoiErrors ( } } } + +function isValibotSchema (schema: any): schema is ValibotObjectSchema { + return schema._parse !== undefined +} + +async function getValibotError ( + state: any, + schema: ValibotObjectSchema +): Promise { + const result = await safeParseAsync(schema, state) + if (result.success === false) { + return result.issues.map((issue) => ({ + path: issue.path.map(p => p.key).join('.'), + message: issue.message + })) + } + return [] +}