diff --git a/README.fr-FR.md b/README.fr-FR.md index 6ebb306b..a228c54e 100644 --- a/README.fr-FR.md +++ b/README.fr-FR.md @@ -128,3 +128,10 @@ Toute forme de contribution est la bienvenue, voici quelques exemples de façons - Utiliser Ant Design Pro dans votre travail quotidien. - Soumettre des [issues](http://github.com/ant-design/ant-design-pro/issues) pour reporter les bugs ou poser des questions. - Proposer des [pull requests](http://github.com/ant-design/ant-design-pro/pulls) pour améliorer notre code. + + +
+ + + +
\ No newline at end of file diff --git a/README.ja-JP.md b/README.ja-JP.md index b1217775..e02077d7 100644 --- a/README.ja-JP.md +++ b/README.ja-JP.md @@ -130,3 +130,9 @@ Gitpod(GitHub 用の無料オンライン開発環境)でプロジェクト - 更新すること。 改善を、[pull requests](http://github.com/ant-design/ant-design-pro/pulls) で送ってください。 [![DevDependencies](https://img.shields.io/david/dev/ant-design/ant-design-pro.svg)](https://david-dm.org/ant-design/ant-design-pro?type=dev) + +
+ + + +
\ No newline at end of file diff --git a/README.md b/README.md index 233095a4..65625f8d 100644 --- a/README.md +++ b/README.md @@ -130,3 +130,9 @@ Any type of contribution is welcome, here are some examples of how you may contr - Use Ant Design Pro in your daily work. - Submit [issues](http://github.com/ant-design/ant-design-pro/issues) to report bugs or ask questions. - Propose [pull requests](http://github.com/ant-design/ant-design-pro/pulls) to improve our code. + +
+ + + +
\ No newline at end of file diff --git a/README.ru-RU.md b/README.ru-RU.md index 804c9828..3c084cb5 100644 --- a/README.ru-RU.md +++ b/README.ru-RU.md @@ -94,3 +94,9 @@ $ npm start # visit http://localhost:8000 - Использовать Ant Design Pro в ежедневной работе. - Создавать [задачи](http://github.com/ant-design/ant-design-pro/issues) заводить баги или отвечать на вопросы. - Делать [pull-реквесты](http://github.com/ant-design/ant-design-pro/pulls) для совершенствования нашего кода. + +
+ + + +
diff --git a/README.tr-TR.md b/README.tr-TR.md index 82921ab7..ec2b6632 100644 --- a/README.tr-TR.md +++ b/README.tr-TR.md @@ -122,3 +122,9 @@ Her türlü desteğinize açığız, bu projeye nasıl katkıda bulunabileceğin - Günlük işinizde Ant Design Pro kullanın. - Hataları bildirmek veya soru sormak için [issues](http://github.com/ant-design/ant-design-pro/issues) gönderin. - kodumuzu geliştirmek için [pull requests](http://github.com/ant-design/ant-design-pro/pulls) gönderin. + +
+ + + +
diff --git a/README.zh-CN.md b/README.zh-CN.md index 9e020581..d66d7d03 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -120,3 +120,9 @@ $ npm run docker-prod:build - 在你的公司或个人项目中使用 Ant Design Pro。 - 通过 [Issue](http://github.com/ant-design/ant-design-pro/issues) 报告 bug 或进行咨询。 - 提交 [Pull Request](http://github.com/ant-design/ant-design-pro/pulls) 改进 Pro 的代码。 + +
+ + + +
diff --git a/config/config.ts b/config/config.ts index f8650cab..ee881103 100644 --- a/config/config.ts +++ b/config/config.ts @@ -5,6 +5,7 @@ import defaultSettings from './defaultSettings'; import os from 'os'; import slash from 'slash2'; import webpackPlugin from './plugin.config'; + const { pwa, primaryColor } = defaultSettings; // preview.pro.ant.design only do not use in your production ; diff --git a/config/plugin.config.ts b/config/plugin.config.ts index c76b333c..7044fed3 100644 --- a/config/plugin.config.ts +++ b/config/plugin.config.ts @@ -1,7 +1,8 @@ // Change theme plugin - -import AntDesignThemePlugin from 'antd-theme-webpack-plugin'; -import MergeLessPlugin from 'antd-pro-merge-less'; +// 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 }) { @@ -30,27 +31,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/'); - - config.plugin('merge-less').use(MergeLessPlugin, [ - { - stylesDir, - outFile, - }, - ]); + // const outFile = path.join(__dirname, '../.temp/ant-design-pro.less'); + // const stylesDir = path.join(__dirname, '../src/'); - config.plugin('ant-design-theme').use(AntDesignThemePlugin, [ + // config.plugin('merge-less').use(MergeLessPlugin, [ + // { + // stylesDir, + // outFile, + // }, + // ]); + config.plugin('webpack-theme-color-replacer').use(ThemeColorReplacer, [ { - 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 +101,14 @@ 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); + return lightens.concat(colorPalettes); +}; diff --git a/create-umi/README.md b/create-umi/README.md deleted file mode 100644 index 14c3286a..00000000 --- a/create-umi/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# Ant Design Pro - -This project is initialized with [Ant Design Pro](https://pro.ant.design). Follow is the quick guide for how to use. - -## Environment Prepare - -Install `node_modules`: -```bash -npm install -``` - -or - -```bash -yarn -``` - -## Provided Scripts - -Ant Design Pro provides some useful script to help you quick start and build with web project, code style check and test. - -Scripts provided in `package.json`. It's safe to modify or add additional script: - -### Start project - -```bash -npm start -``` - -### Build project - -```bash -npm run build -``` - -### Check code style - -```bash -npm run lint -``` - -You can also use script to auto fix some lint error: - -```bash -npm run lint:fix -``` - -### Test code - -```bash -npm test -``` - -## More - -You can view full document on our [official website](https://pro.ant.design). And welcome any feedback in our [github](https://github.com/ant-design/ant-design-pro). \ No newline at end of file diff --git a/package.json b/package.json index 6fb4d8ad..2accece5 100644 --- a/package.json +++ b/package.json @@ -14,9 +14,9 @@ "docker:push": "npm run docker-hub:build && npm run docker:tag && docker push antdesign/ant-design-pro", "docker:tag": "docker tag ant-design-pro antdesign/ant-design-pro", "fetch:blocks": "node ./scripts/fetch-blocks.js", + "format-imports": "import-sort --write '**/*.{js,jsx,ts,tsx}'", "functions:build": "netlify-lambda build ./lambda", "functions:run": "cross-env NODE_ENV=dev netlify-lambda serve ./lambda", - "generateMock": "node ./scripts/generateMock", "lint": "npm run lint:js && npm run lint:style && npm run lint:prettier", "lint-staged": "lint-staged", "lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx ", @@ -30,8 +30,7 @@ "start:no-mock": "cross-env MOCK=none umi dev", "test": "umi test", "test:all": "node ./tests/run-tests.js", - "test:component": "umi test ./src/components", - "format-imports": "import-sort --write '**/*.{js,jsx,ts,tsx}'" + "test:component": "umi test ./src/components" }, "husky": { "hooks": { @@ -40,11 +39,11 @@ }, "lint-staged": { "**/*.less": "stylelint --syntax less", - "**/*.{js,ts,tsx}": "npm run lint-staged:js", "**/*.{js,ts,tsx,md,json,jsx,less}": [ "npm run prettier", "git add" - ] + ], + "**/*.{js,ts,tsx}": "npm run lint-staged:js" }, "browserslist": [ "> 1%", @@ -82,6 +81,7 @@ "umi-request": "^1.0.7" }, "devDependencies": { + "@ant-design/colors": "^3.1.0", "@types/classnames": "^2.2.7", "@types/history": "^4.7.2", "@types/jest": "^24.0.13", @@ -92,7 +92,6 @@ "@types/react-dom": "^16.8.4", "@typescript-eslint/eslint-plugin": "^1.9.0", "antd-pro-merge-less": "^1.0.0", - "antd-theme-webpack-plugin": "^1.2.0", "babel-eslint": "^10.0.1", "chalk": "^2.4.2", "check-prettier": "^1.0.3", @@ -137,7 +136,12 @@ "stylelint-config-rational-order": "^0.1.2", "stylelint-config-standard": "^18.3.0", "stylelint-declaration-block-no-ignored-properties": "^2.1.0", - "stylelint-order": "^3.0.0" + "stylelint-order": "^3.0.0", + "tslint": "^5.17.0", + "tslint-config-prettier": "^1.18.0", + "tslint-eslint-rules": "^5.4.0", + "tslint-react": "^4.0.0", + "webpack-theme-color-replacer": "^1.1.5" }, "optionalDependencies": { "puppeteer": "^1.17.0" @@ -153,15 +157,16 @@ "scripts/**/*.js" ], "create-umi": { - "copy": [ - [ - "create-umi/README.md", - "README.md" - ], - [ - "create-umi/package.json", - "package.json" - ] + "ignoreScript": [ + "docker*", + "functions*", + "site", + "generateMock" + ], + "ignoreDependencies": [ + "netlify*", + "serverless", + "express" ], "ignore": [ ".dockerignore", @@ -174,7 +179,6 @@ "LICENSE", "netlify.toml", "README.*.md", - "scripts", "azure-pipelines.yml", "docker", "create-umi" diff --git a/src/components/Authorized/PromiseRender.tsx b/src/components/Authorized/PromiseRender.tsx index c990df3c..4f0c7df8 100644 --- a/src/components/Authorized/PromiseRender.tsx +++ b/src/components/Authorized/PromiseRender.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { Spin } from 'antd'; -// eslint-disable-next-line import/no-cycle import isEqual from 'lodash/isEqual'; import { isComponentClass } from './Secured'; +// eslint-disable-next-line import/no-cycle interface PromiseRenderProps { ok: T; diff --git a/src/components/SettingDrawer/themeColorClient.js b/src/components/SettingDrawer/themeColorClient.js new file mode 100644 index 00000000..1302e5f4 --- /dev/null +++ b/src/components/SettingDrawer/themeColorClient.js @@ -0,0 +1,27 @@ +// 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 { + 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/layouts/BasicLayout.tsx b/src/layouts/BasicLayout.tsx index 4165cef2..d146ddd0 100644 --- a/src/layouts/BasicLayout.tsx +++ b/src/layouts/BasicLayout.tsx @@ -19,6 +19,7 @@ import RightContent from '@/components/GlobalHeader/RightContent'; import { connect } from 'dva'; import { formatMessage } from 'umi-plugin-react/locale'; import logo from '../assets/logo.svg'; +import { isAntDesignPro } from '@/utils/utils'; export interface BasicLayoutProps extends ProLayoutComponentsProps, ConnectProps { breadcrumbNameMap: { @@ -37,11 +38,39 @@ export type BasicLayoutContext = { [K in 'location']: BasicLayoutProps[K] } & { const menuDataRender = (menuList: MenuDataItem[]): MenuDataItem[] => { return menuList.map(item => { - const localItem = { ...item, children: item.children ? menuDataRender(item.children) : [] }; + const localItem = { + ...item, + children: item.children ? menuDataRender(item.children) : [], + }; return Authorized.check(item.authority, localItem, null) as MenuDataItem; }); }; +const footerRender: BasicLayoutProps['footerRender'] = (_, defaultDom) => { + if (!isAntDesignPro()) { + return defaultDom; + } + return ( + <> + {defaultDom} +
+ + netlify logo + +
+ + ); +}; + const BasicLayout: React.FC = props => { const { dispatch, children, settings } = props; /** @@ -88,6 +117,7 @@ const BasicLayout: React.FC = props => { ...routers, ]; }} + footerRender={footerRender} menuDataRender={menuDataRender} formatMessage={formatMessage} rightContentRender={rightProps => } diff --git a/src/models/setting.ts b/src/models/setting.ts index fd43803d..aa6af6a1 100644 --- a/src/models/setting.ts +++ b/src/models/setting.ts @@ -1,6 +1,9 @@ -import { Reducer } from 'redux'; +// eslint-disable-next-line eslint-comments/disable-enable-pair +/* eslint-disable promise/catch-or-return */ 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 +13,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 => { @@ -72,6 +83,7 @@ const updateTheme: (primaryColor?: string) => void = primaryColor => { buildIt(); } }; +*/ const updateColorWeak: (colorWeak: boolean) => void = colorWeak => { const root = document.getElementById('root'); diff --git a/src/typings.d.ts b/src/typings.d.ts index d32d9d23..4c77556c 100644 --- a/src/typings.d.ts +++ b/src/typings.d.ts @@ -19,6 +19,7 @@ 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'; // preview.pro.ant.design only do not use in your production ; // preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。 diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 5516e12e..e7c70ce3 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -1,18 +1,24 @@ /* eslint no-useless-escape:0 import/prefer-default-export:0 */ const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/; -export function isUrl(path: string): string { +const isUrl = (path: string): boolean => { return reg.test(path); -} +}; -// 给官方演示站点用,用于关闭真实开发环境不需要使用的特性 -export function isAntDesignProOrDev(): boolean { - const { NODE_ENV } = process.env; +const isAntDesignPro = (): boolean => { if (ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site') { return true; } + return window.location.hostname === 'preview.pro.ant.design'; +}; + +// 给官方演示站点用,用于关闭真实开发环境不需要使用的特性 +const isAntDesignProOrDev = (): boolean => { + const { NODE_ENV } = process.env; if (NODE_ENV === 'development') { return true; } - return window.location.hostname === 'preview.pro.ant.design'; -} + return isAntDesignPro(); +}; + +export { isAntDesignProOrDev, isAntDesignPro, isUrl };