OpenMetadata 图标库(Icon Library)完全指南:从 SVG 到类型化 React 组件的自动化流水线
【免费下载链接】OpenMetadataThe Open Context Layer for Data and AI , OpenMetadata is the open platform for building trusted data context and business semantics for humans, AI assistants, and agents.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMetadata
OpenMetadata 在@openmetadata/ui-core-components包中内置了一套第一方(first-party)图标库:以 SVG 为唯一事实来源,通过yarn icons:generate自动生成带类型的 React 组件并提交入库。本文以仓库文档 ICONS.md 为主体,结合 generate-icons.mjs 生成器源码,完整讲解目录结构、导入与 Props 规范、新增图标的四步工作流、Storybook 可视化验证,以及底层 SVGO + SVGR 的生成原理。读完你将能独立为 OpenMetadata 添加一个图标、理解常规图标与自定义彩色图标两条管线的差异,并掌握在不改动构建配置的前提下让新图标自动进入产物与文档的方法。
目录结构与文件职责
图标库位于仓库的 openmetadata-ui-core-components/src/main/resources/ui 目录,整体分为“源 SVG”与“生成产物”两层:
icons/ ← 常规图标的源 SVG(kebab-case 命名,已提交) icons-custom/ ← 自定义/渐变图标的源 SVG(保留原始颜色) src/icons/ ← 生成的 TSX 组件(已提交,禁止手改) AddAlert.tsx Memories.tsx Gold.tsx ← 由 icons-custom/gold.svg 生成 index.ts src/icons-static/ types.ts ← IconProps 接口(手写,不参与生成)两个关键设计约束:
- SVG 源文件与生成的 TSX 文件都提交到 git。生成器
yarn icons:generate是开发者工具,只在 SVG 变化时显式运行并提交结果;yarn build是纯粹的vite build,不包含生成步骤,因此构建保持快速。 - 产物目录中的手写文件受保护。生成器只覆盖
.tsx文件,types.ts等手写文件永远不会被触碰(详见下文生成器源码分析)。
从当前仓库实际内容看,icons/目录收录了约 180 个常规 SVG(如data-quality.svg、api-collection.svg、ml-model-2.svg、memories.svg等),icons-custom/目录收录了 4 个品牌彩色图标(bronze.svg、gold.svg、silver.svg、none.svg),覆盖了数据质量、数据资产、实体类型、测试套件等 OpenMetadata 核心领域。
导入语法与 Props 规范
统一导入路径
无论图标来自icons/还是icons-custom/,都从同一个入口导入:
import { Memories, AddAlert, Domain } from '@openmetadata/ui-core-components/icons';这一行为由 package.json 的exports字段中的"./icons"子路径导出保证:类型、ESM、CJS 三个入口分别指向dist/types/src/icons/index.d.ts、dist/icons/index.es.js与dist/icons/index.cjs.js。
Props 与@untitledui/icons保持一致
图标组件的 Props 形状与@untitledui/icons相同:
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
size | number | 24 | 宽高(px),同时作用于 width 与 height |
color | string | 'currentColor' | SVG 描边颜色 |
className | string | — | 附加 CSS 类名 |
...props | SVGProps<SVGSVGElement> | — | 其他任意 SVG 属性 |
对应的类型定义是手写的 src/icons-static/types.ts,其中IconProps extends SVGProps<SVGSVGElement>并补充了color?: string与size?: number。
用法示例
<Memories size={20} color="#667085" /> <AddAlert size={16} className="tw:text-brand-600" />以实际生成的 Memories.tsx 为例,可以看到默认参数、aria-hidden、strokeLinecap="round"、strokeLinejoin="round"等属性都由模板统一注入,使用方只需关心size与color。
新增图标的四步工作流
第 1 步:从 Figma 导出 SVG
- 在 Figma 中选择图标 frame;
- 导出格式必须选SVG(而非 PNG/PDF);
- 确保不包含画板(artboard)背景。
第 2 步:命名并放置文件
文件名使用kebab-case,放入包根目录的icons/目录:
openmetadata-ui-core-components/src/main/resources/ui/icons/my-new-icon.svg合法命名示例及其对应的组件名映射规则:
data-quality.svg→DataQualityapi-collection.svg→ApiCollectionml-model-2.svg→MlModel2
数字和连字符都是允许的;空格、&等特殊字符会在生成时被剔除——因此务必用连字符作为单词分隔符。这一规则在生成器源码的toComponentName()中实现(见 generate-icons.mjs):先按非字母数字字符切分,再对每个片段首字母大写后拼接成 PascalCase。
第 3 步:运行生成器并提交产物
cd openmetadata-ui-core-components/src/main/resources/ui yarn icons:generate该命令在 package.json 中定义为node scripts/generate-icons.mjs。运行后会发生三件事:
- 用 SVGO 优化 SVG;
- 生成
src/icons/MyNewIcon.tsx; - 更新
src/icons/index.ts将其导出。
SVG 与生成的.tsx必须在同一个 PR 中一起提交。因为生成产物被 git 跟踪,yarn build保持为纯vite build,不依赖运行时生成。
第 4 步:在 Storybook 中验证
yarn storybook打开 http://localhost:6006,进入Icons → Library,新图标应出现在可搜索的网格中。注意 package.json 中storybook与build-storybook脚本都会先执行yarn icons:generate再启动/构建,保证文档与最新图标同步。
使用 Storybook 浏览图标库
cd openmetadata-ui-core-components/src/main/resources/ui yarn storybook # dev server on http://localhost:6006 yarn build-storybook # static build to storybook-static/在左侧边栏进入Icons → Library后,可用的交互能力:
| 功能 | 使用方法 |
|---|---|
| 搜索 | 在搜索框中输入图标名,跨所有类别过滤 |
| 大小调节 | 使用屏幕底部 Controls 面板中的size滑块 |
| 复制导入语句 | 点击任意图标单元格,import 语句即复制到剪贴板 |
生成器工作原理:SVGO + SVGR 双管线
文件角色一览
| 文件 | 角色 |
|---|---|
icons/*.svg | 源 SVG——kebab-case、已提交、唯一事实来源 |
| scripts/generate-icons.mjs | 读取icons/,执行 SVGO + SVGR,写出src/icons/ |
| templates/component.cjs | SVGR 模板,产出每个.tsx文件 |
src/icons/index.ts | 由模板逻辑生成的统一导出入口 |
| src/icons-static/types.ts | IconProps接口(手写) |
Vite 库构建配置(vite.config.ts)会自动发现src/icons/index.ts作为入口——新增图标无需修改任何构建配置。
两条管线:常规图标 vs 自定义图标
生成器将icons/(常规)与icons-custom/(自定义)视为两个源目录、同一输出目录、同一导入路径。核心差异体现在 SVGO 配置与 SVGR 配置上:
常规图标管线(svgoRegularConfig,见 generate-icons.mjs):
- 使用
preset-default(保留viewBox)、cleanupIds、removeDimensions、removeAttrs(剔除xmlns、data-name、style)等共享插件; - 额外剔除
stroke-linecap/stroke-linejoin(根节点会统一重新注入); - 通过自定义
replaceHardcodedColors插件把硬编码十六进制颜色替换为currentColor(fill="none"、fill="white"、fill="url(...)"除外),从而让图标完全可通过colorprop 主题化。
自定义图标管线(svgoCustomConfig,见 generate-icons.mjs):
- 跳过颜色替换,保留品牌色与渐变;
- 用
prefixIds给 ID 添加图标名前缀,防止多个自定义图标同页渲染时渐变/mask ID 冲突; - 在 SVGR 阶段不注入
stroke/fill覆盖,只注入width/height与aria-hidden(见buildSvgrConfig中isCustom分支)。
组件模板(templates/component.cjs)对两条管线做了统一处理:常规图标直接绑定color,自定义图标将color重命名为_color以满足 ESLint 未使用变量规则,同时保持两侧 Props 接口一致。每个生成的组件都会设置displayName。
增量更新与产物自洁
main()执行时还包含一个容易被忽略的关键逻辑(见 generate-icons.mjs):删除过期产物。当某个 SVG 从icons/或icons-custom/移除后,重新运行生成器会把对应的陈旧.tsx一并清理——清理范围严格限定为.tsx,绝不动types.ts等手写文件。随后重新生成index.ts(导出IconProps类型与全部组件),并对生成代码依次执行本包 ESLint--fix与 Prettier 格式化,保证产物与 CI 的 ui-checkstyle 规范一致。
完整重新生成
yarn icons:generate # 重新读取 icons/ 下所有 SVG,覆盖 src/icons/*.tsx 与 index.ts该命令可随时安全运行——它只会触碰生成文件,绝不修改types.ts或其他手写文件。
实践要点小结
- 新增图标时把 SVG 放入 icons/(常规)或 icons-custom/(彩色/渐变),文件名用 kebab-case;
- 运行
yarn icons:generate后,将源 SVG 与生成的 TSX 一起提交; - 组件默认
size=24、color='currentColor',与@untitledui/icons生态保持一致; - 常规图标颜色跟随
colorprop 主题化;icons-custom/下的品牌图标保留原始颜色,仅暴露尺寸控制; - 新增图标无需改动
vite.config.ts,构建入口自动发现; - 用
yarn storybook打开 Icons → Library 做可视化验收与导入语句复制。
【免费下载链接】OpenMetadataThe Open Context Layer for Data and AI , OpenMetadata is the open platform for building trusted data context and business semantics for humans, AI assistants, and agents.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMetadata
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考