4.1 KiB
4.1 KiB
name: stash-ui description: Use, extend, or restyle the Stash UI component library (@stash/ui): a zero-dependency React design system with tokens, 37 components, an in-repo docs site and a full-page demo. Load before writing or changing any component, or before composing pages with @stash/ui.
Stash UI
这是一套独立的设计系统(React + CSS Modules + 设计令牌),零运行时依赖。 文档是唯一事实来源,这个 skill 只做「入口 + 硬约束 + 验证流程」,不要把它当成文档的副本。
先读哪几份
按任务选读,不必全读:
| 文档 | 什么时候读 |
|---|---|
DESIGN.md |
任何改动前:分层、令牌、状态矩阵、代码约定、验收清单 |
docs/COMPONENTS.md |
想用组件 / 判断有没有 / 看契约 / 看候选清单 |
docs/ADDING-A-COMPONENT.md |
要新增组件时,照 12 步走 |
docs/ALRIGHT-DECOMPOSITION.md |
怀疑某个数值(字号、阴影、间距)对不对时 |
site/demo.html 的源码 |
想看真实页面怎么把组件拼起来 |
三种任务
A. 用组件拼页面
- 先查
COMPONENTS.md §2「用哪个」决策表;能用现有组件组合就不要新增组件。 - 颜色 / 间距 / 字号 / 圆角只用
--su-*令牌;页面自己的布局样式写页面级 CSS Module。 - 深色主题靠
<html data-scheme="dark|auto">,页面和组件都不用改。 - 常见组合(分区卡片、行式条目、工具条、海报卡)见
COMPONENTS.md §4。 - 页面外壳用
Layout(header / sider / children / footer),不要自己写一套 div 骨架。
B. 改组件
- 先看现有契约(
COMPONENTS.md §3)。改 props = 改契约,必须同步三处: 组件代码、展示页 section、COMPONENTS.md+ README 组件表。 - 只用语义令牌(
bg-card/bg-subtle/bg-hover/text-*/border-*); 不要直接用--su-gray-*——灰阶在深色下是反相的。 - 状态要对齐
DESIGN.md §4.3:默认 / hover / active / disabled / loading / focus-visible / 空 / 错误。 - 改完跑下面的验证命令,并截图核对(含深色)。
C. 加组件
严格按 docs/ADDING-A-COMPONENT.md:
登记(COMPONENTS §1 + §3 草稿) → 定层级/API → Xxx.tsx → Xxx.module.css
→ src/index.ts 导出 → site/sections 展示页 → site/App.tsx 导航
→ README 清单 → 契约定稿 → 验收清单 → 截图 → 提交
命令
npm run dev # 文档站 5199;整页示例 /demo.html(?scheme=dark)
npm run typecheck # tsc --noEmit
npm run lint # oxlint(要求 0 warnings)
npm run build # 库产物 dist/stash-ui.js + .css + types
npm run build:site # 静态站点 dist-site(index.html + demo.html)
# 视觉核对:需要本机 Chrome / Edge
node scripts/screenshot.mjs http://127.0.0.1:5199/#buttons shots/buttons.png
node scripts/screenshot.mjs http://127.0.0.1:5199/demo.html shots/demo.png full
硬约束(违反就不合并)
- 组件 CSS 里禁止 hex / rgba / 字号 / 间距字面量;允许的只有
0、1px边框、100%、 以及组件内声明的--xxx-size尺寸变量。 className/style落在外层元素;组件不带 margin,间距交给Space。- 只有图标的控件必须传
label;错误提示role="alert";focus-visible不得移除。 - 不新增运行时依赖(只 peer 依赖 react / react-dom)。
- 展示页的 demo 必须直接用真实组件,不写「演示专用版本」。
- 组件不认识业务:不请求接口、不 import 业务类型、props 里不出现
categoryId这类字段。
已知坑
- 比例封面不要放进
flex-direction: column的父容器(行高会被压扁),用 grid / block。 - 展示站
site/main.tsx必须显式 importtokens.css和iconfont.css,否则生产构建会摇掉图标。 <dialog>的居中被宿主* { margin: 0 }覆盖过,Modal / Drawer 里已显式写回margin。- 图标名来自全量 iconfont(446 个,
src/theme/icons.ts),新增字形要走COMPONENTS.md §7的流程。