@kingsoft-ai/theme
v0.2.3
Published
基于 Emotion 的主题包,提供“全局层 → 语义层 → 组件层”的三层 Design Token 体系,服务于金山AI官网、后台与组件库的一致设计风格与主题切换能力。
Readme
@kingsoft-ai/theme — 金山AI 主题包(三层 Design Token 体系)
基于 Emotion 的主题包,提供“全局层 → 语义层 → 组件层”的三层 Design Token 体系,服务于金山AI官网、后台与组件库的一致设计风格与主题切换能力。
- 适配场景: 网站与后台界面、
@kai/design组件库 - 核心能力: 三层 Token、类型安全、多主题(亮/暗)、集中治理、与组件库直连
特性
- 三层 Token 架构: Global(基础值)→ Semantic(语义映射)→ Component(组件专用)
- 类型安全: 完整的 TypeScript 类型,使用时具备自动补全与校验
- 多主题: 内置
lightComponentTheme与darkComponentTheme,可扩展更多品牌/业务主题 - 零硬编码: 组件与页面不直接写颜色/尺寸,统一由 Token 决策
- 易协作: 与设计规范一致,更新 Token 即全局生效
- 模块化设计: 语义层独立导出,可供多个项目复用
安装
确保已配置公司内部 NPM 源(可在工程 .npmrc 中设置):
npm config set registry https://npm.kingsoft-ai.com/安装依赖:
pnpm add @kingsoft-ai/theme @emotion/react @emotion/styled
# 或
npm i @kingsoft-ai/theme @emotion/react @emotion/styled本包对 react/react-dom 要求版本 >= 18(为 peerDependencies)。
快速开始
使用 CustomThemeProvider 注入主题(默认亮色主题):
import { CustomThemeProvider } from '@kingsoft-ai/theme'
export default function App() {
return (
<CustomThemeProvider>
{/* 你的应用 */}
</CustomThemeProvider>
)
}搭配 @kai/design 组件库:
import { CustomThemeProvider } from '@kingsoft-ai/theme'
import { Button } from '@kai/design'
export default function App() {
return (
<CustomThemeProvider>
<Button variant="primary" size="md">开始使用</Button>
</CustomThemeProvider>
)
}主题切换
import { CustomThemeProvider, lightComponentTheme, darkComponentTheme } from '@kingsoft-ai/theme'
export default function App({ isDark }: { isDark: boolean }) {
return (
<CustomThemeProvider theme={isDark ? darkComponentTheme : lightComponentTheme}>
{/* ... */}
</CustomThemeProvider>
)
}在组件中消费 Token
优先使用“组件层” Token,确保一致与可维护:
import styled from '@emotion/styled'
const PrimaryAction = styled('button')(({ theme }) => ({
background: theme.components.button.primary.background.default,
color: theme.components.button.primary.text.default,
borderRadius: theme.components.button.borderRadius,
'&:hover': { background: theme.components.button.primary.background.hover },
}))页面/容器等通用样式可使用“语义层” Token:
const Page = styled('div')(({ theme }) => ({
background: theme.semantic.colors.background.surface,
color: theme.semantic.colors.text.primary,
}))如需特指原子值(谨慎使用),可访问“全局层” Token:
const AccentBorder = styled('div')(({ theme }) => ({
borderColor: theme.global.colors.blue[500],
}))导出 API
- 组件主题:
lightComponentTheme,darkComponentTheme - 语义层:
lightSemantic,darkSemantic(可供其他项目引用) - 主题提供者:
CustomThemeProvider,CustomThemeProviderProps - 全局层 Token:
globalColors,globalSpacing,globalRadii,globalTypography,globalShadows,globalGradients - 类型:
Theme(=AppTheme)、ComponentTheme、以及types/目录中的各细分类型
目录结构(核心)
packages/theme/src/
├── types/ # 类型定义目录
│ ├── tokens.types.ts # Tier 1: 全局层类型
│ ├── semantic.types.ts # Tier 2: 语义层类型
│ ├── components.types.ts # Tier 3: 组件层类型
│ └── index.ts # 类型汇总导出
├── tokens.ts # Tier 1: 全局层 Token(色板/间距/圆角/排版/阴影/渐变)
├── semantic.ts # Tier 2: 语义层(亮/暗色语义映射,可独立引用)
├── themes/ # 主题目录
│ └── components.ts # 设计组件主题(完整的三层 Token)
├── CustomThemeProvider.tsx # 主题注入(基于 Emotion ThemeProvider)
└── index.ts # 对外导出入口语义层独立使用
语义层(Semantic Layer)现已独立导出,其他项目可以直接引用语义层而不必引入完整的组件主题:
import { lightSemantic, darkSemantic, globalColors, globalSpacing } from '@kingsoft-ai/theme'
// 创建自定义主题,复用语义层
const customTheme = {
semantic: lightSemantic,
global: {
colors: globalColors,
spacing: globalSpacing,
// ...
},
components: {
// 你的自定义组件 Token
}
}这样设计的好处:
- 可复用: 多个项目可以共享相同的语义层规则
- 灵活性: 每个项目可以基于相同的语义层定制自己的组件层
- 一致性: 保证不同项目的设计语言一致
开发与构建
# 构建(生成 dist/)
pnpm build:lib
# 清理构建产物
pnpm clean设计与使用规范
- 优先组件层:组件样式应使用
theme.components.* - 其次语义层:页面/布局使用
theme.semantic.* - 避免硬编码:不在代码中直接写
#RRGGBB/px等魔法值 - 单一数据源:变更 Token 即全局生效,便于治理与回溯
深入阅读:docs/kingsoft-ai-design-token-system.md
常见问题(FAQ)
- 如何新增主题? 复制
lightComponentTheme/darkComponentTheme的结构,按需映射语义层,再导出即可。 - 语义层和组件主题有什么区别? 语义层定义设计规则(如品牌色、文本色),组件主题将这些规则应用到具体组件。语义层可以独立使用,组件主题包含完整的三层 Token。
- 组件没有对应的组件层 Token 怎么办? 在
types/components.types.ts增加接口定义,并在themes/components.ts的components.*补齐实现。 - 能直接用全局层吗? 仅在表达"必须是该原始值"且不破坏语义一致性的前提下使用。
