dynamic-theme-component-library1
v1.1.0
Published
A React component library with dynamic theme switching support
Maintainers
Readme
动态主题 React 组件库
基于 Ant Design v4 令牌系统架构设计的 React 组件库,支持构建时主题定制和运行时动态主题切换。
特性
- 🎨 动态主题切换: 支持运行时通过 CSS 变量动态切换主题
- 🏗️ Ant Design v4 架构: 基于成熟的令牌系统设计
- 📦 TypeScript 支持: 完整的类型定义
- 🎯 构建时主题定制: 通过 Webpack 配置定制构建主题
- 🔧 灵活的配置: 支持自定义主题配置
- 🚀 现代化构建: 使用 Webpack 5 和 Babel 构建
- 🌐 国际化支持: 支持多语言切换
- 📏 企业级代码规范: 集成 ESLint + Prettier,确保代码质量
- ✅ 提交规范: 使用 husky + lint-staged + commitlint,遵循 Conventional Commits
- 📦 按需加载: 支持组件级 ESM 构建,减少打包体积
- 🔄 CI/CD 自动化: GitHub Actions 工作流,自动化测试、构建和发布
- 📋 版本管理: standard-version 自动生成 CHANGELOG,遵循语义化版本
- 🧪 完整测试覆盖: Jest + React Testing Library,支持组件单元测试
- 📚 组件文档: Storybook 集成,提供可视化组件文档
- 📄 API 文档: TypeDoc 自动生成 API 文档
安装
npm install dynamic-theme-component-library
# 或
yarn add dynamic-theme-component-library快速开始
基本使用
import React from 'react';
import { Button, ThemeProvider } from 'dynamic-theme-component-library';
function App() {
return (
<ThemeProvider>
<Button type="primary">主要按钮</Button>
<Button type="default">默认按钮</Button>
</ThemeProvider>
);
}
export default App;动态主题切换
import React from 'react';
import { Button, useThemeSwitcher } from 'dynamic-theme-component-library';
function ThemeDemo() {
const { switchToLightTheme, switchToDarkTheme, resetTheme } = useThemeSwitcher();
return (
<div>
<Button type="primary" onClick={switchToLightTheme}>
浅色主题
</Button>
<Button type="primary" onClick={switchToDarkTheme}>
深色主题
</Button>
<Button onClick={resetTheme}>
重置主题
</Button>
</div>
);
}自定义主题配置
import React from 'react';
import { Button, useThemeSwitcher } from 'dynamic-theme-component-library';
function CustomThemeDemo() {
const { switchToCustomTheme } = useThemeSwitcher();
const applyCustomTheme = () => {
switchToCustomTheme({
primaryColor: '#ff6b6b',
successColor: '#51cf66',
textColor: '#2b2d42',
backgroundColorBase: '#f8f9fa'
});
};
return (
<Button type="primary" onClick={applyCustomTheme}>
应用自定义主题
</Button>
);
}国际化
组件库内置支持多语言,默认提供中文(zh-CN)和英文(en-US):
import React from 'react';
import { Modal, i18n, Button } from 'dynamic-theme-component-library';
function App() {
const changeLanguage = (lng: string) => {
i18n.changeLanguage(lng);
};
return (
<div>
<Button onClick={() => changeLanguage('zh-CN')}>中文</Button>
<Button onClick={() => changeLanguage('en-US')}>English</Button>
<Modal visible={true} title="提示">
<p>这是模态框内容</p>
</Modal>
</div>
);
}使用 useTranslation Hook
import { useTranslation } from 'dynamic-theme-component-library';
function MyComponent() {
const { t } = useTranslation();
return (
<div>
<h1>{t('modal.title')}</h1>
</div>
);
}添加新语言
在 src/locales/ 目录下添加新的语言文件,并在 src/locales/index.ts 中注册:
按需加载
组件库支持按需加载,减少应用打包体积。提供两种使用方式:
方式一:ESM 模块直接导入 (推荐)
// 直接导入特定组件
import { Button } from 'dynamic-theme-component-library/dist/esm/Button';
import { Input } from 'dynamic-theme-component-library/dist/esm/Input';
// 使用组件
function App() {
return (
<>
<Button type="primary">按钮</Button>
<Input placeholder="请输入" />
</>
);
}方式二:通过构建工具配置
如果你的项目使用 Webpack 或 Rollup,可以通过配置别名实现自动按需加载:
// webpack.config.js
module.exports = {
resolve: {
alias: {
'dynamic-theme-component-library': 'dynamic-theme-component-library/dist/esm',
},
},
};注意事项
- 按需加载时,需要确保同时导入组件的样式文件
- 主题相关的 CSS 变量会自动注入,无需额外配置
- 对于 Tree Shaking,建议使用 ESM 构建版本
主题系统架构
令牌层级
组件库采用三层令牌设计:
- 基础令牌 (Base Tokens): 定义原始颜色、间距、字体等
- 语义令牌 (Semantic Tokens): 基于基础令牌定义语义变量
- 组件令牌 (Component Tokens): 组件级别的具体样式变量
CSS 变量支持
所有样式都使用 CSS 变量实现,支持运行时动态修改:
:root {
--primary-color: #1890ff;
--success-color: #52c41a;
--text-color: #262626;
--background-color-base: #fafafa;
/* ... 更多变量 */
}构建时主题定制
在 Webpack 配置中通过 less-loader 的 modifyVars 选项定制主题:
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
{
loader: 'less-loader',
options: {
lessOptions: {
modifyVars: {
'primary-color': '#ff6b6b',
'success-color': '#51cf66',
// 更多自定义变量
},
},
},
},
],
},
],
},
};组件
Button 按钮
支持多种类型、大小和状态:
import { Button } from 'dynamic-theme-component-library';
// 不同类型
<Button type="primary">主要按钮</Button>
<Button type="default">默认按钮</Button>
<Button type="danger">危险按钮</Button>
<Button type="link">链接按钮</Button>
// 不同大小
<Button size="large">大按钮</Button>
<Button size="middle">中按钮</Button>
<Button size="small">小按钮</Button>
// 状态
<Button disabled>禁用按钮</Button>
<Button loading>加载中</Button>API 参考
ThemeProvider
主题提供者组件,用于包装应用:
<ThemeProvider theme={customTheme}>
<App />
</ThemeProvider>useTheme Hook
获取当前主题状态和管理功能:
const { currentTheme, applyTheme, resetTheme } = useTheme();useThemeSwitcher Hook
提供主题切换功能:
const {
switchToLightTheme,
switchToDarkTheme,
switchToCustomTheme,
resetTheme
} = useThemeSwitcher();themeManager
直接的主题管理器实例:
import { themeManager } from 'dynamic-theme-component-library';
// 应用主题
themeManager.applyTheme(customTheme);
// 重置主题
themeManager.resetToDefault();
// 订阅主题变化
const unsubscribe = themeManager.subscribe((theme) => {
console.log('主题已更新:', theme);
});i18n 实例
i18n 实例,用于语言切换:
import { i18n } from 'dynamic-theme-component-library';
// 切换语言
i18n.changeLanguage('en-US');
// 获取当前语言
const currentLang = i18n.language;
// 监听语言变化
i18n.on('languageChanged', (lng) => {
console.log('语言已切换:', lng);
});useTranslation Hook
翻译 hook:
const { t } = useTranslation();
// 使用翻译
t('button.confirm'); // 确认
t('modal.okText'); // 确定
t('input.placeholder'); // 请输入开发
本地开发
# 安装依赖
npm install
# 启动开发服务器
npm run dev
# 启动 Storybook 开发环境
npm run storybook
# 访问 http://localhost:3000 或 http://localhost:6006代码质量
# 代码检查
npm run lint
# 自动修复代码风格
npm run lint:fix
# 代码格式化
npm run format
# 检查格式化
npm run format:check测试
# 运行测试
npm run test
# 生成测试覆盖率报告
npm run test -- --coverage构建
# 构建组件库 (CJS + ESM + 类型定义)
npm run build
# 构建 CJS 版本
npm run build:cjs
# 构建 ESM 版本 (支持按需加载)
npm run build:esm
# 构建类型定义
npm run build:types
# 构建 Storybook 文档
npm run build-storybook发布流程
# 生成新版本和更新 CHANGELOG
npm run release
# 发布补丁版本
npm run release:patch
# 发布次要版本
npm run release:minor
# 发布主要版本
npm run release:major
# 预览版本更新
npm run release:dry-run项目结构
dynamic-theme-component-library/
├── src/ # 源代码
│ ├── components/ # 组件目录
│ │ ├── Button/ # 按钮组件
│ │ ├── Input/ # 输入框组件
│ │ ├── Modal/ # 模态框组件
│ │ └── Select/ # 选择器组件
│ ├── theme/ # 主题系统
│ │ ├── tokens.less # 令牌定义
│ │ ├── component-variables.less # 组件变量
│ │ └── theme-manager.ts # 主题管理器
│ ├── hooks/ # React Hooks
│ │ └── useTheme.ts # 主题 Hook
│ ├── locales/ # 国际化
│ │ ├── index.ts # i18n 配置
│ │ ├── zh-CN.ts # 中文语言包
│ │ └── en-US.ts # 英文语言包
│ └── index.ts # 主入口文件
├── dist/ # 构建输出
│ ├── index.js # CJS 主入口
│ ├── index.d.ts # 类型定义
│ ├── esm/ # ESM 模块 (支持按需加载)
│ │ ├── index.js # ESM 主入口
│ │ ├── Button.js # 按钮组件独立包
│ │ ├── Input.js # 输入框组件独立包
│ │ ├── Modal.js # 模态框组件独立包
│ │ └── Select.js # 选择器组件独立包
│ └── components/ # 组件类型定义
├── demo/ # 演示应用
├── .storybook/ # Storybook 配置
├── .github/workflows/ # CI/CD 工作流
│ ├── ci.yml # 测试和构建工作流
│ └── release.yml # 发布工作流
├── .husky/ # Git hooks 配置
├── scripts/ # 构建脚本
├── coverage/ # 测试覆盖率报告
├── docs/ # API 文档 (TypeDoc 生成)
├── .eslintrc.js # ESLint 配置
├── .prettierrc.js # Prettier 配置
├── .commitlintrc.js # Commitlint 配置
├── .lintstagedrc.js # lint-staged 配置
├── .versionrc.json # standard-version 配置
├── CHANGELOG.md # 变更日志
├── jest.config.js # Jest 配置
├── webpack.config.js # Webpack 配置
├── package.json # 项目配置
└── README.md # 项目说明许可证
MIT License
贡献
欢迎为项目做出贡献!在提交贡献前,请确保:
开发流程
代码规范
- 代码提交前运行
npm run lint:fix自动修复代码风格 - 使用
npm run format格式化代码 - 确保所有测试通过
npm run test
- 代码提交前运行
提交规范
- 遵循 Conventional Commits 规范
- 提交信息格式:
type(scope): subject - 有效的类型:feat, fix, docs, style, refactor, test, chore, perf, ci, build, revert
分支管理
- 从
main分支创建功能分支 - 分支命名:
feat/xxx,fix/xxx,docs/xxx等 - 提交 Pull Request 前确保 CI 通过
- 从
测试要求
- 新增功能需包含相应测试用例
- 保持测试覆盖率不降低
- 组件变更需更新 Storybook 文档
报告问题
- 使用 Issue 模板报告 bug 或提出功能建议
- 提供复现步骤和预期行为
- 包含环境信息和版本号
提交 Pull Request
- Fork 项目并创建功能分支
- 实现功能或修复 bug
- 添加或更新测试用例
- 更新相关文档(README、Storybook 等)
- 运行完整测试流程
- 提交 Pull Request 并描述变更内容
我们使用自动化工具确保代码质量,所有提交都会经过 CI 检查。感谢您的贡献!
