Button
Thu Sep 11 2025
Buttons
Install - Shadcn UI
我们默认使用 shadcn 作为我们的基础组件库,并且根据 shadcn 组件库的组件增改我们的样式。
另外,我们会使用的是 shadcn ui button 组件的副本,所以可能与您的版本有所不同,可以关注我们是“如何在原有基础上修改”的。
Default Button
更改 shadcn ui 的默认 button。
大小
颜色
Primary color
Secondary color
Code
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const defaultButtonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
{
variants: {
variant: {
default:
"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
destructive:
"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
outline:
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
secondary:
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
ghost:
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
link: "text-primary underline-offset-4 hover:underline",
// Primary 颜色变体
"primary-blue":
"bg-blue-600 text-white shadow-xs hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600",
"primary-green":
"bg-green-600 text-white shadow-xs hover:bg-green-700 dark:bg-green-500 dark:hover:bg-green-600",
"primary-purple":
"bg-purple-600 text-white shadow-xs hover:bg-purple-700 dark:bg-purple-500 dark:hover:bg-purple-600",
"primary-red":
"bg-red-600 text-white shadow-xs hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600",
// Secondary 颜色变体 - 与 secondary 变体相似的设计哲学(颜色深度上调一阶)
"secondary-blue":
"bg-blue-100 text-blue-900 shadow-xs hover:bg-blue-200 dark:bg-blue-900 dark:text-blue-100 dark:hover:bg-blue-800",
"secondary-green":
"bg-green-100 text-green-900 shadow-xs hover:bg-green-200 dark:bg-green-900 dark:text-green-100 dark:hover:bg-green-800",
"secondary-purple":
"bg-purple-100 text-purple-900 shadow-xs hover:bg-purple-200 dark:bg-purple-900 dark:text-purple-100 dark:hover:bg-purple-800",
"secondary-red":
"bg-red-100 text-red-900 shadow-xs hover:bg-red-200 dark:bg-red-900 dark:text-red-100 dark:hover:bg-red-800",
},
size: {
default: "h-9 px-4 py-2 has-[>svg]:px-3",
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
icon: "size-9",
// customize size
huge: "h-12 rounded-md has-[>svg]:px-6 px-8 text-lg",
badge: "h-8 text-sm px-4 gap-1 rounded-full",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
},
);
function DefaultButton({
className,
variant,
size,
asChild = false,
...props
}: React.ComponentProps<"button"> &
VariantProps<typeof defaultButtonVariants> & {
asChild?: boolean;
}) {
const Comp = asChild ? Slot : "button";
return (
<Comp
data-slot="button"
className={cn(defaultButtonVariants({ variant, size, className }))}
{...props}
/>
);
}
export { DefaultButton, defaultButtonVariants };