diff --git a/config/plugin.config.ts b/config/plugin.config.ts index d9d150bc00cf6ee07e40baf3a86ab7fbc8073dbd..806c344d4187987bcbcc0d5eae0a91e05a6ee7f1 100644 --- a/config/plugin.config.ts +++ b/config/plugin.config.ts @@ -1,8 +1,10 @@ // Change theme plugin -import MergeLessPlugin from 'antd-pro-merge-less'; -import AntDesignThemePlugin from 'antd-theme-webpack-plugin'; +// import MergeLessPlugin from 'antd-pro-merge-less'; +// import AntDesignThemePlugin from 'antd-theme-webpack-plugin'; +import ThemeColorReplacer from 'webpack-theme-color-replacer'; import path from 'path'; +import generate from '@ant-design/colors/lib/generate'; function getModulePackageName(module: { context: string }) { if (!module.context) return null; @@ -30,27 +32,45 @@ export default (config: any) => { process.env.NODE_ENV !== 'production' ) { // 将所有 less 合并为一个供 themePlugin使用 - const outFile = path.join(__dirname, '../.temp/ant-design-pro.less'); - const stylesDir = path.join(__dirname, '../src/'); + // const outFile = path.join(__dirname, '../.temp/ant-design-pro.less'); + // 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, - outFile, - }, - ]); - - 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', + fileName: 'css/theme-colors.css', + 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', + // }, + // ]); } // optimize chunks config.optimization @@ -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); +} diff --git a/package.json b/package.json index 627dd7227b82a1459049047bafe89b2e69a9dd1b..cece9f918ad62a1fee3450df076f61dbd5561deb 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,7 @@ "@types/react-document-title": "^2.0.3", "@types/react-dom": "^16.8.4", "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", "chalk": "^2.4.2", "check-prettier": "^1.0.3", @@ -131,7 +131,8 @@ "tslint": "^5.17.0", "tslint-config-prettier": "^1.18.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": { "puppeteer": "^1.17.0" @@ -174,4 +175,4 @@ "create-umi" ] } -} \ No newline at end of file +} diff --git a/src/components/SettingDrawer/themeColorClient.js b/src/components/SettingDrawer/themeColorClient.js new file mode 100644 index 0000000000000000000000000000000000000000..a0e476dece71ebc3c47cf2cebfd791f77b02ea42 --- /dev/null +++ b/src/components/SettingDrawer/themeColorClient.js @@ -0,0 +1,26 @@ +/* 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; + }, +}; diff --git a/src/models/setting.ts b/src/models/setting.ts index a5a278ae897862c362c09fb50dad54b06c59c5c7..d0d76da7b31cba322c4053dacb6b1df8ff002ee9 100644 --- a/src/models/setting.ts +++ b/src/models/setting.ts @@ -1,6 +1,7 @@ import { message } from 'antd'; import { Reducer } from 'redux'; import defaultSettings, { DefaultSettings } from '../../config/defaultSettings'; +import themeColorClient from '../components/SettingDrawer/themeColorClient'; export interface SettingModelType { namespace: 'settings'; @@ -10,6 +11,14 @@ export interface SettingModelType { changeSetting: Reducer; }; } + +const updateTheme = (newPrimaryColor?: string) => { + const timeOut = 0; + const hideMessage = message.loading('正在切换主题!', timeOut); + themeColorClient.changeColor(newPrimaryColor).finally(() => hideMessage()); +}; + +/* let lessNodesAppended: boolean; const updateTheme: (primaryColor?: string) => void = primaryColor => { @@ -71,6 +80,7 @@ const updateTheme: (primaryColor?: string) => void = primaryColor => { buildIt(); } }; +*/ const updateColorWeak: (colorWeak: boolean) => void = colorWeak => { const root = document.getElementById('root');