Regression / regression (push) Canceled after 0s
## 品牌标识(本次会话) 起因:品牌此前没有任何图形标识 —— 唯一 favicon 是内联 data-URI 里的字母「A」, 那是 v2.0.0「Aurora Admin → Kole UI」改名漏掉的一处(PC 顶栏也是「A」, 移动端站已是「K」;移动端文档站则完全没有 favicon)。 - 几何:24 网格三个互不接触的笔画(竖 + 两斜),圆头描边; 描边 2.25 → 16px 标签页尺寸下正好 1.5px = 规范原文「描边1.5px」 - 取色分两套(刻意):favicon 硬编码品牌蓝/白(渲染在浏览器标签栏,不继承 kole-dark); 顶栏标记走 currentColor(实测暗色下自动转 rgb(20,22,28)) - 新增 theme-color 双条(light #FFFFFF / dark #1C1F26,取 --kole-color-card-bg) - 修 site/app.js hero 标语 KOLE ADMIN → KOLE UI(改名变形残留) - 移动端 7 个模板补 favicon(此前计数 0) 验收:门禁 9 条全 OK(site-routing/site-routes/mobile-docs/mobile-site/isolation/ theme/nav/i18n/icons);PC 回归 1464/1464 · 移动端 807/807,各连跑 8 次一致; 两端 favicon 405 字节逐字节一致;PC 站控制台错误 1→0。 ## 并行会话成果(本次一并入库) - 图标系统:2576 图标(TDesign/Element Plus,MIT)+ 11 端注入 + 5 个构建门禁工具 + IconPreview 预览页 + ICON-SPEC.md 冻结规格 - 移动端平台:47 组件 × 6 端 + 文档站 53 页 + 隔离门禁 - PC 组件:103 个大后台组件 / 组件11 批次 - uni-app:PC 端试点 + 移动端端实现 + 真实编译验证 ## 工程 - .gitignore 补 .scratch/ 与 .zcode-preexisting-*.txt(会话中间产物,实测 9.1MB,不入库) - CHANGELOG 补品牌标识条目 - ROADMAP 登 S8-P4(品牌标识任务包 + og:image/apple-touch-icon 未做部分)
8.1 KiB
8.1 KiB
图标系统冻结规格(IconSpec v1)
本文件是图标相关任务的唯一真源。改图标行为先改这里,再改实现。 冻结日期:2026-09-20 | 依据:三库实测(见 §一)+ 本仓库既有规范原文。
一 · 参考基准(实测,非推测)
用户指定参考 TDesign 与 Element 组件库。以下是 2026-09-20 对三个上游的实测数据:
| 上游 | 版本 | 许可 | 图标数 | 形态 | 网格 |
|---|---|---|---|---|---|
| TDesign Icons(线性) | tdesign-icons-svg@0.4.7 |
MIT | 1334 | stroke="currentColor" 描边 |
24×24(少数 24×25 / 25×24) |
| TDesign Icons(面性) | 同上 | MIT | 1020 | fill="currentColor" 填充 |
同上 |
| Element Plus Icons | @element-plus/icons-svg@2.3.2 |
MIT | 293 | fill="currentColor" 填充 |
1024×1024 |
| Element UI Icons | element-ui@2.15.14 |
MIT | 283 名 | 图标字体(无独立 SVG) | — |
- 名称并集:1511 个不同名(归一化后);在 ≥2 个库里都出现的:217 个。
- 进入本仓库:2576 个图标(TDesign 线性 1334 + 面性 1020 + Element Plus 293)。 Element UI 的 283 个字体图标名不单独引入字形(它是字体不是 SVG), 而是通过别名层映射到上述三类里语义相同的图标(见 §三)。
上游参考组件的图标相关功能(用户点名)
| 组件 | 上游的图标能力 | 本仓库如何覆盖 |
|---|---|---|
TDesign TabBar / TabBarItem |
icon(函数或插槽)、badgeProps(图标右上角角标)、subTabBar(二级菜单) |
图标组件提供 name + 角标由 Badge 承担(既有设计);subTabBar 不在图标职责内 |
Element UI PageHeader |
返回箭头(内置 el-icon-back)、标题 / 副标题、右侧 extra 插槽 |
图标组件提供 back / chevron-left / arrow-left 三个语义名,PageHeader 既有实现继续用 |
TDesign Icon |
size 支持关键字(xs/small/medium/large/xl)与任意 CSS 值(写成内联 font-size)、onClick、class/style 透传 |
本规格 §四:size 同名关键字 + 任意 CSS 值;onClick 由端上事件绑定承担 |
二 · 归一化(我们做了哪些修正,不是照抄)
| # | 上游问题 | 我们的处理 | 谁卡这条 |
|---|---|---|---|
| 1 | TDesign 全部 2356 个 SVG 把 viewBox 写成 view-box(无效属性,浏览器忽略 → 图标按默认视口缩放) |
构建期两种拼写都读,产物统一写回 viewBox |
tools/verify-icons.mjs |
| 2 | TDesign 描边宽度 stroke-width="2"(24 网格) |
归一为 1.5,依据 组件1.txt「图标规范:线性图标,描边1.5px」 |
同上 |
| 3 | fill="transparent" 命中区路径 |
丢弃(那是热区不是视觉内容) | 同上 |
| 4 | 路径数字精度不一(最多 6 位小数) | 归一到 2 位小数 + 折叠空白(实测省 25% 体积) | 同上 |
| 5 | 两库同名不同形 | 优先级 tdesign-outline > element-plus > tdesign-filled |
同上 |
为什么优先级是线性优先:本仓库规范明示「线性图标」,且 PC 既有实现(Button.html 的内联 SVG)与移动端 TabBar 都是描边风格。面性图标保留 -filled 后缀供需要时选用。
三 · 命名与别名
3.1 主名(canonical name)
- 一律 kebab-case,
[a-z0-9-]。 - 面性图标保留
-filled后缀(与上游一致,不发明第二套词)。 - 例:
search/star/star-filled/chevron-right/logo-github。
3.2 别名层(alias)
用途:让 Element UI 的 283 个历史图标名、以及常见同义词都能落到某个真实图标上。
别名表 aliases.json 是显式列出的映射,不做启发式猜测。
- 断言:每个别名必须指向一个真实存在的 canonical name(
verify-icons.mjs卡)。 - 别名不产生新图标,只改查找路径。
四 · 组件 API(PC 与移动端共用同一套语义)
4.1 props
| 名 | 类型 | 默认 | PC | 移动端 | 说明 |
|---|---|---|---|---|---|
name |
string | '' |
✅ | ✅ | 图标名;空则渲染 default 插槽 |
size |
string | number | 'default'(PC)/ 'default'(移动端) |
✅ | ✅ | 关键字或任意 CSS 长度(见 4.2) |
tone |
string | 'default' |
✅ | ✅ | default / brand / secondary / danger / success / warning |
spin |
boolean | false |
✅ | ✅ | 持续旋转,仅表示「进行中」 |
label |
string | '' |
✅ | ✅ | 无障碍名称;有值 → role="img",无值 → aria-hidden |
color |
string | '' |
✅ | — | 任意 CSS 颜色,优先于 tone(PC 历史字段,保留兼容) |
icon |
string | '★' |
✅ | — | PC 历史字段:直接给字形字符而非图标名(保留兼容,见 §六) |
4.2 size 取值(覆盖 TDesign 的关键字 + 任意值双模式)
| 关键字 | 边长 | 出处 |
|---|---|---|
small |
16px | PC 规范 16/20/24;移动端四档 |
default |
20px | 同上 |
large |
24px | 同上 |
xlarge |
32px | 仅移动端(空状态大图标) |
| 其他字符串 | 原样作为 CSS 长度 | 对齐 TDesign「任意值写内联 fontSize」 |
PC 端另有 --kole-icon-size-* 令牌层;移动端 --kole-m-icon-size 可被业务覆盖。
4.3 无障碍(硬要求)
label有值 →role="img"+aria-label。label为空 →aria-hidden="true",装饰性图标不进读屏序列。- 图标不得作为唯一信息载体:颜色变化必须伴随文字或
label。 - 语义色图标与背景对比度 ≥ 3:1(WCAG 1.4.11 非文本对比)。
spin=true在prefers-reduced-motion: reduce下停止旋转。
五 · 分层与加载策略(按实测体积决定,不是拍脑袋)
| 层 | 数量 | 加载方式 | 实测体积 |
|---|---|---|---|
core |
151 | 内联进组件包(core.js) |
35KB |
standard |
1993 | 按需 loadAll() |
— |
extended |
432 | 按需 loadAll() |
— |
全量 registry.json |
2576 | 按需 | 670KB |
为什么不全内联:实测全量 670KB —— 内联等于给每一页都加 670KB,
直接破坏 ROADMAP 的 data.js 150KB 预算精神。core 层 151 个 35KB 是可接受的常驻成本。
六 · 兼容与迁移
- PC
iconprop 保留:既有 5 端实现用icon(字形字符,默认'★')。 v1 起新增name(图标名)。两者都在时name优先;icon仍按字形字符直接渲染。 这样既有调用点(frameworks/Icon.*)不破,新调用点用name。 - 移动端
GLYPHS9 名字形表保留:check/close/star/warn/info/arrow/plus/minus/more是移动端既有语义名,通过别名层映射到新图标集(warn→warning等), 既有 4 端实现的行为不破。
七 · 产物清单
| 路径 | 内容 | 入库 |
|---|---|---|
.design_library/kole-ui/icons/sources.json |
上游原始路径数据(归一化后) | ✅ |
.design_library/kole-ui/icons/registry.json |
全量渲染数据 2574 | ✅ |
.design_library/kole-ui/icons/manifest.json |
清单(名字 / 层 / 组 / viewBox / 模式) | ✅ |
.design_library/kole-ui/icons/core.js |
内联运行时(UMD) | ✅ |
.design_library/kole-ui/icons/viewbox.js |
viewBox 例外表 | ✅ |
.design_library/kole-ui/icons/aliases.json |
别名表 | ✅ |
.design_library/kole-ui/icons/ATTRIBUTION.md |
MIT 归属(分发必带) | ✅ |
site/icons.json |
文档站轻量索引 | ✅ |
八 · 验收门
npm run build:icons # 离线重建全部产物
npm run verify:icons # 静态断言(见 tools/verify-icons.mjs)
verify:icons 至少覆盖:
- 产物齐全且互相一致(manifest ↔ registry 双向)。
- 无
view-box拼写残留。 - 描边宽度全部 1.5。
- core 层图标真的能从
core.js渲染出非空 SVG。 - 别名全部指向真实图标。
- 每个端实现的
name查找路径都能落到 registry(不出现"端上有 API 但取不到图标")。 - 分组覆盖率 ≥ 75%(低于则说明分组规则退化)。