这是教程的最后一章。
前面 8 章讲的是"怎么从 0 到 1"。这一章讲"1 之后怎么继续"——加新图标的 checklist、容易踩的坑、还有 sag-icons 的路线图。
读完这一章你会知道:
sag-icons 加图标的步骤是固定的。下面以"加一个 user-circle 图标"为例。
按第 2 章规范画 24×24 多色图标。命名约定:icon-user-circle(kebab-case)。
按第 3 章流程:
fill="currentColor" / stroke="currentColor"data-tone="blue|cyan|green|amber|white"<svg>)对应目录:
src/data/icons/<category>/
ICON_PATHS 注册注意:键名用 kebab-case("user-circle"),变量名用 camelCase(userCircle)。这样 IconName 联合类型自动包含 "user-circle"。
ICON_CATEGORIES 注册打开文档站确认:
应该看到新图标出现在"基础界面"分类下。
类型 IconName 仍然正常("brand" 不会出现在 union 里),但 <sag-icon name="brand" /> 渲染为空。
修复:在 src/data/index.ts 顶部加 import 和 ICON_PATHS 注册。
CSS 选择器是 [data-tone="blue"](小写)。如果 data-tone 拼错,CSS 主题切换不生效。图标看起来永远是默认灰色。
修复:统一小写。可以加个 lint 规则检查:
如果忘改 currentColor,CSS 主题切换无效——图标永远是你写的那个颜色。
保持键名 = 文件名(去后缀),变量名 = camelCase。这是 sag-icons 的强约定。
如果用户手动 register() 又 import 主入口,主入口的自动注册会静默跳过:
但用户改 tagName 时(如 register("my-icon")),自动注册会冲突:
修复:要么只用 import "@jujiuyey/sag-icons",要么只手动 register("custom-name")。
用户应用可能也用了 --sag-icon-blue 变量做其他事。冲突时:
修复:用户应该用不同前缀(--my-app-blue),或者 sag-icons 改成更难冲突的变量名。
这是 CSS 变量方案天生的局限。如果你需要更严格的隔离,考虑:
sag-icon 加 Shadow DOM(放弃 CSS 主题穿透)sag-icons 当前没有自动化测试。建议至少做这几项手动测试:
每个图标渲染出来要和 Figma 里的基本一致。1px 偏差可以接受,2px 以上需要改。
每个图标在 is-active 状态应该正确显示彩色:
sag-icons 主打跨框架,至少在 React、Vue、原生 HTML 各跑一次:
在 Next.js / Nuxt 项目里安装,确认 import "@jujiuyey/sag-icons" 不抛错(SSR 阶段)。
当前 sag-icons 是 0.0.1——还没到 1.0。Roadmap:
exports 子路径:让 @jujiuyey/sag-icons/data/... 和 @jujiuyey/sag-icons/css/... 真正可访问(第 8 章讲过)<sag-icon name="x" /> 不会带全包进 bundle<SagIcon name="x" /> 而不是 <sag-icon>data-tone 映射data-tone如果你要做一个图标库,下面这些是 sag-icons 已经验证过的不要做的事:
最早 sag-icons 想做 react-sag-icons / vue-sag-icons / svelte-sag-icons 三个包。
结果:维护成本 * 3。Web Component 一个包搞定所有。
最早想给 sag-icon 加 color / primary / secondary props。
结果:用户传 5 个颜色,参数列表爆炸;还要做 props → CSS 变量同步。
CSS 变量穿透 + is-active 一招鲜。
最早想支持 light / dark / brand 4 套主题。
结果:每个图标要为每个主题各做一套配色,复杂度 × 4。
只做"1 套主题下的状态切换",把简单留给 CSS。
最早想给 sag-icon 加 Shadow DOM 做样式隔离。
结果:CSS 变量穿透失败,主题系统崩盘。
外部 CSS 变量穿透是 sag-icons 的命脉,Shadow DOM 不能上。
最早想对标 Lucide / IconPark 做 1500+ 图标。
结果:风格一致性崩盘,每个图标都有点违和。
聚焦 200+ 高质量 + 风格统一,远比 1500+ 但风格杂好。
一些可能的方向:
size 属性支持 xs / sm / md / lg / xl 五档预设。但 CSS 覆盖 width / height 也行,看用户偏好。
color 直接传色绕过 data-tone 直接覆盖。代价:和 is-active 系统冲突,需要二选一。
outline /filled 切换每个图标做两套 SVG 字符串。包体积 × 2。不推荐。
让用户按场景分组查找图标。但 sag-icons 已经按目录分类了,价值不大。
到这里,sag-icons 的 9 章教程讲完了。我们走过的路:
| 章 | 主题 | 关键设计 |
|---|---|---|
| 02 | Figma 画图 | 24×24 + 2px stroke + 5 色板 |
| 03 | 图标数据层 | data-tone 标记 + 字符串存储 + ICON_PATHS 派生 |
| 04 | 包工程 | exports 子路径 + tsconfig 双层 + Vite 库模式 |
| 05 | Web Component | observedAttributes + 幂等 register + SSR 安全 |
| 06 | CSS 多色调 | CSS 变量 + data-tone + is-active 状态切换 |
| 07 | 类型系统 | as const + IconName + JSX 增强 .d.ts |
| 08 | 构建发布 | tsc + vite 双步 + pnpm pack 验证 |
| 09 | 迭代路线 | checklist + 避坑 + 路线图 |
<sag-icon> 一套走天下,省 N 个包as const + keyof typeof 让 IconName 自动维护这些设计可以搬到任何图标库,不是 sag-icons 专属。
教程结束。如果有问题,欢迎到 sag-icons GitHub Issues 讨论。