Communitygithub.com

Icon Forge - SVG 图标锻造器

绘制一组风格统一的原创 SVG UI 图标,并将其生成为零依赖的 React、Vue、Svelte 或 HTML-sprite 组件,内置无障碍默认值。

Icon Forge - SVG 图标锻造器 是什么?

Icon Forge 是一个 AI 智能体技能,专为需要为 Web 应用创建自定义 SVG 图标集的场景设计。它通过一套严谨的设计规则与自动化工作流,确保每个图标都遵循 24px 网格、统一笔触、圆角与间距,并经过 lint 检查、优化、PNG 预览后,最终输出为支持 tree-shaking 的无依赖框架组件。该技能适用于侧边栏、导航栏、仪表盘、设置页面等需要图标组件的场景,特别适合用户希望用轻量级自定义图标替换 emoji、占位图标或重型图标库的情况。它强调“自己绘制每个图标”,而非复制已有图标库的路径数据,从而在保持独特外观的同时最小化打包体积。支持 React、Vue、Svelte、HTML sprite 四种输出格式,并内置了完整的无障碍实践指导。不适合处理 logo、品牌标识、favicon、插图或位图。

兼容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/Abhijit-Jha/icon-skill/tree/HEAD/icon-forge

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Icon Forge

绘制自定义图标,使其看起来像来自同一套专业图标库,并零运行时依赖地交付。当每个图标都通过 lint 检查、你已查看 16/20/24px 的预览图且其在明暗背景下清晰一致、以及生成的组件已通过无障碍用法接入时,任务才算完成。

<skill> 指包含此文件的文件夹(例如 .claude/skills/icon-forge、.cursor/skills/icon-forge、.agents/skills/icon-forge)。脚本需要 Node ≥18 且无需项目依赖。

何时使用 / 何时不用

  • 使用场景: 侧边栏、导航栏、仪表盘、设置页面、空状态或工具栏需要图标;用户要求自定义或缺失的图标;用户希望用轻量级自定义图标集替换 emoji/占位图标或繁重的图标包。
  • 不用场景: Logo 和品牌标识(商标问题;需要设计师处理)、favicon/应用图标、插画或点缀图、照片/位图、动效 Lottie。如果用户明确要求安装一个图标库(例如“直接用 Lucide”),请按他们的要求做;此技能仅服务于自定义路径。

硬性规则(及其原因)

  1. 每个图标自己绘制;不添加任何图标库依赖。 用户选择自定义图标是为了减小打包体积和获得独特外观。不要粘贴来自 Lucide、Heroicons、Material 等库的路径数据(涉及许可和原创性)。使用 references/glyph-cookbook.md(原创绘图)作为起始几何参考。
  2. 如果项目已使用某个图标库,则匹配其网格、笔触、端点和圆角半径(参见 scripts/detect.mjs 和设计规则 §10)。新图标必须与现有图标放在一起而不显突兀。
  3. 一套图标,一种风格。 所有图标使用相同的网格、笔触宽度、端点/连接样式、半径比例、边距和细节密度。一致性比任何一个别出心裁的图标更重要。
  4. 表现属性只存在于根 <svg> 上,颜色使用 currentColor,源文件中不包含 id、样式、class、transform 或 <g>。 否则,主题切换、暗黑模式、strokeWidth 属性和内联方式都会失效。
  5. 切勿在不渲染并查看 PNG 的情况下声称图标没问题。 在代码中看起来正确的几何形状在 16px 时常常会出问题:模糊、闭合间隙、重心偏移、粗细不均。
  6. 运行脚本;不要手动重新实现它们。 Lint、优化、预览和代码生成都是确定性的。永远不要手动编辑生成的文件;修改 icons/src/ 然后重新构建。
  7. 不要修改用户的依赖。 预览工具会安装到 ~/.cache/icon-forge(使用 --install);SVGO 在本地缺失时通过 npx 运行。在向项目添加任何包之前先询问用户。
  8. 默认无障碍。 图标默认 aria-hidden,除非被标记;仅图标控件需设置 aria-label;可交互目标 ≥44px;有意义的图标需 ≥3:1 对比度。

工作流

1. 检测技术栈和现有风格

node <skill>/scripts/detect.mjs .

注意框架、TypeScript、Tailwind、任何图标库(及其样式预设)、本地 SVG 图标以及建议的输出目录。如果存在现有图标集,打开其中的 2-3 个 SVG 并复制它们的根属性值。否则使用默认值:24 网格、笔画 2、圆角端点/连接。

2. 计划列表:含义 → 隐喻 → 文件名

在绘图前编写一个简短表格:标签 | 隐喻(绘制什么) | 文件名 | cookbook 起点。例如:Projects | kanban board | kanban.svg | kanban。选择主流隐喻(设计规则 §7)且每个含义只用一个隐喻。以 kebab-case 格式为对象命名文件。仅在标签有歧义且选择会改变 UI 含义时才询问用户;否则自行决定并说明选择。

3. 在 24 网格上绘图

创建 icons/src/<name>.svg,包含规范根元素(参见 svg-code-rules.md)。对于每个图标:

  • 从匹配的关键线开始:圆形 r10,方形 18(x/y 3),竖屏 16×20,横屏 20×16。关键线是笔触的中心线。
  • 保持笔触外缘距画布边缘 ≥1 单位。大角使用半径 2,小角使用 1–1.5;保持间隙 ≥2 单位的空白区域。
  • 让部件要么精确连接,要么保持明显间隙。2px 笔画使用整数坐标。尽可能使用最少的元素(通常 ≤6 个)。
  • 从最接近的 references/glyph-cookbook.md 条目开始,然后进行调整。当字形完全适用时,直接从 <skill>/assets/cookbook/<name>.svg 复制几何形状。
  • 使用几行 JS 计算重复几何形状(齿、射线、星点),而不是手动猜测。 先绘制整套图标,再逐步完善。一致性需要横向对比判断。

4. Lint 检查

node <skill>/scripts/lint.mjs icons/src

修复每个 ✖。将 ⚠ gap、density、scale 和 bounds 视为需要修复的设计问题,而非无关噪声。注意每个 ℹ gap 并在步骤 6 中检查;紧密的平行笔画(条、线)在 16px 时会模糊,除非它们相距 4 个单位。重新运行直到显示 PASS 且没有无法解释的警告。标志:--grid、--padding、--mode fill、--strict、--json。

5. 优化

node <skill>/scripts/optimize.mjs icons/src icons/svg

此步骤会四舍五入数字、运行 SVGO(本地安装或 npx svgo@4;离线时回退到内置规范化器)、重新排序根属性,并输出每个图标字节数及 gzip 总大小。也要对输出进行 lint 检查:node <skill>/scripts/lint.mjs icons/svg。

6. 预览并查看,然后迭代

node <skill>/scripts/preview.mjs icons/svg --out icons/preview.png \
  --sidebar "dashboard:Dashboard,kanban:Projects" --active dashboard   # 首次使用时添加 --install(如果没有 PNG 引擎)

使用你的图片查看工具按以下顺序查看 PNG:

  1. icons/[email protected]:图标集条和侧边栏模拟图。它足够小,可以查看全部细节。
  2. icons/[email protected]:每个图标在不同尺寸下的展示,以及检查视图。它很高,如果查看器缩放显示请裁剪。
  3. icons/preview.png:真正的 1× 像素。

它们共同展示:

  • 24/16px 明暗背景对比条;
  • 带活动项和折叠侧栏的侧边栏模拟图;
  • 每个图标在 16/20/24/48 尺寸下的行;
  • 4× 检查视图,包含网格、蓝色关键线和红色 1px 边距限制。

回答设计规则 §12 中的自审问题。典型修复方案:

你看到的问题修复方法
某个图标在条中显得更轻/更小放大到其关键线,或添加框架/轴线(开放字形视觉上较轻)
某个图标看起来更重/更拥挤移除细节;≤3 条线,≤6 个齿,≤2 行文字
部件在 16px 处交汇处模糊精确连接或将间隙打开至 ≥2 单位
检查视图中形状偏向一侧重新居中,或为光学平衡微调 0.5–1 单位
折叠侧栏中隐喻不清晰选择更直观的隐喻(步骤 2)

重复步骤 3-6,直到第二次查看时找不到任何需要修复的问题。通常需要 1-3 轮。

7. 生成框架输出

node <skill>/scripts/build.mjs icons/svg --out src/components/icons --framework react --lang ts \
  --labels "kanban:Projects,dashboard:Dashboard"

--framework react|vue|svelte|html|all;--lang ts|js;--package @app/icons 会写入一个 sideEffects:false 的 package.json。输出为每个图标一个可 tree-shaking 的模块、一个共享基础组件(支持 size、color、strokeWidth、absoluteStrokeWidth、title、className)、index 命名导出,以及 icons.json。HTML 输出提供 sprite.svg + usage.html。详情参见 references/output-formats.md。

然后对项目进行类型检查或构建(如果它有相应脚本:npx tsc --noEmit、npm run build),并修复任何错误。

8. 通过无障碍用法接入

使用 references/accessibility-and-usage.md 中的模式:

  • <nav aria-label>;aria-current="page" 以及活动项的颜色和背景;
  • 图标使用 size-5 shrink-0 且为装饰性;
  • 仅图标按钮设置 aria-label;退出按钮作为 <button>;
  • 行高 ≥44px;使用仍能达到 3:1 对比度的柔和颜色。

输出格式

最后给用户一份简短报告:

  1. 图标: 表格 标签 → 组件 → 隐喻 以及文件夹路径(icons/src、icons/svg、生成目录)。
  2. 检查: lint 结果(错误/警告)、优化总计(平均字节/图标、gzip 总计),以及你检查过的预览路径,还有你查看后修改的内容。
  3. 使用代码片段(针对用户的框架),包含无障碍属性。
  4. 备注: 风格决策(匹配的网格/笔触/预设)、需要镜像的 RTL 图标,以及你无法验证的任何内容。

示例

用户:“我的 Next.js + Tailwind 应用需要侧边栏图标:仪表盘、项目、团队、设置。” → detect:React (Next) + TS + Tailwind,无图标库 → plan:仪表盘/磁贴、看板、用户、设置/齿轮 → 从 cookbook 绘制并调整 → lint PASS → optimize:4 个图标,平均 ~340 B,~0.4 KB gzip → 预览:项目图标看起来轻了,所以添加横条;重新检查 → build --framework react 到 src/components/icons → 在导航中使用 <DashboardIcon className="size-5 shrink-0" /> 并设置 aria-current。

参考文档

当你需要……时打开阅读
选择尺寸、关键线、半径、间隙、隐喻,或修复预览问题references/design-rules.md
编写或调试 SVG 标记,或理解 lint 错误references/svg-code-rules.md
从经过验证的几何形状开始绘制常见 UI 图标(56 个已绘制字形)references/glyph-cookbook.md + assets/cookbook/*.svg
生成或手动适配 React/Vue/Svelte/Angular/HTML 输出,或减小打包体积references/output-formats.md
编写使用代码片段:导航/侧边栏模式、激活状态、标签、对比度、RTLreferences/accessibility-and-usage.md
更改生成组件的形状(props、类名、无障碍默认值)templates/<framework>/,build.mjs 会读取;在此处编辑,绝不在输出中编辑
测试对此技能的更改evals/evals.json

验证清单(报告完成前必须全部为真)

  • 未添加任何图标库;每个图标均为本次任务绘制或从 cookbook 改编而来。
  • 整组图标的风格与项目现有图标(或默认预设)匹配。
  • lint.mjs 在 icons/src 和 icons/svg 上返回 PASS;剩余警告已在报告中说明理由。
  • 你在最后一次修改后查看了预览 PNG;16px 明暗背景行清晰;没有图标比同级图标更重、更轻或更大。
  • 组件由 build.mjs 生成;项目类型检查/构建通过(如果可用)。
  • 使用方面:装饰性图标已隐藏,仅图标控件已标记,激活状态不单独依赖颜色,目标区域 ≥44px,对比度 ≥3:1。
  • 报告包含尺寸信息(平均字节/图标、gzip 总计)和预览路径。

相关技能