组件与令牌
结构化令牌与组件映射以 Kototoro Design System Frontmatter 为唯一规范入口。 本文提供面向设计和工程审查的可读说明;数值调整必须先修改 DESIGN.md,再同步本文中的展示表格。
1. 共享令牌
业务页面只使用语义令牌,不直接持有某种风格的材质实现。
间距
| 令牌 | 值 | 用途 |
|---|---|---|
space-xs | 4 dp | 图标内部、极紧密关联 |
space-sm | 8 dp | 同组元素 |
space-md | 12 dp | 紧凑容器内边距 |
space-lg | 16 dp | 页面常规间距 |
space-xl | 24 dp | 分组分隔 |
space-2xl | 32 dp | 大区块分隔 |
尺寸
- 最小触摸目标:48 × 48 dp。
- 紧凑图标可见尺寸:20–24 dp,使用透明命中区域补足触摸目标。
- 正文页面水平边距:窄屏通常 16–24 dp,由内容类型决定。
- 浮动工具组必须有最大宽度,不能以
fillMaxWidth作为默认策略。
这些是设计基线,不要求所有可见容器达到 48 dp 高。
主界面顶栏
主界面顶栏的布局骨架属于共享信息架构,不随视觉风格改变。状态栏高度由系统 Insets 提供,以下尺寸均不含状态栏:
| 项目 | 共享值 | Material 3 Expressive | iOS Glass |
|---|---|---|---|
| 顶栏内容区高度 | 64 dp | 相同 | 相同 |
| 水平边距 | 16 dp | 相同 | 相同 |
| 控件布局槽/命中区 | 48 × 48 dp | 相同 | 相同 |
| 可见控件 | — | 48 × 48 dp 语义 Surface | 居中的 44 × 44 dp Glass |
| 图标 | 22–24 dp | 通常 24 dp | 通常 22 dp |
| 控件间距 | 8 dp | 相同 | 相同 |
- 不采用当前 40 dp Material 行高,也不采用由
44 dp + 上下各 15 dp形成的 74 dp iOS 行高。 - 64 dp 是内容区和导航控制之间的折中:允许 28/36 sp 的主标题,同时保持内容优先和紧凑浏览。
- 可见轮廓可以小于命中区;禁止通过缩小命中区获得紧凑感。
- 一级目的地主标题使用单行大标题;标题过长时优先省略,不能自动降级成两行小字造成顶栏跳高。
- 顶栏包含内联标签/筛选轨道时,主行仍为 64 dp;附加轨道单独测量,并在展开时让标题或低优先级操作让位。
- 设置、搜索结果、管理页等二级页面使用 56 dp 小顶栏,不套用一级目的地的大标题。
排版基础
Kototoro 使用一套语义排版系统,两种风格共享字号和行高,只允许字体族、字重和材质表达存在有限差异。
字体族
- 默认使用 Android 系统
sans-serif,确保离线可用、中文覆盖完整,并遵循系统字形渲染。 - Material 3 Expressive 推荐
Roboto Flex或系统字体;iOS Glass 在 Android 上仍使用系统字体,不捆绑或仿冒 SF Pro。 - 用户选择的应用字体可以替换整个 UI 字体族,但不能改变字号、行高、语义角色和字重上限。
- 数字、进度和时间沿用同一字体族;只有确有对齐需求时使用等宽数字特性,不另设装饰字体。
语义字号
| 语义角色 | Compose 基础角色 | 字号/行高 | 默认字重 | 典型用途 |
|---|---|---|---|---|
| 一级目的地主标题 | headlineMedium | 28/36 sp | SemiBold | 主页、收藏、浏览等主界面顶栏 |
| Hero 标题 | headlineLarge | 32/40 sp | SemiBold | 详情页 Hero、空状态唯一焦点;不用于普通列表 |
| 页面/面板标题 | titleLarge | 22/28 sp | SemiBold | 二级页顶栏、Sheet、Dialog |
| 区块标题 | titleMedium | 16/24 sp | SemiBold | 内容分组、设置分组、对话面板小节 |
| 条目主标题 | bodyLarge | 16/24 sp | Medium | 列表、菜单中需要强调的名称 |
| 正文 | bodyLarge | 16/24 sp | Regular | 说明、对话正文、表单内容 |
| 条目说明 | bodyMedium | 14/20 sp | Regular | 副标题、摘要、辅助说明 |
| 紧凑标签 | labelLarge | 14/20 sp | Medium | 按钮、普通菜单项、紧凑工具 |
| 次级标签 | labelMedium | 12/16 sp | Medium | Chip、Tab、元数据、状态 |
| 微型标签 | labelSmall | 11/16 sp | Medium | Badge、极短辅助标记;不得承载必要说明 |
SemiBold 是常规层级上限。Bold 只用于 iOS Glass 的一级目的地主标题、极少数关键数值或需要额外对比保护的媒体叠加标题,禁止把整页标题和控件全部设为 Bold。
两种风格的字重差异
| 语义 | Material 3 Expressive | iOS Glass |
|---|---|---|
| 一级目的地主标题 | 28/36 sp, SemiBold | 28/36 sp, Bold |
| Hero 标题 | 32/40 sp, SemiBold | 32/40 sp, Bold |
| 页面/面板标题 | 22/28 sp, SemiBold | 22/28 sp, SemiBold |
| 正文与说明 | Regular | Regular |
| 标签与操作 | Medium;选中可 SemiBold | Medium;选中可 SemiBold |
差异只强化风格气质,不改变信息层级。业务组件不得通过 if (isIosStyle) 自行指定字号。
对比度
- 主标题、条目主标题、正文和关键操作使用
onSurface或对应容器的on*Container。 - 副标题和说明使用
onSurfaceVariant,保持完整语义色;禁止再叠加任意低透明度制造“柔和”。 - 时间、来源等低优先级元数据可用
onSurfaceVariant,但字号不得小于 12 sp。 - 禁用态才使用组件规范的透明度;不可用状态还需通过控件状态或语义说明表达。
- 大标题与小说明的层级同时依靠字号、字重、间距和语义色,不能只靠把说明变灰。
组件排版映射
| 组件 | 标题/主文本 | 说明/正文 | 操作/状态 |
|---|---|---|---|
| 一级主界面顶栏 | 28/36 SemiBold;iOS 可 Bold | 不放副标题 | 图标操作,无可见标签 |
| 二级页顶栏 | 22/28 SemiBold | 不放副标题 | 图标或 14/20 Medium |
| 普通列表/设置项 | 16/24 Medium | 14/20 Regular | 12/16 Medium |
| 内容卡片 | 16/24 SemiBold,最多两行 | 14/20 Regular,最多两行 | 12/16 Medium |
| 详情页简介 | 14/20 SemiBold | 14/20 Regular | — |
| Popup Menu | 14/20 Medium | 原则上不放说明 | 快捷键/状态 12/16 Medium |
| Sheet/对话式面板 | 22/28 SemiBold | 14/20 Regular | 按钮 14/20 SemiBold |
| Alert Dialog | 22/28 SemiBold | 14/20 Regular | 按钮 14/20 SemiBold |
| 表单字段 | 输入 16/24 Regular | 支持/错误 12/16 Regular | 标签 12/16 Medium |
| Button | — | — | 14/20 SemiBold |
| Chip/Tab/Segment | — | — | 12/16 Medium;选中 SemiBold |
| Snackbar | — | 14/20 Medium | 14/20 SemiBold |
| Tooltip | — | 12/16 Medium | — |
- Popup Menu 是快速命令列表,不使用大标题、粗体正文或卡片式子容器;分组依靠顺序、间距和 Divider。
- Sheet/对话式面板承载一个短任务。顶部只有一个标题;需要解释时在标题下使用正文,不重复入口名称。
- Dialog 只在必须打断当前任务时使用。长表单、连续设置或可实时预览的任务改用 Sheet/对话式面板。
- 控件内部不允许通过
Text(..., fontWeight = ...)随意覆盖主题;例外必须对应上表中的选中、危险或关键状态。
Expressive 容器与紧凑布局
- 容器用于表达一个任务组、选中状态、可交互范围或与背景的层级,不用于包装每一行文字。
- 同一容器内使用 12–16 dp 内边距;标题与说明间距 2–4 dp,同组条目间距 8–12 dp,分组之间 20–24 dp。
- 大标题负责建立页面身份;进入列表后,主标题回到 16/24 sp,避免每张卡片都竞争页面焦点。
- 紧凑指减少无意义的可见空白和嵌套容器,不减少 48 dp 触摸目标,也不压缩正文行高。
- 优先使用一个外层容器加平面条目;避免“页面 Surface → 卡片 → 行容器 → 胶囊按钮”的连续套层。
2. 组件解剖
每个共享组件必须分离:
- 语义:动作、状态、可访问名称;
- 布局:内容、间距、命中区域;
- 视觉:颜色、形状、材质;
- 行为:点击、拖动、展开、动效;
- 风格适配:Material 或 iOS Glass 的渲染策略。
业务页面提供前两项所需数据,不直接拼装长串 Glass 或 Material Modifier。
3. 关键组件
ContinueAction
- 语义:恢复最近的阅读或播放位置。
- 可选内容:封面缩略图、作品名、章节/剧集、进度。
- 主界面可渲染为 FAB;卡片内渲染为右下角紧凑按钮。
- 没有可恢复内容时不显示。
SpaceSidekick
- 可见轮廓窄,命中区域完整。
- 支持点击和向左滑动,两个入口触发相同状态机。
- 展开、切换、关闭不改变系统返回语义。
- Material 使用语义 Surface;iOS 入口可使用 Glass,面板主体仍优先稳定 Surface。
ReaderControls
- 内容自适应宽度,进度与高频按钮共享紧凑层级。
- 动画初始值必须等于最终布局约束,避免首帧横向铺满。
- 隐藏时从语义树和命中测试中正确退出。
SpaceCard
- 背景:最近继续作品封面;无作品时使用主题占位。
- 前景:对比保护层、Space 图标、名称、进度与继续动作。
- 名称固定在左侧图标下方,继续按钮固定在右下角。
- 卡片整体进入 Space;继续按钮直接恢复内容,两者命中区域不得重叠。
SettingsGroup
- 使用标题、说明和控件建立清晰层级。
- Space 设置只保留功能开关、Sidekick 位置和既有 Space 管理入口。
- 不提供重复或能从上下文自动推导的外观选项。
4. 状态模型
共享组件至少考虑:
- default;
- pressed/focused;
- selected;
- disabled;
- loading;
- error;
- empty。
动画是状态之间的表达,不是额外状态。两种视觉风格必须覆盖同一状态集合。
5. 命名与文案
- 标签优先使用任务词:“继续”“进度”“翻译”,避免“功能”“模式”“AI”等冗余前缀。
- 同一动作在主界面、详情、Space 和阅读器保持同一动词。
- 类型名称使用“漫画”“小说”“动画”,不追加
Space后缀。 - 图标不能单独承载用户难以推断的业务概念,必要时提供短标签或无障碍说明。