feat(Form): new component (#439)

Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
Romain Hamel
2023-07-31 15:22:14 +02:00
committed by GitHub
parent c37a927b4e
commit a3aba1abad
22 changed files with 945 additions and 17 deletions

View File

@@ -0,0 +1,44 @@
<script setup lang="ts">
import { ref } from 'vue'
import type { FormError } from '@nuxthq/ui/dist/runtime/types'
const state = ref({
email: undefined,
password: undefined
})
const validate = (state: any): FormError[] => {
const errors = []
if (!state.email) errors.push({ path: 'email', message: 'Required' })
if (!state.password) errors.push({ path: 'password', message: 'Required' })
return errors
}
const form = ref()
async function submit () {
await form.value!.validate()
// Do something with state.value
}
</script>
<template>
<UForm
ref="form"
:validate="validate"
:state="state"
@submit.prevent="submit"
>
<UFormGroup label="Email" name="email">
<UInput v-model="state.email" />
</UFormGroup>
<UFormGroup label="Password" name="password">
<UInput v-model="state.password" type="password" />
</UFormGroup>
<UButton type="submit">
Submit
</UButton>
</UForm>
</template>

View File

@@ -0,0 +1,100 @@
<script setup lang="ts">
import { ref } from 'vue'
import { z } from 'zod'
import type { Form } from '@nuxthq/ui/dist/runtime/types'
const options = [
{ label: 'Option 1', value: 'option-1' },
{ label: 'Option 2', value: 'option-2' },
{ label: 'Option 3', value: 'option-3' }
]
const state = ref({
input: undefined,
textarea: undefined,
select: undefined,
selectMenu: undefined,
checkbox: undefined,
toggle: undefined,
radio: undefined,
switch: undefined,
range: undefined
})
const schema = z.object({
input: z.string().min(10),
textarea: z.string().min(10),
select: z.string().refine(value => value === 'option-2', {
message: 'Select Option 2'
}),
selectMenu: z.any().refine(option => option?.value === 'option-2', {
message: 'Select Option 2'
}),
toggle: z.boolean().refine(value => value === true, {
message: 'Toggle me'
}),
checkbox: z.boolean().refine(value => value === true, {
message: 'Check me'
}),
radio: z.string().refine(value => value === 'option-2', {
message: 'Select Option 2'
}),
range: z.number().max(20, { message: 'Must be less than 20' })
})
type Schema = z.infer<typeof schema>
const form = ref<Form<Schema>>()
async function submit () {
await form.value!.validate()
// Do something with state.value
}
</script>
<template>
<UForm
ref="form"
:schema="schema"
:state="state"
@submit.prevent="submit"
>
<UFormGroup name="input" label="Input">
<UInput v-model="state.input" />
</UFormGroup>
<UFormGroup name="textarea" label="Textarea">
<UTextarea v-model="state.textarea" />
</UFormGroup>
<UFormGroup name="select" label="Select">
<USelect v-model="state.select" placeholder="Select..." :options="options" />
</UFormGroup>
<UFormGroup name="selectMenu" label="Select Menu">
<USelectMenu v-model="state.selectMenu" placeholder="Select..." :options="options" />
</UFormGroup>
<UFormGroup name="toggle" label="Toggle">
<UToggle v-model="state.toggle" />
</UFormGroup>
<UFormGroup name="checkbox" label="Checkbox">
<UCheckbox v-model="state.checkbox" />
</UFormGroup>
<UFormGroup name="radio" label="Radio">
<URadio v-for="option in options" :key="option.value" v-model="state.radio" v-bind="option">
{{ option.label }}
</URadio>
</UFormGroup>
<UFormGroup name="range" label="Range">
<URange v-model="state.range" />
</UFormGroup>
<UButton type="submit">
Submit
</UButton>
</UForm>
</template>

View File

@@ -0,0 +1,44 @@
<script setup lang="ts">
import { ref } from 'vue'
import Joi from 'joi'
const schema = Joi.object({
email: Joi.string().required(),
password: Joi.string()
.min(8)
.required()
})
const state = ref({
email: undefined,
password: undefined
})
const form = ref()
async function submit () {
await form.value!.validate()
// Do something with state.value
}
</script>
<template>
<UForm
ref="form"
:schema="schema"
:state="state"
@submit.prevent="submit"
>
<UFormGroup label="Email" name="email">
<UInput v-model="state.email" />
</UFormGroup>
<UFormGroup label="Password" name="password">
<UInput v-model="state.password" type="password" />
</UFormGroup>
<UButton type="submit">
Submit
</UButton>
</UForm>
</template>

View File

@@ -0,0 +1,47 @@
<script setup lang="ts">
import { ref } from 'vue'
import { object, string, InferType } from 'yup'
import type { Form } from '@nuxthq/ui/dist/runtime/types'
const schema = object({
email: string().email('Invalid email').required('Required'),
password: string()
.min(8, 'Must be at least 8 characters')
.required('Required')
})
type Schema = InferType<typeof schema>
const state = ref({
email: undefined,
password: undefined
})
const form = ref<Form<Schema>>()
async function submit () {
await form.value!.validate()
// Do something with state.value
}
</script>
<template>
<UForm
ref="form"
:schema="schema"
:state="state"
@submit.prevent="submit"
>
<UFormGroup label="Email" name="email">
<UInput v-model="state.email" />
</UFormGroup>
<UFormGroup label="Password" name="password">
<UInput v-model="state.password" type="password" />
</UFormGroup>
<UButton type="submit">
Submit
</UButton>
</UForm>
</template>

View File

@@ -0,0 +1,45 @@
<script setup lang="ts">
import { ref } from 'vue'
import { z } from 'zod'
import type { Form } from '@nuxthq/ui/dist/runtime/types'
const schema = z.object({
email: z.string().email('Invalid email'),
password: z.string().min(8, 'Must be at least 8 characters')
})
type Schema = z.output<typeof schema>
const state = ref({
email: undefined,
password: undefined
})
const form = ref<Form<Schema>>()
async function submit () {
await form.value!.validate()
// Do something with state.value
}
</script>
<template>
<UForm
ref="form"
:schema="schema"
:state="state"
@submit.prevent="submit"
>
<UFormGroup label="Email" name="email">
<UInput v-model="state.email" />
</UFormGroup>
<UFormGroup label="Password" name="password">
<UInput v-model="state.password" type="password" />
</UFormGroup>
<UButton type="submit">
Submit
</UButton>
</UForm>
</template>