Browse Source

feat: real dark (#4356)

* new dark

* change config  name

* merge master

* button use less var

* add popover config

* style: change less var

* better hove color

* new style

* use @ant-design/dark-theme

* add umi-plugin-antd-theme

* add theme config

* add  Welcome style

* better config for dark

* rm ThemeColorReplacer

* remove webpack-theme-color

* add load theme info

* fix test

* add test config

* rm more theme values

* remove unuse package
pull/5653/head
陈帅 6 years ago
committed by GitHub
parent
commit
4799ec156c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      azure-pipelines.yml
  2. 73
      config/config.ts
  3. 44
      config/plugin.config.ts
  4. 115
      config/themePluginConfig.ts
  5. 15
      package.json
  6. 7
      src/components/CopyBlock/index.less
  7. 2
      src/components/HeaderDropdown/index.less
  8. 4
      src/components/NoticeIcon/NoticeList.less
  9. 31
      src/components/SettingDrawer/themeColorClient.ts
  10. 8
      src/e2e/baseLayout.e2e.js
  11. 2
      src/e2e/topMenu.e2e.js
  12. 42
      src/models/setting.ts
  13. 8
      src/pages/Welcome.less
  14. 12
      src/pages/Welcome.tsx
  15. 4
      src/typings.d.ts
  16. 3
      tests/run-tests.js

3
azure-pipelines.yml

@ -39,6 +39,7 @@ jobs:
- script: npm run test:all
env:
PROGRESS: none
UMI_UI: none
displayName: test
- job: Windows
@ -55,6 +56,7 @@ jobs:
- script: npm run test:all
env:
PROGRESS: none
UMI_UI: none
displayName: test
- script: npm run build
env:
@ -75,4 +77,5 @@ jobs:
- script: npm run
env:
PROGRESS: none
UMI_UI: none
displayName: build

73
config/config.ts

@ -1,14 +1,17 @@
import { IConfig, IPlugin } from 'umi-types';
import defaultSettings from './defaultSettings'; // https://umijs.org/config/
import slash from 'slash2';
import webpackPlugin from './plugin.config';
import themePluginConfig from './themePluginConfig';
// import darkTheme from '@ant-design/dark-theme';
const { pwa, primaryColor } = defaultSettings;
// preview.pro.ant.design only do not use in your production ;
// preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。
const { ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION } = process.env;
const { ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION, TEST } = process.env;
const isAntDesignProPreview = ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site';
const plugins: IPlugin[] = [
[
'umi-plugin-react',
@ -37,8 +40,7 @@ const plugins: IPlugin[] = [
importWorkboxFrom: 'local',
},
}
: false,
// default close dll, because issue https://github.com/ant-design/ant-design-pro/issues/4665
: false, // default close dll, because issue https://github.com/ant-design/ant-design-pro/issues/4665
// dll features https://webpack.js.org/plugins/dll-plugin/
// dll: {
// include: ['dva', 'dva/router', 'dva/saga', 'dva/fetch'],
@ -55,15 +57,55 @@ const plugins: IPlugin[] = [
autoAddMenu: true,
},
],
]; // 针对 preview.pro.ant.design 的 GA 统计代码
];
if (isAntDesignProPreview) {
// 针对 preview.pro.ant.design 的 GA 统计代码
plugins.push([
'umi-plugin-ga',
{
code: 'UA-72788897-6',
},
]);
plugins.push(['umi-plugin-antd-theme', themePluginConfig]);
}
if (!TEST) {
plugins.push([
'umi-plugin-antd-theme',
{
theme: [
{
key: 'dark',
fileName: 'dark.css',
theme: 'dark',
},
{
key: 'dust',
fileName: 'dust.css',
modifyVars: {
'@primary-color': '#F5222D',
},
},
{
key: 'dust',
theme: 'dark',
fileName: 'dark-dust.css',
modifyVars: {
'@primary-color': '#F5222D',
},
},
{
key: 'volcano',
theme: 'dark',
fileName: 'dark-volcano.css',
modifyVars: {
'@primary-color': '#FA541C',
},
},
],
},
]);
}
export default {
@ -134,6 +176,7 @@ export default {
],
// Theme for antd: https://ant.design/docs/react/customize-theme-cn
theme: {
// ...darkTheme,
'primary-color': primaryColor,
},
define: {
@ -179,14 +222,12 @@ export default {
manifest: {
basePath: '/',
},
chainWebpack: webpackPlugin,
/*
proxy: {
'/server/api/': {
target: 'https://preview.pro.ant.design/',
changeOrigin: true,
pathRewrite: { '^/server': '' },
},
},
*/
// chainWebpack: webpackPlugin,
// proxy: {
// '/server/api/': {
// target: 'https://preview.pro.ant.design/',
// changeOrigin: true,
// pathRewrite: { '^/server': '' },
// },
// },
} as IConfig;

44
config/plugin.config.ts

@ -1,8 +1,3 @@
// Change theme plugin
// eslint-disable-next-line eslint-comments/abdeils - enable - pair;
/* eslint-disable import/no-extraneous-dependencies */
import ThemeColorReplacer from 'webpack-theme-color-replacer';
import generate from '@ant-design/colors/lib/generate';
import path from 'path';
function getModulePackageName(module: { context: string }) {
@ -25,33 +20,6 @@ function getModulePackageName(module: { context: string }) {
}
export default (config: any) => {
// preview.pro.ant.design only do not use in your production;
if (
process.env.ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site' ||
process.env.NODE_ENV !== 'production'
) {
config.plugin('webpack-theme-color-replacer').use(ThemeColorReplacer, [
{
fileName: 'css/theme-colors-[contenthash:8].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;
}
},
// isJsUgly: true,
},
]);
}
// optimize chunks
config.optimization
// share the same chunks across different modules
@ -90,15 +58,3 @@ export default (config: any) => {
},
});
};
const getAntdSerials = (color: string) => {
const lightNum = 9;
const devide10 = 10;
// 淡化(即less的tint)
const lightens = new Array(lightNum).fill(undefined).map((_, i: number) => {
return ThemeColorReplacer.varyColor.lighten(color, i / devide10);
});
const colorPalettes = generate(color);
const rgb = ThemeColorReplacer.varyColor.toNum3(color.replace('#', '')).join(',');
return lightens.concat(colorPalettes).concat(rgb);
};

115
config/themePluginConfig.ts

@ -0,0 +1,115 @@
export default {
theme: [
{
key: 'dark',
fileName: 'dark.css',
theme: 'dark',
},
{
key: 'dust',
fileName: 'dust.css',
modifyVars: {
'@primary-color': '#F5222D',
},
},
{
key: 'volcano',
fileName: 'volcano.css',
modifyVars: {
'@primary-color': '#FA541C',
},
},
{
key: 'sunset',
fileName: 'sunset.css',
modifyVars: {
'@primary-color': '#FAAD14',
},
},
{
key: 'cyan',
fileName: 'cyan.css',
modifyVars: {
'@primary-color': '#13C2C2',
},
},
{
key: 'green',
fileName: 'green.css',
modifyVars: {
'@primary-color': '#52C41A',
},
},
{
key: 'geekblue',
fileName: 'geekblue.css',
modifyVars: {
'@primary-color': '#2F54EB',
},
},
{
key: 'purple',
fileName: 'purple.css',
modifyVars: {
'@primary-color': '#722ED1',
},
},
{
key: 'dust',
theme: 'dark',
fileName: 'dark-dust.css',
modifyVars: {
'@primary-color': '#F5222D',
},
},
{
key: 'volcano',
theme: 'dark',
fileName: 'dark-volcano.css',
modifyVars: {
'@primary-color': '#FA541C',
},
},
{
key: 'sunset',
theme: 'dark',
fileName: 'dark-sunset.css',
modifyVars: {
'@primary-color': '#FAAD14',
},
},
{
key: 'cyan',
theme: 'dark',
fileName: 'dark-cyan.css',
modifyVars: {
'@primary-color': '#13C2C2',
},
},
{
key: 'green',
theme: 'dark',
fileName: 'dark-green.css',
modifyVars: {
'@primary-color': '#52C41A',
},
},
{
key: 'geekblue',
theme: 'dark',
fileName: 'dark-geekblue.css',
modifyVars: {
'@primary-color': '#2F54EB',
},
},
{
key: 'purple',
theme: 'dark',
fileName: 'dark-purple.css',
modifyVars: {
'@primary-color': '#722ED1',
},
},
],
};

15
package.json

@ -57,8 +57,8 @@
"not ie <= 10"
],
"dependencies": {
"@ant-design/colors": "^3.1.0",
"@ant-design/pro-layout": "^4.5.16",
"@ant-design/dark-theme": "1.0.3",
"@ant-design/pro-layout": "4.8.0",
"@antv/data-set": "^0.10.2",
"antd": "^3.23.6",
"classnames": "^2.2.6",
@ -73,12 +73,11 @@
"react-dom": "^16.8.6",
"react-helmet": "^5.2.1",
"redux": "^4.0.1",
"slash2": "^2.0.0",
"umi": "^2.9.6",
"umi-plugin-pro-block": "^1.3.4",
"umi-plugin-react": "^1.10.1",
"umi-request": "^1.2.7",
"webpack-theme-color-replacer": "^1.2.15"
"umi": "^2.8.7",
"umi-plugin-antd-theme": "^1.0.1",
"umi-plugin-pro-block": "^1.3.2",
"umi-plugin-react": "^1.9.5",
"umi-request": "^1.0.8"
},
"devDependencies": {
"@ant-design/pro-cli": "^1.0.13",

7
src/components/CopyBlock/index.less

@ -1,3 +1,5 @@
@import '~antd/es/style/themes/default.less';
.copy-block {
position: fixed;
right: 80px;
@ -10,10 +12,9 @@
width: 40px;
height: 40px;
font-size: 20px;
background: #fff;
background: @input-bg;
border-radius: 40px;
box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14),
0 1px 10px 0 rgba(0, 0, 0, 0.12);
box-shadow: @card-shadow;
cursor: pointer;
}

2
src/components/HeaderDropdown/index.less

@ -1,7 +1,7 @@
@import '~antd/es/style/themes/default.less';
.container > * {
background-color: #fff;
background-color: @popover-bg;
border-radius: 4px;
box-shadow: @shadow-1-down;
}

4
src/components/NoticeIcon/NoticeList.less

@ -92,9 +92,7 @@
cursor: pointer;
transition: all 0.3s;
user-select: none;
&:hover {
color: @heading-color;
}
&:only-child {
width: 100%;
}

31
src/components/SettingDrawer/themeColorClient.ts

@ -1,31 +0,0 @@
// eslint-disable-next-line eslint-comments/disable-enable-pair
/* eslint-disable import/no-extraneous-dependencies */
import client from 'webpack-theme-color-replacer/client';
import generate from '@ant-design/colors/lib/generate';
export default {
getAntdSerials(color: string): string[] {
const lightCount = 9;
const divide = 10;
// 淡化(即less的tint)
let lightens = new Array(lightCount).fill(0);
lightens = lightens.map((_, i) => client.varyColor.lighten(color, i / divide));
const colorPalettes = generate(color);
const rgb = client.varyColor.toNum3(color.replace('#', '')).join(',');
return lightens.concat(colorPalettes).concat(rgb);
},
changeColor(color?: string): Promise<void> {
if (!color) {
return Promise.resolve();
}
const options = {
// new colors array, one-to-one corresponde with `matchColors`
newColors: this.getAntdSerials(color),
changeUrl(cssUrl: string): string {
// while router is not `hash` mode, it needs absolute path
return `/${cssUrl}`;
},
};
return client.changer.changeColor(options, Promise);
},
};

8
src/e2e/baseLayout.e2e.js

@ -19,6 +19,13 @@ function formatter(routes, parentPath = '') {
return uniq(result.filter(item => !!item));
}
beforeAll(async () => {
await page.goto(`${BASE_URL}`);
await page.evaluate(() => {
localStorage.setItem('antd-pro-authority', '["admin"]');
});
});
describe('Ant Design Pro E2E test', () => {
const testPage = path => async () => {
await page.goto(`${BASE_URL}${path}`);
@ -32,7 +39,6 @@ describe('Ant Design Pro E2E test', () => {
};
const routers = formatter(RouterConfig);
console.log('routers', routers);
routers.forEach(route => {
it(`test pages ${route}`, testPage(route));
});

2
src/e2e/topMenu.e2e.js

@ -2,7 +2,7 @@ const BASE_URL = `http://localhost:${process.env.PORT || 8000}`;
describe('Homepage', () => {
it('topmenu should have footer', async () => {
const params = '/form/basic-form?navTheme=light&layout=topmenu';
const params = '?navTheme=light&layout=topmenu';
await page.goto(`${BASE_URL}${params}`);
await page.waitForSelector('footer', {
timeout: 2000,

42
src/models/setting.ts

@ -1,7 +1,5 @@
import { Reducer } from 'redux';
import { message } from 'antd';
import defaultSettings, { DefaultSettings } from '../../config/defaultSettings';
import themeColorClient from '../components/SettingDrawer/themeColorClient';
export interface SettingModelType {
namespace: 'settings';
@ -12,14 +10,6 @@ export interface SettingModelType {
};
}
const updateTheme = (newPrimaryColor?: string) => {
if (newPrimaryColor) {
const timeOut = 0;
const hideMessage = message.loading('正在切换主题!', timeOut);
themeColorClient.changeColor(newPrimaryColor).finally(() => hideMessage());
}
};
const updateColorWeak: (colorWeak: boolean) => void = colorWeak => {
const root = document.getElementById('root');
if (root) {
@ -37,14 +27,11 @@ const SettingModel: SettingModelType = {
Object.keys(state).forEach(key => {
if (urlParams.searchParams.has(key)) {
const value = urlParams.searchParams.get(key);
setting[key] = value === '1' ? true : value;
setting[key] = value;
}
});
const { primaryColor, colorWeak } = setting;
const { colorWeak } = setting;
if (primaryColor && state.primaryColor !== primaryColor) {
updateTheme(primaryColor);
}
updateColorWeak(!!colorWeak);
return {
...state,
@ -52,33 +39,12 @@ const SettingModel: SettingModelType = {
};
},
changeSetting(state = defaultSettings, { payload }) {
const urlParams = new URL(window.location.href);
Object.keys(defaultSettings).forEach(key => {
if (urlParams.searchParams.has(key)) {
urlParams.searchParams.delete(key);
}
});
Object.keys(payload).forEach(key => {
if (key === 'collapse') {
return;
}
let value = payload[key];
if (value === true) {
value = 1;
}
if (defaultSettings[key] !== value) {
urlParams.searchParams.set(key, value);
}
});
const { primaryColor, colorWeak, contentWidth } = payload;
if (primaryColor && state.primaryColor !== primaryColor) {
updateTheme(primaryColor);
}
const { colorWeak, contentWidth } = payload;
if (state.contentWidth !== contentWidth && window.dispatchEvent) {
window.dispatchEvent(new Event('resize'));
}
updateColorWeak(!!colorWeak);
window.history.replaceState(null, 'setting', urlParams.href);
return {
...state,
...payload,

8
src/pages/Welcome.less

@ -0,0 +1,8 @@
@import '~antd/lib/style/themes/default.less';
.pre {
margin: 12px 0;
padding: 12px 20px;
background: @input-bg;
box-shadow: @card-shadow;
}

12
src/pages/Welcome.tsx

@ -1,16 +1,12 @@
import React from 'react';
import { Card, Typography, Alert } from 'antd';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { FormattedMessage } from 'umi-plugin-react/locale';
import { Card, Typography, Alert } from 'antd';
import styles from './Welcome.less';
const CodePreview: React.FC<{}> = ({ children }) => (
<pre
style={{
background: '#f2f4f5',
padding: '12px 20px',
margin: '12px 0',
}}
>
<pre className={styles.pre}>
<code>
<Typography.Text copyable>{children}</Typography.Text>
</code>

4
src/typings.d.ts

@ -1,6 +1,4 @@
declare module 'slash2';
declare module 'antd-theme-webpack-plugin';
declare module '*.css';
declare module '*.less';
declare module '*.scss';
@ -17,8 +15,6 @@ declare module 'react-copy-to-clipboard';
declare module 'react-fittext';
declare module '@antv/data-set';
declare module 'nzh/cn';
declare module 'webpack-theme-color-replacer';
declare module 'webpack-theme-color-replacer/client';
// google analytics interface
interface GAFieldsObject {

3
tests/run-tests.js

@ -2,11 +2,14 @@
/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable eslint-comments/no-unlimited-disable */
const { spawn } = require('child_process');
// eslint-disable-next-line import/no-extraneous-dependencies
const { kill } = require('cross-port-killer');
const env = Object.create(process.env);
env.BROWSER = 'none';
env.TEST = true;
env.UMI_UI = 'none';
env.PROGRESS = 'none';
// flag to prevent multiple test
let once = false;

Loading…
Cancel
Save