Usage
Built on top of the Form component, the AuthForm
component can be used in your pages or wrapped in a PageCard.
The form will construct itself based on the fields
prop and the state will be handled internally. You can pass all the props you would pass to a FormField or an Input to each field.
<script setup lang="ts">
import * as z from 'zod'
import type { FormSubmitEvent } from '@nuxt/ui'
const toast = useToast()
const fields = [{
name: 'email',
type: 'text' as const,
label: 'Email',
placeholder: 'Enter your email',
required: true
}, {
name: 'password',
label: 'Password',
type: 'password' as const,
placeholder: 'Enter your password'
}, {
name: 'remember',
label: 'Remember me',
type: 'checkbox' as const
}]
const providers = [{
label: 'Google',
icon: 'i-simple-icons-google',
onClick: () => {
toast.add({ title: 'Google', description: 'Login with Google' })
}
}, {
label: 'GitHub',
icon: 'i-simple-icons-github',
onClick: () => {
toast.add({ title: 'GitHub', description: 'Login with GitHub' })
}
}]
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>
function onSubmit(payload: FormSubmitEvent<Schema>) {
console.log('Submitted', payload)
}
</script>
<template>
<div class="flex flex-col items-center justify-center gap-4 p-4">
<UPageCard class="w-full max-w-md">
<UAuthForm
:schema="schema"
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:fields="fields"
:providers="providers"
@submit="onSubmit"
/>
</UPageCard>
</div>
</template>
Title
Use the title
prop to set the title of the form.
<script setup lang="ts">
const fields = ref([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm class="max-w-md" title="Login" :fields="fields" />
</template>
Description
Use the description
prop to set the description of the form.
<script setup lang="ts">
const fields = ref([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
class="max-w-md"
title="Login"
description="Enter your credentials to access your account."
:fields="fields"
/>
</template>
Icon
Use the icon
prop to set the icon of the form.
<script setup lang="ts">
const fields = ref([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
class="max-w-md"
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:fields="fields"
/>
</template>
Providers
Use the providers
prop to add providers to the form.
You can pass any property from the Button component such as variant
, color
, to
, etc.
<script setup lang="ts">
const fields = ref([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
const providers = ref([
{
label: 'Google',
icon: 'i-simple-icons-google',
color: 'neutral',
variant: 'subtle'
},
{
label: 'GitHub',
icon: 'i-simple-icons-github',
color: 'neutral',
variant: 'subtle'
}
])
</script>
<template>
<UAuthForm
class="max-w-md"
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:providers="providers"
:fields="fields"
/>
</template>
Separator
Use the separator
prop to customize the Separator between the providers and the fields. Defaults to or
.
<script setup lang="ts">
const providers = ref([
{
label: 'Google',
icon: 'i-simple-icons-google',
color: 'neutral',
variant: 'subtle'
},
{
label: 'GitHub',
icon: 'i-simple-icons-github',
color: 'neutral',
variant: 'subtle'
}
])
const fields = ref([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
class="max-w-md"
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:providers="providers"
:fields="fields"
separator="Providers"
/>
</template>
You can pass any property from the Separator component to customize it.
<script setup lang="ts">
const providers = ref([
{
label: 'Google',
icon: 'i-simple-icons-google',
color: 'neutral',
variant: 'subtle'
},
{
label: 'GitHub',
icon: 'i-simple-icons-github',
color: 'neutral',
variant: 'subtle'
}
])
const fields = ref([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
class="max-w-md"
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:providers="providers"
:fields="fields"
:separator="{
icon: 'i-lucide-user'
}"
/>
</template>
Submit
Use the submit
prop to change the submit button of the form.
You can pass any property from the Button component such as variant
, color
, to
, etc.
<script setup lang="ts">
const fields = ref([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
class="max-w-md"
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:fields="fields"
:submit="{
label: 'Submit',
color: 'error',
variant: 'subtle'
}"
/>
</template>
Examples
Within a page
You can wrap the AuthForm
component with the PageCard component to display it within a login.vue
page for example.
<script setup lang="ts">
import * as z from 'zod'
import type { FormSubmitEvent } from '@nuxt/ui'
const toast = useToast()
const fields = [{
name: 'email',
type: 'text' as const,
label: 'Email',
placeholder: 'Enter your email',
required: true
}, {
name: 'password',
label: 'Password',
type: 'password' as const,
placeholder: 'Enter your password'
}, {
name: 'remember',
label: 'Remember me',
type: 'checkbox' as const
}]
const providers = [{
label: 'Google',
icon: 'i-simple-icons-google',
onClick: () => {
toast.add({ title: 'Google', description: 'Login with Google' })
}
}, {
label: 'GitHub',
icon: 'i-simple-icons-github',
onClick: () => {
toast.add({ title: 'GitHub', description: 'Login with GitHub' })
}
}]
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>
function onSubmit(payload: FormSubmitEvent<Schema>) {
console.log('Submitted', payload)
}
</script>
<template>
<div class="flex flex-col items-center justify-center gap-4 p-4">
<UPageCard class="w-full max-w-md">
<UAuthForm
:schema="schema"
:fields="fields"
:providers="providers"
title="Welcome back!"
icon="i-lucide-lock"
@submit="onSubmit"
>
<template #description>
Don't have an account? <ULink to="#" class="text-(--ui-primary) font-medium">Sign up</ULink>.
</template>
<template #password-hint>
<NuxtLink to="/" class="text-(--ui-primary) font-medium">Forgot password?</NuxtLink>
</template>
<template #validation>
<UAlert color="error" icon="i-lucide-info" title="Error signing in" />
</template>
<template #footer>
By signing in, you agree to our <ULink to="#" class="text-(--ui-primary) font-medium">Terms of Service</ULink>.
</template>
</UAuthForm>
</UPageCard>
</div>
</template>
API
Props
Prop | Default | Type |
---|---|---|
as |
|
The element or component this component should render as. |
title |
| |
description |
| |
icon |
| |
fields |
| |
providers |
Display a list of Button under the description.
| |
separator |
|
The text displayed in the separator.
|
submit |
Display a submit button at the bottom of the form.
| |
schema |
| |
validate |
| |
validateOn |
| |
validateOnInputDelay |
| |
disabled |
| |
ui |
|
Slots
Slot | Type |
---|---|
header |
|
leading |
|
title |
|
description |
|
validation |
|
footer |
|
Emits
Event | Type |
---|---|
submit |
|
Theme
export default defineAppConfig({
uiPro: {
authForm: {
slots: {
root: 'w-full space-y-6',
header: 'flex flex-col text-center',
leading: 'mb-2',
leadingIcon: 'size-8 shrink-0',
title: 'text-xl text-pretty font-semibold text-(--ui-text-highlighted)',
description: 'mt-1 text-base text-pretty text-(--ui-text-muted)',
body: 'gap-y-6 flex flex-col',
providers: 'space-y-3',
separator: '',
form: 'space-y-5',
footer: 'text-sm text-center text-(--ui-text-muted) mt-2'
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import uiPro from '@nuxt/ui-pro/vite'
export default defineConfig({
plugins: [
vue(),
uiPro({
uiPro: {
authForm: {
slots: {
root: 'w-full space-y-6',
header: 'flex flex-col text-center',
leading: 'mb-2',
leadingIcon: 'size-8 shrink-0',
title: 'text-xl text-pretty font-semibold text-(--ui-text-highlighted)',
description: 'mt-1 text-base text-pretty text-(--ui-text-muted)',
body: 'gap-y-6 flex flex-col',
providers: 'space-y-3',
separator: '',
form: 'space-y-5',
footer: 'text-sm text-center text-(--ui-text-muted) mt-2'
}
}
}
})
]
})