diff --git a/package.json b/package.json
index 3dc9f73373e8..504f874753d8 100644
--- a/package.json
+++ b/package.json
@@ -160,9 +160,9 @@
"dist": "antd-tools run dist",
"compile": "antd-tools run compile",
"tsc": "tsc",
- "start": "cross-env NODE_ENV=development bisheng start -c ./site/bisheng.config.js --no-livereload",
+ "start": "cross-env NODE_ENV=development node ./scripts/generateColorLess.js && bisheng start -c ./site/bisheng.config.js --no-livereload",
"site": "cross-env NODE_ENV=production bisheng build --ssr -c ./site/bisheng.config.js",
- "deploy": "antd-tools run clean && npm run site && bisheng gh-pages --push-only",
+ "deploy": "antd-tools run clean && npm run site && node ./scripts/generateColorLess.js && bisheng gh-pages --push-only",
"pub": "antd-tools run pub",
"prepublish": "antd-tools run guard",
"pre-publish": "npm run test-all && node ./scripts/prepub",
diff --git a/scripts/generateColorLess.js b/scripts/generateColorLess.js
new file mode 100644
index 000000000000..0dcad3ac11a2
--- /dev/null
+++ b/scripts/generateColorLess.js
@@ -0,0 +1,95 @@
+#!/usr/bin/env node
+
+const fs = require('fs');
+const path = require('path');
+const glob = require('glob');
+const postcss = require('postcss');
+const less = require('less');
+
+const COLOR_MAP = {
+ '#ecf6fd': 'color(~`colorPalette("@{primary-color}", 1)`)', // @primary-1
+ '#d2eafb': 'color(~`colorPalette("@{primary-color}", 2)`)', // @primary-2
+ '#49a9ee': 'color(~`colorPalette("@{primary-color}", 5)`)', // @primary-5
+ '#108ee9': '@primary-color',
+ '#0e77ca': 'color(~`colorPalette("@{primary-color}", 7)`)', // @primary-7
+ '#40a5ed': 'tint(@primary-color, 20%)',
+ '#70bbf2': 'tint(@primary-color, 40%)',
+ '#88c7f4': 'tint(@primary-color, 50%)',
+ '#9fd2f6': 'tint(@primary-color, 60%)',
+ 'rgba(16, 142, 233, 0.2)': 'fadeout(@primary-color, 80%)',
+};
+
+const reducePlugin = postcss.plugin('reducePlugin', () => {
+ const cleanRule = (rule) => {
+ let removeRule = true;
+ rule.walkDecls((decl) => {
+ if (
+ !decl.prop.includes('color') &&
+ !decl.prop.includes('background') &&
+ !decl.prop.includes('border') &&
+ !decl.prop.includes('box-shadow')
+ ) {
+ decl.remove();
+ } else {
+ removeRule = false;
+ }
+ });
+ if (removeRule) {
+ rule.remove();
+ }
+ };
+ return (css) => {
+ css.walkAtRules((atRule) => {
+ atRule.remove();
+ });
+
+ css.walkRules(cleanRule);
+
+ css.walkComments(c => c.remove());
+ };
+});
+
+async function generateCss() {
+ const antd = path.resolve(__dirname, '../');
+ const entry = path.join(antd, 'components/style/index.less');
+ let content = fs.readFileSync(entry).toString();
+ const styles = glob.sync(path.join(antd, 'components/*/style/index.less'));
+ content += '\n';
+ styles.forEach((style) => {
+ content += `@import "${style}";\n`;
+ });
+ content += `@import "${path.join(antd, 'site/theme/static/index.less')}";\n`;
+ fs.writeFileSync('/tmp/style.less', content);
+
+ let result = (await less.render.call(less, content, {
+ paths: [path.join(antd, 'components/style')],
+ })).css;
+
+ result = (await postcss([
+ reducePlugin,
+ ]).process(result, { parser: less.parser, from: entry })).css;
+
+ Object.keys(COLOR_MAP).forEach((key) => {
+ result = result.replace(new RegExp(key, 'g'), COLOR_MAP[key]);
+ });
+
+ const bezierEasing = fs.readFileSync(path.join(antd, 'components/style/color/bezierEasing.less')).toString();
+ const tinyColor = fs.readFileSync(path.join(antd, 'components/style/color/tinyColor.less')).toString();
+ const colorPalette = fs.readFileSync(path.join(antd, 'components/style/color/colorPalette.less'))
+ .toString()
+ .replace('@import "bezierEasing";', '')
+ .replace('@import "tinyColor";', '');
+
+ result = `${colorPalette}\n${result}`;
+ result = `${tinyColor}\n${result}`;
+ result = `${bezierEasing}\n${result}`;
+ result = `@primary-color: #108ee9;\n${result}`;
+
+ const siteDir = path.resolve(__dirname, '../_site');
+ if (!fs.existsSync(siteDir)) {
+ fs.mkdirSync(siteDir);
+ }
+ fs.writeFileSync(path.resolve(__dirname, '../_site/color.less'), result);
+}
+
+generateCss();
diff --git a/site/theme/static/template.html b/site/theme/static/template.html
index 8f6db60736b7..dc2f58a09b69 100644
--- a/site/theme/static/template.html
+++ b/site/theme/static/template.html
@@ -61,6 +61,7 @@
+
diff --git a/site/theme/template/Layout/Footer.jsx b/site/theme/template/Layout/Footer.jsx
index 32dea35339f7..655e46c779d7 100644
--- a/site/theme/template/Layout/Footer.jsx
+++ b/site/theme/template/Layout/Footer.jsx
@@ -1,14 +1,15 @@
import React from 'react';
import { FormattedMessage, injectIntl } from 'react-intl';
import { Modal, Icon, message } from 'antd';
-import reqwest from 'reqwest';
-import { isLocalStorageNameSupported } from '../utils';
+import { isLocalStorageNameSupported, loadScript } from '../utils';
import ColorPicker from '../Color/ColorPicker';
class Footer extends React.Component {
constructor(props) {
super(props);
+ this.lessLoaded = false;
+
this.state = {
color: '#108ee9',
};
@@ -32,23 +33,29 @@ class Footer extends React.Component {
}
handleColorChange = (color) => {
- const { messages } = this.props.intl;
- reqwest({
- url: 'https://ant-design-theme.now.sh/compile',
- method: 'post',
- data: {
- variables: {
- '@primary-color': color,
- },
- },
- }).then((data) => {
- message.success(messages['app.footer.primary-color-changed']);
- this.setState({ color });
- const head = document.querySelector('head');
- const style = document.createElement('style');
- style.innerText = data;
- head.appendChild(style);
- });
+ const changeColor = () => {
+ const { messages } = this.props.intl;
+ window.less.modifyVars({
+ '@primary-color': color,
+ }).then(() => {
+ message.success(messages['app.footer.primary-color-changed']);
+ this.setState({ color });
+ });
+ };
+
+ const lessUrl = 'https://cdnjs.cloudflare.com/ajax/libs/less.js/2.7.2/less.min.js';
+
+ if (this.lessLoaded) {
+ changeColor();
+ } else {
+ window.less = {
+ async: true,
+ };
+ loadScript(lessUrl).then(() => {
+ this.lessLoaded = true;
+ changeColor();
+ });
+ }
}
infoNewVersion() {
diff --git a/site/theme/template/utils.jsx b/site/theme/template/utils.jsx
index a9125a277592..bb9104dbb9d6 100644
--- a/site/theme/template/utils.jsx
+++ b/site/theme/template/utils.jsx
@@ -64,3 +64,14 @@ export function isLocalStorageNameSupported() {
return false;
}
}
+
+export function loadScript(src) {
+ return new Promise((resolve, reject) => {
+ const script = document.createElement('script');
+ script.type = 'text/javascript';
+ script.src = src;
+ script.onload = resolve;
+ script.onerror = reject;
+ document.head.appendChild(script);
+ });
+}