Skip to content

Commit

Permalink
feat(Form): new component (#439)
Browse files Browse the repository at this point in the history
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
  • Loading branch information
romhml and benjamincanac committed Jul 31, 2023
1 parent c37a927 commit a3aba1a
Show file tree
Hide file tree
Showing 22 changed files with 945 additions and 17 deletions.
44 changes: 44 additions & 0 deletions docs/components/content/examples/FormExampleBasic.vue
Original file line number Diff line number Diff line change
@@ -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>
100 changes: 100 additions & 0 deletions docs/components/content/examples/FormExampleElements.vue
Original file line number Diff line number Diff line change
@@ -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>
44 changes: 44 additions & 0 deletions docs/components/content/examples/FormExampleJoi.vue
Original file line number Diff line number Diff line change
@@ -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>
47 changes: 47 additions & 0 deletions docs/components/content/examples/FormExampleYup.vue
Original file line number Diff line number Diff line change
@@ -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>
45 changes: 45 additions & 0 deletions docs/components/content/examples/FormExampleZod.vue
Original file line number Diff line number Diff line change
@@ -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>
Loading

1 comment on commit a3aba1a

@vercel
Copy link

@vercel vercel bot commented on a3aba1a Jul 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

ui – ./

ui-nuxtlabs.vercel.app
ui-git-dev-nuxtlabs.vercel.app
ui.nuxtlabs.com

Please sign in to comment.