Button
用法
标签(Label)
使用默认插槽来设置按钮的标签。
<template>
<UButton>Button</UButton>
</template>
你也可以使用 label prop 来达到同样的效果。
<template>
<UButton label="Button" />
</template>
颜色(Color)
使用 color prop 来改变按钮的颜色。
<template>
<UButton color="neutral">Button</UButton>
</template>
变体(Variant)
使用 variant prop 来改变按钮的变体。
<template>
<UButton color="neutral" variant="outline">Button</UButton>
</template>
尺寸(Size)
使用 size prop 来改变按钮的尺寸。
<template>
<UButton size="xl">Button</UButton>
</template>
图标(Icon)
使用 icon prop 在按钮内部显示一个 Icon。
<template>
<UButton icon="i-lucide-rocket" size="md" color="primary" variant="solid">Button</UButton>
</template>
使用 leading 和 trailing props 来设置图标位置,或者使用 leading-icon 和 trailing-icon props 为每个位置设置不同的图标。
<template>
<UButton trailing-icon="i-lucide-arrow-right" size="md">Button</UButton>
</template>
label 作为 prop 或插槽是可选的,所以你可以将按钮用作纯图标按钮。
<template>
<UButton icon="i-lucide-search" size="md" color="primary" variant="solid" />
</template>
头像(Avatar)
使用 avatar prop 在按钮内部显示一个 Avatar。
<template>
<UButton
:avatar="{
src: 'https://github.com/nuxt.png'
}"
size="md"
color="neutral"
variant="outline"
>
Button
</UButton>
</template>
label 作为 prop 或插槽是可选的,所以你可以将按钮用作纯头像按钮。
<template>
<UButton
:avatar="{
src: 'https://github.com/nuxt.png'
}"
size="md"
color="neutral"
variant="outline"
/>
</template>
链接(Link)
你可以传递 Link 组件的任何属性,例如 to、target 等。
<template>
<UButton to="https://github.com/nuxt/ui" target="_blank">Button</UButton>
</template>
当按钮是链接或使用 active prop 时,你可以使用 active-color 和 active-variant props 来定制活跃状态。
<template>
<UButton active color="neutral" variant="outline" active-color="primary" active-variant="solid">
Button
</UButton>
</template>
你也可以使用 active-class 和 inactive-class props 来定制活跃状态。
<template>
<UButton active active-class="font-bold" inactive-class="font-light">Button</UButton>
</template>
app.config.ts 文件中的 ui.button.variants.active 键下全局配置这些样式。export default defineAppConfig({
ui: {
button: {
variants: {
active: {
true: {
base: 'font-bold'
}
}
}
}
}
})
加载中(Loading)
使用 loading prop 来显示加载图标并禁用按钮。
<template>
<UButton loading>Button</UButton>
</template>
使用 loading-auto prop 在 @click promise 待处理时自动显示加载图标。
<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>
这也适用于 Form 组件。
<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)
使用 loading-icon prop 来自定义加载图标。默认为 i-lucide-loader-circle。
<template>
<UButton loading loading-icon="i-lucide-loader">Button</UButton>
</template>
禁用(Disabled)
使用 disabled prop 来禁用按钮。
<template>
<UButton disabled>Button</UButton>
</template>
示例
class prop
使用 class prop 来覆盖按钮的基础样式。
<template>
<UButton class="font-bold rounded-full">Button</UButton>
</template>
ui prop
使用 ui prop 来覆盖按钮的插槽样式。
<template>
<UButton
icon="i-lucide-rocket"
color="neutral"
variant="outline"
:ui="{
leadingIcon: 'text-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 |
|
|
activeColor |
| |
variant |
|
|
activeVariant |
| |
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 | |
avatar |
Display an avatar on the left side.
| |
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 |
| |
to |
Route Location the link should navigate to when clicked on.
| |
active |
Force the link to be active independent of the current route. | |
target |
Where to display the linked URL, as the name for a browsing context. | |
ui |
|
Slots
| Slot | Type |
|---|---|
leading |
|
default |
|
trailing |
|
Emits
在 Button 组件中,onClick prop 被设计得非常灵活:
onClick?: ((event: MouseEvent) => void | Promise<void>) | Array<((event: MouseEvent) => void | Promise<void>)>
这意味着 onClick prop 可以接受:
- 单个函数:最常见的用法,当点击按钮时执行一个函数。
- 函数数组:当点击按钮时,按顺序执行多个函数。
更重要的是,这些函数可以返回 void (没有返回值) 或者是 Promise<void> (一个 Promise)。当返回 Promise 时,组件内部的 loadingAuto 机制会非常有用。
onClick prop 的使用场景
- 简单的点击事件 (返回
void)
这是最基础的用法,点击按钮后立即执行一个动作。
<template>
<div class="space-y-4">
<UButton label="普通点击" :on-click="handleClick" />
<UButton label="内联点击" :on-click="() => alert('你点击了内联按钮!')" />
</div>
</template>
<script setup lang="ts">
const handleClick = (event: MouseEvent) => {
console.log('按钮被点击了!', event);
alert('你点击了普通点击按钮!');
};
</script>
- 执行异步操作 (返回
Promise<void>)
当你的点击事件涉及到异步操作(例如 API 调用、数据加载、等待动画完成等)时,onClick 可以返回一个 Promise。配合 loadingAuto prop,这会提供非常好的用户体验。
<template>
<div class="space-y-4">
<UButton
label="保存数据"
icon="i-heroicons-light-cloud-arrow-up"
:loading-auto="true"
:on-click="saveData"
/>
<UButton
label="加载内容"
icon="i-heroicons-light-arrow-path"
:loading-auto="true"
:on-click="loadContent"
/>
</div>
</template>
<script setup lang="ts">
const saveData = async (event: MouseEvent) => {
console.log('开始保存数据...', event);
await new Promise(resolve => setTimeout(resolve, 2500)); // 模拟异步 API 调用
console.log('数据保存成功!');
alert('数据已保存!');
};
const loadContent = async () => {
console.log('开始加载内容...');
await new Promise(resolve => setTimeout(resolve, 1500)); // 模拟异步内容加载
console.log('内容加载完成!');
alert('内容已加载!');
};
</script>
解释:
saveData和loadContent都是async函数,它们返回一个Promise。- 当你将
loadingAuto设置为true时:- 当
onClick函数开始执行时(即Promise处于 pending 状态),按钮会自动进入加载状态(显示加载图标,禁用按钮)。 - 当
Promise解决 (resolved) 或拒绝 (rejected) 时,按钮会自动退出加载状态。
- 当
- 这种模式非常适合表单提交、数据更新等异步操作。
- 执行多个操作 (函数数组)
如果你希望点击一个按钮能触发一系列独立的动作,你可以传递一个函数数组。
<template>
<div class="space-y-4">
<UButton
label="执行多步操作"
icon="i-heroicons-light-play"
:loading-auto="true"
:on-click="[step1, step2, step3]"
/>
</div>
</template>
<script setup lang="ts">
const step1 = async () => {
console.log('执行第一步:验证用户...');
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('第一步完成。');
};
const step2 = async (event: MouseEvent) => {
console.log('执行第二步:处理数据...', event);
await new Promise(resolve => setTimeout(resolve, 1500));
console.log('第二步完成。');
};
const step3 = async () => {
console.log('执行第三步:通知结果...');
await new Promise(resolve => setTimeout(resolve, 500));
console.log('所有步骤完成!');
alert('多步操作已完成!');
};
</script>
解释:
- 当
onClick是一个函数数组时,组件内部的onClickWrapper会使用Promise.all来等待所有函数执行完毕。 - 这意味着:
- 如果任何一个函数是异步的 (
async函数或返回Promise),按钮会进入加载状态。 - 只有当所有函数(无论同步还是异步)都执行完毕后,按钮才会退出加载状态。
- 如果任何一个函数是异步的 (
- 这种用法适用于需要按顺序执行一系列独立任务的场景。
- 参数传递:onClick 接收的函数都会自动获得 MouseEvent 对象作为第一个参数。
- 优先级:如果你同时使用了 onClick 和 @click (Vue 原生事件监听器),两者都会触发。onClick 是 Nuxt UI 按钮组件特有的 prop,通常建议优先使用它,尤其是在需要利用 loadingAuto 等高级功能时。
- 类型安全:由于 ButtonProps 中对 onClick 进行了类型定义,TypeScript 会帮助你确保传入的函数符合预期。
通过这种设计,UButton 组件的 onClick prop 提供了极大的灵活性,能够轻松处理简单的点击事件、复杂的异步操作,甚至是多步任务流,同时保持了良好的用户体验,尤其是在结合 loadingAuto prop 使用时。
Theme
export default defineAppConfig({
ui: {
button: {
slots: {
base: [
'rounded-md font-medium inline-flex items-center 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',
leadingAvatarSize: '',
trailingIcon: 'shrink-0'
},
variants: {
buttonGroup: {
horizontal: 'not-only:first:rounded-e-none not-only:last:rounded-s-none not-last:not-first:rounded-none focus-visible:z-[1]',
vertical: 'not-only:first:rounded-b-none not-only:last:rounded-t-none not-last:not-first:rounded-none focus-visible:z-[1]'
},
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',
leadingAvatarSize: '3xs',
trailingIcon: 'size-4'
},
sm: {
base: 'px-2.5 py-1.5 text-xs gap-1.5',
leadingIcon: 'size-4',
leadingAvatarSize: '3xs',
trailingIcon: 'size-4'
},
md: {
base: 'px-2.5 py-1.5 text-sm gap-1.5',
leadingIcon: 'size-5',
leadingAvatarSize: '2xs',
trailingIcon: 'size-5'
},
lg: {
base: 'px-3 py-2 text-sm gap-2',
leadingIcon: 'size-5',
leadingAvatarSize: '2xs',
trailingIcon: 'size-5'
},
xl: {
base: 'px-3 py-2 text-base gap-2',
leadingIcon: 'size-6',
leadingAvatarSize: 'xs',
trailingIcon: 'size-6'
}
},
block: {
true: {
base: 'w-full justify-center',
trailingIcon: 'ms-auto'
}
},
square: {
true: ''
},
leading: {
true: ''
},
trailing: {
true: ''
},
loading: {
true: ''
},
active: {
true: {
base: ''
},
false: {
base: ''
}
}
},
compoundVariants: [
{
color: 'primary',
variant: 'solid',
class: 'text-inverted bg-primary hover:bg-primary/75 active:bg-primary/75 disabled:bg-primary aria-disabled:bg-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary'
},
{
color: 'primary',
variant: 'outline',
class: 'ring ring-inset ring-primary/50 text-primary hover:bg-primary/10 active:bg-primary/10 disabled:bg-transparent aria-disabled:bg-transparent dark:disabled:bg-transparent dark:aria-disabled:bg-transparent focus:outline-none focus-visible:ring-2 focus-visible:ring-primary'
},
{
color: 'primary',
variant: 'soft',
class: 'text-primary bg-primary/10 hover:bg-primary/15 active:bg-primary/15 focus:outline-none focus-visible:bg-primary/15 disabled:bg-primary/10 aria-disabled:bg-primary/10'
},
{
color: 'primary',
variant: 'subtle',
class: 'text-primary ring ring-inset ring-primary/25 bg-primary/10 hover:bg-primary/15 active:bg-primary/15 disabled:bg-primary/10 aria-disabled:bg-primary/10 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary'
},
{
color: 'primary',
variant: 'ghost',
class: 'text-primary hover:bg-primary/10 active:bg-primary/10 focus:outline-none focus-visible:bg-primary/10 disabled:bg-transparent aria-disabled:bg-transparent dark:disabled:bg-transparent dark:aria-disabled:bg-transparent'
},
{
color: 'primary',
variant: 'link',
class: 'text-primary hover:text-primary/75 active:text-primary/75 disabled:text-primary aria-disabled:text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary'
},
{
color: 'neutral',
variant: 'solid',
class: 'text-inverted bg-inverted hover:bg-inverted/90 active:bg-inverted/90 disabled:bg-inverted aria-disabled:bg-inverted focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-inverted'
},
{
color: 'neutral',
variant: 'outline',
class: 'ring ring-inset ring-accented text-default bg-default hover:bg-elevated active:bg-elevated disabled:bg-default aria-disabled:bg-default focus:outline-none focus-visible:ring-2 focus-visible:ring-inverted'
},
{
color: 'neutral',
variant: 'soft',
class: 'text-default bg-elevated hover:bg-accented/75 active:bg-accented/75 focus:outline-none focus-visible:bg-accented/75 disabled:bg-elevated aria-disabled:bg-elevated'
},
{
color: 'neutral',
variant: 'subtle',
class: 'ring ring-inset ring-accented text-default bg-elevated hover:bg-accented/75 active:bg-accented/75 disabled:bg-elevated aria-disabled:bg-elevated focus:outline-none focus-visible:ring-2 focus-visible:ring-inverted'
},
{
color: 'neutral',
variant: 'ghost',
class: 'text-default hover:bg-elevated active:bg-elevated focus:outline-none focus-visible: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-muted hover:text-default active:text-default disabled:text-muted aria-disabled:text-muted focus:outline-none focus-visible:ring-inset focus-visible:ring-2 focus-visible:ring-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'
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
button: {
slots: {
base: [
'rounded-md font-medium inline-flex items-center 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',
leadingAvatarSize: '',
trailingIcon: 'shrink-0'
},
variants: {
buttonGroup: {
horizontal: 'not-only:first:rounded-e-none not-only:last:rounded-s-none not-last:not-first:rounded-none focus-visible:z-[1]',
vertical: 'not-only:first:rounded-b-none not-only:last:rounded-t-none not-last:not-first:rounded-none focus-visible:z-[1]'
},
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',
leadingAvatarSize: '3xs',
trailingIcon: 'size-4'
},
sm: {
base: 'px-2.5 py-1.5 text-xs gap-1.5',
leadingIcon: 'size-4',
leadingAvatarSize: '3xs',
trailingIcon: 'size-4'
},
md: {
base: 'px-2.5 py-1.5 text-sm gap-1.5',
leadingIcon: 'size-5',
leadingAvatarSize: '2xs',
trailingIcon: 'size-5'
},
lg: {
base: 'px-3 py-2 text-sm gap-2',
leadingIcon: 'size-5',
leadingAvatarSize: '2xs',
trailingIcon: 'size-5'
},
xl: {
base: 'px-3 py-2 text-base gap-2',
leadingIcon: 'size-6',
leadingAvatarSize: 'xs',
trailingIcon: 'size-6'
}
},
block: {
true: {
base: 'w-full justify-center',
trailingIcon: 'ms-auto'
}
},
square: {
true: ''
},
leading: {
true: ''
},
trailing: {
true: ''
},
loading: {
true: ''
},
active: {
true: {
base: ''
},
false: {
base: ''
}
}
},
compoundVariants: [
{
color: 'primary',
variant: 'solid',
class: 'text-inverted bg-primary hover:bg-primary/75 active:bg-primary/75 disabled:bg-primary aria-disabled:bg-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary'
},
{
color: 'primary',
variant: 'outline',
class: 'ring ring-inset ring-primary/50 text-primary hover:bg-primary/10 active:bg-primary/10 disabled:bg-transparent aria-disabled:bg-transparent dark:disabled:bg-transparent dark:aria-disabled:bg-transparent focus:outline-none focus-visible:ring-2 focus-visible:ring-primary'
},
{
color: 'primary',
variant: 'soft',
class: 'text-primary bg-primary/10 hover:bg-primary/15 active:bg-primary/15 focus:outline-none focus-visible:bg-primary/15 disabled:bg-primary/10 aria-disabled:bg-primary/10'
},
{
color: 'primary',
variant: 'subtle',
class: 'text-primary ring ring-inset ring-primary/25 bg-primary/10 hover:bg-primary/15 active:bg-primary/15 disabled:bg-primary/10 aria-disabled:bg-primary/10 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary'
},
{
color: 'primary',
variant: 'ghost',
class: 'text-primary hover:bg-primary/10 active:bg-primary/10 focus:outline-none focus-visible:bg-primary/10 disabled:bg-transparent aria-disabled:bg-transparent dark:disabled:bg-transparent dark:aria-disabled:bg-transparent'
},
{
color: 'primary',
variant: 'link',
class: 'text-primary hover:text-primary/75 active:text-primary/75 disabled:text-primary aria-disabled:text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary'
},
{
color: 'neutral',
variant: 'solid',
class: 'text-inverted bg-inverted hover:bg-inverted/90 active:bg-inverted/90 disabled:bg-inverted aria-disabled:bg-inverted focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-inverted'
},
{
color: 'neutral',
variant: 'outline',
class: 'ring ring-inset ring-accented text-default bg-default hover:bg-elevated active:bg-elevated disabled:bg-default aria-disabled:bg-default focus:outline-none focus-visible:ring-2 focus-visible:ring-inverted'
},
{
color: 'neutral',
variant: 'soft',
class: 'text-default bg-elevated hover:bg-accented/75 active:bg-accented/75 focus:outline-none focus-visible:bg-accented/75 disabled:bg-elevated aria-disabled:bg-elevated'
},
{
color: 'neutral',
variant: 'subtle',
class: 'ring ring-inset ring-accented text-default bg-elevated hover:bg-accented/75 active:bg-accented/75 disabled:bg-elevated aria-disabled:bg-elevated focus:outline-none focus-visible:ring-2 focus-visible:ring-inverted'
},
{
color: 'neutral',
variant: 'ghost',
class: 'text-default hover:bg-elevated active:bg-elevated focus:outline-none focus-visible: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-muted hover:text-default active:text-default disabled:text-muted aria-disabled:text-muted focus:outline-none focus-visible:ring-inset focus-visible:ring-2 focus-visible:ring-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'
}
}
}
})
]
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import uiPro from '@nuxt/ui-pro/vite'
export default defineConfig({
plugins: [
vue(),
uiPro({
ui: {
button: {
slots: {
base: [
'rounded-md font-medium inline-flex items-center 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',
leadingAvatarSize: '',
trailingIcon: 'shrink-0'
},
variants: {
buttonGroup: {
horizontal: 'not-only:first:rounded-e-none not-only:last:rounded-s-none not-last:not-first:rounded-none focus-visible:z-[1]',
vertical: 'not-only:first:rounded-b-none not-only:last:rounded-t-none not-last:not-first:rounded-none focus-visible:z-[1]'
},
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',
leadingAvatarSize: '3xs',
trailingIcon: 'size-4'
},
sm: {
base: 'px-2.5 py-1.5 text-xs gap-1.5',
leadingIcon: 'size-4',
leadingAvatarSize: '3xs',
trailingIcon: 'size-4'
},
md: {
base: 'px-2.5 py-1.5 text-sm gap-1.5',
leadingIcon: 'size-5',
leadingAvatarSize: '2xs',
trailingIcon: 'size-5'
},
lg: {
base: 'px-3 py-2 text-sm gap-2',
leadingIcon: 'size-5',
leadingAvatarSize: '2xs',
trailingIcon: 'size-5'
},
xl: {
base: 'px-3 py-2 text-base gap-2',
leadingIcon: 'size-6',
leadingAvatarSize: 'xs',
trailingIcon: 'size-6'
}
},
block: {
true: {
base: 'w-full justify-center',
trailingIcon: 'ms-auto'
}
},
square: {
true: ''
},
leading: {
true: ''
},
trailing: {
true: ''
},
loading: {
true: ''
},
active: {
true: {
base: ''
},
false: {
base: ''
}
}
},
compoundVariants: [
{
color: 'primary',
variant: 'solid',
class: 'text-inverted bg-primary hover:bg-primary/75 active:bg-primary/75 disabled:bg-primary aria-disabled:bg-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary'
},
{
color: 'primary',
variant: 'outline',
class: 'ring ring-inset ring-primary/50 text-primary hover:bg-primary/10 active:bg-primary/10 disabled:bg-transparent aria-disabled:bg-transparent dark:disabled:bg-transparent dark:aria-disabled:bg-transparent focus:outline-none focus-visible:ring-2 focus-visible:ring-primary'
},
{
color: 'primary',
variant: 'soft',
class: 'text-primary bg-primary/10 hover:bg-primary/15 active:bg-primary/15 focus:outline-none focus-visible:bg-primary/15 disabled:bg-primary/10 aria-disabled:bg-primary/10'
},
{
color: 'primary',
variant: 'subtle',
class: 'text-primary ring ring-inset ring-primary/25 bg-primary/10 hover:bg-primary/15 active:bg-primary/15 disabled:bg-primary/10 aria-disabled:bg-primary/10 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary'
},
{
color: 'primary',
variant: 'ghost',
class: 'text-primary hover:bg-primary/10 active:bg-primary/10 focus:outline-none focus-visible:bg-primary/10 disabled:bg-transparent aria-disabled:bg-transparent dark:disabled:bg-transparent dark:aria-disabled:bg-transparent'
},
{
color: 'primary',
variant: 'link',
class: 'text-primary hover:text-primary/75 active:text-primary/75 disabled:text-primary aria-disabled:text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary'
},
{
color: 'neutral',
variant: 'solid',
class: 'text-inverted bg-inverted hover:bg-inverted/90 active:bg-inverted/90 disabled:bg-inverted aria-disabled:bg-inverted focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-inverted'
},
{
color: 'neutral',
variant: 'outline',
class: 'ring ring-inset ring-accented text-default bg-default hover:bg-elevated active:bg-elevated disabled:bg-default aria-disabled:bg-default focus:outline-none focus-visible:ring-2 focus-visible:ring-inverted'
},
{
color: 'neutral',
variant: 'soft',
class: 'text-default bg-elevated hover:bg-accented/75 active:bg-accented/75 focus:outline-none focus-visible:bg-accented/75 disabled:bg-elevated aria-disabled:bg-elevated'
},
{
color: 'neutral',
variant: 'subtle',
class: 'ring ring-inset ring-accented text-default bg-elevated hover:bg-accented/75 active:bg-accented/75 disabled:bg-elevated aria-disabled:bg-elevated focus:outline-none focus-visible:ring-2 focus-visible:ring-inverted'
},
{
color: 'neutral',
variant: 'ghost',
class: 'text-default hover:bg-elevated active:bg-elevated focus:outline-none focus-visible: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-muted hover:text-default active:text-default disabled:text-muted aria-disabled:text-muted focus:outline-none focus-visible:ring-inset focus-visible:ring-2 focus-visible:ring-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'
}
}
}
})
]
})