Skip to content

Commit

Permalink
Merge pull request #38 from victorgarciaesgi/feat/valibot
Browse files Browse the repository at this point in the history
feat: added `Valibot` support, `$silentValue` and docs update
  • Loading branch information
victorgarciaesgi authored Dec 23, 2024
2 parents 4fd93dd + cd6e543 commit bfe09c4
Show file tree
Hide file tree
Showing 66 changed files with 3,302 additions and 1,205 deletions.
46 changes: 35 additions & 11 deletions docs/.vitepress/config.ts

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions docs/.vitepress/theme/custom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,44 @@ html.dark {
}
}

.VPFeature .VPImage {
border-radius: 6px;
background-color: var(--vp-c-default-soft);
}

.item .VPFeature {
position: relative;
padding: 2px;
background-clip: content-box;
border: none;
overflow: hidden;

&:before {
content: '';
position: absolute;
top: -50%;
right: 0;
bottom: 0;
left: -50%;
z-index: -1;
width: 200%;
height: 200%;
border-radius: inherit;
background: radial-gradient(ellipse at top, #048d62, #191a19);
animation: rotate 3s infinite linear;
animation-delay: 500ms;
}
}

@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

iframe {
border: none;
margin-top: 40px;
Expand Down
9 changes: 7 additions & 2 deletions docs/src/core-concepts/validation-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,15 @@ Similar to `$dirty`, with one exception. The `$anyDirty` flag is considered true

### `$value`
- Type: `TValue` (The current property value type)

A reference to the original validated model. It can be used to bind your form with `v-model`.

### `$silentValue`
- Type: `TValue` (The current property value type)


`$value` variant that will not "touch" the field and update the value silently, running only the rules, so you can easily swap values without impacting user interaction.


### `$pending`
- Type: `readonly boolean`
Expand Down Expand Up @@ -125,7 +131,6 @@ Resets the `$dirty` state on all nested properties of a form.

Will reset both your validation state and your form state to their initial values.


### `$clearExternalErrors`
- Type: `() => void`

Expand Down
11 changes: 6 additions & 5 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ features:
- icon: <svg width="800px" height="800px" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M16 4C14 4 11 5 11 9C11 13 11 15 11 18C11 21 6 23 6 23C6 23 11 25 11 28C11 31 11 35 11 39C11 43 14 44 16 44" stroke="#048d62" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M32 4C34 4 37 5 37 9C37 13 37 15 37 18C37 21 42 23 42 23C42 23 37 25 37 28C37 31 37 35 37 39C37 43 34 44 32 44" stroke="#048d62" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg>
title: Model based
details: You can focus on your validations, not on your DOM.
- icon: 🪗
title: Extensible
- title: Extensible
icon: 🪗
details: Extend validation schema with your own properties.
- icon: <svg xmlns="http://www.w3.org/2000/svg" width="1.27em" height="1em" viewBox="0 0 256 203"><defs><filter id="logosZod0" width="105.2%" height="106.5%" x="-2.2%" y="-2.8%" filterUnits="objectBoundingBox"><feOffset dx="1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"/><feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="2"/><feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.36 0"/></filter><path id="logosZod1" fill="#000" d="M200.42 0H53.63L0 53.355l121.76 146.624l9.714-10.9L252 53.857zm-5.362 12.562l39.84 41.6l-112.8 126.558L17 54.162l41.815-41.6z"/></defs><g transform="translate(2 1.51)"><path fill="#18253f" d="M58.816 12.522h136.278l39.933 41.691l-112.989 126.553L16.957 54.213z"/><path fill="#274d82" d="M149.427 150.875H96.013l-24.124-29.534l68.364-.002l.002-4.19h39.078z"/><path fill="#274d82" d="M223.56 42.323L76.178 127.414l-19.226-24.052l114.099-65.877l-2.096-3.631l30.391-17.546zm-78.964-29.759L33.93 76.457L16.719 54.972l74.095-42.779z"/><use filter="url(#logosZod0)" href="#logosZod1"/><use fill="#3068b7" href="#logosZod1"/></g></svg>
title: Zod support
details: Use Zod schemas to control your validations.
- title: Zod & Valibot support
icon:
src: /zod-valibot.png
details: Use Zod or Valibot to control your validations.
---

129 changes: 129 additions & 0 deletions docs/src/integrations/valibot.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
title: Valibot
---

<script setup>
import QuickUsage from '../parts/components/valibot/QuickUsage.vue';
import ComputedSchema from '../parts/components/valibot/ComputedSchema.vue';
</script>

# Valibot <span data-title="valibot"></span>

Regle offers an adapter for [Valibot](https://valibot.dev/). You can use any valibot object schema to validate your state. It offers the same DX as using `@regle/rules`.

## Prerequisites

- `valibot` version `1.x`

::: code-group
```sh [pnpm]
pnpm add @regle/valibot
```

```sh [npm]
npm install @regle/valibot
```

```sh [yarn]
yarn add @regle/valibot
```

```sh [bun]
bun add @regle/valibot
```
:::



## Usage


To use `@regle/valibot`, you only need one composable: `useValibotRegle`.

The `useValibot` composable has the same type definitions as `useRegle` for state and options. However, instead of passing rules as the second parameter, you provide a Valibot schema.

You still benefit from features like dirty tracking and custom error handling.

All schemas are parsed using `safeParse` and `safeParseAsync` (if your schema includes asynchronous transformations or refinements). Error messages defined in the schema will automatically be retrieved.

```ts twoslash
import { useValibotRegle } from '@regle/valibot';
import * as v from 'valibot';

const { r$ } = useValibotRegle({ name: '' }, v.object({
name: v.pipe(v.string(), v.minLength(3))
}))

```

<QuickUsage />


## Computed schema

You can also have a computed schema that can be based on other state values.

```ts twoslash
import { useValibotRegle, type toValibot } from '@regle/valibot';
import * as v from 'valibot';
import { ref, computed } from 'vue';

type Form = {
firstName?: string;
lastName?: string
}

const form = ref<Form>({ firstName: '', lastName: '' })

const schema = computed(() => v.object({
firstName: v.string(),
lastName: v.pipe(
v.string(),
v.check((v) => v !== form.value.firstName, "Last name can't be equal to first name")
),
}) satisfies toValibot<Form>)

const { r$ } = useValibotRegle(form, schema);

```

<ComputedSchema />


## Type safe output

Similar to the main `useRegle` composable, `r$.$validate` in useValibotRegle also returns a type-safe output.

```ts twoslash
import { useValibotRegle, toValibot } from '@regle/valibot';
import * as v from 'valibot';
import { ref, computed } from 'vue';

type Form = {
firstName?: string;
lastName?: string
}

const form = ref<Form>({ firstName: '', lastName: '' })

const schema = computed(() => v.object({
firstName: v.optional(v.string()),
lastName: v.pipe(
v.string(),
v.minLength(3),
v.check((v) => v !== form.value.firstName, "Last name can't be equal to first name")
)
}) satisfies toValibot<Form>)

const { r$ } = useValibotRegle(form, schema);

async function submit() {
const { result, data } = await r$.$validate();
if (result) {
console.log(data);
// ^?
}
}

```

2 changes: 2 additions & 0 deletions docs/src/introduction/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Optional
- Pinia version `2.1` or higher
- [Zod](https://zod.dev/) <span data-title="zod"></span>
- Zod version `3` or higher. Check [Zod usage](/integrations/zod)
- [Valibot](https://valibot.dev/) <span data-title="valibot"></span>
- Valibot version `1` or higher. Check [Valibot usage](/integrations/valibot)

<br/>

Expand Down
55 changes: 55 additions & 0 deletions docs/src/parts/components/valibot/ComputedSchema.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<template>
<div class="demo-container">
<div class="row">
<div class="input-container">
<input
v-model="form.firstName"
:class="{ valid: r$.$fields.firstName.$valid, error: r$.$fields.firstName.$error }"
placeholder="Type your first name"
/>

<ul v-if="r$.$errors.firstName.length">
<li v-for="error of r$.$errors.firstName" :key="error">
{{ error }}
</li>
</ul>
</div>

<div class="input-container">
<input
v-model="form.lastName"
:class="{ valid: r$.$fields.lastName.$valid, error: r$.$fields.lastName.$error }"
placeholder="Type your last name"
/>

<ul v-if="r$.$errors.lastName.length">
<li v-for="error of r$.$errors.lastName" :key="error">
{{ error }}
</li>
</ul>
</div>

<button type="button" @click="r$.$resetAll">Reset</button>
</div>
</div>
</template>

<script setup lang="ts">
import { useValibotRegle } from '@regle/valibot';
import * as v from 'valibot';
import { ref, computed } from 'vue';
const form = ref({ firstName: '', lastName: '' });
const schema = computed(() =>
v.object({
firstName: v.string(),
lastName: v.pipe(
v.string(),
v.check((v) => v !== form.value.firstName, "Last name can't be equal to first name")
),
})
);
const { r$ } = useValibotRegle(form, schema);
</script>
31 changes: 31 additions & 0 deletions docs/src/parts/components/valibot/QuickUsage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<template>
<div class="demo-container">
<div>
<input
v-model="r$.$value.name"
:class="{ valid: r$.$fields.name.$valid, error: r$.$fields.name.$error }"
placeholder="Type your name"
/>

<button type="button" @click="r$.$resetAll">Reset</button>
</div>

<ul v-if="r$.$errors.name.length">
<li v-for="error of r$.$errors.name" :key="error">
{{ error }}
</li>
</ul>
</div>
</template>

<script setup lang="ts">
import { useValibotRegle } from '@regle/valibot';
import * as v from 'valibot';
const { r$ } = useValibotRegle(
{ name: '' },
v.object({
name: v.pipe(v.string(), v.minLength(3)),
})
);
</script>
Binary file added docs/src/public/zod-valibot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 21 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,50 +25,53 @@
"docs:preview": "vitepress preview docs"
},
"devDependencies": {
"@playwright/test": "1.49.0",
"@pinia/testing": "0.1.7",
"@playwright/test": "1.49.1",
"@regle/core": "workspace:*",
"@regle/rules": "workspace:*",
"@regle/zod": "workspace:*",
"@shikijs/vitepress-twoslash": "1.24.1",
"@typescript-eslint/eslint-plugin": "8.18.0",
"@typescript-eslint/parser": "8.18.0",
"@regle/valibot": "workspace:*",
"@shikijs/vitepress-twoslash": "1.24.4",
"@tailwindcss/forms": "0.5.9",
"@types/semver": "7.5.8",
"@typescript-eslint/eslint-plugin": "8.18.1",
"@typescript-eslint/parser": "8.18.1",
"@vitejs/plugin-vue": "5.2.1",
"@vitest/coverage-istanbul": "2.1.8",
"@vitest/coverage-v8": "2.1.8",
"@vue/reactivity": "catalog:",
"@vue/test-utils": "2.4.6",
"@types/semver": "7.5.8",
"bumpp": "9.9.0",
"autoprefixer": "10.4.20",
"bumpp": "9.9.2",
"changelogithub": "0.13.11",
"check-password-strength": "2.0.10",
"cross-env": "7.0.3",
"@pinia/testing": "0.1.7",
"date-fns": "4.1.0",
"eslint": "catalog:",
"eslint-config-prettier": "catalog:",
"eslint-plugin-vue": "catalog:",
"happy-dom": "15.11.7",
"pinia": "catalog:",
"playwright": "1.49.0",
"playwright-core": "1.49.0",
"playwright": "1.49.1",
"playwright-core": "1.49.1",
"postcss": "8.4.49",
"prettier": "catalog:",
"sass": "1.83.0",
"semver": "7.6.3",
"sass": "1.82.0",
"sitemap": "8.0.0",
"tailwindcss": "3.4.17",
"tsup": "catalog:",
"tsx": "4.19.2",
"typescript": "catalog:",
"vitepress": "1.5.0",
"vitepress-plugin-group-icons": "1.3.1",
"vitepress-plugin-group-icons": "1.3.2",
"vitest": "2.1.8",
"vue": "catalog:",
"vue-eslint-parser": "catalog:",
"vue-tsc": "catalog:",
"zod": "3.23.8",
"zx": "8.2.4",
"tsx": "4.19.2",
"tailwindcss": "3.4.16",
"autoprefixer": "10.4.20",
"postcss": "8.4.49",
"@tailwindcss/forms": "0.5.9"
"zod": "3.24.1",
"valibot": "1.0.0-beta.9",
"zx": "8.2.4"
},
"type": "module",
"main": "./dist/module.cjs",
Expand Down
Loading

0 comments on commit bfe09c4

Please sign in to comment.