docs: add @formkit/auto-animate example in form.md (#108)

* fix: typo for injection key

* docs: add `@formkit/auto-animate` example
This commit is contained in:
Sadegh Barati 2023-10-09 16:05:49 +03:30 committed by GitHub
parent 137ecb8d01
commit 9b75dcf9d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 123 additions and 10 deletions

View File

@ -12,6 +12,7 @@
"build:registry": "tsx ./scripts/build-registry.ts" "build:registry": "tsx ./scripts/build-registry.ts"
}, },
"dependencies": { "dependencies": {
"@formkit/auto-animate": "^0.8.0",
"@morev/vue-transitions": "^2.3.6", "@morev/vue-transitions": "^2.3.6",
"@radix-icons/vue": "^1.0.0", "@radix-icons/vue": "^1.0.0",
"@tanstack/vue-table": "^8.10.3", "@tanstack/vue-table": "^8.10.3",

View File

@ -329,3 +329,10 @@ See the following links for more examples on how to use the `vee-validate` featu
- [Switch](/docs/components/switch#form) - [Switch](/docs/components/switch#form)
- [Textarea](/docs/components/textarea#form) - [Textarea](/docs/components/textarea#form)
- [Combobox](/docs/components/combobox#form) - [Combobox](/docs/components/combobox#form)
## Extras
This example shows how to add motion to your forms with [Formkit AutoAnimate](https://auto-animate.formkit.com/)
<ComponentPreview name="InputFormAutoAnimate" />

View File

@ -139,7 +139,7 @@ const onSubmit = handleSubmit((values) => {
<FormControl> <FormControl>
<Input type="url" v-bind="componentField" /> <Input type="url" v-bind="componentField" />
</FormControl> </FormControl>
<button class="absolute py-2 pe-3 end-0 text-muted-foreground" @click="remove(index)"> <button type="button" class="absolute py-2 pe-3 end-0 text-muted-foreground" @click="remove(index)">
<Cross1Icon class="w-3" /> <Cross1Icon class="w-3" />
</button> </button>
</div> </div>

View File

@ -0,0 +1,49 @@
<script setup lang="ts">
import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod'
import * as z from 'zod'
import { vAutoAnimate } from '@formkit/auto-animate/vue'
import { Button } from '@/lib/registry/default/ui/button'
import {
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/lib/registry/default/ui/form'
import { Input } from '@/lib/registry/default/ui/input'
const formSchema = toTypedSchema(z.object({
username: z.string().min(2).max(50),
}))
const { handleSubmit } = useForm({
validationSchema: formSchema,
})
const onSubmit = handleSubmit((values) => {
console.log('Form submitted!', values)
})
</script>
<template>
<form class="w-2/3 space-y-6" @submit="onSubmit">
<FormField v-slot="{ componentField }" name="username">
<FormItem v-auto-animate>
<FormLabel>Username</FormLabel>
<FormControl>
<Input type="text" placeholder="shadcn" v-bind="componentField" />
</FormControl>
<FormDescription>
This is your public display name.
</FormDescription>
<FormMessage />
</FormItem>
</FormField>
<Button type="submit">
Submit
</Button>
</Form>
</template>

View File

@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { type InjectionKey } from 'vue' import { type InjectionKey } from 'vue'
export const FORMI_TEM_INJECTION_KEY export const FORM_ITEM_INJECTION_KEY
= Symbol() as InjectionKey<string> = Symbol() as InjectionKey<string>
</script> </script>
@ -15,7 +15,7 @@ defineOptions({
}) })
const id = useId() const id = useId()
provide(FORMI_TEM_INJECTION_KEY, id) provide(FORM_ITEM_INJECTION_KEY, id)
const { class: className, ...rest } = useAttrs() const { class: className, ...rest } = useAttrs()
</script> </script>

View File

@ -1,10 +1,10 @@
import { FieldContextKey, useFieldError, useIsFieldDirty, useIsFieldTouched, useIsFieldValid } from 'vee-validate' import { FieldContextKey, useFieldError, useIsFieldDirty, useIsFieldTouched, useIsFieldValid } from 'vee-validate'
import { inject } from 'vue' import { inject } from 'vue'
import { FORMI_TEM_INJECTION_KEY } from './FormItem.vue' import { FORM_ITEM_INJECTION_KEY } from './FormItem.vue'
export function useFormField() { export function useFormField() {
const fieldContext = inject(FieldContextKey) const fieldContext = inject(FieldContextKey)
const fieldItemContext = inject(FORMI_TEM_INJECTION_KEY) const fieldItemContext = inject(FORM_ITEM_INJECTION_KEY)
const fieldState = { const fieldState = {
valid: useIsFieldValid(), valid: useIsFieldValid(),

View File

@ -0,0 +1,49 @@
<script setup lang="ts">
import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod'
import * as z from 'zod'
import { vAutoAnimate } from '@formkit/auto-animate/vue'
import { Button } from '@/lib/registry/new-york/ui/button'
import {
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/lib/registry/new-york/ui/form'
import { Input } from '@/lib/registry/new-york/ui/input'
const formSchema = toTypedSchema(z.object({
username: z.string().min(2).max(50),
}))
const { isFieldDirty, handleSubmit } = useForm({
validationSchema: formSchema,
})
const onSubmit = handleSubmit((values) => {
console.log('Form submitted!', values)
})
</script>
<template>
<form class="w-2/3 space-y-6" @submit="onSubmit">
<FormField v-slot="{ componentField }" name="username" :validate-on-blur="!isFieldDirty">
<FormItem v-auto-animate>
<FormLabel>Username</FormLabel>
<FormControl>
<Input type="text" placeholder="shadcn" v-bind="componentField" />
</FormControl>
<FormDescription>
This is your public display name.
</FormDescription>
<FormMessage />
</FormItem>
</FormField>
<Button type="submit">
Submit
</Button>
</Form>
</template>

View File

@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { type InjectionKey } from 'vue' import { type InjectionKey } from 'vue'
export const FORMI_TEM_INJECTION_KEY export const FORM_ITEM_INJECTION_KEY
= Symbol() as InjectionKey<string> = Symbol() as InjectionKey<string>
</script> </script>
@ -11,7 +11,7 @@ import { useId } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const id = useId() const id = useId()
provide(FORMI_TEM_INJECTION_KEY, id) provide(FORM_ITEM_INJECTION_KEY, id)
</script> </script>
<template> <template>

View File

@ -1,10 +1,10 @@
import { FieldContextKey, useFieldError, useIsFieldDirty, useIsFieldTouched, useIsFieldValid } from 'vee-validate' import { FieldContextKey, useFieldError, useIsFieldDirty, useIsFieldTouched, useIsFieldValid } from 'vee-validate'
import { inject } from 'vue' import { inject } from 'vue'
import { FORMI_TEM_INJECTION_KEY } from './FormItem.vue' import { FORM_ITEM_INJECTION_KEY } from './FormItem.vue'
export function useFormField() { export function useFormField() {
const fieldContext = inject(FieldContextKey) const fieldContext = inject(FieldContextKey)
const fieldItemContext = inject(FORMI_TEM_INJECTION_KEY) const fieldItemContext = inject(FORM_ITEM_INJECTION_KEY)
const fieldState = { const fieldState = {
valid: useIsFieldValid(), valid: useIsFieldValid(),

View File

@ -50,6 +50,9 @@ importers:
apps/www: apps/www:
dependencies: dependencies:
'@formkit/auto-animate':
specifier: ^0.8.0
version: 0.8.0
'@morev/vue-transitions': '@morev/vue-transitions':
specifier: ^2.3.6 specifier: ^2.3.6
version: 2.3.6(vue@3.3.4) version: 2.3.6(vue@3.3.4)
@ -1386,6 +1389,10 @@ packages:
- '@vue/composition-api' - '@vue/composition-api'
- vue - vue
/@formkit/auto-animate@0.8.0:
resolution: {integrity: sha512-G8f7489ka0mWyi+1IEZT+xgIwcpWtRMmE2x+IrVoQ+KM1cP6VDj/TbujZjwxdb0P8w8b16/qBfViRmydbYHwMw==}
dev: false
/@humanwhocodes/config-array@0.11.11: /@humanwhocodes/config-array@0.11.11:
resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==} resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==}
engines: {node: '>=10.10.0'} engines: {node: '>=10.10.0'}
@ -3534,7 +3541,7 @@ packages:
dev: true dev: true
/concat-map@0.0.1: /concat-map@0.0.1:
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
/consola@3.2.3: /consola@3.2.3:
resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==}