共享规则见设计规范 · 共享核心,平台差异见
macOS / Windows。本页是逐控件正反例,新增控件时先在此登记再实现。
| 组件 | 基于 | 职责 |
|---|
Panel | 框架 tool/Panel.vue | 模块面板(外框 + 头部条 + 正文) |
SettingsSection / SettingsRow / SettingsField | @/components/settings | 分组 + 行 + 字段 |
EmptyState / LoadingState / ErrorState | @/components/native | 三态标准件(图标 20 + 文案 + 动作) |
FormRow | @/components/native | 标签 + 控件 + 行内校验 |
ListRow | @/components/native | 列表行:主文本 + 副文本 + 尾部控件 |
SearchField | @/components/native | 放大镜 + 清除按钮 + 输入即搜 |
Segmented | @/components/native | 2–7 项互斥分段控件,含 ←/→ 键盘语义 |
Toolbar / SidebarList / PopUp / ToggleRow / StatusBar / ProgressBar / AlertDialog 封装
为规划项,用到时按§2 约定实现并回填本表。
data-active: / data-inactive: 变体是死规则:reka 的 TabsTrigger 只输出
data-state="active|inactive"。改样式一律用 data-[state=active]:。
TabsList 横向高度被 group 变体钉死:group-data-[orientation=horizontal]/tabs:h-9,普通
h-* 覆盖不掉,需用内联样式覆盖。
- 禁用全局过渡压制:
transition-duration: 75ms !important 已移除,动效走 token;
reka popper 定位容器的 transition-duration: 0s 例外必须保留。
| Do | Don’t |
|---|
每屏一个主按钮(default),其余 secondary / ghost | 一屏多个 default 争抢注意力 |
ghost 只用于面板头部 / 工具栏动作 | ghost 作为主操作 |
高度取两档(h-8 常规 / h-7 紧凑),图标 size-3.5 + mr-1 | h-9 与其他尺寸混排(除页面级主操作) |
破坏性操作 destructive + Alert 确认 | 用红色表达「取消」或普通操作 |
文案用动词、与结果一致(导出 →「已导出」) | 确定 / 提交 / 执行 等泛化词 |
| Do | Don’t |
|---|
FormRow 提供标签 + 说明 + 行内校验 | 只有 placeholder 没有标签 |
| 固定高度 + 超出滚动 | 自动增高导致布局跳动 |
数字输入右对齐 + tabular-nums | 数字左对齐、字体非等宽 |
校验就地(控件下方 text-xs text-destructive) | 只在 toast 报错、或提交后才校验 |
| 等宽字体用于代码 / 路径 / 密钥 | 用等宽字体承载正文 |
| Do | Don’t |
|---|
| 2–5 项互斥 → 分段;≥6 项 → 下拉 | 用一排开关表达互斥选项 |
| 细粒度布尔 → 复选框(标题在右) | 细粒度布尔用开关 |
分组表单内的开关用 mini(size="sm") | 分组表单内用大开关导致行高不齐 |
开关必须与其标题同行同区(SettingRow) | justify-between 把标题与开关拉到两端 |
| 搜索框输入即搜 + 清除按钮 | 搜索框配「搜索」按钮 |
| 下拉宽度固定(控件列对齐) | 每个下拉宽度不同、左边缘参差 |
| Do | Don’t |
|---|
模块一律 Panel 包裹;头部条 + 正文 p-4 | 模块裸露在页面上 |
同一容器内子分组用 divide-y + 小标题 + 间距 | 卡片套卡片、盒子叠盒子 |
行:主文本 + 副文本(text-xs 灰)+ 尾部控件 | 行内塞三行以上说明 |
列表行可键盘聚焦(tabindex + role) | 行只能鼠标点击 |
| Do | Don’t |
|---|
| 浮层圆角 12(Windows 8)、统一阴影 + 1px 描边 | 各浮层圆角 / 阴影不一致 |
| Esc 关闭并把焦点还原到触发元素 | 关闭后焦点丢失 |
| 菜单项 ≥24px 行高、图标 16、危险项置末并分隔 | 菜单项过密、危险项与普通项相邻 |
| Tooltip 仅承载补充说明(图标按钮、截断文本) | 用 Tooltip 承载必读信息 |
| Toast 只用于系统级失败 / 长任务完成 | 用 toast 报告表单校验错误 |
| Do | Don’t |
|---|
divide-y 分隔行、表头粘性、数字列右对齐 | 每行画盒子边框、单元格居中数字 |
空数据用 EmptyState | 空白表格 |
| 滚动区用实色底(禁毛玻璃) | 表格上叠材质 |
| 超宽时横向滚动 + 首列粘性(如需) | 压缩列宽到文字换行 |
| Do | Don’t |
|---|
| 空态:图标(20)+ 主文案 + 说明 + 动作 | 只显示「暂无数据」 |
| <1s 不显示加载态;1–10s 骨架;>10s 进度 + 取消 | 一切操作都盖转圈遮罩 |
| 错误条:说明原因 + 下一步 + 重试 | 「出错了」「操作失败」等无信息文案 |
| Do | Don’t |
|---|
| 尺寸 14/16/20 三档,描边 2 | 每个页面自定义图标大小 |
图标按钮必有 aria-label + tooltip | 纯图标无提示 |
快捷键在菜单项 / 提示中可见(⌘K / Ctrl+K 按平台) | 隐藏快捷键、只在文档里写 |
Web 层可在普通浏览器里渲染(预览桥模拟 Tauri API),因此可脚本化截图自查:
node scripts/design-shot.mjs \
--url "/tool/hello-table" --out /tmp/a.png \
--theme dark --font 14 [--platform win] \
[--eval "document.querySelector('button').click()"] # 可先点击 / 输入再截图
- 预览桥
src/dev/preview-bridge.ts:仅 import.meta.env.DEV 且非 Tauri 环境生效;实现
__TAURI_INTERNALS__ 协议 + localStorage 版 plugin-store + 框架命令夹具。
- 插件自己的业务命令夹具放
plugins/<id>/frontend/preview.ts(默认导出
Record<命令名, 返回值>),dev 预览时自动并入;base 不含任何插件业务命令。
- URL 参数:
?theme=light|dark、?font=13|14|15、?accent=<name>、?platform=win。
- 用途:逐屏核对规范条款、验证浮层 / 焦点 / 三态;原生窗口壳与材质仍需真机确认。
base 只含 _template / hello-world / system 三个插件,均已按本规范整改完成。
fork 的个人插件按同一清单逐批整改,进度由各 fork 自行维护(框架层不需要知道 fork 的插件名)。
每批完成后:pnpm lint && pnpm build && pnpm test,并按共享核心 §7 评审清单逐条自检;
涉及 Rust 的批次额外跑 pnpm fmt:rs && pnpm lint:rs && pnpm test:rs。