feat(ui): 补齐分层设计 token 并迁移共享变体(对标 Claude DESIGN.md)
- 面色阶 surface-soft/card/strong + 文字 5 级 body-strong/body/muted-soft - 边框 line-soft、coral 状态 cinnabar-active/disabled(按压变深 + 奶油化禁用) - 圆角刻度 xs..xl/full:按钮 rounded-md、卡片 rounded-lg、徽章 pill - 排版档 display/title/caption/eyebrow/prose(衬线负字距) - 动效 token duration-fast/base + ease-standard,transitionUi 常量统一过渡 - 焦点环统一 cinnabar/35;双主题成对定义
This commit is contained in:
@@ -23,30 +23,31 @@ export function cn(...classes: Array<string | false | null | undefined>): string
|
||||
return classes.filter(Boolean).join(" ");
|
||||
}
|
||||
|
||||
// 统一焦点环(与 buttonBase 现有焦点环一致),供导航/输入等可聚焦元素复用。
|
||||
// 统一焦点环(供按钮/输入/导航等所有可聚焦元素复用,统一到 cinnabar/35)。
|
||||
export const focusRing =
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cinnabar/35";
|
||||
|
||||
// 手稿正文统一排版:衬线 18px、行高 1.9。
|
||||
export const proseBody = "font-serif text-[18px] leading-[1.9]";
|
||||
// 统一交互过渡(颜色变化 + 动效 token),供按钮/输入/导航复用,全局可调。
|
||||
export const transitionUi = "transition-colors duration-fast ease-standard";
|
||||
|
||||
// 手稿正文统一排版:衬线 18px(text-prose 档)、行高 1.9。
|
||||
export const proseBody = "font-serif text-prose";
|
||||
|
||||
// Drawer / CommandPalette 共用的全屏遮罩。
|
||||
export const overlayScrim = "fixed inset-0 z-40 bg-black/30";
|
||||
|
||||
const buttonBase =
|
||||
"inline-flex items-center justify-center gap-1.5 rounded border text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cinnabar/35 disabled:cursor-not-allowed disabled:opacity-45";
|
||||
const buttonBase = `inline-flex items-center justify-center gap-1.5 rounded-md border text-sm disabled:cursor-not-allowed ${transitionUi} ${focusRing}`;
|
||||
|
||||
// 非主按钮的禁用淡化(主按钮改用奶油化禁用底,见下)。
|
||||
const disabledFade = "disabled:opacity-45";
|
||||
|
||||
const buttonVariants: Record<ButtonVariant, string> = {
|
||||
primary:
|
||||
"border-cinnabar bg-cinnabar text-panel shadow-paper hover:bg-cinnabar/95",
|
||||
secondary:
|
||||
"border-line bg-panel text-ink hover:border-cinnabar hover:text-cinnabar",
|
||||
outline:
|
||||
"border-cinnabar bg-transparent text-cinnabar hover:bg-[var(--color-cinnabar-wash)]",
|
||||
ghost:
|
||||
"border-transparent bg-transparent text-ink-soft hover:bg-[var(--color-cinnabar-wash)] hover:text-cinnabar",
|
||||
danger:
|
||||
"border-conflict bg-transparent text-conflict hover:bg-conflict/10",
|
||||
"border-cinnabar bg-cinnabar text-panel shadow-paper hover:bg-cinnabar-active active:bg-cinnabar-active disabled:border-cinnabar-disabled disabled:bg-cinnabar-disabled disabled:text-muted-soft",
|
||||
secondary: `border-line bg-panel text-ink hover:border-cinnabar hover:text-cinnabar ${disabledFade}`,
|
||||
outline: `border-cinnabar bg-transparent text-cinnabar hover:bg-[var(--color-cinnabar-wash)] active:bg-[var(--color-cinnabar-wash)] ${disabledFade}`,
|
||||
ghost: `border-transparent bg-transparent text-ink-soft hover:bg-[var(--color-cinnabar-wash)] hover:text-cinnabar ${disabledFade}`,
|
||||
danger: `border-conflict bg-transparent text-conflict hover:bg-conflict/10 ${disabledFade}`,
|
||||
};
|
||||
|
||||
const buttonSizes: Record<ButtonSize, string> = {
|
||||
@@ -68,7 +69,7 @@ export function buttonClass({
|
||||
}
|
||||
|
||||
const badgeBase =
|
||||
"inline-flex items-center gap-1 rounded border px-2 py-0.5 text-xs leading-5";
|
||||
"inline-flex items-center gap-1 rounded-full border px-2.5 py-0.5 text-xs leading-5";
|
||||
|
||||
const badgeVariants: Record<BadgeVariant, string> = {
|
||||
neutral: "border-line bg-bg text-ink-soft",
|
||||
@@ -91,7 +92,7 @@ export function badgeClass({
|
||||
}
|
||||
|
||||
export function cardClass(className?: string): string {
|
||||
return cn("rounded border border-line bg-panel shadow-paper", className);
|
||||
return cn("rounded-lg border border-line bg-panel shadow-paper", className);
|
||||
}
|
||||
|
||||
const fieldTextBase = "block text-sm font-medium text-ink";
|
||||
@@ -108,8 +109,7 @@ export function fieldErrorClass(className?: string): string {
|
||||
return cn("mt-1 text-xs leading-5 text-conflict", className);
|
||||
}
|
||||
|
||||
const inputBase =
|
||||
"w-full rounded border bg-bg text-ink transition-colors placeholder:text-ink-soft/65 focus:outline-none focus-visible:ring-2 focus-visible:ring-cinnabar/30 disabled:cursor-not-allowed disabled:bg-line/20 disabled:text-ink-soft";
|
||||
const inputBase = `w-full rounded-md border bg-bg text-ink placeholder:text-ink-soft/80 disabled:cursor-not-allowed disabled:bg-line/20 disabled:text-ink-soft ${transitionUi} ${focusRing}`;
|
||||
|
||||
const inputStates: Record<InputState, string> = {
|
||||
default: "border-line focus:border-cinnabar",
|
||||
|
||||
Reference in New Issue
Block a user