01按钮
sm 32 · default 40 · lg 48 · icon 40- 每屏只有一个主按钮。次要操作用 outline 或 secondary;危险操作用 destructive 并须二次确认。
- 文字以动词开头,不超过 3 个词或 6 个汉字;仅图标按钮须加 aria-label。
- 禁用为 40% 不透明度;不得以隐藏按钮表示不可用。
// components/ui/button.tsx
const buttonVariants = cva(
[
"relative isolate inline-flex shrink-0 items-center justify-center gap-2 overflow-hidden border border-transparent font-medium whitespace-nowrap select-none",
"transition-[translate,background-color,border-color,color,text-decoration-color] duration-(--duration-fast) ease-standard",
"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
"disabled:pointer-events-none disabled:opacity-40",
],
{
variants: {
variant: {
default: [
"bg-primary text-primary-foreground hover:bg-blue-600 active:bg-blue-700 hover:-translate-y-px active:translate-y-0 motion-reduce:hover:translate-y-0",
"before:absolute before:inset-y-0 before:left-0 before:-z-10 before:w-1/3 before:-translate-x-[150%] before:-skew-x-12 before:bg-white/20",
"hover:before:translate-x-[320%] hover:before:transition-transform hover:before:duration-(--duration-scene) hover:before:ease-emphasized motion-reduce:before:hidden",
],
secondary: "bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_8%)] hover:-translate-y-px active:translate-y-0 motion-reduce:hover:translate-y-0",
outline: "border-strong bg-background text-foreground hover:border-foreground hover:-translate-y-px active:translate-y-0 motion-reduce:hover:translate-y-0",
ghost: "text-foreground hover:bg-surface active:bg-surface-2",
link: "text-link underline decoration-transparent decoration-1 underline-offset-4 hover:decoration-current",
destructive: "bg-destructive text-destructive-foreground hover:bg-[color-mix(in_oklab,var(--destructive),var(--foreground)_14%)] hover:-translate-y-px active:translate-y-0 motion-reduce:hover:translate-y-0",
},
size: {
sm: "h-8 px-3 text-[13px] [&_svg]:size-3.5",
default: "h-10 px-4 text-sm [&_svg]:size-4",
lg: "h-12 px-5 text-[15px] [&_svg]:size-4.5",
icon: "size-10 [&_svg]:size-4.5",
},
},
compoundVariants: [{ variant: "link", class: "h-auto px-0" }],
defaultVariants: { variant: "default", size: "default" },
},
)
<Button>Deploy</Button>
<Button variant="outline" size="sm"><Icon name="download" />Download</Button>