Button
Usage
Label
Use the default slot to set the label of the Button.
<template>
<UButton>Button</UButton>
</template>
You can achieve the same result by using the label prop.
<template>
<UButton label="Button" />
</template>
Link
You can pass any property from the Link component such as to, target, etc.
<template>
<UButton to="https://github.com/nuxt/ui" target="_blank">Button</UButton>
</template>
Color
Use the color prop to change the color of the Button.
<template>
<UButton color="neutral">Button</UButton>
</template>
Variant
Use the variant prop to change the variant of the Button.
<template>
<UButton color="neutral" variant="outline">Button</UButton>
</template>
Size
Use the size prop to change the size of the Button.
<template>
<UButton size="xl">Button</UButton>
</template>
Icon
Use the icon prop to show an Icon inside the Button.
<template>
<UButton icon="i-heroicons-rocket-launch">Button</UButton>
</template>
Use the leading and trailing props to set the icon position or the leading-icon and trailing-icon props to set a different icon for each position.
<template>
<UButton trailing-icon="i-heroicons-arrow-right">Button</UButton>
</template>
The label as prop or slot is optional so you can use the Button as an icon-only button.
<template>
<UButton icon="i-heroicons-magnifying-glass" />
</template>
Loading
Use the loading prop to show a loading icon and disable the Button.
<template>
<UButton loading>Button</UButton>
</template>
Use the loading-auto prop to show the loading icon automatically while the @click promise is pending.
<script setup lang="ts">
async function onClick() {
return new Promise<void>(res => setTimeout(res, 1000))
}
</script>
<template>
<UButton loading-auto @click="onClick">
Button
</UButton>
</template>
This also works with the Form component.
<script setup lang="ts">
const state = reactive({ fullName: '' })
async function onSubmit() {
return new Promise<void>(res => setTimeout(res, 1000))
}
async function validate(data: Partial<typeof state>) {
if (!data.fullName?.length) return [{ name: 'fullName', message: 'Required' }]
return []
}
</script>
<template>
<UForm :state="state" :validate="validate" @submit="onSubmit">
<UFormField name="fullName" label="Full name">
<UInput v-model="state.fullName" />
</UFormField>
<UButton type="submit" class="mt-2" loading-auto>
Submit
</UButton>
</UForm>
</template>
Loading Icon
Use the loading-icon prop to customize the loading icon. Defaults to i-heroicons-arrow-path-20-solid.
<template>
<UButton loading loading-icon="i-heroicons-arrow-path-rounded-square">Button</UButton>
</template>
Disabled
Use the disabled prop to disable the Button.
<template>
<UButton disabled>Button</UButton>
</template>
Examples
class prop
Use the class prop to override the base styles of the Button.
<template>
<UButton class="font-bold rounded-full">Button</UButton>
</template>
ui prop
Use the ui prop to override the slots styles of the Button.
<template>
<UButton
icon="i-heroicons-rocket-launch"
color="neutral"
variant="outline"
:ui="{
leadingIcon: 'text-[--ui-primary]'
}"
>
Button
</UButton>
</template>
API
Props
| Prop | Default | Type |
|---|---|---|
as |
|
The element or component this component should render as when not a link. |
label |
| |
color |
|
|
variant |
|
|
size |
|
|
square |
Render the button with equal padding on all sides. | |
block |
Render the button full width. | |
loadingAuto |
Set loading state automatically based on the | |
icon |
Display an icon based on the | |
leading |
When | |
leadingIcon |
Display an icon on the left side. | |
trailing |
When | |
trailingIcon |
Display an icon on the right side. | |
loading |
When | |
loadingIcon |
|
The icon when the |
type |
|
The type of the button when not a link. |
disabled |
| |
ui |
|
Slots
| Slot | Type |
|---|---|
leading |
|
default |
|
trailing |
|
Theme
export default defineAppConfig({
ui: {
button: {
slots: {
base: [
'rounded-md font-medium inline-flex items-center focus:outline-none disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:opacity-75 aria-disabled:opacity-75',
'transition-colors'
],
label: 'truncate',
leadingIcon: 'shrink-0',
leadingAvatar: 'shrink-0',
trailingIcon: 'shrink-0'
},
variants: {
buttonGroup: {
horizontal: 'not-only:first:rounded-e-none not-only:last:rounded-s-none not-last:not-first:rounded-none',
vertical: 'not-only:first:rounded-b-none not-only:last:rounded-t-none not-last:not-first:rounded-none'
},
color: {
primary: '',
secondary: '',
success: '',
info: '',
warning: '',
error: '',
neutral: ''
},
variant: {
solid: '',
outline: '',
soft: '',
subtle: '',
ghost: '',
link: ''
},
size: {
xs: {
base: 'px-2 py-1 text-xs gap-1',
leadingIcon: 'size-4',
trailingIcon: 'size-4'
},
sm: {
base: 'px-2.5 py-1.5 text-xs gap-1.5',
leadingIcon: 'size-4',
trailingIcon: 'size-4'
},
md: {
base: 'px-2.5 py-1.5 text-sm gap-1.5',
leadingIcon: 'size-5',
trailingIcon: 'size-5'
},
lg: {
base: 'px-3 py-2 text-sm gap-2',
leadingIcon: 'size-5',
trailingIcon: 'size-5'
},
xl: {
base: 'px-3 py-2 text-base gap-2',
leadingIcon: 'size-6',
trailingIcon: 'size-6'
}
},
block: {
true: {
base: 'w-full justify-center',
trailingIcon: 'ms-auto'
}
},
square: {
true: ''
},
leading: {
true: ''
},
trailing: {
true: ''
},
loading: {
true: ''
}
},
compoundVariants: [
{
color: 'primary',
variant: 'solid',
class: 'text-[--ui-bg] bg-[--ui-primary] hover:bg-[--ui-primary]/75 disabled:bg-[--ui-primary] aria-disabled:bg-[--ui-primary] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[--ui-primary]'
},
{
color: 'primary',
variant: 'outline',
class: 'ring ring-inset ring-[--ui-primary]/50 text-[--ui-primary] hover:bg-[--ui-primary]/10 disabled:bg-transparent aria-disabled:bg-transparent dark:disabled:bg-transparent dark:aria-disabled:bg-transparent focus-visible:ring-2 focus-visible:ring-[--ui-primary]'
},
{
color: 'primary',
variant: 'soft',
class: 'text-[--ui-primary] bg-[--ui-primary]/10 hover:bg-[--ui-primary]/15 focus-visible:bg-[--ui-primary]/15 disabled:bg-[--ui-primary]/10 aria-disabled:bg-[--ui-primary]/10'
},
{
color: 'primary',
variant: 'subtle',
class: 'text-[--ui-primary] ring ring-inset ring-[--ui-primary]/25 bg-[--ui-primary]/10 hover:bg-[--ui-primary]/15 disabled:bg-[--ui-primary]/10 aria-disabled:bg-[--ui-primary]/10 focus-visible:ring-2 focus-visible:ring-[--ui-primary]'
},
{
color: 'primary',
variant: 'ghost',
class: 'text-[--ui-primary] hover:bg-[--ui-primary]/10 focus-visible:bg-[--ui-primary]/10 disabled:bg-transparent aria-disabled:bg-transparent dark:disabled:bg-transparent dark:aria-disabled:bg-transparent'
},
{
color: 'primary',
variant: 'link',
class: 'text-[--ui-primary] hover:text-[--ui-primary] disabled:text-[--ui-primary] aria-disabled:text-[--ui-primary] focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[--ui-primary]'
},
{
color: 'neutral',
variant: 'solid',
class: 'text-[--ui-bg] bg-[--ui-bg-inverted] hover:bg-[--ui-bg-inverted]/80 disabled:bg-[--ui-bg-inverted] aria-disabled:bg-[--ui-bg-inverted] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[--ui-border-inverted]'
},
{
color: 'neutral',
variant: 'outline',
class: 'ring ring-inset ring-[--ui-border-accented] text-[--ui-text] bg-[--ui-bg] hover:bg-[--ui-bg-elevated] disabled:bg-[--ui-bg] aria-disabled:bg-[--ui-bg] focus-visible:ring-2 focus-visible:ring-[--ui-border-inverted]'
},
{
color: 'neutral',
variant: 'soft',
class: 'text-[--ui-text] bg-[--ui-bg-elevated] hover:bg-[--ui-bg-accented]/75 focus-visible:bg-[--ui-bg-accented]/75 disabled:bg-[--ui-bg-elevated] aria-disabled:bg-[--ui-bg-elevated]'
},
{
color: 'neutral',
variant: 'subtle',
class: 'ring ring-inset ring-[--ui-border-accented] text-[--ui-text] bg-[--ui-bg-elevated] hover:bg-[--ui-bg-accented]/75 disabled:bg-[--ui-bg-elevated] aria-disabled:bg-[--ui-bg-elevated] focus-visible:ring-2 focus-visible:ring-[--ui-border-inverted]'
},
{
color: 'neutral',
variant: 'ghost',
class: 'text-[--ui-text] hover:bg-[--ui-bg-elevated] focus-visible:bg-[--ui-bg-elevated] hover:disabled:bg-transparent dark:hover:disabled:bg-transparent hover:aria-disabled:bg-transparent dark:hover:aria-disabled:bg-transparent'
},
{
color: 'neutral',
variant: 'link',
class: 'text-[--ui-text-muted] hover:text-[--ui-text] disabled:text-[--ui-text-muted] aria-disabled:text-[--ui-text-muted] focus-visible:ring-inset focus-visible:ring-2 focus-visible:ring-[--ui-border-inverted]'
},
{
size: 'xs',
square: true,
class: 'p-1'
},
{
size: 'sm',
square: true,
class: 'p-1.5'
},
{
size: 'md',
square: true,
class: 'p-1.5'
},
{
size: 'lg',
square: true,
class: 'p-2'
},
{
size: 'xl',
square: true,
class: 'p-2'
},
{
loading: true,
leading: true,
class: {
leadingIcon: 'animate-spin'
}
},
{
loading: true,
leading: false,
trailing: true,
class: {
trailingIcon: 'animate-spin'
}
}
],
defaultVariants: {
color: 'primary',
variant: 'solid',
size: 'md'
}
}
}
})