Carbon 设计系统 React 图形组件库 @carbon/pictograms-react 使用指南
【免费下载链接】carbonA design system built by IBM项目地址: https://gitcode.com/GitHub_Trending/carbo/carbon
本篇指南以 packages/pictograms-react/README.md 为主体,系统讲解 IBM Carbon Design System 官方 React 图形(Pictogram)组件库
@carbon/pictograms-react的安装方式、模块导入策略、颜色定制与无障碍(a11y)实践,并结合仓库源码深入剖析其底层渲染原理、类型生成机制与构建流程。读完本文,你将能够在 React 应用中正确引入 pictogram 组件、按设计规范自定义填充色,并写出对屏幕阅读器友好、可聚焦的 SVG 图形。
@carbon/pictograms-react(当前仓库版本 11.110.0)是 packages/pictograms 中 1500+ 张官方 SVG 图形(pictogram)的 React 组件化封装。它不直接存放图形资源,而是通过构建脚本把packages/pictograms/src/svg/下的原始.svg文件批量转换为可被 React 组件消费的 JavaScript 模块,同时提供 ESM、CommonJS、UMD 三种模块格式和完整的 TypeScript 类型声明。它被广泛应用于数字产品与软件产品中,帮助团队在不引入整棵组件树的前提下,快速复用 Carbon 官方图形资产。
一、安装与版本要求
在项目中安装@carbon/pictograms-react,可以使用 npm:
npm install -S @carbon/pictograms-react如果项目使用 Yarn:
yarn add @carbon/pictograms-react从 package.json 可以看到本包的运行时约束:
- peerDependencies:
react >= 16,即要求宿主项目安装 React 16 及以上版本,本包不会重复捆绑 React; - dependencies:
@carbon/icon-helpers(SVG 属性装配与渲染工具)、prop-types(组件运行时类型校验)、@ibm/telemetry-js(遥测采集); - sideEffects:
false,声明模块无副作用,便于 webpack、Rollup 等打包器进行 tree-shaking,按需摇掉未使用的组件。
二、组件导入方式
2.1 ESM 命名导入(推荐)
每个图形对应一个以 PascalCase 命名的 React 组件,直接按名称从包入口导入即可:
import { Airplane } from '@carbon/pictograms-react';组件名称由原始 SVG 文件名转换而来。例如packages/pictograms/src/svg/airplane.svg对应的组件就是Airplane,packages/pictograms/src/svg/cloud--analytics.svg对应的组件是CloudAnalytics(双连字符--会被转换为 CamelCase 的驼峰分隔)。
2.2 CommonJS 导入
对于未启用 ESM 的构建环境,包提供了 CommonJS 版本(lib目录):
const { Airplane } = require('@carbon/pictograms-react');2.3 模块格式与 UMD
包在发布时同时产出三种格式,分别对应 package.json 中的入口字段:
| 入口字段 | 目录 | 格式 | 适用场景 |
|---|---|---|---|
main | lib/index.js | CommonJS | Node.js / 传统打包器 |
module | es/index.js | ES Module | webpack / Rollup 等现代打包器 |
| — | umd/ | UMD | 浏览器<script>直接引入 |
其中es与lib目录均由 tasks/build.js 中的构建任务生成:先用@carbon/icon-build-helpers的builders.react基于@carbon/pictograms/metadata.json生成组件源码,再通过 TypeScript 编译器分别以ESNext和CommonJS两种模块体系产出声明文件。
2.4 查找某个图形的导入路径
仓库中每个图形的原始定义位于 packages/pictograms/pictograms.yml,该文件为每张图提供了三项关键元数据:
name:文件级标识名(如accelerated-computing),用于生成组件名;friendly_name:人类可读的友好名称(如Accelerated computing),用于设计资产检索;aliases:检索别名(如speed、stopwatch、fast),用于模糊搜索。
如果你在开发时不确定某个图形的准确导入路径,可以在该 YAML 文件中按关键词反查name,再据此推导出组件名。
三、通过fill属性定制图形颜色
所有 pictogram 组件生成的<svg>都支持通过fill属性修改填充色。官方推荐的方式是传入自定义 class 名,在 CSS 中设置该属性(比内联样式更易维护、可复用,也更适合主题切换):
/* CSS 自定义类名,将图标填充色设置为 rebeccapurple */ svg.my-custom-class { fill: rebeccapurple; }import { Airplane } from '@carbon/pictograms-react'; function MyComponent() { return ( <button> <Airplane aria-label="Add" className="my-custom-class" /> </button> ); }需要说明的是,className与fill都属于透传到<svg>节点的常规属性,最终由底层的@carbon/icon-helpers统一装配(详见第五节)。
四、无障碍支持:聚焦与aria-label
默认情况下,@carbon/pictograms-react生成的图形被视为装饰性内容(decorative content),即:只要组件上未传入特定的可访问性相关 props,渲染出的<svg>就会被自动加上aria-hidden="true",屏幕阅读器不会朗读它。这种默认行为对纯装饰图形是正确且必要的,可以避免噪音。
4.1 让图形被屏幕阅读器朗读
当你希望图形承载语义信息(例如作为按钮的一部分传达动作含义)时,传入aria-label或aria-labelledby即可:
import { Airplane } from '@carbon/pictograms-react'; function MyComponent() { return ( <button> <Airplane aria-label="Add" /> </button> ); }传入这两个属性中的任意一个后,组件会自动为<svg>节点补充合适的role(具体为role="img"),从而被辅助技术正确识别为一个图像角色。
4.2 让图形获得键盘焦点
如果希望<svg>本身能接收焦点(例如作为可点击图形),需要显式传入tabIndex:
import { Airplane } from '@carbon/pictograms-react'; function MyComponent() { return <Airplane aria-label="Add" tabIndex="0" />; }当同时传入tabIndex与aria-label(或aria-labelledby)时,组件会在底层<svg>上设置对应的tabindex,并把focusable设为true,以兼容旧版浏览器(如 Internet Explorer 11)对 SVG 焦点支持不足的问题。
4.3 属性装配的源码级原理
上述默认与条件行为并非散落在每个组件里,而是统一由依赖包@carbon/icon-helpers中的 getAttributes 函数实现,其核心逻辑为:
- 为每个
<svg>注入默认属性:focusable: 'false'与preserveAspectRatio: 'xMidYMid meet'(其中focusable是字符串属性,因此不使用布尔值); - 若传入的 attributes 中存在
aria-label或aria-labelledby,则设置role = 'img';若此时还传入了tabindex,则同时将focusable置为'true'并写入tabindex; - 否则(纯装饰场景),设置
aria-hidden = true。
该函数的注释中还引用了allyjs.io关于 SVG 聚焦的文档,说明focusable的兼容性处理是经过调研的刻意设计。相应逻辑也在 getAttributes 的测试 中覆盖。
五、底层渲染原理:从 SVG 文件到 React 组件
pictogram 组件并没有在运行时直接读取.svg文件,而是把图形描述为图标描述符(icon descriptor)。描述符是一个纯数据对象,结构定义于 types.ts:
interface IconDescriptor { elem?: string; // 元素名,默认 'svg' attrs?: Record<string, string>; // 该元素的属性集合 content?: Array<IconDescriptor>; // 子节点(可递归嵌套 path、circle 等) }在非浏览器环境或需要字符串输出的场景,toString 会把描述符递归序列化为 SVG 字符串;在浏览器场景,toSVG 则会通过document.createElementNS('http://www.w3.org/2000/svg', elem)递归创建真实的 DOM 节点。两者都会在根节点上调用getAttributes完成前述无障碍属性的装配。
React 组件层则由构建任务 tasks/build.js 中的builders.react.run(metadata, ...)批量生成:它以@carbon/pictograms构建出的metadata.json为输入,为packages/pictograms/src/svg/下的每一张图形生成一个独立的 React 组件文件,并最终聚合出index.js作为包入口。生成的文件带有 “Code generated by @carbon/pictograms-react. DO NOT EDIT.” 的横幅注释,明确这些产物是构建生成、不应手工修改。
六、TypeScript 支持
@carbon/pictograms-react对 TypeScript 一等公民支持。package.json的types字段指向es/index.d.ts,构建脚本在产出 JS 的同时会生成配套声明:
- 为每个图形组件生成独立的
.d.ts,声明其类型为CarbonPictogramType(见 tasks/build.js 中的generateModuleTypes); - 汇总入口类型
index.d.ts,导出通用Icon组件与CarbonPictogramProps、CarbonPictogramType类型; - 按打包器输出格式(Rollup 的单引号与 tsdown 的双引号)分别解析 ESM 与 CommonJS 的分桶(bucket)导出,并为每个 bucket 生成对应的声明文件。
这意味着在 TypeScript 项目中,import { Airplane } from '@carbon/pictograms-react'即可获得完整的属性类型提示与校验。
七、遥测、许可证与进一步阅读
- 许可证:本包以 Apache 2.0 License 开源。
- IBM Telemetry:包通过
postinstall脚本运行ibmtelemetry --config=telemetry.yml(配置见 packages/pictograms-react/telemetry.yml),仅收集去标识化、匿名化的指标数据(例如 JSX 属性名是否使用了aria-hidden、aria-label、tabIndex等可访问性属性)。安装即表示同意采集,可通过环境变量等方式退出采集。 - 图形资产源头:所有图形的原始 SVG 位于 packages/pictograms/src/svg,其清单与别名定义在 packages/pictograms/pictograms.yml,配套的贡献指南见 packages/pictograms/docs/contributing.md。
- 框架生态对照:除 React 外,Carbon 还提供了
@carbon/pictograms(纯 SVG/SCSS 资产)以及 Vue(packages/pictograms-vue)等变体,便于在不同技术栈间复用同一套图形语义。
【免费下载链接】carbonA design system built by IBM项目地址: https://gitcode.com/GitHub_Trending/carbo/carbon
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考