mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-23 18:50:06 +08:00
Add variable.less
to support css variable (#31496)
* chore: use varaible.less * chore: basic primary varaible * chore: Move to variable * chore: align active color * chore: global fix of css variable * chore: primary colors * chore: button danger * chore: btn default error color * chore: button series * chore: More examples * chore: More components * chore: Form demo * chore: form style * fix: Tag & Alert variable * chore: update footer * chore: rm tmp code * chore: transfer * fix: picker column active color * chore: Adjust active bg color * chore: table hover color * chore: all css variables * chore: Global using variables * chore: Test case * chore: Update test logic * chore: back of default less * chore: entry of site use proxy style * chore: update entry * chore: split of variables * refactor: quick dist speed * fix: site use variable version * chore: Update less config * chore: add mv script * chore: Update repalcement script * chore: Add inject variables * chore: Update script * fix: script path * chore: Move to component instead * chore: fix condition * chore: update config * chore: Update in less transform * chore: Modify logic * chore: change to variables * chore: Update name * fix: script name * chore: do inject * revert: back of path * chore: 2 way of generate * bump tools * chore: Add auto replacement script * chore: auto genrate less file * chore: fix test * test: More test case * chore: Update limit config * test: coverage * docs: Update doc
This commit is contained in:
parent
9c17f94cab
commit
36bcaaef85
@ -90,6 +90,7 @@ function finalizeDist() {
|
||||
buildThemeFile('default', defaultVars);
|
||||
buildThemeFile('dark', darkVars);
|
||||
buildThemeFile('compact', compactVars);
|
||||
buildThemeFile('variable', {});
|
||||
fs.writeFileSync(
|
||||
path.join(process.cwd(), 'dist', `theme.js`),
|
||||
`
|
||||
@ -125,8 +126,56 @@ module.exports = {
|
||||
}
|
||||
}
|
||||
|
||||
function isComponentStyle(file) {
|
||||
return file.path.match(/style(\/|\\)index\.tsx/);
|
||||
}
|
||||
|
||||
function needTransformStyle(content) {
|
||||
return content.includes('./index.less');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
compile: {
|
||||
transformTSFile(file) {
|
||||
if (isComponentStyle(file)) {
|
||||
let content = file.contents.toString();
|
||||
|
||||
if (needTransformStyle(content)) {
|
||||
const cloneFile = file.clone();
|
||||
|
||||
// Origin
|
||||
content = content.replace('./index.less', './index-default.less');
|
||||
cloneFile.contents = Buffer.from(content);
|
||||
|
||||
return cloneFile;
|
||||
}
|
||||
}
|
||||
},
|
||||
transformFile(file) {
|
||||
if (isComponentStyle(file)) {
|
||||
const content = file.contents.toString();
|
||||
|
||||
if (needTransformStyle(content)) {
|
||||
const cloneFile = file.clone();
|
||||
cloneFile.contents = Buffer.from(
|
||||
[
|
||||
// Inject variable
|
||||
'@root-entry-name: default',
|
||||
// Point to origin file
|
||||
"@import './index';",
|
||||
].join('\n\n'),
|
||||
);
|
||||
cloneFile.path = cloneFile.path.replace('index.tsx', 'index-default.less');
|
||||
return cloneFile;
|
||||
}
|
||||
}
|
||||
return [];
|
||||
},
|
||||
lessConfig: {
|
||||
modifyVars: {
|
||||
'root-entry-name': 'default',
|
||||
},
|
||||
},
|
||||
finalize: finalizeCompile,
|
||||
},
|
||||
dist: {
|
||||
|
@ -206,11 +206,8 @@ describe('Affix Render', () => {
|
||||
|
||||
// Mock trigger resize
|
||||
updateCalled.mockReset();
|
||||
const resizeObserverInstance: ReactWrapper<
|
||||
HTMLAttributes,
|
||||
unknown,
|
||||
ResizeObserverImpl
|
||||
> = affixMounterWrapper.find('ResizeObserver') as any;
|
||||
const resizeObserverInstance: ReactWrapper<HTMLAttributes, unknown, ResizeObserverImpl> =
|
||||
affixMounterWrapper.find('ResizeObserver') as any;
|
||||
resizeObserverInstance
|
||||
.at(index)
|
||||
.instance()
|
||||
@ -225,7 +222,7 @@ describe('Affix Render', () => {
|
||||
contentBoxSize: [],
|
||||
},
|
||||
],
|
||||
({} as unknown) as ResizeObserver,
|
||||
{} as unknown as ResizeObserver,
|
||||
);
|
||||
await sleep(20);
|
||||
|
||||
|
@ -207,19 +207,19 @@
|
||||
}
|
||||
|
||||
&-background-ghost&-primary {
|
||||
.button-variant-ghost(@btn-primary-bg);
|
||||
.button-variant-ghost(@btn-primary-bg, @btn-primary-bg, @primary-color-hover, @primary-color-active);
|
||||
}
|
||||
|
||||
&-background-ghost&-danger {
|
||||
.button-variant-ghost(@btn-danger-border);
|
||||
.button-variant-ghost(@btn-danger-border, @btn-danger-border, @error-color-hover, @error-color-active);
|
||||
}
|
||||
|
||||
&-background-ghost&-dangerous {
|
||||
.button-variant-ghost(@btn-danger-border);
|
||||
.button-variant-ghost(@btn-danger-border, @btn-danger-border, @error-color-hover, @error-color-active);
|
||||
}
|
||||
|
||||
&-background-ghost&-dangerous&-link {
|
||||
.button-variant-ghost(@btn-danger-border, transparent);
|
||||
.button-variant-ghost(@btn-danger-border, transparent, @error-color-hover, @error-color-active);
|
||||
}
|
||||
|
||||
&-two-chinese-chars::first-letter {
|
||||
|
@ -11,134 +11,6 @@
|
||||
border-radius: @border-radius;
|
||||
}
|
||||
|
||||
.button-disabled(@color: @btn-disable-color; @background: @btn-disable-bg; @border: @btn-disable-border) {
|
||||
&[disabled] {
|
||||
&,
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
.button-color(@color; @background; @border);
|
||||
|
||||
text-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button-variant-primary(@color; @background) {
|
||||
.button-color(@color; @background; @background);
|
||||
|
||||
text-shadow: @btn-text-shadow;
|
||||
box-shadow: @btn-primary-shadow;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
& when (@theme = dark) {
|
||||
.button-color(
|
||||
@color; ~`colorPalette('@{background}', 7) `; ~`colorPalette('@{background}', 7) `
|
||||
);
|
||||
}
|
||||
& when not (@theme = dark) {
|
||||
.button-color(
|
||||
@color; ~`colorPalette('@{background}', 5) `; ~`colorPalette('@{background}', 5) `
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
& when (@theme = dark) {
|
||||
.button-color(
|
||||
@color; ~`colorPalette('@{background}', 5) `; ~`colorPalette('@{background}', 5) `
|
||||
);
|
||||
}
|
||||
& when not (@theme = dark) {
|
||||
.button-color(
|
||||
@color; ~`colorPalette('@{background}', 7) `; ~`colorPalette('@{background}', 7) `
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
.button-disabled();
|
||||
}
|
||||
|
||||
.button-variant-other(@color; @background; @border) {
|
||||
.button-color(@color; @background; @border);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
& when (@theme = dark) {
|
||||
.button-color(@primary-5; @background; @primary-5);
|
||||
}
|
||||
& when not (@theme = dark) {
|
||||
.button-color(
|
||||
~`colorPalette('@{btn-primary-bg}', 5) `; @background;
|
||||
~`colorPalette('@{btn-primary-bg}', 5) `
|
||||
);
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
& when (@theme = dark) {
|
||||
.button-color(@primary-7; @background; @primary-7);
|
||||
}
|
||||
& when not (@theme = dark) {
|
||||
.button-color(
|
||||
~`colorPalette('@{btn-primary-bg}', 7) `; @background;
|
||||
~`colorPalette('@{btn-primary-bg}', 7) `
|
||||
);
|
||||
}
|
||||
}
|
||||
.button-disabled();
|
||||
}
|
||||
.button-variant-ghost(@color; @border: @color) {
|
||||
.button-color(@color; null; @border);
|
||||
text-shadow: none;
|
||||
&:hover,
|
||||
&:focus {
|
||||
& when (@border = transparent) {
|
||||
& when (@theme = dark) {
|
||||
.button-color(~`colorPalette('@{color}', 7) `; null; transparent);
|
||||
}
|
||||
& when not (@theme = dark) {
|
||||
.button-color(~`colorPalette('@{color}', 5) `; null; transparent);
|
||||
}
|
||||
}
|
||||
& when not (@border = transparent) {
|
||||
& when (@theme = dark) {
|
||||
.button-color(
|
||||
~`colorPalette('@{color}', 7) `; null; ~`colorPalette('@{color}', 7) `
|
||||
);
|
||||
}
|
||||
& when not (@theme = dark) {
|
||||
.button-color(
|
||||
~`colorPalette('@{color}', 5) `; null; ~`colorPalette('@{color}', 5) `
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
& when (@border = transparent) {
|
||||
& when (@theme = dark) {
|
||||
.button-color(~`colorPalette('@{color}', 5) `; null; transparent);
|
||||
}
|
||||
& when not (@theme = dark) {
|
||||
.button-color(~`colorPalette('@{color}', 7) `; null; transparent);
|
||||
}
|
||||
}
|
||||
& when not (@border = transparent) {
|
||||
& when (@theme = dark) {
|
||||
.button-color(
|
||||
~`colorPalette('@{color}', 5) `; null; ~`colorPalette('@{color}', 5) `
|
||||
);
|
||||
}
|
||||
& when not (@theme = dark) {
|
||||
.button-color(
|
||||
~`colorPalette('@{color}', 7) `; null; ~`colorPalette('@{color}', 7) `
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
.button-disabled();
|
||||
}
|
||||
.button-color(@color; @background; @border) {
|
||||
color: @color;
|
||||
border-color: @border; // a inside Button which only work in Chrome
|
||||
@ -159,6 +31,161 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button-disabled(@color: @btn-disable-color; @background: @btn-disable-bg; @border: @btn-disable-border) {
|
||||
&[disabled] {
|
||||
&,
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
.button-color(@color; @background; @border);
|
||||
|
||||
text-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button-variant-primary(@color; @background; @backgroundHover: yellow; @backgroundActive: yellow) {
|
||||
.button-color(@color; @background; @background);
|
||||
|
||||
text-shadow: @btn-text-shadow;
|
||||
box-shadow: @btn-primary-shadow;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
& when (@theme = dark) {
|
||||
.button-color(
|
||||
@color; ~`colorPalette('@{background}', 7) `; ~`colorPalette('@{background}', 7) `
|
||||
);
|
||||
}
|
||||
& when (not (@theme = dark) and not (@theme = variable)) {
|
||||
.button-color(
|
||||
@color; ~`colorPalette('@{background}', 5) `; ~`colorPalette('@{background}', 5) `
|
||||
);
|
||||
}
|
||||
& when (@theme = variable) {
|
||||
.button-color(@color; @backgroundHover; @backgroundHover);
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
& when (@theme = dark) {
|
||||
.button-color(
|
||||
@color; ~`colorPalette('@{background}', 5) `; ~`colorPalette('@{background}', 5) `
|
||||
);
|
||||
}
|
||||
& when (not (@theme = dark) and not (@theme = variable)) {
|
||||
.button-color(
|
||||
@color; ~`colorPalette('@{background}', 7) `; ~`colorPalette('@{background}', 7) `
|
||||
);
|
||||
}
|
||||
& when (@theme = variable) {
|
||||
.button-color(@color; @backgroundActive; @backgroundActive);
|
||||
}
|
||||
}
|
||||
|
||||
.button-disabled();
|
||||
}
|
||||
|
||||
.button-variant-other(@color; @background; @border) {
|
||||
.button-color(@color; @background; @border);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
& when (@theme = dark) {
|
||||
.button-color(@primary-5; @background; @primary-5);
|
||||
}
|
||||
& when (not (@theme = dark) and not (@theme = variable)) {
|
||||
.button-color(
|
||||
~`colorPalette('@{btn-primary-bg}', 5) `; @background;
|
||||
~`colorPalette('@{btn-primary-bg}', 5) `
|
||||
);
|
||||
}
|
||||
& when (@theme = variable) {
|
||||
.button-color(@primary-color-hover; @background; @primary-color-hover);
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
& when (@theme = dark) {
|
||||
.button-color(@primary-7; @background; @primary-7);
|
||||
}
|
||||
& when (not (@theme = dark) and not (@theme = variable)) {
|
||||
.button-color(
|
||||
~`colorPalette('@{btn-primary-bg}', 7) `; @background;
|
||||
~`colorPalette('@{btn-primary-bg}', 7) `
|
||||
);
|
||||
}
|
||||
& when (@theme = variable) {
|
||||
.button-color(@primary-color-active; @background; @primary-color-active);
|
||||
}
|
||||
}
|
||||
.button-disabled();
|
||||
}
|
||||
|
||||
.button-variant-ghost(@color; @border; @borderHover: yellow; @borderActive: yellow) {
|
||||
.button-color(@color; null; @border);
|
||||
text-shadow: none;
|
||||
&:hover,
|
||||
&:focus {
|
||||
& when (@border = transparent) {
|
||||
& when (@theme = dark) {
|
||||
.button-color(~`colorPalette('@{color}', 7) `; null; transparent);
|
||||
}
|
||||
& when (not (@theme = dark) and not (@theme = variable)) {
|
||||
.button-color(~`colorPalette('@{color}', 5) `; null; transparent);
|
||||
}
|
||||
& when (@theme = variable) {
|
||||
.button-color(@borderActive; transparent; transparent);
|
||||
}
|
||||
}
|
||||
& when not (@border = transparent) {
|
||||
& when (@theme = dark) {
|
||||
.button-color(
|
||||
~`colorPalette('@{color}', 7) `; null; ~`colorPalette('@{color}', 7) `
|
||||
);
|
||||
}
|
||||
& when (not (@theme = dark) and not (@theme = variable)) {
|
||||
.button-color(
|
||||
~`colorPalette('@{color}', 5) `; null; ~`colorPalette('@{color}', 5) `
|
||||
);
|
||||
}
|
||||
& when (@theme = variable) {
|
||||
.button-color(@borderHover; transparent; @borderHover);
|
||||
}
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
& when (@border = transparent) {
|
||||
& when (@theme = dark) {
|
||||
.button-color(~`colorPalette('@{color}', 5) `; null; transparent);
|
||||
}
|
||||
& when (not (@theme = dark) and not (@theme = variable)) {
|
||||
.button-color(~`colorPalette('@{color}', 7) `; null; transparent);
|
||||
}
|
||||
& when (@theme = variable) {
|
||||
.button-color(@borderActive; transparent; transparent);
|
||||
}
|
||||
}
|
||||
& when not (@border = transparent) {
|
||||
& when (@theme = dark) {
|
||||
.button-color(
|
||||
~`colorPalette('@{color}', 5) `; null; ~`colorPalette('@{color}', 5) `
|
||||
);
|
||||
}
|
||||
& when (not (@theme = dark) and not (@theme = variable)) {
|
||||
.button-color(
|
||||
~`colorPalette('@{color}', 7) `; null; ~`colorPalette('@{color}', 7) `
|
||||
);
|
||||
}
|
||||
& when (@theme = variable) {
|
||||
.button-color(@borderActive; transparent; @borderActive);
|
||||
}
|
||||
}
|
||||
}
|
||||
.button-disabled();
|
||||
}
|
||||
|
||||
.button-group-base(@btnClassName) {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
@ -252,11 +279,11 @@
|
||||
}
|
||||
// primary button style
|
||||
.btn-primary() {
|
||||
.button-variant-primary(@btn-primary-color; @btn-primary-bg);
|
||||
.button-variant-primary(@btn-primary-color; @btn-primary-bg; @primary-color-hover; @primary-color-active);
|
||||
}
|
||||
// default button style
|
||||
.btn-default() {
|
||||
.button-variant-other(@btn-default-color; @btn-default-bg; @btn-default-border);
|
||||
.button-variant-other(@btn-default-color; @btn-default-bg; @btn-default-border; );
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
@ -275,7 +302,7 @@
|
||||
}
|
||||
// danger button style
|
||||
.btn-danger() {
|
||||
.button-variant-primary(@btn-danger-color, @btn-danger-bg);
|
||||
.button-variant-primary(@btn-danger-color, @btn-danger-bg, @error-color-hover, @error-color-active);
|
||||
}
|
||||
// danger default button style
|
||||
.btn-danger-default() {
|
||||
@ -288,12 +315,15 @@
|
||||
`
|
||||
);
|
||||
}
|
||||
& when not (@theme = dark) {
|
||||
& when (not (@theme = dark) and not (@theme = variable)) {
|
||||
.button-color(
|
||||
~`colorPalette('@{error-color}', 5) `; @btn-default-bg; ~`colorPalette('@{error-color}', 5)
|
||||
`
|
||||
);
|
||||
}
|
||||
& when (@theme = variable) {
|
||||
.button-color(@error-color-hover, @btn-default-bg, @error-color-hover);
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
& when (@theme = dark) {
|
||||
@ -302,12 +332,15 @@
|
||||
`
|
||||
);
|
||||
}
|
||||
& when not (@theme = dark) {
|
||||
& when (not (@theme = dark) and not (@theme = variable)) {
|
||||
.button-color(
|
||||
~`colorPalette('@{error-color}', 7) `; @btn-default-bg; ~`colorPalette('@{error-color}', 7)
|
||||
`
|
||||
);
|
||||
}
|
||||
& when (@theme = variable) {
|
||||
.button-color(@error-color-active, @btn-default-bg, @error-color-active);
|
||||
}
|
||||
}
|
||||
.button-disabled();
|
||||
}
|
||||
@ -320,17 +353,23 @@
|
||||
& when (@theme = dark) {
|
||||
.button-color(~`colorPalette('@{error-color}', 7) `; transparent; transparent);
|
||||
}
|
||||
& when not (@theme = dark) {
|
||||
& when (not (@theme = dark) and not (@theme = variable)) {
|
||||
.button-color(~`colorPalette('@{error-color}', 5) `; transparent; transparent);
|
||||
}
|
||||
& when (@theme = variable) {
|
||||
.button-color(@error-color-hover; transparent; transparent);
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
& when (@theme = dark) {
|
||||
.button-color(~`colorPalette('@{error-color}', 5) `; transparent; transparent);
|
||||
}
|
||||
& when not (@theme = dark) {
|
||||
& when (not (@theme = dark) and not (@theme = variable)) {
|
||||
.button-color(~`colorPalette('@{error-color}', 7) `; transparent; transparent);
|
||||
}
|
||||
& when (@theme = variable) {
|
||||
.button-color(@error-color-active; transparent; transparent);
|
||||
}
|
||||
}
|
||||
.button-disabled(@disabled-color; transparent; transparent);
|
||||
}
|
||||
@ -375,18 +414,24 @@
|
||||
& when (@theme = dark) {
|
||||
.button-color(~`colorPalette('@{error-color}', 7) `; @btn-text-hover-bg; transparent);
|
||||
}
|
||||
& when not (@theme = dark) {
|
||||
& when (not (@theme = dark) and not (@theme = variable)) {
|
||||
.button-color(~`colorPalette('@{error-color}', 5) `; @btn-text-hover-bg; transparent);
|
||||
}
|
||||
& when (@theme = variable) {
|
||||
.button-color(@error-color-hover; @btn-text-hover-bg; transparent);
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
& when (@theme = dark) {
|
||||
.button-color(~`colorPalette('@{error-color}', 5) `; fadein(@btn-text-hover-bg, 1%); transparent);
|
||||
}
|
||||
& when not (@theme = dark) {
|
||||
& when (not (@theme = dark) and not (@theme = variable)) {
|
||||
.button-color(~`colorPalette('@{error-color}', 7) `; fadein(@btn-text-hover-bg, 1%); transparent);
|
||||
}
|
||||
& when (@theme = variable) {
|
||||
.button-color(@error-color-active; fadein(@btn-text-hover-bg, 1%); transparent);
|
||||
}
|
||||
}
|
||||
.button-disabled(@disabled-color; transparent; transparent);
|
||||
}
|
||||
|
23
components/config-provider/__tests__/theme.test.ts
Normal file
23
components/config-provider/__tests__/theme.test.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { kebabCase } from 'lodash';
|
||||
import ConfigProvider from '..';
|
||||
|
||||
describe('ConfigProvider.Theme', () => {
|
||||
const colorList = ['primaryColor', 'successColor', 'warningColor', 'errorColor', 'infoColor'];
|
||||
|
||||
colorList.forEach(colorName => {
|
||||
it(colorName, () => {
|
||||
ConfigProvider.config({
|
||||
prefixCls: 'bamboo',
|
||||
theme: {
|
||||
[colorName]: '#0000FF',
|
||||
},
|
||||
});
|
||||
|
||||
const styles: any[] = Array.from(document.querySelectorAll('style'));
|
||||
const themeStyle = styles.find(style => style['rc-util-key'].includes('-dynamic-theme'));
|
||||
expect(themeStyle).toBeTruthy();
|
||||
|
||||
expect(themeStyle.innerHTML).toContain(`--bamboo-${kebabCase(colorName)}: rgb(0, 0, 255)`);
|
||||
});
|
||||
});
|
||||
});
|
@ -4,6 +4,15 @@ import { Locale } from '../locale-provider';
|
||||
import { SizeType } from './SizeContext';
|
||||
import { RequiredMark } from '../form/Form';
|
||||
|
||||
export interface Theme {
|
||||
primaryColor?: string;
|
||||
infoColor?: string;
|
||||
successColor?: string;
|
||||
processingColor?: string;
|
||||
errorColor?: string;
|
||||
warningColor?: string;
|
||||
}
|
||||
|
||||
export interface CSPConfig {
|
||||
nonce?: string;
|
||||
}
|
||||
|
97
components/config-provider/cssVariables.tsx
Normal file
97
components/config-provider/cssVariables.tsx
Normal file
@ -0,0 +1,97 @@
|
||||
/* eslint-disable import/prefer-default-export, prefer-destructuring */
|
||||
|
||||
import { updateCSS } from 'rc-util/lib/Dom/dynamicCSS';
|
||||
import { TinyColor } from '@ctrl/tinycolor';
|
||||
import { generate } from '@ant-design/colors';
|
||||
import { Theme } from './context';
|
||||
|
||||
const dynamicStyleMark = `-ant-${Date.now()}-${Math.random()}`;
|
||||
|
||||
export function registerTheme(globalPrefixCls: string, theme: Theme) {
|
||||
const variables: Record<string, string> = {};
|
||||
|
||||
const formatColor = (
|
||||
color: TinyColor,
|
||||
updater?: (cloneColor: TinyColor) => TinyColor | undefined,
|
||||
) => {
|
||||
let clone = color.clone();
|
||||
clone = updater?.(clone) || clone;
|
||||
return clone.toRgbString();
|
||||
};
|
||||
|
||||
const fillColor = (colorVal: string, type: string) => {
|
||||
const baseColor = new TinyColor(colorVal);
|
||||
const colorPalettes = generate(baseColor.toRgbString());
|
||||
|
||||
variables[`${type}-color`] = formatColor(baseColor);
|
||||
variables[`${type}-color-disabled`] = colorPalettes[1];
|
||||
variables[`${type}-color-hover`] = colorPalettes[4];
|
||||
variables[`${type}-color-active`] = colorPalettes[7];
|
||||
variables[`${type}-color-outline`] = baseColor.clone().setAlpha(0.2).toRgbString();
|
||||
variables[`${type}-color-deprecated-bg`] = colorPalettes[1];
|
||||
variables[`${type}-color-deprecated-border`] = colorPalettes[3];
|
||||
};
|
||||
|
||||
// ================ Primary Color ================
|
||||
if (theme.primaryColor) {
|
||||
fillColor(theme.primaryColor, 'primary');
|
||||
|
||||
const primaryColor = new TinyColor(theme.primaryColor);
|
||||
const primaryColors = generate(primaryColor.toRgbString());
|
||||
|
||||
// Legacy - We should use semantic naming standard
|
||||
primaryColors.forEach((color, index) => {
|
||||
variables[`primary-${index + 1}`] = color;
|
||||
});
|
||||
// Deprecated
|
||||
variables['primary-color-deprecated-l-35'] = formatColor(primaryColor, c => c.lighten(35));
|
||||
variables['primary-color-deprecated-l-20'] = formatColor(primaryColor, c => c.lighten(20));
|
||||
variables['primary-color-deprecated-t-20'] = formatColor(primaryColor, c => c.tint(20));
|
||||
variables['primary-color-deprecated-t-50'] = formatColor(primaryColor, c => c.tint(50));
|
||||
variables['primary-color-deprecated-f-12'] = formatColor(primaryColor, c =>
|
||||
c.setAlpha(c.getAlpha() * 0.12),
|
||||
);
|
||||
|
||||
const primaryActiveColor = new TinyColor(primaryColors[0]);
|
||||
variables['primary-color-active-deprecated-f-30'] = formatColor(primaryActiveColor, c =>
|
||||
c.setAlpha(c.getAlpha() * 0.3),
|
||||
);
|
||||
variables['primary-color-active-deprecated-d-02'] = formatColor(primaryActiveColor, c =>
|
||||
c.darken(2),
|
||||
);
|
||||
}
|
||||
|
||||
// ================ Success Color ================
|
||||
if (theme.successColor) {
|
||||
fillColor(theme.successColor, 'success');
|
||||
}
|
||||
|
||||
// ================ Warning Color ================
|
||||
if (theme.warningColor) {
|
||||
fillColor(theme.warningColor, 'warning');
|
||||
}
|
||||
|
||||
// ================= Error Color =================
|
||||
if (theme.errorColor) {
|
||||
fillColor(theme.errorColor, 'error');
|
||||
}
|
||||
|
||||
// ================= Info Color ==================
|
||||
if (theme.infoColor) {
|
||||
fillColor(theme.infoColor, 'info');
|
||||
}
|
||||
|
||||
// Convert to css variables
|
||||
const cssList = Object.keys(variables).map(
|
||||
key => `--${globalPrefixCls}-${key}: ${variables[key]};`,
|
||||
);
|
||||
|
||||
updateCSS(
|
||||
`
|
||||
:root {
|
||||
${cssList.join('\n')}
|
||||
}
|
||||
`,
|
||||
`${dynamicStyleMark}-dynamic-theme`,
|
||||
);
|
||||
}
|
633
components/config-provider/demo/theme.md
Normal file
633
components/config-provider/demo/theme.md
Normal file
@ -0,0 +1,633 @@
|
||||
---
|
||||
order: 5
|
||||
title:
|
||||
zh-CN: 全局样式
|
||||
en-US: Global Theme
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
通过 css variable 修改全局主题色(你可以切换到组件页面查看更详细的样式展示),不支持 IE。自动生成的变量可能会根据设计调整,请勿直接依赖。详细配置请[点击查看](/docs/react/customize-theme-variable)。
|
||||
|
||||
## en-US
|
||||
|
||||
Modify global theme color by css variable which IE not support. Css variable depends on the design, it may adjust so please do not directly use it. You can go to other components page for more detail style. [Check this](/docs/react/customize-theme-variable) to view detail.
|
||||
|
||||
```jsx
|
||||
import { SketchPicker } from 'react-color';
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
DownOutlined,
|
||||
MailOutlined,
|
||||
SettingOutlined,
|
||||
ClockCircleOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import {
|
||||
ConfigProvider,
|
||||
Tag,
|
||||
Mentions,
|
||||
Steps,
|
||||
Button,
|
||||
Radio,
|
||||
Space,
|
||||
Form,
|
||||
Input,
|
||||
Row,
|
||||
Col,
|
||||
Typography,
|
||||
Menu,
|
||||
Dropdown,
|
||||
Divider,
|
||||
Pagination,
|
||||
Select,
|
||||
Checkbox,
|
||||
DatePicker,
|
||||
TimePicker,
|
||||
InputNumber,
|
||||
Slider,
|
||||
Switch,
|
||||
TreeSelect,
|
||||
Card,
|
||||
Table,
|
||||
Tabs,
|
||||
Timeline,
|
||||
Tree,
|
||||
Alert,
|
||||
Progress,
|
||||
Spin,
|
||||
Transfer,
|
||||
} from 'antd';
|
||||
|
||||
const SplitSpace = props => <Space split={<Divider type="vertical" />} size={4} {...props} />;
|
||||
|
||||
const inputProps = {
|
||||
style: { width: 128 },
|
||||
};
|
||||
|
||||
const selectProps = {
|
||||
...inputProps,
|
||||
options: [
|
||||
{ value: 'light', label: 'Light' },
|
||||
{ value: 'bamboo', label: 'Bamboo' },
|
||||
{ value: 'little', label: 'Little' },
|
||||
],
|
||||
};
|
||||
|
||||
const treeData = [
|
||||
{
|
||||
value: 'little',
|
||||
key: 'little',
|
||||
label: 'Little',
|
||||
title: 'Little',
|
||||
children: [
|
||||
{ value: 'light', key: 'light', label: 'Light', title: 'Light' },
|
||||
{ value: 'bamboo', key: 'bamboo', label: 'Bamboo', title: 'Bamboo' },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const treeSelectProps = {
|
||||
...inputProps,
|
||||
treeCheckable: true,
|
||||
maxTagCount: 'responsive',
|
||||
treeData,
|
||||
};
|
||||
|
||||
const carTabListNoTitle = [
|
||||
{
|
||||
key: 'article',
|
||||
tab: 'article',
|
||||
},
|
||||
{
|
||||
key: 'app',
|
||||
tab: 'app',
|
||||
},
|
||||
{
|
||||
key: 'project',
|
||||
tab: 'project',
|
||||
},
|
||||
];
|
||||
|
||||
const MyTransfer = () => {
|
||||
const mockData = [];
|
||||
for (let i = 0; i < 20; i++) {
|
||||
mockData.push({
|
||||
key: i.toString(),
|
||||
title: `content${i + 1}`,
|
||||
description: `description of content${i + 1}`,
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<Transfer
|
||||
dataSource={mockData}
|
||||
targetKeys={['18']}
|
||||
selectedKeys={['3']}
|
||||
render={item => item.title}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const FormSizeDemo = () => {
|
||||
const [color, setColor] = useState({
|
||||
primaryColor: '#1890ff',
|
||||
errorColor: '#ff4d4f',
|
||||
warningColor: '#faad14',
|
||||
successColor: '#52c41a',
|
||||
infoColor: '#1890ff',
|
||||
});
|
||||
|
||||
function onColorChange(nextColor) {
|
||||
const mergedNextColor = {
|
||||
...color,
|
||||
...nextColor,
|
||||
};
|
||||
setColor(mergedNextColor);
|
||||
ConfigProvider.config({
|
||||
theme: mergedNextColor,
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<Row gutter={16} wrap={false}>
|
||||
<Col flex="none">
|
||||
<Space direction="vertical" align="center">
|
||||
{/* Primary Color */}
|
||||
<SketchPicker
|
||||
presetColors={['#1890ff', '#25b864', '#ff6f00']}
|
||||
color={color.primaryColor}
|
||||
onChange={({ hex }) => {
|
||||
onColorChange({
|
||||
primaryColor: hex,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<span style={{ color: 'var(--ant-primary-color)' }}>var(`--ant-primary-color`)</span>
|
||||
|
||||
{/* Error Color */}
|
||||
<SketchPicker
|
||||
presetColors={['#ff4d4f']}
|
||||
color={color.errorColor}
|
||||
onChange={({ hex }) => {
|
||||
onColorChange({
|
||||
errorColor: hex,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<span style={{ color: 'var(--ant-error-color)' }}>var(`--ant-error-color`)</span>
|
||||
|
||||
{/* Warning Color */}
|
||||
<SketchPicker
|
||||
presetColors={['#faad14']}
|
||||
color={color.warningColor}
|
||||
onChange={({ hex }) => {
|
||||
onColorChange({
|
||||
warningColor: hex,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<span style={{ color: 'var(--ant-warning-color)' }}>var(`--ant-warning-color`)</span>
|
||||
|
||||
{/* Success Color */}
|
||||
<SketchPicker
|
||||
presetColors={['#52c41a']}
|
||||
color={color.successColor}
|
||||
onChange={({ hex }) => {
|
||||
onColorChange({
|
||||
successColor: hex,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<span style={{ color: 'var(--ant-success-color)' }}>var(`--ant-success-color`)</span>
|
||||
|
||||
{/* Info Color */}
|
||||
<SketchPicker
|
||||
presetColors={['#1890ff']}
|
||||
color={color.infoColor}
|
||||
onChange={({ hex }) => {
|
||||
onColorChange({
|
||||
infoColor: hex,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<span style={{ color: 'var(--ant-info-color)' }}>var(`--ant-info-color`)</span>
|
||||
</Space>
|
||||
</Col>
|
||||
|
||||
<Col flex="auto">
|
||||
<Space direction="vertical" split={<Divider />} style={{ width: '100%' }} size={0}>
|
||||
{/* Primary Button */}
|
||||
<SplitSpace>
|
||||
<Button type="primary">Primary</Button>
|
||||
<Button>Default</Button>
|
||||
<Button type="dashed">Dashed</Button>
|
||||
<Button type="text">Text</Button>
|
||||
<Button type="link">Link</Button>
|
||||
</SplitSpace>
|
||||
|
||||
{/* Danger Button */}
|
||||
<SplitSpace>
|
||||
<Button danger type="primary">
|
||||
Primary
|
||||
</Button>
|
||||
<Button danger>Default</Button>
|
||||
<Button danger type="dashed">
|
||||
Dashed
|
||||
</Button>
|
||||
<Button danger type="text">
|
||||
Text
|
||||
</Button>
|
||||
<Button danger type="link">
|
||||
Link
|
||||
</Button>
|
||||
</SplitSpace>
|
||||
|
||||
{/* Ghost Button */}
|
||||
<SplitSpace style={{ background: 'rgb(190, 200, 200)' }}>
|
||||
<Button type="primary" ghost>
|
||||
Primary
|
||||
</Button>
|
||||
<Button ghost>Default</Button>
|
||||
<Button type="dashed" ghost>
|
||||
Dashed
|
||||
</Button>
|
||||
<Button type="primary" ghost danger>
|
||||
Primary
|
||||
</Button>
|
||||
<Button ghost danger>
|
||||
Default
|
||||
</Button>
|
||||
<Button type="dashed" ghost danger>
|
||||
Dashed
|
||||
</Button>
|
||||
</SplitSpace>
|
||||
|
||||
{/* Typography */}
|
||||
<SplitSpace>
|
||||
<Typography.Text type="success">Text (success)</Typography.Text>
|
||||
<Typography.Text type="warning">Text(warning)</Typography.Text>
|
||||
<Typography.Text type="danger">Text(danger)</Typography.Text>
|
||||
<Typography.Link href="https://ant.design" target="_blank">
|
||||
Link
|
||||
</Typography.Link>
|
||||
<Typography.Text copyable>Text</Typography.Text>
|
||||
|
||||
{/* Dropdown */}
|
||||
<Dropdown
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.Item>1st menu item</Menu.Item>
|
||||
<Menu.Item danger>a danger item</Menu.Item>
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<a className="ant-dropdown-link" onClick={e => e.preventDefault()}>
|
||||
Hover me <DownOutlined />
|
||||
</a>
|
||||
</Dropdown>
|
||||
|
||||
{/* Spin */}
|
||||
<Spin />
|
||||
</SplitSpace>
|
||||
|
||||
{/* Menu - horizontal */}
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<Menu mode="horizontal" defaultSelectedKeys={['mail']}>
|
||||
<Menu.Item key="mail" icon={<MailOutlined />}>
|
||||
Mail
|
||||
</Menu.Item>
|
||||
<Menu.SubMenu key="SubMenu" icon={<SettingOutlined />} title="Submenu">
|
||||
<Menu.ItemGroup title="Item 1">
|
||||
<Menu.Item key="setting:1">Option 1</Menu.Item>
|
||||
<Menu.Item key="setting:2">Option 2</Menu.Item>
|
||||
</Menu.ItemGroup>
|
||||
</Menu.SubMenu>
|
||||
</Menu>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Menu mode="horizontal" theme="dark" defaultSelectedKeys={['mail']}>
|
||||
<Menu.Item key="mail" icon={<MailOutlined />}>
|
||||
Mail
|
||||
</Menu.Item>
|
||||
<Menu.SubMenu key="SubMenu" icon={<SettingOutlined />} title="Submenu">
|
||||
<Menu.ItemGroup title="Item 1">
|
||||
<Menu.Item key="setting:1">Option 1</Menu.Item>
|
||||
<Menu.Item key="setting:2">Option 2</Menu.Item>
|
||||
</Menu.ItemGroup>
|
||||
</Menu.SubMenu>
|
||||
</Menu>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/* Menu - vertical */}
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<Menu mode="inline" defaultSelectedKeys={['mail']}>
|
||||
<Menu.Item key="mail" icon={<MailOutlined />}>
|
||||
Mail
|
||||
</Menu.Item>
|
||||
<Menu.SubMenu key="SubMenu" icon={<SettingOutlined />} title="Submenu">
|
||||
<Menu.ItemGroup title="Item 1">
|
||||
<Menu.Item key="setting:1">Option 1</Menu.Item>
|
||||
<Menu.Item key="setting:2">Option 2</Menu.Item>
|
||||
</Menu.ItemGroup>
|
||||
</Menu.SubMenu>
|
||||
</Menu>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Menu mode="vertical" theme="dark" defaultSelectedKeys={['mail']}>
|
||||
<Menu.Item key="mail" icon={<MailOutlined />}>
|
||||
Mail
|
||||
</Menu.Item>
|
||||
<Menu.SubMenu key="SubMenu" icon={<SettingOutlined />} title="Submenu">
|
||||
<Menu.ItemGroup title="Item 1">
|
||||
<Menu.Item key="setting:1">Option 1</Menu.Item>
|
||||
<Menu.Item key="setting:2">Option 2</Menu.Item>
|
||||
</Menu.ItemGroup>
|
||||
</Menu.SubMenu>
|
||||
</Menu>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/* Pagination */}
|
||||
<Pagination showQuickJumper defaultCurrent={2} total={500} />
|
||||
|
||||
{/* Steps */}
|
||||
<Steps current={1} percent={60}>
|
||||
<Steps.Step title="Finished" description="This is a description." />
|
||||
<Steps.Step
|
||||
title="In Progress"
|
||||
subTitle="Left 00:00:08"
|
||||
description="This is a description."
|
||||
/>
|
||||
<Steps.Step title="Waiting" description="This is a description." />
|
||||
</Steps>
|
||||
|
||||
{/* Steps - dot */}
|
||||
<Steps current={2} status="error" progressDot>
|
||||
<Steps.Step title="Finished" description="You can hover on the dot." />
|
||||
<Steps.Step title="In Progress" description="You can hover on the dot." />
|
||||
<Steps.Step title="Error" description="You can hover on the dot." />
|
||||
<Steps.Step title="Waiting" description="You can hover on the dot." />
|
||||
</Steps>
|
||||
|
||||
{/* Form - Input */}
|
||||
<Form>
|
||||
<SplitSpace>
|
||||
<Form.Item>
|
||||
<Input {...inputProps} />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="success">
|
||||
<Input {...inputProps} />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="warning">
|
||||
<Input {...inputProps} />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="error">
|
||||
<Input {...inputProps} />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="validating">
|
||||
<Input {...inputProps} />
|
||||
</Form.Item>
|
||||
</SplitSpace>
|
||||
</Form>
|
||||
|
||||
{/* Form - Select */}
|
||||
<Form>
|
||||
<SplitSpace>
|
||||
<Form.Item>
|
||||
<Select {...selectProps} />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="success">
|
||||
<Select {...selectProps} />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="warning">
|
||||
<Select {...selectProps} />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="error">
|
||||
<Select {...selectProps} />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="validating">
|
||||
<Select {...selectProps} />
|
||||
</Form.Item>
|
||||
</SplitSpace>
|
||||
</Form>
|
||||
|
||||
{/* Form - TreeSelect */}
|
||||
<Form>
|
||||
<SplitSpace>
|
||||
<Form.Item>
|
||||
<TreeSelect {...treeSelectProps} />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="success">
|
||||
<TreeSelect {...treeSelectProps} />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="warning">
|
||||
<TreeSelect {...treeSelectProps} />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="error">
|
||||
<TreeSelect {...treeSelectProps} />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="validating">
|
||||
<TreeSelect {...treeSelectProps} />
|
||||
</Form.Item>
|
||||
</SplitSpace>
|
||||
</Form>
|
||||
|
||||
{/* Form - InputNumber */}
|
||||
<Form>
|
||||
<SplitSpace>
|
||||
<Form.Item>
|
||||
<InputNumber />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="success">
|
||||
<InputNumber />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="warning">
|
||||
<InputNumber />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="error">
|
||||
<InputNumber />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="validating">
|
||||
<InputNumber />
|
||||
</Form.Item>
|
||||
</SplitSpace>
|
||||
</Form>
|
||||
|
||||
{/* Form - DatePicker */}
|
||||
<Form>
|
||||
<SplitSpace>
|
||||
<Form.Item>
|
||||
<DatePicker />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="success">
|
||||
<DatePicker />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="warning">
|
||||
<DatePicker />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="error">
|
||||
<DatePicker />
|
||||
</Form.Item>
|
||||
<Form.Item hasFeedback validateStatus="validating">
|
||||
<DatePicker />
|
||||
</Form.Item>
|
||||
</SplitSpace>
|
||||
</Form>
|
||||
|
||||
<SplitSpace>
|
||||
<Checkbox>Checkbox</Checkbox>
|
||||
|
||||
<Radio.Group defaultValue="bamboo">
|
||||
<Radio value="bamboo">Bamboo</Radio>
|
||||
<Radio value="light">Light</Radio>
|
||||
<Radio value="little">Little</Radio>
|
||||
</Radio.Group>
|
||||
|
||||
<Mentions placeholder="Mention by @">
|
||||
<Mentions.Option value="afc163">afc163</Mentions.Option>
|
||||
<Mentions.Option value="zombieJ">zombieJ</Mentions.Option>
|
||||
<Mentions.Option value="yesmeck">yesmeck</Mentions.Option>
|
||||
</Mentions>
|
||||
|
||||
<Slider defaultValue={30} style={{ width: 100 }} />
|
||||
|
||||
<Switch defaultChecked />
|
||||
</SplitSpace>
|
||||
|
||||
<SplitSpace>
|
||||
<DatePicker.RangePicker />
|
||||
<TimePicker.RangePicker />
|
||||
</SplitSpace>
|
||||
|
||||
<Row gutter={16}>
|
||||
<Col span={8}>
|
||||
{/* Card */}
|
||||
<Card
|
||||
style={{ width: '100%' }}
|
||||
tabList={carTabListNoTitle}
|
||||
tabBarExtraContent={<a href="#">More</a>}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
{/* Table */}
|
||||
<Table
|
||||
size="small"
|
||||
bordered
|
||||
rowSelection={{}}
|
||||
columns={[
|
||||
{
|
||||
title: 'Key',
|
||||
dataIndex: 'key',
|
||||
filters: [
|
||||
{
|
||||
text: 'Little',
|
||||
value: 'little',
|
||||
},
|
||||
],
|
||||
sorter: (a, b) => a.key.length - b.key.length,
|
||||
},
|
||||
]}
|
||||
dataSource={[
|
||||
{
|
||||
key: 'Bamboo',
|
||||
},
|
||||
{
|
||||
key: 'Light',
|
||||
},
|
||||
{
|
||||
key: 'Little',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
{/* Table */}
|
||||
<Tabs defaultActiveKey="1">
|
||||
<Tabs.TabPane tab="Tab 1" key="1">
|
||||
Content of Tab Pane 1
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="Tab 2" key="2">
|
||||
Content of Tab Pane 2
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="Tab 3" key="3">
|
||||
Content of Tab Pane 3
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<SplitSpace>
|
||||
<Tag color="success">success</Tag>
|
||||
<Tag color="processing">processing</Tag>
|
||||
<Tag color="error">error</Tag>
|
||||
<Tag color="warning">warning</Tag>
|
||||
<Tag color="default">default</Tag>
|
||||
<Tag.CheckableTag checked>CheckableTag</Tag.CheckableTag>
|
||||
</SplitSpace>
|
||||
|
||||
<Row gutter={16}>
|
||||
<Col span={16}>
|
||||
<Timeline mode="alternate">
|
||||
<Timeline.Item>Create a services site 2015-09-01</Timeline.Item>
|
||||
<Timeline.Item color="gray">
|
||||
Solve initial network problems 2015-09-01
|
||||
</Timeline.Item>
|
||||
<Timeline.Item dot={<ClockCircleOutlined style={{ fontSize: '16px' }} />}>
|
||||
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium
|
||||
doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore
|
||||
veritatis et quasi architecto beatae vitae dicta sunt explicabo.
|
||||
</Timeline.Item>
|
||||
</Timeline>
|
||||
</Col>
|
||||
|
||||
<Col span={8}>
|
||||
<Tree treeData={treeData} height={200} defaultExpandAll checkable />
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/* Alert */}
|
||||
<Row gutter={16}>
|
||||
<Col span={6}>
|
||||
<Alert showIcon message="Success Text" type="success" />
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Alert showIcon message="Info Text" type="info" />
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Alert showIcon message="Warning Text" type="warning" />
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Alert showIcon message="Error Text" type="error" />
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/* Progress */}
|
||||
<Row gutter={16}>
|
||||
<Col flex="auto">
|
||||
<Progress percent={30} />
|
||||
<Progress percent={70} status="exception" />
|
||||
<Progress percent={100} />
|
||||
</Col>
|
||||
<Col flex="none">
|
||||
<Progress type="circle" percent={75} />
|
||||
<Progress type="circle" percent={70} status="exception" />
|
||||
<Progress type="circle" percent={100} />
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<MyTransfer />
|
||||
</Space>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
ReactDOM.render(<FormSizeDemo />, mountNode);
|
||||
```
|
@ -12,11 +12,13 @@ import {
|
||||
CSPConfig,
|
||||
DirectionType,
|
||||
ConfigConsumerProps,
|
||||
Theme,
|
||||
} from './context';
|
||||
import SizeContext, { SizeContextProvider, SizeType } from './SizeContext';
|
||||
import message from '../message';
|
||||
import notification from '../notification';
|
||||
import { RequiredMark } from '../form/Form';
|
||||
import { registerTheme } from './cssVariables';
|
||||
import defaultLocale from '../locale/default';
|
||||
|
||||
export {
|
||||
@ -89,18 +91,6 @@ export const defaultIconPrefixCls = 'anticon';
|
||||
let globalPrefixCls: string;
|
||||
let globalIconPrefixCls: string;
|
||||
|
||||
const setGlobalConfig = ({
|
||||
prefixCls,
|
||||
iconPrefixCls,
|
||||
}: Pick<ConfigProviderProps, 'prefixCls' | 'iconPrefixCls'>) => {
|
||||
if (prefixCls !== undefined) {
|
||||
globalPrefixCls = prefixCls;
|
||||
}
|
||||
if (iconPrefixCls !== undefined) {
|
||||
globalIconPrefixCls = iconPrefixCls;
|
||||
}
|
||||
};
|
||||
|
||||
function getGlobalPrefixCls() {
|
||||
return globalPrefixCls || defaultPrefixCls;
|
||||
}
|
||||
@ -109,6 +99,23 @@ function getGlobalIconPrefixCls() {
|
||||
return globalIconPrefixCls || defaultIconPrefixCls;
|
||||
}
|
||||
|
||||
const setGlobalConfig = ({
|
||||
prefixCls,
|
||||
iconPrefixCls,
|
||||
theme,
|
||||
}: Pick<ConfigProviderProps, 'prefixCls' | 'iconPrefixCls'> & { theme?: Theme }) => {
|
||||
if (prefixCls !== undefined) {
|
||||
globalPrefixCls = prefixCls;
|
||||
}
|
||||
if (iconPrefixCls !== undefined) {
|
||||
globalIconPrefixCls = iconPrefixCls;
|
||||
}
|
||||
|
||||
if (theme) {
|
||||
registerTheme(getGlobalPrefixCls(), theme);
|
||||
}
|
||||
};
|
||||
|
||||
export const globalConfig = () => ({
|
||||
getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => {
|
||||
if (customizePrefixCls) return customizePrefixCls;
|
||||
|
@ -610,7 +610,7 @@
|
||||
}
|
||||
|
||||
&-active {
|
||||
background: fade(@calendar-item-active-bg, 20%);
|
||||
background: @calendar-column-active-bg;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
@ -31,7 +31,7 @@ Commonly displayed on the details page.
|
||||
### DescriptionItem
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| ------------ | ------------------------------ | ------------- | ------- | ------- |
|
||||
| contentStyle | Customize content style | CSSProperties | - | 4.9.0 |
|
||||
| label | The description of the content | ReactNode | - | |
|
||||
| labelStyle | Customize label style | CSSProperties | - | 4.9.0 |
|
||||
|
@ -1,6 +1,12 @@
|
||||
@import '../../input/style/mixin';
|
||||
|
||||
.form-control-validation(@text-color: @input-color; @border-color: @input-border-color; @background-color: @input-bg) {
|
||||
.form-control-validation(
|
||||
@text-color: @input-color;
|
||||
@border-color: @input-border-color;
|
||||
@background-color: @input-bg;
|
||||
@hoverBorderColor: @primary-color-hover;
|
||||
@outlineColor: @primary-color-outline;
|
||||
) {
|
||||
.@{ant-prefix}-form-item-split {
|
||||
color: @text-color;
|
||||
}
|
||||
@ -15,12 +21,12 @@
|
||||
|
||||
&:focus,
|
||||
&-focused {
|
||||
.active(@border-color);
|
||||
.active(@border-color, @hoverBorderColor, @outlineColor);
|
||||
}
|
||||
}
|
||||
|
||||
.@{ant-prefix}-calendar-picker-open .@{ant-prefix}-calendar-picker-input {
|
||||
.active(@border-color);
|
||||
.active(@border-color, @hoverBorderColor, @outlineColor);
|
||||
}
|
||||
|
||||
.@{ant-prefix}-input-prefix {
|
||||
|
@ -127,7 +127,7 @@
|
||||
|
||||
// ======================== Warning ========================
|
||||
&-has-warning {
|
||||
.form-control-validation(@warning-color; @warning-color; @form-warning-input-bg);
|
||||
.form-control-validation(@warning-color; @warning-color; @form-warning-input-bg; @warning-color-hover; @warning-color-outline);
|
||||
|
||||
&.@{form-item-prefix-cls}-has-feedback .@{form-item-prefix-cls}-children-icon {
|
||||
color: @warning-color;
|
||||
@ -142,7 +142,7 @@
|
||||
}
|
||||
&.@{ant-prefix}-select-open .@{ant-prefix}-select-selector,
|
||||
&.@{ant-prefix}-select-focused .@{ant-prefix}-select-selector {
|
||||
.active(@warning-color);
|
||||
.active(@warning-color, @warning-color-hover, @warning-color-outline);
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,7 +153,7 @@
|
||||
border-color: @warning-color;
|
||||
&-focused,
|
||||
&:focus {
|
||||
.active(@warning-color);
|
||||
.active(@warning-color, @warning-color-hover, @warning-color-outline);
|
||||
}
|
||||
&:not([disabled]):hover {
|
||||
background-color: @form-warning-input-bg;
|
||||
@ -162,13 +162,13 @@
|
||||
}
|
||||
|
||||
.@{ant-prefix}-cascader-picker:focus .@{ant-prefix}-cascader-input {
|
||||
.active(@warning-color);
|
||||
.active(@warning-color, @warning-color-hover, @warning-color-outline);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================= Error =========================
|
||||
&-has-error {
|
||||
.form-control-validation(@error-color; @error-color; @form-error-input-bg);
|
||||
.form-control-validation(@error-color; @error-color; @form-error-input-bg; @error-color-hover; @error-color-outline);
|
||||
|
||||
&.@{form-item-prefix-cls}-has-feedback .@{form-item-prefix-cls}-children-icon {
|
||||
color: @error-color;
|
||||
@ -183,7 +183,7 @@
|
||||
}
|
||||
&.@{ant-prefix}-select-open .@{ant-prefix}-select-selector,
|
||||
&.@{ant-prefix}-select-focused .@{ant-prefix}-select-selector {
|
||||
.active(@error-color);
|
||||
.active(@error-color, @error-color-hover, @error-color-outline);
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,7 +213,7 @@
|
||||
border-color: @error-color;
|
||||
&-focused,
|
||||
&:focus {
|
||||
.active(@error-color);
|
||||
.active(@error-color, @error-color-hover, @error-color-outline);
|
||||
}
|
||||
&:not([disabled]):hover {
|
||||
background-color: @form-error-input-bg;
|
||||
@ -231,7 +231,7 @@
|
||||
}
|
||||
&.@{ant-prefix}-mention-active:not([disabled]) .@{ant-prefix}-mention-editor,
|
||||
.@{ant-prefix}-mention-editor:not([disabled]):focus {
|
||||
.active(@error-color);
|
||||
.active(@error-color, @error-color-hover, @error-color-outline);
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,7 +245,7 @@
|
||||
|
||||
&:focus .@{ant-prefix}-cascader-input {
|
||||
background-color: @form-error-input-bg;
|
||||
.active(@error-color);
|
||||
.active(@error-color, @error-color-hover, @error-color-outline);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,20 +14,27 @@
|
||||
}
|
||||
|
||||
// input status
|
||||
// == when focus or actived
|
||||
.active(@color: @outline-color) {
|
||||
// == when focus or active
|
||||
.active(@borderColor: @primary-color; @hoverBorderColor: @primary-color-hover; @outlineColor: @primary-color-outline) {
|
||||
& when (@theme = dark) {
|
||||
border-color: @color;
|
||||
border-color: @borderColor;
|
||||
}
|
||||
& when not (@theme = dark) {
|
||||
border-color: ~`colorPalette('@{color}', 5) `;
|
||||
& when (not (@theme = dark) and not (@theme = variable)) {
|
||||
border-color: @hoverBorderColor;
|
||||
}
|
||||
& when not (@theme = variable) {
|
||||
box-shadow: @input-outline-offset @outline-blur-size @outline-width
|
||||
fade(@borderColor, @outline-fade);
|
||||
}
|
||||
& when (@theme = variable) {
|
||||
border-color: @hoverBorderColor;
|
||||
box-shadow: @input-outline-offset @outline-blur-size @outline-width @outlineColor;
|
||||
}
|
||||
border-right-width: @border-width-base !important;
|
||||
outline: 0;
|
||||
box-shadow: @input-outline-offset @outline-blur-size @outline-width fade(@color, @outline-fade);
|
||||
}
|
||||
|
||||
// == when hoverd
|
||||
// == when hover
|
||||
.hover(@color: @input-hover-border-color) {
|
||||
border-color: @color;
|
||||
border-right-width: @border-width-base !important;
|
||||
|
@ -6,7 +6,7 @@
|
||||
@menu-animation-duration-normal: 0.15s;
|
||||
|
||||
.accessibility-focus() {
|
||||
box-shadow: 0 0 0 2px fade(@primary-color, 20%);
|
||||
box-shadow: 0 0 0 2px @primary-1;
|
||||
}
|
||||
|
||||
// TODO: Should remove icon style compatible in v5
|
||||
|
@ -5,7 +5,7 @@
|
||||
@radio-group-prefix-cls: ~'@{radio-prefix-cls}-group';
|
||||
@radio-inner-prefix-cls: ~'@{radio-prefix-cls}-inner';
|
||||
@radio-duration: 0.3s;
|
||||
@radio-focus-shadow: 0 0 0 3px fade(@radio-dot-color, 8%);
|
||||
@radio-focus-shadow: 0 0 0 3px @primary-1;
|
||||
@radio-button-focus-shadow: @radio-focus-shadow;
|
||||
|
||||
.@{radio-group-prefix-cls} {
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import '../../style/themes/default';
|
||||
@import '../../style/themes/index';
|
||||
@import '../../style/mixins/index';
|
||||
|
||||
@result-prefix-cls: ~'@{ant-prefix}-result';
|
||||
|
@ -1,2 +1,4 @@
|
||||
@root-entry-name: default;
|
||||
|
||||
@import './themes/compact.less';
|
||||
@import './core/index';
|
||||
|
@ -1,2 +1,4 @@
|
||||
@root-entry-name: default;
|
||||
|
||||
@import './themes/dark.less';
|
||||
@import './core/index';
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import '../../style/themes/default';
|
||||
@import (reference) '../../style/themes/index';
|
||||
|
||||
.operation-unit() {
|
||||
color: @link-color;
|
||||
|
@ -9,14 +9,48 @@
|
||||
// An override for the html selector for theme prefixes
|
||||
@html-selector: html;
|
||||
|
||||
// [CSS-VARIABLE-REPLACE-BEGIN: html-variables]
|
||||
// [CSS-VARIABLE-REPLACE-END: html-variables]
|
||||
|
||||
// -------- Colors -----------
|
||||
// >>> Primary
|
||||
@primary-color: @blue-6;
|
||||
@info-color: @primary-color;
|
||||
@success-color: @green-6;
|
||||
@primary-color-hover: color(~`colorPalette('@{primary-color}', 5) `);
|
||||
@primary-color-active: color(~`colorPalette('@{primary-color}', 7) `);
|
||||
@primary-color-outline: fade(@primary-color, @outline-fade);
|
||||
|
||||
@processing-color: @blue-6;
|
||||
@error-color: @red-5;
|
||||
@highlight-color: @red-5;
|
||||
|
||||
// >>> Info
|
||||
@info-color: @primary-color;
|
||||
@info-color-deprecated-bg: color(~`colorPalette('@{info-color}', 1) `);
|
||||
@info-color-deprecated-border: color(~`colorPalette('@{info-color}', 3) `);
|
||||
|
||||
// >>> Success
|
||||
@success-color: @green-6;
|
||||
@success-color-hover: color(~`colorPalette('@{success-color}', 5) `);
|
||||
@success-color-active: color(~`colorPalette('@{success-color}', 7) `);
|
||||
@success-color-outline: fade(@success-color, @outline-fade);
|
||||
@success-color-deprecated-bg: color(~`colorPalette('@{success-color}', 1) `);
|
||||
@success-color-deprecated-border: color(~`colorPalette('@{success-color}', 3) `);
|
||||
|
||||
// >>> Warning
|
||||
@warning-color: @gold-6;
|
||||
@warning-color-hover: color(~`colorPalette('@{warning-color}', 5) `);
|
||||
@warning-color-active: color(~`colorPalette('@{warning-color}', 7) `);
|
||||
@warning-color-outline: fade(@warning-color, @outline-fade);
|
||||
@warning-color-deprecated-bg: color(~`colorPalette('@{warning-color}', 1) `);
|
||||
@warning-color-deprecated-border: color(~`colorPalette('@{warning-color}', 3) `);
|
||||
|
||||
// >>> Error
|
||||
@error-color: @red-5;
|
||||
@error-color-hover: color(~`colorPalette('@{error-color}', 5) `);
|
||||
@error-color-active: color(~`colorPalette('@{error-color}', 7) `);
|
||||
@error-color-outline: fade(@error-color, @outline-fade);
|
||||
@error-color-deprecated-bg: color(~`colorPalette('@{error-color}', 1) `);
|
||||
@error-color-deprecated-border: color(~`colorPalette('@{error-color}', 3) `);
|
||||
|
||||
@highlight-color: @red-5;
|
||||
@normal-color: #d9d9d9;
|
||||
@white: #fff;
|
||||
@black: #000;
|
||||
@ -140,7 +174,7 @@
|
||||
// Outline
|
||||
@outline-blur-size: 0;
|
||||
@outline-width: 2px;
|
||||
@outline-color: @primary-color;
|
||||
@outline-color: @primary-color; // No use anymore
|
||||
@outline-fade: 20%;
|
||||
|
||||
@background-color-light: hsv(0, 0, 98%); // background of header and selected item
|
||||
@ -659,6 +693,7 @@
|
||||
@calendar-input-bg: @input-bg;
|
||||
@calendar-border-color: @border-color-inverse;
|
||||
@calendar-item-active-bg: @item-active-bg;
|
||||
@calendar-column-active-bg: fade(@calendar-item-active-bg, 20%);
|
||||
@calendar-full-bg: @calendar-bg;
|
||||
@calendar-full-panel-bg: @calendar-full-bg;
|
||||
|
||||
@ -887,6 +922,7 @@
|
||||
@transfer-disabled-bg: @disabled-bg;
|
||||
@transfer-list-height: 200px;
|
||||
@transfer-item-hover-bg: @item-hover-bg;
|
||||
@transfer-item-selected-hover-bg: darken(@item-active-bg, 2%);
|
||||
@transfer-item-padding-vertical: 6px;
|
||||
@transfer-list-search-icon-top: 12px;
|
||||
|
||||
|
@ -1 +1,7 @@
|
||||
@import './default.less';
|
||||
// Default using variable as entry to support site variable version
|
||||
// This will be replaced in webpack bundle
|
||||
// @root-entry-name: variable;
|
||||
|
||||
// @import './default.less';
|
||||
// @import './variable.less';
|
||||
@import './@{root-entry-name}.less';
|
||||
|
1113
components/style/themes/variable.less
Normal file
1113
components/style/themes/variable.less
Normal file
File diff suppressed because it is too large
Load Diff
4
components/style/variable.less
Normal file
4
components/style/variable.less
Normal file
@ -0,0 +1,4 @@
|
||||
@root-entry-name: variable;
|
||||
|
||||
@import './themes/variable.less';
|
||||
@import './core/index';
|
@ -30,7 +30,7 @@
|
||||
}
|
||||
|
||||
&-checked:focus {
|
||||
box-shadow: 0 0 0 2px fade(@switch-color, 20%);
|
||||
box-shadow: 0 0 0 2px @primary-1;
|
||||
}
|
||||
|
||||
&:focus:hover {
|
||||
|
@ -97,23 +97,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
.make-status-color-classes(@color, @status) {
|
||||
@lightColor: '@{color}-1';
|
||||
@lightBorderColor: '@{color}-3';
|
||||
@darkColor: '@{color}-6';
|
||||
.make-status-color-classes(@status, @cssVariableType) {
|
||||
@bgColor: '@{cssVariableType}-color-deprecated-bg';
|
||||
@borderColor: '@{cssVariableType}-color-deprecated-border';
|
||||
@textColor: '@{cssVariableType}-color';
|
||||
&-@{status} {
|
||||
color: @@darkColor;
|
||||
background: @@lightColor;
|
||||
border-color: @@lightBorderColor;
|
||||
color: @@textColor;
|
||||
background: @@bgColor;
|
||||
border-color: @@borderColor;
|
||||
}
|
||||
}
|
||||
|
||||
.make-color-classes();
|
||||
|
||||
.make-status-color-classes('green', success);
|
||||
.make-status-color-classes('blue', processing);
|
||||
.make-status-color-classes('red', error);
|
||||
.make-status-color-classes('orange', warning);
|
||||
.make-status-color-classes(success, success);
|
||||
.make-status-color-classes(processing, info);
|
||||
.make-status-color-classes(error, error);
|
||||
.make-status-color-classes(warning, warning);
|
||||
|
||||
// To ensure that a space will be placed between character and `Icon`.
|
||||
> .@{iconfont-css-prefix} + span,
|
||||
|
@ -152,7 +152,7 @@
|
||||
}
|
||||
|
||||
&.@{transfer-prefix-cls}-list-content-item-checked:hover {
|
||||
background-color: darken(@item-active-bg, 2%);
|
||||
background-color: @transfer-item-selected-hover-bg;
|
||||
}
|
||||
}
|
||||
|
||||
|
72
docs/react/customize-theme-variable.en-US.md
Normal file
72
docs/react/customize-theme-variable.en-US.md
Normal file
@ -0,0 +1,72 @@
|
||||
---
|
||||
order: 7.1
|
||||
title: Dynamic Theme (experience)
|
||||
---
|
||||
|
||||
Except [less customize theme](/docs/react/customize-theme), We also provide CSS Variable version to enable dynamic theme. You can check on [ConfigProvider](/components/config-provider/#components-config-provider-demo-theme) demo.
|
||||
|
||||
## Notice
|
||||
|
||||
This function need CSS Variable support which mean it can not support IE. Please make sure your browser requirement.
|
||||
|
||||
## How to use
|
||||
|
||||
### Import antd.variable.min.css
|
||||
|
||||
Replace your import style file with CSS Variable version:
|
||||
|
||||
```diff
|
||||
-- import 'antd/dist/antd.min.css';
|
||||
++ import 'antd/dist/antd.variable.min.css';
|
||||
```
|
||||
|
||||
### Static config
|
||||
|
||||
Call ConfigProvider static function to modify theme color:
|
||||
|
||||
```ts
|
||||
import { ConfigProvider } from 'antd';
|
||||
|
||||
ConfigProvider.config({
|
||||
theme: {
|
||||
primaryColor: '#25b864',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## Conflict resolve
|
||||
|
||||
CSS Variable use `--ant` prefix by default. When exist multiple antd style file in your project, you can modify prefix to fix it.
|
||||
|
||||
### Adjust
|
||||
|
||||
Modify `prefixCls` on the root of ConfigProvider:
|
||||
|
||||
```tsx
|
||||
import { ConfigProvider } from 'antd';
|
||||
|
||||
export default () => (
|
||||
<ConfigProvider prefixCls="custom">
|
||||
<MyApp />
|
||||
</ConfigProvider>
|
||||
);
|
||||
```
|
||||
|
||||
Also need call the static function to modify `prefixCls`:
|
||||
|
||||
```ts
|
||||
ConfigProvider.config({
|
||||
theme: {
|
||||
prefixCls: 'custom',
|
||||
primaryColor: '#25b864',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Compile less
|
||||
|
||||
Since prefix modified. Origin `antd.variable.css` should also be replaced:
|
||||
|
||||
```bash
|
||||
lessc --modify-var="ant-prefix=custom" antd/dist/antd.variable.less modified.css
|
||||
```
|
72
docs/react/customize-theme-variable.zh-CN.md
Normal file
72
docs/react/customize-theme-variable.zh-CN.md
Normal file
@ -0,0 +1,72 @@
|
||||
---
|
||||
order: 7.1
|
||||
title: 动态主题(实验性)
|
||||
---
|
||||
|
||||
除了 [less 定制主题外](/docs/react/customize-theme) 外,我们还提供了 CSS Variable 版本以支持动态切换主题能力。你可以在 [ConfigProvider](/components/config-provider/#components-config-provider-demo-theme) 进行体验。
|
||||
|
||||
## 注意事项
|
||||
|
||||
该功能通过动态修改 CSS Variable 实现,因而在 IE 中页面将无法正常展示。请先确认你的用户环境是否需要支持 IE。
|
||||
|
||||
## 如何使用
|
||||
|
||||
### 引入 antd.variable.min.css
|
||||
|
||||
替换当前项目引入样式文件为 CSS Variable 版本:
|
||||
|
||||
```diff
|
||||
-- import 'antd/dist/antd.min.css';
|
||||
++ import 'antd/dist/antd.variable.min.css';
|
||||
```
|
||||
|
||||
### 静态方法配置
|
||||
|
||||
调用 ConfigProvider 配置方法设置主题色:
|
||||
|
||||
```ts
|
||||
import { ConfigProvider } from 'antd';
|
||||
|
||||
ConfigProvider.config({
|
||||
theme: {
|
||||
primaryColor: '#25b864',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## 冲突解决
|
||||
|
||||
默认情况下,CSS Variable 会以 `--ant` 作为前缀。当你的项目中引用多份 css 文件时,可以通过修改前缀的方式避免冲突。
|
||||
|
||||
### 代码调整
|
||||
|
||||
通过 ConfigProvider 在顶层修改 `prefixCls`:
|
||||
|
||||
```tsx
|
||||
import { ConfigProvider } from 'antd';
|
||||
|
||||
export default () => (
|
||||
<ConfigProvider prefixCls="custom">
|
||||
<MyApp />
|
||||
</ConfigProvider>
|
||||
);
|
||||
```
|
||||
|
||||
通过静态方法设置主题色以及对应 `prefixCls`:
|
||||
|
||||
```ts
|
||||
ConfigProvider.config({
|
||||
theme: {
|
||||
prefixCls: 'custom',
|
||||
primaryColor: '#25b864',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### 编译 less
|
||||
|
||||
由于前缀变更,你需要重新生成一份对应的 css 文件。
|
||||
|
||||
```bash
|
||||
lessc --modify-var="ant-prefix=custom" antd/dist/antd.variable.less modified.css
|
||||
```
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
order: 7.1
|
||||
order: 7.5
|
||||
title: Replace Moment.js
|
||||
---
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
order: 7.1
|
||||
order: 7.5
|
||||
title: 替换 Moment.js
|
||||
---
|
||||
|
||||
|
24
index-style-only.js
Normal file
24
index-style-only.js
Normal file
@ -0,0 +1,24 @@
|
||||
function pascalCase(name) {
|
||||
return name.charAt(0).toUpperCase() + name.slice(1).replace(/-(\w)/g, (m, n) => n.toUpperCase());
|
||||
}
|
||||
|
||||
// Just import style for https://github.com/ant-design/ant-design/issues/3745
|
||||
const req = require.context('./components', true, /^\.\/[^_][\w-]+\/style\/index\.tsx?$/);
|
||||
|
||||
req.keys().forEach(mod => {
|
||||
let v = req(mod);
|
||||
if (v && v.default) {
|
||||
v = v.default;
|
||||
}
|
||||
const match = mod.match(/^\.\/([^_][\w-]+)\/index\.tsx?$/);
|
||||
if (match && match[1]) {
|
||||
if (match[1] === 'message' || match[1] === 'notification') {
|
||||
// message & notification should not be capitalized
|
||||
exports[match[1]] = v;
|
||||
} else {
|
||||
exports[pascalCase(match[1])] = v;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = exports;
|
24
index.js
24
index.js
@ -1,25 +1,3 @@
|
||||
/* eslint no-console:0 */
|
||||
function pascalCase(name) {
|
||||
return name.charAt(0).toUpperCase() + name.slice(1).replace(/-(\w)/g, (m, n) => n.toUpperCase());
|
||||
}
|
||||
|
||||
// Just import style for https://github.com/ant-design/ant-design/issues/3745
|
||||
const req = require.context('./components', true, /^\.\/[^_][\w-]+\/style\/index\.tsx?$/);
|
||||
|
||||
req.keys().forEach(mod => {
|
||||
let v = req(mod);
|
||||
if (v && v.default) {
|
||||
v = v.default;
|
||||
}
|
||||
const match = mod.match(/^\.\/([^_][\w-]+)\/index\.tsx?$/);
|
||||
if (match && match[1]) {
|
||||
if (match[1] === 'message' || match[1] === 'notification') {
|
||||
// message & notification should not be capitalized
|
||||
exports[match[1]] = v;
|
||||
} else {
|
||||
exports[pascalCase(match[1])] = v;
|
||||
}
|
||||
}
|
||||
});
|
||||
require('./index-style-only');
|
||||
|
||||
module.exports = require('./components');
|
||||
|
12
package.json
12
package.json
@ -62,7 +62,6 @@
|
||||
"presite": "npm run version",
|
||||
"color-less": "node ./scripts/generate-color-less",
|
||||
"compile": "npm run clean && antd-tools run compile",
|
||||
"compile:less": "antd-tools run compile:less",
|
||||
"changelog": "node ./scripts/print-changelog",
|
||||
"predeploy": "antd-tools run clean && npm run site && cp CNAME _site && npm run site:test",
|
||||
"deploy": "bisheng gh-pages --push-only --dotfiles",
|
||||
@ -94,7 +93,7 @@
|
||||
"test-node": "jest --config .jest.node.js --cache=false",
|
||||
"tsc": "tsc --noEmit",
|
||||
"site:test": "jest --config .jest.site.js --cache=false --force-exit",
|
||||
"test-image": "npm run compile:less && docker-compose run tests",
|
||||
"test-image": "npm run dist && docker-compose run tests",
|
||||
"version": "node ./scripts/generate-version",
|
||||
"install-react-16": "npm i --no-save react@16 react-dom@16 react-test-renderer@16 enzyme-adapter-react-16",
|
||||
"argos": "argos upload imageSnapshots"
|
||||
@ -112,6 +111,7 @@
|
||||
"@ant-design/icons": "^4.6.3",
|
||||
"@ant-design/react-slick": "~0.28.1",
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@ctrl/tinycolor": "^3.4.0",
|
||||
"array-tree-filter": "^2.1.0",
|
||||
"classnames": "^2.2.6",
|
||||
"copy-to-clipboard": "^3.2.0",
|
||||
@ -153,7 +153,7 @@
|
||||
"devDependencies": {
|
||||
"@ant-design/bisheng-plugin": "^2.3.0",
|
||||
"@ant-design/hitu": "^0.0.0-alpha.13",
|
||||
"@ant-design/tools": "^13.6.2",
|
||||
"@ant-design/tools": "^14.0.0-alpha.2",
|
||||
"@docsearch/css": "^3.0.0-alpha.39",
|
||||
"@docsearch/react": "^3.0.0-alpha.39",
|
||||
"@qixian.cs/github-contributors-list": "^1.0.3",
|
||||
@ -291,7 +291,7 @@
|
||||
"bundlesize": [
|
||||
{
|
||||
"path": "./dist/antd.min.js",
|
||||
"maxSize": "270 kB"
|
||||
"maxSize": "275 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/antd.min.css",
|
||||
@ -304,6 +304,10 @@
|
||||
{
|
||||
"path": "./dist/antd.compact.min.css",
|
||||
"maxSize": "65 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/antd.variable.min.css",
|
||||
"maxSize": "65 kB"
|
||||
}
|
||||
],
|
||||
"tnpm": {
|
||||
|
221
scripts/css-variable-sync.js
Normal file
221
scripts/css-variable-sync.js
Normal file
@ -0,0 +1,221 @@
|
||||
/**
|
||||
* ZombieJ: Since we still need mainly maintain the `default.less`. Create a script that generate
|
||||
* `variable.less` from the `default.less`
|
||||
*/
|
||||
|
||||
const fse = require('fs-extra');
|
||||
const path = require('path');
|
||||
const chalk = require('chalk');
|
||||
|
||||
const folderPath = path.resolve(__dirname, '..', 'components', 'style', 'themes');
|
||||
const targetPath = path.resolve(folderPath, 'variable.less');
|
||||
|
||||
const defaultContent = fse.readFileSync(path.resolve(folderPath, 'default.less'), 'utf8');
|
||||
|
||||
// const variableContent = fse.readFileSync(
|
||||
// path.resolve(__dirname, '..', 'components', 'style', 'themes', 'variable.less'),
|
||||
// 'utf8',
|
||||
// );
|
||||
|
||||
let variableContent = defaultContent;
|
||||
|
||||
function replaceVariable(key, value) {
|
||||
variableContent = variableContent.replace(new RegExp(`@${key}:[^;]*;`), `@${key}: ${value};`);
|
||||
}
|
||||
|
||||
function replaceVariableContent(key, content) {
|
||||
const lines = variableContent.split(/\n/);
|
||||
const startIndex = lines.findIndex(line => line.includes(`[CSS-VARIABLE-REPLACE-BEGIN: ${key}]`));
|
||||
const endIndex = lines.findIndex(line => line.includes(`[CSS-VARIABLE-REPLACE-END: ${key}]`));
|
||||
|
||||
if (startIndex !== -1 && endIndex !== -1) {
|
||||
variableContent = [...lines.slice(0, startIndex), content, ...lines.slice(endIndex + 1)].join(
|
||||
'\n',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
replaceVariable('theme', 'variable');
|
||||
|
||||
replaceVariableContent(
|
||||
'html-variables',
|
||||
`
|
||||
html {
|
||||
@base-primary: @blue-6;
|
||||
|
||||
// ========= Primary Color =========
|
||||
--@{ant-prefix}-primary-color: @base-primary;
|
||||
--@{ant-prefix}-primary-color-hover: color(~\`colorPalette('@{base-primary}', 5) \`);
|
||||
--@{ant-prefix}-primary-color-active: color(~\`colorPalette('@{base-primary}', 7) \`);
|
||||
--@{ant-prefix}-primary-color-outline: fade(@base-primary, @outline-fade);
|
||||
|
||||
// Legacy
|
||||
@legacy-primary-1: color(~\`colorPalette('@{base-primary}', 1) \`);
|
||||
|
||||
--@{ant-prefix}-primary-1: @legacy-primary-1;
|
||||
--@{ant-prefix}-primary-2: color(~\`colorPalette('@{base-primary}', 2) \`);
|
||||
--@{ant-prefix}-primary-3: color(~\`colorPalette('@{base-primary}', 3) \`);
|
||||
--@{ant-prefix}-primary-4: color(~\`colorPalette('@{base-primary}', 4) \`);
|
||||
--@{ant-prefix}-primary-5: color(~\`colorPalette('@{base-primary}', 5) \`);
|
||||
--@{ant-prefix}-primary-6: @base-primary;
|
||||
--@{ant-prefix}-primary-7: color(~\`colorPalette('@{base-primary}', 7) \`);
|
||||
|
||||
// Deprecated
|
||||
--@{ant-prefix}-primary-color-deprecated-pure: ~'';
|
||||
--@{ant-prefix}-primary-color-deprecated-l-35: lighten(@base-primary, 35%);
|
||||
--@{ant-prefix}-primary-color-deprecated-l-20: lighten(@base-primary, 20%);
|
||||
--@{ant-prefix}-primary-color-deprecated-t-20: tint(@base-primary, 20%);
|
||||
--@{ant-prefix}-primary-color-deprecated-t-50: tint(@base-primary, 50%);
|
||||
--@{ant-prefix}-primary-color-deprecated-f-12: fade(@base-primary, 12%);
|
||||
--@{ant-prefix}-primary-color-active-deprecated-f-30: fade(@legacy-primary-1, 30%);
|
||||
--@{ant-prefix}-primary-color-active-deprecated-d-02: darken(@legacy-primary-1, 2%);
|
||||
|
||||
// ========= Success Color =========
|
||||
--@{ant-prefix}-success-color: @green-6;
|
||||
--@{ant-prefix}-success-color-hover: color(~\`colorPalette('@{green-6}', 5) \`);
|
||||
--@{ant-prefix}-success-color-active: color(~\`colorPalette('@{green-6}', 7) \`);
|
||||
--@{ant-prefix}-success-color-outline: fade(@green-6, @outline-fade);
|
||||
--@{ant-prefix}-success-color-deprecated-bg: ~\`colorPalette('@{green-6}', 1) \`;
|
||||
--@{ant-prefix}-success-color-deprecated-border: ~\`colorPalette('@{green-6}', 3) \`;
|
||||
|
||||
// ========== Error Color ==========
|
||||
--@{ant-prefix}-error-color: @red-5;
|
||||
--@{ant-prefix}-error-color-hover: color(~\`colorPalette('@{red-5}', 5) \`);
|
||||
--@{ant-prefix}-error-color-active: color(~\`colorPalette('@{red-5}', 7) \`);
|
||||
--@{ant-prefix}-error-color-outline: fade(@red-5, @outline-fade);
|
||||
--@{ant-prefix}-error-color-deprecated-bg: ~\`colorPalette('@{red-5}', 1) \`;
|
||||
--@{ant-prefix}-error-color-deprecated-border: ~\`colorPalette('@{red-5}', 3) \`;
|
||||
|
||||
// ========= Warning Color =========
|
||||
--@{ant-prefix}-warning-color: @gold-6;
|
||||
--@{ant-prefix}-warning-color-hover: color(~\`colorPalette('@{gold-6}', 5) \`);
|
||||
--@{ant-prefix}-warning-color-active: color(~\`colorPalette('@{gold-6}', 7) \`);
|
||||
--@{ant-prefix}-warning-color-outline: fade(@gold-6, @outline-fade);
|
||||
--@{ant-prefix}-warning-color-deprecated-bg: ~\`colorPalette('@{gold-6}', 1) \`;
|
||||
--@{ant-prefix}-warning-color-deprecated-border: ~\`colorPalette('@{gold-6}', 3) \`;
|
||||
|
||||
// ========== Info Color ===========
|
||||
--@{ant-prefix}-info-color: @base-primary;
|
||||
--@{ant-prefix}-info-color-deprecated-bg: ~\`colorPalette('@{base-primary}', 1) \`;
|
||||
--@{ant-prefix}-info-color-deprecated-border: ~\`colorPalette('@{base-primary}', 3) \`;
|
||||
}
|
||||
`.trim(),
|
||||
);
|
||||
|
||||
// >>> Primary
|
||||
replaceVariable('primary-color', "~'var(--@{ant-prefix}-primary-color)'");
|
||||
replaceVariable('primary-color-hover', "~'var(--@{ant-prefix}-primary-color-hover)'");
|
||||
replaceVariable('primary-color-active', "~'var(--@{ant-prefix}-primary-color-active)'");
|
||||
replaceVariable('primary-color-outline', "~'var(--@{ant-prefix}-primary-color-outline)'");
|
||||
|
||||
replaceVariable('processing-color', '@primary-color');
|
||||
|
||||
// >>> Info
|
||||
replaceVariable('info-color', "~'var(--@{ant-prefix}-info-color)'");
|
||||
replaceVariable('info-color-deprecated-bg', "~'var(--@{ant-prefix}-info-color-deprecated-bg)'");
|
||||
replaceVariable(
|
||||
'info-color-deprecated-border',
|
||||
"~'var(--@{ant-prefix}-info-color-deprecated-border)'",
|
||||
);
|
||||
|
||||
// >>> Success
|
||||
replaceVariable('success-color', "~'var(--@{ant-prefix}-success-color)'");
|
||||
replaceVariable('success-color-hover', "~'var(--@{ant-prefix}-success-color-hover)'");
|
||||
replaceVariable('success-color-active', "~'var(--@{ant-prefix}-success-color-active)'");
|
||||
replaceVariable('success-color-outline', "~'var(--@{ant-prefix}-success-color-outline)'");
|
||||
replaceVariable(
|
||||
'success-color-deprecated-bg',
|
||||
"~'var(--@{ant-prefix}-success-color-deprecated-bg)'",
|
||||
);
|
||||
replaceVariable(
|
||||
'success-color-deprecated-border',
|
||||
"~'var(--@{ant-prefix}-success-color-deprecated-border)'",
|
||||
);
|
||||
|
||||
// >>> Warning
|
||||
replaceVariable('warning-color', "~'var(--@{ant-prefix}-warning-color)'");
|
||||
replaceVariable('warning-color-hover', "~'var(--@{ant-prefix}-warning-color-hover)'");
|
||||
replaceVariable('warning-color-active', "~'var(--@{ant-prefix}-warning-color-active)'");
|
||||
replaceVariable('warning-color-outline', "~'var(--@{ant-prefix}-warning-color-outline)'");
|
||||
replaceVariable(
|
||||
'warning-color-deprecated-bg',
|
||||
"~'var(--@{ant-prefix}-warning-color-deprecated-bg)'",
|
||||
);
|
||||
replaceVariable(
|
||||
'warning-color-deprecated-border',
|
||||
"~'var(--@{ant-prefix}-warning-color-deprecated-border)'",
|
||||
);
|
||||
|
||||
// >>> Error
|
||||
replaceVariable('error-color', "~'var(--@{ant-prefix}-error-color)'");
|
||||
replaceVariable('error-color-hover', "~'var(--@{ant-prefix}-error-color-hover)'");
|
||||
replaceVariable('error-color-active', "~'var(--@{ant-prefix}-error-color-active)'");
|
||||
replaceVariable('error-color-outline', "~'var(--@{ant-prefix}-error-color-outline)'");
|
||||
replaceVariable('error-color-deprecated-bg', "~'var(--@{ant-prefix}-error-color-deprecated-bg)'");
|
||||
replaceVariable(
|
||||
'error-color-deprecated-border',
|
||||
"~'var(--@{ant-prefix}-error-color-deprecated-border)'",
|
||||
);
|
||||
|
||||
// >>> Primary Level Color
|
||||
replaceVariable('primary-1', "~'var(--@{ant-prefix}-primary-1)'");
|
||||
replaceVariable('primary-2', "~'var(--@{ant-prefix}-primary-2)'");
|
||||
replaceVariable('primary-3', "~'var(--@{ant-prefix}-primary-3)'");
|
||||
replaceVariable('primary-4', "~'var(--@{ant-prefix}-primary-4)'");
|
||||
replaceVariable('primary-5', "~'var(--@{ant-prefix}-primary-5)'");
|
||||
replaceVariable('primary-6', "~'var(--@{ant-prefix}-primary-6)'");
|
||||
replaceVariable('primary-7', "~'var(--@{ant-prefix}-primary-7)'");
|
||||
|
||||
// Link
|
||||
replaceVariable('link-hover-color', '@primary-color-hover');
|
||||
replaceVariable('link-active-color', '@primary-color-active');
|
||||
|
||||
replaceVariable(
|
||||
'table-selected-row-hover-bg',
|
||||
"~'var(--@{ant-prefix}-primary-color-active-deprecated-d-02)'",
|
||||
);
|
||||
|
||||
replaceVariable(
|
||||
'picker-basic-cell-hover-with-range-color',
|
||||
"~'var(--@{ant-prefix}-primary-color-deprecated-l-35)'",
|
||||
);
|
||||
replaceVariable(
|
||||
'picker-date-hover-range-border-color',
|
||||
"~'var(--@{ant-prefix}-primary-color-deprecated-l-20)'",
|
||||
);
|
||||
|
||||
replaceVariable(
|
||||
'calendar-column-active-bg',
|
||||
"~'var(--@{ant-prefix}-primary-color-active-deprecated-f-30)'",
|
||||
);
|
||||
|
||||
replaceVariable(
|
||||
'slider-handle-color-focus',
|
||||
"~'var(--@{ant-prefix}-primary-color-deprecated-t-20)'",
|
||||
);
|
||||
replaceVariable(
|
||||
'slider-handle-color-focus-shadow',
|
||||
"~'var(--@{ant-prefix}-primary-color-deprecated-f-12)'",
|
||||
);
|
||||
replaceVariable(
|
||||
'slider-dot-border-color-active',
|
||||
"~'var(--@{ant-prefix}-primary-color-deprecated-t-50)'",
|
||||
);
|
||||
|
||||
replaceVariable(
|
||||
'transfer-item-selected-hover-bg',
|
||||
"~'var(--@{ant-prefix}-primary-color-active-deprecated-d-02)'",
|
||||
);
|
||||
|
||||
replaceVariable('alert-success-border-color', '@success-color-deprecated-border');
|
||||
replaceVariable('alert-success-bg-color', '@success-color-deprecated-bg');
|
||||
replaceVariable('alert-info-border-color', '@info-color-deprecated-border');
|
||||
replaceVariable('alert-info-bg-color', '@info-color-deprecated-bg');
|
||||
replaceVariable('alert-warning-border-color', '@warning-color-deprecated-border');
|
||||
replaceVariable('alert-warning-bg-color', '@warning-color-deprecated-bg');
|
||||
replaceVariable('alert-error-border-color', '@error-color-deprecated-border');
|
||||
replaceVariable('alert-error-bg-color', '@error-color-deprecated-bg');
|
||||
|
||||
fse.writeFileSync(targetPath, variableContent, 'utf8');
|
||||
|
||||
console.log(chalk.green('Success! Replaced path:'), targetPath);
|
29
site/antd.js
Normal file
29
site/antd.js
Normal file
@ -0,0 +1,29 @@
|
||||
/* eslint no-console:0 */
|
||||
function pascalCase(name) {
|
||||
return name.charAt(0).toUpperCase() + name.slice(1).replace(/-(\w)/g, (m, n) => n.toUpperCase());
|
||||
}
|
||||
|
||||
// Import all the component less file.
|
||||
// This is mostly like index.js but we do not need root `themes/index`
|
||||
const req = require.context('../components', true, /^\.\/[^_][\w-]+\/style\/index\.less$/);
|
||||
|
||||
req.keys().forEach(mod => {
|
||||
let v = req(mod);
|
||||
if (v && v.default) {
|
||||
v = v.default;
|
||||
}
|
||||
const match = mod.match(/^\.\/([^_][\w-]+)\/index\.less$/);
|
||||
if (match && match[1]) {
|
||||
if (match[1] === 'message' || match[1] === 'notification') {
|
||||
// message & notification should not be capitalized
|
||||
exports[match[1]] = v;
|
||||
} else {
|
||||
exports[pascalCase(match[1])] = v;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Need import for the additional core style
|
||||
exports.styleCore = require('../components/style/core/index.less');
|
||||
|
||||
module.exports = require('../components');
|
@ -56,12 +56,16 @@ module.exports = {
|
||||
},
|
||||
lessConfig: {
|
||||
javascriptEnabled: true,
|
||||
modifyVars: {
|
||||
'root-entry-name': 'variable',
|
||||
},
|
||||
},
|
||||
webpackConfig(config) {
|
||||
config.resolve.alias = {
|
||||
'antd/lib': path.join(process.cwd(), 'components'),
|
||||
'antd/es': path.join(process.cwd(), 'components'),
|
||||
antd: path.join(process.cwd(), 'index'),
|
||||
// Change antd from `index.js` to `site/antd.js` to remove deps of root style
|
||||
antd: path.join(process.cwd(), 'site', 'antd'),
|
||||
site: path.join(process.cwd(), 'site'),
|
||||
'react-router': 'react-router/umd/ReactRouter',
|
||||
};
|
||||
|
@ -88,6 +88,7 @@ module.exports = {
|
||||
'app.footer.community': 'Community',
|
||||
'app.footer.help': 'Help',
|
||||
'app.footer.change-log': 'Change Log',
|
||||
'app.footer.theme': 'Change theme color',
|
||||
'app.footer.faq': 'FAQ',
|
||||
'app.footer.feedback': 'Feedback',
|
||||
'app.footer.stackoverflow': 'StackOverflow',
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import '../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../components/style/themes/variable.less';
|
||||
|
||||
#header {
|
||||
// ===================== Home Page =====================
|
||||
|
@ -1,5 +1,5 @@
|
||||
@import './reset.less';
|
||||
@import '../../../components/style/themes/default.less';
|
||||
@import '../../../components/style/themes/variable.less';
|
||||
@import './common';
|
||||
@import './header';
|
||||
@import './footer';
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import '../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../components/style/themes/variable.less';
|
||||
|
||||
.nav-phone-icon {
|
||||
position: absolute;
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import '../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../components/style/themes/variable.less';
|
||||
@import './colors.less';
|
||||
@import './home.less';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import '../../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../../components/style/themes/variable.less';
|
||||
|
||||
.components-overview {
|
||||
padding: 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import '../../../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../../../components/style/themes/variable.less';
|
||||
|
||||
.home-banner-background {
|
||||
position: absolute;
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import '../../../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../../../components/style/themes/variable.less';
|
||||
|
||||
.home-card-logo {
|
||||
position: relative;
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import '../../../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../../../components/style/themes/variable.less';
|
||||
|
||||
@home-color: #0170fe;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import '../../../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../../../components/style/themes/variable.less';
|
||||
|
||||
.design-card {
|
||||
position: relative;
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import '../../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../../components/style/themes/variable.less';
|
||||
|
||||
.more-card {
|
||||
&:hover {
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import '../../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../../components/style/themes/variable.less';
|
||||
|
||||
.linear-gradient(@mid-pos, @end-pos) {
|
||||
background: linear-gradient(
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import '../../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../../components/style/themes/variable.less';
|
||||
|
||||
.home-container {
|
||||
h1,
|
||||
|
@ -16,6 +16,7 @@ import {
|
||||
BugOutlined,
|
||||
IssuesCloseOutlined,
|
||||
QuestionCircleOutlined,
|
||||
BgColorsOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import ColorPicker from '../Color/ColorPicker';
|
||||
import { loadScript, getLocalizedPathname } from '../utils';
|
||||
@ -306,7 +307,13 @@ class Footer extends React.Component<WrappedComponentProps & { location: any }>
|
||||
openExternal: true,
|
||||
},
|
||||
{
|
||||
title: this.renderThemeChanger(),
|
||||
icon: <BgColorsOutlined />,
|
||||
title: <FormattedMessage id="app.footer.theme" />,
|
||||
url: getLinkHash('/components/config-provider/', {
|
||||
zhCN: 'components-config-provider-demo-theme',
|
||||
enUS: 'components-config-provider-demo-theme',
|
||||
}),
|
||||
LinkComponent: Link,
|
||||
style: {
|
||||
marginTop: 20,
|
||||
},
|
||||
|
@ -1,5 +1,5 @@
|
||||
@import '../../../static/theme.less';
|
||||
@import '../../../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../../../components/style/themes/variable.less';
|
||||
|
||||
#github-btn {
|
||||
display: flex;
|
||||
|
@ -1,5 +1,5 @@
|
||||
@import '../../../static/theme.less';
|
||||
@import '../../../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../../../components/style/themes/variable.less';
|
||||
@import './index.less';
|
||||
|
||||
#logo {
|
||||
|
@ -1,5 +1,5 @@
|
||||
@import '../../../static/theme.less';
|
||||
@import '../../../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../../../components/style/themes/variable.less';
|
||||
@import './index.less';
|
||||
|
||||
#nav {
|
||||
|
@ -1,5 +1,5 @@
|
||||
@import '../../../static/theme.less';
|
||||
@import '../../../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../../../components/style/themes/variable.less';
|
||||
@import './index.less';
|
||||
@import './DocSearch.less';
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
@import '../../../static/theme.less';
|
||||
@import '../../../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../../../components/style/themes/variable.less';
|
||||
|
||||
@header-height: 64px;
|
||||
@menu-item-border: 2px;
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import '../../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../../components/style/themes/variable.less';
|
||||
@import './index.less';
|
||||
|
||||
.resource-affix-tabs {
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import '../../../../components/style/themes/default.less';
|
||||
@import (reference) '../../../../components/style/themes/variable.less';
|
||||
|
||||
@ArticleMaxWidth: 1208px;
|
||||
@resource-padding: 40px;
|
||||
|
@ -86,6 +86,7 @@ module.exports = {
|
||||
'app.footer.community': '社区',
|
||||
'app.footer.help': '帮助',
|
||||
'app.footer.change-log': '更新日志',
|
||||
'app.footer.theme': '切换主题色',
|
||||
'app.footer.faq': '常见问题',
|
||||
'app.footer.feedback': '反馈和建议',
|
||||
'app.footer.stackoverflow': 'StackOverflow',
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* eslint no-param-reassign: 0 */
|
||||
// This config is for building dist files
|
||||
const chalk = require('chalk');
|
||||
const getWebpackConfig = require('@ant-design/tools/lib/getWebpackConfig');
|
||||
const IgnoreEmitPlugin = require('ignore-emit-webpack-plugin');
|
||||
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
|
||||
@ -10,6 +11,30 @@ const compactVars = require('./scripts/compact-vars');
|
||||
|
||||
const { webpack } = getWebpackConfig;
|
||||
|
||||
function injectLessVariables(config, variables) {
|
||||
(Array.isArray(config) ? config : [config]).forEach(conf => {
|
||||
conf.module.rules.forEach(rule => {
|
||||
// filter less rule
|
||||
if (rule.test instanceof RegExp && rule.test.test('.less')) {
|
||||
const lessRule = rule.use[rule.use.length - 1];
|
||||
if (lessRule.options.lessOptions) {
|
||||
lessRule.options.lessOptions.modifyVars = {
|
||||
...lessRule.options.lessOptions.modifyVars,
|
||||
...variables,
|
||||
};
|
||||
} else {
|
||||
lessRule.options.modifyVars = {
|
||||
...lessRule.options.modifyVars,
|
||||
...variables,
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
// noParse still leave `require('./locale' + name)` in dist files
|
||||
// ignore is better: http://stackoverflow.com/q/25384360
|
||||
function ignoreMomentLocale(webpackConfig) {
|
||||
@ -60,22 +85,22 @@ function processWebpackThemeConfig(themeConfig, theme, vars) {
|
||||
|
||||
// rename default entry to ${theme} entry
|
||||
Object.keys(config.entry).forEach(entryName => {
|
||||
config.entry[entryName.replace('antd', `antd.${theme}`)] = config.entry[entryName];
|
||||
const originPath = config.entry[entryName];
|
||||
let replacedPath = [...originPath];
|
||||
|
||||
// We will replace `./index` to `./index-style-only` since theme dist only use style file
|
||||
if (originPath.length === 1 && originPath[0] === './index') {
|
||||
replacedPath = ['./index-style-only'];
|
||||
} else {
|
||||
console.log(chalk.red('🆘 Seems entry has changed! It should be `./index`'));
|
||||
}
|
||||
|
||||
config.entry[entryName.replace('antd', `antd.${theme}`)] = replacedPath;
|
||||
delete config.entry[entryName];
|
||||
});
|
||||
|
||||
// apply ${theme} less variables
|
||||
config.module.rules.forEach(rule => {
|
||||
// filter less rule
|
||||
if (rule.test instanceof RegExp && rule.test.test('.less')) {
|
||||
const lessRule = rule.use[rule.use.length - 1];
|
||||
if (lessRule.options.lessOptions) {
|
||||
lessRule.options.lessOptions.modifyVars = vars;
|
||||
} else {
|
||||
lessRule.options.modifyVars = vars;
|
||||
}
|
||||
}
|
||||
});
|
||||
injectLessVariables(config, vars);
|
||||
|
||||
const themeReg = new RegExp(`${theme}(.min)?\\.js(\\.map)?$`);
|
||||
// ignore emit ${theme} entry js & js.map file
|
||||
@ -83,9 +108,15 @@ function processWebpackThemeConfig(themeConfig, theme, vars) {
|
||||
});
|
||||
}
|
||||
|
||||
const webpackConfig = getWebpackConfig(false);
|
||||
const webpackDarkConfig = getWebpackConfig(false);
|
||||
const webpackCompactConfig = getWebpackConfig(false);
|
||||
const legacyEntryVars = {
|
||||
'root-entry-name': 'default',
|
||||
};
|
||||
const webpackConfig = injectLessVariables(getWebpackConfig(false), legacyEntryVars);
|
||||
const webpackDarkConfig = injectLessVariables(getWebpackConfig(false), legacyEntryVars);
|
||||
const webpackCompactConfig = injectLessVariables(getWebpackConfig(false), legacyEntryVars);
|
||||
const webpackVariableConfig = injectLessVariables(getWebpackConfig(false), {
|
||||
'root-entry-name': 'variable',
|
||||
});
|
||||
|
||||
webpackConfig.forEach(config => {
|
||||
injectWarningCondition(config);
|
||||
@ -124,6 +155,12 @@ if (process.env.RUN_ENV === 'PRODUCTION') {
|
||||
|
||||
processWebpackThemeConfig(webpackDarkConfig, 'dark', darkVars);
|
||||
processWebpackThemeConfig(webpackCompactConfig, 'compact', compactVars);
|
||||
processWebpackThemeConfig(webpackVariableConfig, 'variable', {});
|
||||
}
|
||||
|
||||
module.exports = [...webpackConfig, ...webpackDarkConfig, ...webpackCompactConfig];
|
||||
module.exports = [
|
||||
...webpackConfig,
|
||||
...webpackDarkConfig,
|
||||
...webpackCompactConfig,
|
||||
...webpackVariableConfig,
|
||||
];
|
||||
|
Loading…
Reference in New Issue
Block a user