58 lines
1.9 KiB
TypeScript
58 lines
1.9 KiB
TypeScript
import { cva, type VariantProps } from "class-variance-authority";
|
||
import { cn } from "@/lib/utils";
|
||
|
||
/**
|
||
* 按钮样式变体。
|
||
*
|
||
* 对应 DESIGN.md 的组件定义:
|
||
* - primary → button-primary(黑底胶囊,主 CTA)
|
||
* - secondary → button-secondary(描边胶囊)
|
||
* - accent → button-accent-green(品牌薄荷绿,谨慎使用)
|
||
* - ghost → button-ghost(无背景矩形)
|
||
* - link → button-link(内联文字链接)
|
||
*
|
||
* 规范要求:所有按钮一律 `{rounded.full}` 胶囊形,不软化圆角。
|
||
*/
|
||
export const buttonVariants = cva(
|
||
"inline-flex items-center justify-center gap-xs font-medium whitespace-nowrap rounded-full transition-colors duration-150 ease-out disabled:pointer-events-none disabled:bg-hairline disabled:text-muted",
|
||
{
|
||
variants: {
|
||
variant: {
|
||
primary: "bg-primary text-on-primary active:bg-charcoal",
|
||
secondary:
|
||
"bg-transparent text-ink border border-hairline active:bg-surface",
|
||
accent: "bg-brand-green text-primary active:bg-brand-green-deep",
|
||
onDark: "bg-on-dark text-primary active:bg-on-dark-muted",
|
||
ghost: "rounded-md bg-transparent text-ink active:bg-surface",
|
||
link: "rounded-none bg-transparent text-ink underline-offset-4 active:underline p-0 h-auto",
|
||
},
|
||
size: {
|
||
sm: "h-9 px-md text-body-sm",
|
||
// DESIGN.md: padding 10px 20px,字号 14px / 行高 1.3
|
||
md: "h-10 px-lg text-button-md",
|
||
// 移动端触控目标 ≥ 44px
|
||
lg: "h-11 px-xl text-body-md",
|
||
},
|
||
},
|
||
defaultVariants: {
|
||
variant: "primary",
|
||
size: "md",
|
||
},
|
||
},
|
||
);
|
||
|
||
export type ButtonVariantProps = VariantProps<typeof buttonVariants>;
|
||
|
||
export interface ButtonStyleOptions extends ButtonVariantProps {
|
||
className?: string;
|
||
}
|
||
|
||
/** 生成按钮 className,供 <button> 与 <Link> 复用同一套样式 */
|
||
export function buttonClassName({
|
||
className,
|
||
variant,
|
||
size,
|
||
}: ButtonStyleOptions = {}): string {
|
||
return cn(buttonVariants({ variant, size }), className);
|
||
}
|