Unverified Commit 3916692c authored by 陈帅's avatar 陈帅 Committed by GitHub

Merge pull request #4289 from hzsrc/master

高性能方案实现ant-design在运行时动态改变主题色(利用webpack-theme-color-replacer)
parents a775889e 2ba7d715
// Change theme plugin // Change theme plugin
import MergeLessPlugin from 'antd-pro-merge-less'; // import MergeLessPlugin from 'antd-pro-merge-less';
import AntDesignThemePlugin from 'antd-theme-webpack-plugin'; // import AntDesignThemePlugin from 'antd-theme-webpack-plugin';
import ThemeColorReplacer from 'webpack-theme-color-replacer';
import path from 'path'; import path from 'path';
import generate from '@ant-design/colors/lib/generate';
function getModulePackageName(module: { context: string }) { function getModulePackageName(module: { context: string }) {
if (!module.context) return null; if (!module.context) return null;
...@@ -30,27 +32,45 @@ export default (config: any) => { ...@@ -30,27 +32,45 @@ export default (config: any) => {
process.env.NODE_ENV !== 'production' process.env.NODE_ENV !== 'production'
) { ) {
// 将所有 less 合并为一个供 themePlugin使用 // 将所有 less 合并为一个供 themePlugin使用
const outFile = path.join(__dirname, '../.temp/ant-design-pro.less'); // const outFile = path.join(__dirname, '../.temp/ant-design-pro.less');
const stylesDir = path.join(__dirname, '../src/'); // const stylesDir = path.join(__dirname, '../src/');
config.plugin('merge-less').use(MergeLessPlugin, [ // config.plugin('merge-less').use(MergeLessPlugin, [
// {
// stylesDir,
// outFile,
// },
// ]);
config.plugin('webpack-theme-color-replacer').use(ThemeColorReplacer, [
{ {
stylesDir, fileName: 'css/theme-colors.css',
outFile, matchColors: getAntdSerials('#1890ff'), // 主色系列
// 改变样式选择器,解决样式覆盖问题
changeSelector(selector: string): string {
switch (selector) {
case '.ant-calendar-today .ant-calendar-date':
return ':not(.ant-calendar-selected-date)' + selector;
case '.ant-btn:focus,.ant-btn:hover':
return '.ant-btn:focus:not(.ant-btn-primary),.ant-btn:hover:not(.ant-btn-primary)';
case '.ant-btn.active,.ant-btn:active':
return '.ant-btn.active:not(.ant-btn-primary),.ant-btn:active:not(.ant-btn-primary)';
default:
return selector;
}
}, },
]);
config.plugin('ant-design-theme').use(AntDesignThemePlugin, [
{
antDir: path.join(__dirname, '../node_modules/antd'),
stylesDir,
varFile: path.join(__dirname, '../node_modules/antd/lib/style/themes/default.less'),
mainLessFile: outFile, // themeVariables: ['@primary-color'],
indexFileName: 'index.html',
generateOne: true,
lessUrl: 'https://gw.alipayobjects.com/os/lib/less.js/3.8.1/less.min.js',
}, },
]); ]);
// config.plugin('ant-design-theme').use(AntDesignThemePlugin, [
// {
// antDir: path.join(__dirname, '../node_modules/antd'),
// stylesDir,
// varFile: path.join(__dirname, '../node_modules/antd/lib/style/themes/default.less'),
// mainLessFile: outFile, // themeVariables: ['@primary-color'],
// indexFileName: 'index.html',
// generateOne: true,
// lessUrl: 'https://gw.alipayobjects.com/os/lib/less.js/3.8.1/less.min.js',
// },
// ]);
} }
// optimize chunks // optimize chunks
config.optimization config.optimization
...@@ -82,3 +102,14 @@ export default (config: any) => { ...@@ -82,3 +102,14 @@ export default (config: any) => {
}, },
}); });
}; };
const getAntdSerials = (color: string) => {
const lightNum = 9;
const devide10 = 10;
// 淡化(即less的tint)
const lightens = new Array(lightNum).fill().map((t, i) => {
return ThemeColorReplacer.varyColor.lighten(color, i / devide10);
});
const colorPalettes = generate(color);
return lightens.concat(colorPalettes);
}
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
"@types/react-document-title": "^2.0.3", "@types/react-document-title": "^2.0.3",
"@types/react-dom": "^16.8.4", "@types/react-dom": "^16.8.4",
"antd-pro-merge-less": "^1.0.0", "antd-pro-merge-less": "^1.0.0",
"antd-theme-webpack-plugin": "^1.2.0", "@ant-design/colors": "^3.1.0",
"babel-eslint": "^10.0.1", "babel-eslint": "^10.0.1",
"chalk": "^2.4.2", "chalk": "^2.4.2",
"check-prettier": "^1.0.3", "check-prettier": "^1.0.3",
...@@ -131,7 +131,8 @@ ...@@ -131,7 +131,8 @@
"tslint": "^5.17.0", "tslint": "^5.17.0",
"tslint-config-prettier": "^1.18.0", "tslint-config-prettier": "^1.18.0",
"tslint-eslint-rules": "^5.4.0", "tslint-eslint-rules": "^5.4.0",
"tslint-react": "^4.0.0" "tslint-react": "^4.0.0",
"webpack-theme-color-replacer": "^1.1.5"
}, },
"optionalDependencies": { "optionalDependencies": {
"puppeteer": "^1.17.0" "puppeteer": "^1.17.0"
......
/* eslint-disable import/no-extraneous-dependencies */
import generate from '@ant-design/colors/lib/generate';
import client from 'webpack-theme-color-replacer/client';
export default {
primaryColor: '#1890ff',
getAntdSerials(color) {
// 淡化(即less的tint)
const lightens = new Array(9).fill().map((t, i) => {
return client.varyColor.lighten(color, i / 10);
});
const colorPalettes = generate(color);
return lightens.concat(colorPalettes);
},
changeColor(newColor) {
const lastColor = this.lastColor || this.primaryColor;
const options = {
cssUrl: '/css/theme-colors.css', // hash模式下用相对路径
oldColors: this.getAntdSerials(lastColor), // current colors array. The same as `matchColors`
newColors: this.getAntdSerials(newColor || this.primaryColor), // new colors array, one-to-one corresponde with `oldColors`
};
const promise = client.changer.changeColor(options, Promise);
this.lastColor = lastColor;
return promise;
},
};
import { message } from 'antd'; import { message } from 'antd';
import { Reducer } from 'redux'; import { Reducer } from 'redux';
import defaultSettings, { DefaultSettings } from '../../config/defaultSettings'; import defaultSettings, { DefaultSettings } from '../../config/defaultSettings';
import themeColorClient from '../components/SettingDrawer/themeColorClient';
export interface SettingModelType { export interface SettingModelType {
namespace: 'settings'; namespace: 'settings';
...@@ -10,6 +11,14 @@ export interface SettingModelType { ...@@ -10,6 +11,14 @@ export interface SettingModelType {
changeSetting: Reducer<DefaultSettings>; changeSetting: Reducer<DefaultSettings>;
}; };
} }
const updateTheme = (newPrimaryColor?: string) => {
const timeOut = 0;
const hideMessage = message.loading('正在切换主题!', timeOut);
themeColorClient.changeColor(newPrimaryColor).finally(() => hideMessage());
};
/*
let lessNodesAppended: boolean; let lessNodesAppended: boolean;
const updateTheme: (primaryColor?: string) => void = primaryColor => { const updateTheme: (primaryColor?: string) => void = primaryColor => {
...@@ -71,6 +80,7 @@ const updateTheme: (primaryColor?: string) => void = primaryColor => { ...@@ -71,6 +80,7 @@ const updateTheme: (primaryColor?: string) => void = primaryColor => {
buildIt(); buildIt();
} }
}; };
*/
const updateColorWeak: (colorWeak: boolean) => void = colorWeak => { const updateColorWeak: (colorWeak: boolean) => void = colorWeak => {
const root = document.getElementById('root'); const root = document.getElementById('root');
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment