2.1 KiB
2.1 KiB
组件与样式
组件形状
React 模块使用具名函数组件,不使用无意义的 default export。features/system/pages/system-status-page.tsx 展示了页面组件如何组合 query、store 和 shared UI;shared/ui/card.tsx 展示了通过原生 HTML 属性扩展 primitive 的方式。
export function Button({
className,
size,
type = "button",
variant,
...props
}: ButtonHTMLAttributes<HTMLButtonElement> &
VariantProps<typeof buttonVariants>) {
return (
<button
className={cn(buttonVariants({ size, variant }), className)}
type={type}
{...props}
/>
)
}
可复用组件应保留原生属性和 className,通过 ...props 支持组合;只在确实需要时添加受限的 variant。
样式与组合
- 使用 Tailwind utility class;主题 token 和全局基础规则放在
src/styles/globals.css。 - 使用
cn(shared/ui/utils.ts)合并可选 class,使用class-variance-authority管理 Button、Badge 等有限变体。 - 复杂页面用
Card、CardHeader、CardContent等 composition primitive,而不是复制一套容器样式。 - 新建 shared primitive 前先搜索是否已有
Button、Badge、Card或cn。
页面状态
页面应把加载、错误、成功状态转成用户可见的语义文本。SystemStatusPage 根据 query 状态显示“正在连接”“连接异常”“运行正常”,没有数据时使用安全的默认服务名。
可访问性
- 交互元素必须使用真实的
<button>或其他语义元素;Button默认type="button"以避免意外提交。 - 只有图形含义的 icon 使用
aria-hidden="true";没有文字的主题切换按钮提供aria-label="切换主题",参照system-status-page.tsx。 - 使用
main、标题、段落等语义结构,文本状态不能只靠颜色表达。
避免
- 不要在 shared UI 中请求数据、读取 feature hook 或写业务分支。
- 不要用
dangerouslySetInnerHTML、无理由的any或无语义的<div onClick>。 - 不要把所有页面样式搬进新的全局 CSS;优先使用现有 token 和局部 utility class。