Carbon Themes v10 预览示例完全指南:从 @carbon/themes 主题机制到本地运行
【免费下载链接】carbonA design system built by IBM项目地址: https://gitcode.com/GitHub_Trending/carbo/carbon
本指南以 IBM Carbon Design System 仓库中 packages/themes/examples/preview-v10 示例为核心,系统讲解@carbon/themesv10 版本的主题机制:四种内置主题(white / g10 / g90 / g100)的色板全览、carbon--thememixin 的组件主题化、自定义 token 的扩展方法,以及基于 CSS 自定义属性的运行时主题切换,并给出从零启动该预览页的完整步骤。读完本文,你将能独立运行该示例,并掌握在自研项目中复用这套主题化写法的实战方案。
一、示例概览:这个 preview-v10 展示什么
preview-v10是 packages/themes 包下的一个 Next.js 演示页,用来可视化验证v10 版@carbon/themes的三大核心能力:
- Themes(主题色板):以表格形式逐行列出全部颜色 token,并横向对比每个 token 在
white、g10、g90、g100四种主题下的取值,每个色块旁同时给出该颜色对应的命名色(如gray-100)或十六进制值; - Theming(组件主题化):通过
carbon--thememixin 与自定义 token,演示同一组件在默认主题与g100主题(或自定义主题)下如何呈现不同配色; - Custom Properties(CSS 自定义属性):通过切换容器的主题 class,实时观察
field-01、field-02、inverse-01、inverse-02等 token 对应的--token-name自定义属性值变化。
页面核心实现位于 src/pages/index.js,样式与全部主题化示例代码位于 styles.scss。
二、运行 preview-v10:三步启动本地预览
该示例依赖 monorepo 根目录先完成一次构建,以便解析到仓库内已编译的@carbon/themes、@carbon/grid等包产物。按 README.md 的步骤操作:
第一步:在仓库根目录安装依赖并执行构建
yarn install && yarn build第二步:进入示例目录,安装其独立依赖
yarn install # 或 npm install第三步:启动开发服务器
yarn develop # 或 npm run develop随后在浏览器打开http://localhost:3000即可看到预览结果。
补充说明(来自示例配置):
develop与build脚本定义在 package.json 中,develop对应next,build对应next build;- next.config.js 中为生产构建设置了
basePath: '/themes/examples/preview-v10'、output: 'export'与distDir: 'build',用于将静态站点部署到仓库示例目录;开发模式下则合并默认配置并借助 Turbopack 将 monorepo 根目录(path.resolve(__dirname, '../../../..'))作为解析根; - 依赖方面,示例同时引用
@carbon/themes(^10.55.1)与@carbon/grid(^10.43.1),页面由 Next.js + React 渲染,Sass 样式经由sass编译。
三、Themes:一张表看懂四种 v10 主题
页面第一个区块(#themes)的数据来自@carbon/themes的 JS 导出。在 src/pages/index.js 中:
import * as colors from '@carbon/colors'; import { themes, formatTokenName, unstable__meta as meta } from '@carbon/themes';themes:以white/g10/g90/g100为 key 的主题对象集合。在当前仓库的 v11 源码中,这四种主题仍被保留并导出,例如 src/index.ts 中const themes = { white, g10, g90, g100 },而 v10 专属定义位于 src/v10/index.ts(同样导出white, g10, g90, g100, themes, tokens);formatTokenName:将 snake_case 或短横线命名的 token 规范化为展示名(如interactive-02);unstable__meta(在 v11 源码中对应 src/tokens 导出的unstable_metadata):元数据中meta.colors的每一项带tokens字段,示例用meta.colors.flatMap((color) => color.tokens)拍平出全部颜色 token 列表。
渲染逻辑按 token 逐行建表:行首是formatTokenName(token)的锚点链接,行内对Object.keys(themes)的每个主题取themes[theme][token]作为色块背景;同时通过反向查表colorNameLookup(由@carbon/colors的导出构建)把十六进制值还原成命名色展示。
这段逻辑直接印证了 v10 主题模型的核心事实:主题本质上是 token → 颜色值的映射对象,四种主题共享同一套 token 键,仅取值不同。读者可据此在自己的项目中用同样方式生成“token × 主题”对照表,用于设计评审或 token 变更审计。
四、Theming:用 carbon--theme mixin 做组件级主题化
#theming区块演示了两层主题化能力,完整代码同时存在于页面<details>与 styles.scss 中,二者一一对应。
4.1 基础组件主题化
先定义一个消费主题变量的组件样式 mixin,再用carbon--theme将其注入到g100主题作用域中:
@mixin my-component() { .my-component { color: $interactive-02; } } // 默认使用 $interactive-02 的当前主题取值 @include my-component(); // 在 g100 主题下重新输出,颜色取自 g100 主题 @include carbon--theme($carbon--theme--g100) { .theme { @include my-component(); } }关键机制说明:
$interactive-02是@carbon/themes提供的主题变量之一,其值会随当前激活的主题切换;carbon--theme($theme) { ... }会在花括号作用域内临时激活指定主题(此处为$carbon--theme--g100),内部的 Sass 变量取值为该主题对应的值,作用域结束后恢复;- 页面预览中,
my-component位于普通容器与.theme容器内各渲染一份,可见到两种颜色并排对比。
4.2 自定义 token:扩展现有主题
当内置 token 不够用时,可以在主题 map 上合并自定义 token。示例基于 white 主题派生$default-custom-theme,新增custom-token-01:
$default-custom-theme: map-merge( $carbon--theme--white, ( custom-token-01: #171717, ) ); $custom-token-01: map-get( $default-custom-theme, custom-token-01 ) !default !global;组件 mixin 同时使用内置 token 与自定义 token:
@mixin my-custom-token-component() { .my-custom-token-component { color: $interactive-01; } .my-custom-token-component .custom-token { color: $custom-token-01; } } @include my-custom-token-component();随后自定义一个主题包装 mixin:在carbon--theme作用域内将custom-token-01重新绑定为传入主题中的值,并在传入主题非默认主题时递归回退到默认主题,保证自定义 token 始终有值可依:
@mixin custom-theme($theme: $default-custom-theme) { @include carbon--theme($theme) { $custom-token-01: map-get($theme, custom-token-01) !global; @content; } @if $theme != $default-custom-theme { @include custom-theme($default-custom-theme); } }最后构造一个同时覆盖内置 token 与自定义 token 的主题(interactive-01: #ee538b、custom-token-01: #8a3ffc),并应用到.theme容器:
$custom-theme: map-merge( $default-custom-theme, ( interactive-01: #ee538b, custom-token-01: #8a3ffc, ) ); .theme { @include custom-theme($custom-theme) { @include my-custom-token-component(); } }这套模式的意义在于:无需改动@carbon/themes源码,即可在消费侧安全地扩展 token 集合,且自定义 token 与内置 token 一样支持按主题差异化取值。
五、Custom Properties:运行时切换主题
#custom-properties区块展示基于 CSS 自定义属性的主题切换。页面中的ThemeSwitcher组件维护一个themestate(初始为white),用classnames拼出theme--white/theme--g10/theme--g90/theme--g100之一作为容器 class,并在容器内以var(--${token})引用field-01、field-02、inverse-01、inverse-02四个 token 的色块。
对应样式在 styles.scss 末尾,四个主题 class 均调用carbon--theme(..., true),第二个布尔参数表示以 CSS 自定义属性的形式输出全部 token:
.theme--white { @include carbon--theme($carbon--theme--white, true); } .theme--g10 { @include carbon--theme($carbon--theme--g10, true); } .theme--g90 { @include carbon--theme($carbon--theme--g90, true); } .theme--g100 { @include carbon--theme($carbon--theme--g100, true); }由此产生的效果是:每个主题 class 内部都会定义一套--field-01、--inverse-01等自定义属性,DOM 中切换 class 即切换整套 token 取值,无需重编译样式,非常适合在运行时做浅色/深色主题切换。这一输出逻辑在当前仓库的 v11 实现中依然延续——scss/_theme.scss 的thememixin 会遍历主题 map,逐个 token 调用-custom-property生成 CSS 自定义属性(并支持组件 token 分组);使用@import '@carbon/themes/scss'(见 styles.scss 第 9 行)即可在任意项目中接入同一套主题系统。
六、要点回顾
| 主题化能力 | 关键 API / 写法 | 示例出处 |
|---|---|---|
| 查看四种主题全部 token | themes+meta.colors+formatTokenName | src/pages/index.js |
| 组件级主题化 | carbon--theme($carbon--theme--g100) { ... } | styles.scss |
| 自定义 token | map-merge扩展主题 +!default !global变量 | styles.scss |
| 运行时主题切换 | carbon--theme($theme, true)输出自定义属性 | styles.scss |
| 启动方式 | 根目录yarn build后,示例目录yarn install && yarn develop | README.md |
preview-v10用最短的代码串联起了@carbon/themesv10 的主题查看、组件主题化、自定义 token 与运行时切换四条主线,是理解 Carbon 主题系统的理想入门样例。若需要继续深入,可对照阅读 packages/themes/README.md、主题定义源码 src/v10 以及 v11 主题输出实现 scss/_theme.scss。
【免费下载链接】carbonA design system built by IBM项目地址: https://gitcode.com/GitHub_Trending/carbo/carbon
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考