Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Form): new component #439

Merged
merged 43 commits into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
0d51f8e
feat(Form): implement form component
romhml Jul 19, 2023
de9cdd1
feat(Form): trigger form validation on input blur
romhml Jul 20, 2023
f44d91d
docs(Form): customize error messages in form examples
romhml Jul 20, 2023
dc0008e
feat(Form): add composable to manage form input events
romhml Jul 20, 2023
6830462
docs(Form): update form docs
romhml Jul 20, 2023
dc5c72d
chore(Form): cleanup and format code
romhml Jul 20, 2023
ba76719
chore(Form): debug Form typeguards in final build
romhml Jul 20, 2023
57afe41
feat(Form): add validation hook for all inputs
romhml Jul 21, 2023
010ca1c
feat(Form): move useFormEvents to composables
romhml Jul 21, 2023
447cae6
feat(Form): expose form interfaces through module template
romhml Jul 21, 2023
c0d868d
fix(Form): fixed FormGroup error status injection
romhml Jul 26, 2023
788236e
feat(Form): add support for Joi
romhml Jul 26, 2023
77818b3
chore(Form): move joi to devDependencies
romhml Jul 27, 2023
f010803
Merge branch 'dev' into feat-form-component
benjamincanac Jul 27, 2023
b8c90e4
feat(SelectMenu): emit change event
romhml Jul 27, 2023
9b970c8
fix(Form): removed duplicate interface definition
romhml Jul 27, 2023
a3f8648
improve type imports
benjamincanac Jul 27, 2023
343d44e
chore(module): lint
benjamincanac Jul 27, 2023
4b8e83b
chore(github): run typecheck after build
benjamincanac Jul 27, 2023
3671cd8
docs: improve
benjamincanac Jul 27, 2023
20f16da
chore
benjamincanac Jul 27, 2023
4532788
refactor(FormGroup): remove path prop
romhml Jul 27, 2023
8a2176e
fix(Form): rewrite Form.ts to .vue to fix props parsing with nuxt-com…
romhml Jul 27, 2023
923813a
feat(Tabs): new component (#450)
benjamincanac Jul 27, 2023
38123ea
feat(Alert): new component (#449)
benjamincanac Jul 27, 2023
5b61493
chore(deps): bump
benjamincanac Jul 27, 2023
3420835
feat(Badge): rename `outline` to `subtle` + add `soft` variants
benjamincanac Jul 27, 2023
56d0c47
docs(Alert): uniformize navigation badge
benjamincanac Jul 27, 2023
2d1652f
fix(module): safelist all colors for `toast.add`
benjamincanac Jul 27, 2023
ee320ee
Revert "fix(Form): rewrite Form.ts to .vue to fix props parsing with …
benjamincanac Jul 27, 2023
340ee79
Merge branch 'dev' into pr/439
benjamincanac Jul 27, 2023
939a00d
clean
benjamincanac Jul 27, 2023
22e029a
up
benjamincanac Jul 27, 2023
0a944d3
fix(Form): fix nuxt-component-meta parsing issues
romhml Jul 28, 2023
dc8cdc4
docs(Form): improve documentation
romhml Jul 28, 2023
bd64f81
docs(Form): fix typos
romhml Jul 28, 2023
83d0412
Merge branch 'dev' into pr/439
benjamincanac Jul 30, 2023
39567e0
up
benjamincanac Jul 30, 2023
ae3b97b
docs: clean
benjamincanac Jul 30, 2023
744b4b2
Merge branch 'dev' into feat-form-component
benjamincanac Jul 30, 2023
9193e46
Merge branch 'dev' into feat-form-component
benjamincanac Jul 31, 2023
f7311d7
docs: improve
benjamincanac Jul 31, 2023
aa5a2c7
up
benjamincanac Jul 31, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions docs/components/content/examples/FormExample.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<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"
class="space-y-4 w-60"
@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>

101 changes: 101 additions & 0 deletions docs/components/content/examples/FormExampleElements.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<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"
class="space-y-4 w-60"
@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>
45 changes: 45 additions & 0 deletions docs/components/content/examples/FormExampleJoi.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<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"
class="space-y-4 w-60"
@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>
48 changes: 48 additions & 0 deletions docs/components/content/examples/FormExampleYup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<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"
class="space-y-4 w-60"
@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>
46 changes: 46 additions & 0 deletions docs/components/content/examples/FormExampleZod.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<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"
class="space-y-4 w-60"
@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