chore: cssinjs hashed as default (#34272)

* checkbox hashId support

* chore: tree hashed

* chore: fix lint

* fix: compile
This commit is contained in:
二货机器人 2022-03-03 14:55:19 +08:00 committed by GitHub
parent 989a27ada8
commit 43eaa357b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 365 additions and 203 deletions

View File

@ -19,6 +19,7 @@ const defaultDesignToken: DesignToken = {
fontSize: 14, fontSize: 14,
textColor: new TinyColor('#000').setAlpha(0.85).toRgbString(), textColor: new TinyColor('#000').setAlpha(0.85).toRgbString(),
textColorDisabled: new TinyColor('#000').setAlpha(0.25).toRgbString(), textColorDisabled: new TinyColor('#000').setAlpha(0.25).toRgbString(),
textColorInverse: '#fff',
itemHoverBackground: '#f5f5f5', itemHoverBackground: '#f5f5f5',

View File

@ -21,6 +21,7 @@ export interface DesignToken {
fontSize: number; fontSize: number;
textColor: string; textColor: string;
textColorDisabled: string; textColorDisabled: string;
textColorInverse: string;
itemHoverBackground: string; itemHoverBackground: string;
@ -104,18 +105,24 @@ export const DesignTokenContext = React.createContext<{
}); });
// ================================== Hook ================================== // ================================== Hook ==================================
export function useToken() { export function useToken(): [Theme<DesignToken, DerivativeToken>, DerivativeToken, string] {
const { token: rootDesignToken, hashed } = React.useContext(DesignTokenContext); const { token: rootDesignToken, hashed } = React.useContext(DesignTokenContext);
const theme = React.useContext(ThemeContext); const theme = React.useContext(ThemeContext);
const salt = `${version}-${hashed || ''}`; const salt = `${version}-${hashed || ''}`;
const [token, hashId] = useCacheToken(theme, [defaultDesignToken, rootDesignToken], { const [token, hashId] = useCacheToken<DerivativeToken, DesignToken>(
theme,
[defaultDesignToken, rootDesignToken],
{
salt, salt,
}); },
);
return [theme, token, hashed ? hashId : '']; return [theme, token, hashed ? hashId : ''];
} }
export type UseComponentStyleResult = [(node: React.ReactNode) => React.ReactElement, string];
// ================================== Util ================================== // ================================== Util ==================================
export function withPrefix( export function withPrefix(
style: CSSObject, style: CSSObject,

View File

@ -159,7 +159,7 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
const prefixCls = getPrefixCls('btn', customizePrefixCls); const prefixCls = getPrefixCls('btn', customizePrefixCls);
// Style // Style
const wrapSSR = useStyle(prefixCls, iconPrefixCls); const [wrapSSR, hashId] = useStyle(prefixCls, iconPrefixCls);
const size = React.useContext(SizeContext); const size = React.useContext(SizeContext);
const [innerLoading, setLoading] = React.useState<Loading>(!!loading); const [innerLoading, setLoading] = React.useState<Loading>(!!loading);
@ -244,6 +244,7 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
const classes = classNames( const classes = classNames(
prefixCls, prefixCls,
hashId,
{ {
[`${prefixCls}-${shape}`]: shape !== 'default' && shape, // Note: Shape also has `default` [`${prefixCls}-${shape}`]: shape !== 'default' && shape, // Note: Shape also has `default`
[`${prefixCls}-${type}`]: type, [`${prefixCls}-${type}`]: type,

View File

@ -1,7 +1,13 @@
// deps-lint-skip-all // deps-lint-skip-all
import { CSSInterpolation, CSSObject } from '@ant-design/cssinjs'; import { CSSInterpolation, CSSObject } from '@ant-design/cssinjs';
import { TinyColor } from '@ctrl/tinycolor'; import { TinyColor } from '@ctrl/tinycolor';
import { DerivativeToken, useStyleRegister, useToken, withPrefix } from '../../_util/theme'; import {
DerivativeToken,
UseComponentStyleResult,
useStyleRegister,
useToken,
withPrefix,
} from '../../_util/theme';
// ============================== Shared ============================== // ============================== Shared ==============================
const genSharedButtonStyle = ( const genSharedButtonStyle = (
@ -373,10 +379,14 @@ const genSizeLargeButtonStyle = (
}; };
// ============================== Export ============================== // ============================== Export ==============================
export default function useStyle(prefixCls: string, iconPrefixCls: string) { export default function useStyle(
prefixCls: string,
iconPrefixCls: string,
): UseComponentStyleResult {
const [theme, token, hashId] = useToken(); const [theme, token, hashId] = useToken();
return useStyleRegister({ theme, token, hashId, path: [prefixCls] }, () => [ return [
useStyleRegister({ theme, token, hashId, path: [prefixCls] }, () => [
// Shared // Shared
withPrefix(genSharedButtonStyle(prefixCls, iconPrefixCls, token), prefixCls), withPrefix(genSharedButtonStyle(prefixCls, iconPrefixCls, token), prefixCls),
@ -387,5 +397,7 @@ export default function useStyle(prefixCls: string, iconPrefixCls: string) {
// Group (type, ghost, danger, disabled, loading) // Group (type, ghost, danger, disabled, loading)
genTypeButtonStyle(prefixCls, token), genTypeButtonStyle(prefixCls, token),
]); ]),
hashId,
];
} }

View File

@ -85,7 +85,7 @@ const InternalCheckbox: React.ForwardRefRenderFunction<HTMLInputElement, Checkbo
}, [restProps.value]); }, [restProps.value]);
const prefixCls = getPrefixCls('checkbox', customizePrefixCls); const prefixCls = getPrefixCls('checkbox', customizePrefixCls);
const wrapSSR = useStyle(prefixCls); const [wrapSSR, hashId] = useStyle(prefixCls);
const checkboxProps: CheckboxProps = { ...restProps }; const checkboxProps: CheckboxProps = { ...restProps };
if (checkboxGroup && !skipGroup) { if (checkboxGroup && !skipGroup) {
@ -109,10 +109,14 @@ const InternalCheckbox: React.ForwardRefRenderFunction<HTMLInputElement, Checkbo
[`${prefixCls}-wrapper-disabled`]: checkboxProps.disabled, [`${prefixCls}-wrapper-disabled`]: checkboxProps.disabled,
}, },
className, className,
hashId,
); );
const checkboxClass = classNames({ const checkboxClass = classNames(
{
[`${prefixCls}-indeterminate`]: indeterminate, [`${prefixCls}-indeterminate`]: indeterminate,
}); },
hashId,
);
return wrapSSR( return wrapSSR(
// eslint-disable-next-line jsx-a11y/label-has-associated-control // eslint-disable-next-line jsx-a11y/label-has-associated-control
<label <label

View File

@ -3,6 +3,7 @@ import classNames from 'classnames';
import omit from 'rc-util/lib/omit'; import omit from 'rc-util/lib/omit';
import Checkbox, { CheckboxChangeEvent } from './Checkbox'; import Checkbox, { CheckboxChangeEvent } from './Checkbox';
import { ConfigContext } from '../config-provider'; import { ConfigContext } from '../config-provider';
import useStyle from './style';
export type CheckboxValueType = string | number | boolean; export type CheckboxValueType = string | number | boolean;
@ -112,6 +113,8 @@ const InternalCheckboxGroup: React.ForwardRefRenderFunction<HTMLDivElement, Chec
const prefixCls = getPrefixCls('checkbox', customizePrefixCls); const prefixCls = getPrefixCls('checkbox', customizePrefixCls);
const groupPrefixCls = `${prefixCls}-group`; const groupPrefixCls = `${prefixCls}-group`;
const [wrapSSR, hashId] = useStyle(prefixCls);
const domProps = omit(restProps, ['value', 'disabled']); const domProps = omit(restProps, ['value', 'disabled']);
if (options && options.length > 0) { if (options && options.length > 0) {
@ -147,11 +150,12 @@ const InternalCheckboxGroup: React.ForwardRefRenderFunction<HTMLDivElement, Chec
[`${groupPrefixCls}-rtl`]: direction === 'rtl', [`${groupPrefixCls}-rtl`]: direction === 'rtl',
}, },
className, className,
hashId,
); );
return ( return wrapSSR(
<div className={classString} style={style} {...domProps} ref={ref}> <div className={classString} style={style} {...domProps} ref={ref}>
<GroupContext.Provider value={context}>{children}</GroupContext.Provider> <GroupContext.Provider value={context}>{children}</GroupContext.Provider>
</div> </div>,
); );
}; };

View File

@ -1,6 +1,12 @@
// deps-lint-skip-all // deps-lint-skip-all
import { CSSObject, Keyframes } from '@ant-design/cssinjs'; import { CSSInterpolation, Keyframes } from '@ant-design/cssinjs';
import { DerivativeToken, useStyleRegister, useToken, resetComponent } from '../../_util/theme'; import {
DerivativeToken,
useStyleRegister,
useToken,
resetComponent,
UseComponentStyleResult,
} from '../../_util/theme';
// ============================== Motion ============================== // ============================== Motion ==============================
const antCheckboxEffect = new Keyframes('antCheckboxEffect', { const antCheckboxEffect = new Keyframes('antCheckboxEffect', {
@ -20,11 +26,13 @@ export const genCheckboxStyle = (
prefixCls: string, prefixCls: string,
token: DerivativeToken, token: DerivativeToken,
hashId: string, hashId: string,
): CSSObject => { ): CSSInterpolation => {
const checkboxCls = `.${prefixCls}`; const checkboxCls = `.${prefixCls}`;
const wrapperCls = `${checkboxCls}-wrapper`; const wrapperCls = `${checkboxCls}-wrapper`;
return { return [
// ===================== Basic =====================
{
// Group // Group
[`${checkboxCls}-group`]: { [`${checkboxCls}-group`]: {
...resetComponent(token), ...resetComponent(token),
@ -66,7 +74,7 @@ export const genCheckboxStyle = (
cursor: 'pointer', cursor: 'pointer',
// Wrapper > Checkbox > input // Wrapper > Checkbox > input
'&-input': { [`${checkboxCls}-input`]: {
position: 'absolute', position: 'absolute',
inset: 0, inset: 0,
zIndex: 1, zIndex: 1,
@ -77,7 +85,7 @@ export const genCheckboxStyle = (
}, },
// Wrapper > Checkbox > inner // Wrapper > Checkbox > inner
'&-inner': { [`${checkboxCls}-inner`]: {
position: 'relative', position: 'relative',
top: 0, top: 0,
left: 0, left: 0,
@ -114,9 +122,12 @@ export const genCheckboxStyle = (
paddingRight: token.paddingXS, paddingRight: token.paddingXS,
}, },
}, },
},
// ================= Indeterminate ================= // ================= Indeterminate =================
[`${checkboxCls}-indeterminate`]: { {
[checkboxCls]: {
'&-indeterminate': {
// Wrapper > Checkbox > inner // Wrapper > Checkbox > inner
[`${checkboxCls}-inner`]: { [`${checkboxCls}-inner`]: {
'&:after': { '&:after': {
@ -132,8 +143,11 @@ export const genCheckboxStyle = (
}, },
}, },
}, },
},
},
// ===================== Hover ===================== // ===================== Hover =====================
{
// Wrapper // Wrapper
[`${wrapperCls}:hover ${checkboxCls}:after`]: { [`${wrapperCls}:hover ${checkboxCls}:after`]: {
visibility: 'visible', visibility: 'visible',
@ -149,9 +163,10 @@ export const genCheckboxStyle = (
borderColor: token.primaryColor, borderColor: token.primaryColor,
}, },
}, },
},
// ==================== Checked ==================== // ==================== Checked ====================
{
// Wrapper > Checkbox // Wrapper > Checkbox
[`${checkboxCls}-checked`]: { [`${checkboxCls}-checked`]: {
[`${checkboxCls}-inner`]: { [`${checkboxCls}-inner`]: {
@ -180,8 +195,10 @@ export const genCheckboxStyle = (
content: '""', content: '""',
}, },
}, },
},
// ==================== Disable ==================== // ==================== Disable ====================
{
// Wrapper // Wrapper
[`${wrapperCls}-disabled`]: { [`${wrapperCls}-disabled`]: {
cursor: 'not-allowed', cursor: 'not-allowed',
@ -212,7 +229,8 @@ export const genCheckboxStyle = (
color: token.textColorDisabled, color: token.textColorDisabled,
}, },
}, },
}; },
];
}; };
// ============================== Export ============================== // ============================== Export ==============================
@ -220,10 +238,13 @@ export function getStyle(prefixCls: string, token: DerivativeToken, hashId: stri
return [genCheckboxStyle(prefixCls, token, hashId), antCheckboxEffect]; return [genCheckboxStyle(prefixCls, token, hashId), antCheckboxEffect];
} }
export default function useStyle(prefixCls: string) { export default function useStyle(prefixCls: string): UseComponentStyleResult {
const [theme, token, hashId] = useToken(); const [theme, token, hashId] = useToken();
return useStyleRegister({ theme, token, hashId, path: [prefixCls] }, () => return [
useStyleRegister({ theme, token, hashId, path: [prefixCls] }, () =>
getStyle(prefixCls, token, hashId), getStyle(prefixCls, token, hashId),
); ),
hashId,
];
} }

View File

@ -85,6 +85,7 @@ export interface ConfigProviderProps {
dropdownMatchSelectWidth?: boolean; dropdownMatchSelectWidth?: boolean;
theme?: { theme?: {
token?: Partial<DesignToken>; token?: Partial<DesignToken>;
hashed?: boolean;
}; };
} }
@ -262,10 +263,12 @@ const ProviderChildren: React.FC<ProviderChildrenProps> = props => {
...defaultThemeToken, ...defaultThemeToken,
...theme?.token, ...theme?.token,
}, },
hashed: theme?.hashed,
}), }),
[theme?.token], [theme?.token, theme?.hashed],
); );
if (theme?.token) {
if (theme?.token || theme?.hashed) {
childNode = ( childNode = (
<DesignTokenContext.Provider value={memoTheme}>{childNode}</DesignTokenContext.Provider> <DesignTokenContext.Provider value={memoTheme}>{childNode}</DesignTokenContext.Provider>
); );

View File

@ -173,7 +173,7 @@ const Tree = React.forwardRef<RcTree, TreeProps>((props, ref) => {
dropIndicatorRender, dropIndicatorRender,
}; };
const wrapSSR = useStyle(prefixCls); const [wrapSSR, hashId] = useStyle(prefixCls);
const draggableConfig = React.useMemo(() => { const draggableConfig = React.useMemo(() => {
if (!draggable) { if (!draggable) {
@ -216,6 +216,7 @@ const Tree = React.forwardRef<RcTree, TreeProps>((props, ref) => {
[`${prefixCls}-rtl`]: direction === 'rtl', [`${prefixCls}-rtl`]: direction === 'rtl',
}, },
className, className,
hashId,
)} )}
direction={direction} direction={direction}
checkable={checkable ? <span className={`${prefixCls}-checkbox-inner`} /> : checkable} checkable={checkable ? <span className={`${prefixCls}-checkbox-inner`} /> : checkable}

View File

@ -3,7 +3,13 @@
// deps-lint-skip-all // deps-lint-skip-all
import { CSSObject, CSSInterpolation, Keyframes } from '@ant-design/cssinjs'; import { CSSObject, CSSInterpolation, Keyframes } from '@ant-design/cssinjs';
import { DerivativeToken, useStyleRegister, useToken, resetComponent } from '../../_util/theme'; import {
DerivativeToken,
useStyleRegister,
useToken,
resetComponent,
UseComponentStyleResult,
} from '../../_util/theme';
import { getStyle as getCheckboxStyle } from '../../checkbox/style'; import { getStyle as getCheckboxStyle } from '../../checkbox/style';
// ============================ Keyframes ============================= // ============================ Keyframes =============================
@ -80,7 +86,7 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken, hashId: string
}, },
// =================== Virtual List =================== // =================== Virtual List ===================
'&-list-holder-inner': { [`${treeCls}-list-holder-inner`]: {
alignItems: 'flex-start', alignItems: 'flex-start',
}, },
@ -91,8 +97,6 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken, hashId: string
// >>> Title // >>> Title
[`${treeCls}-node-content-wrapper`]: { [`${treeCls}-node-content-wrapper`]: {
flex: 'auto', flex: 'auto',
display: 'flex',
flexWrap: 'nowrap',
}, },
// >>> Drag // >>> Drag
@ -147,7 +151,7 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken, hashId: string
}, },
// >>> Indent // >>> Indent
'&-indent': { [`${treeCls}-indent`]: {
alignSelf: 'stretch', alignSelf: 'stretch',
whiteSpace: 'nowrap', whiteSpace: 'nowrap',
userSelect: 'none', userSelect: 'none',
@ -158,7 +162,7 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken, hashId: string
}, },
// >>> Drag Handler // >>> Drag Handler
'&-draggable-icon': { [`${treeCls}-draggable-icon`]: {
width: treeTitleHeight, width: treeTitleHeight,
lineHeight: `${treeTitleHeight}px`, lineHeight: `${treeTitleHeight}px`,
textAlign: 'center', textAlign: 'center',
@ -171,7 +175,7 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken, hashId: string
}, },
// >>> Switcher // >>> Switcher
'&-switcher': { [`${treeCls}-switcher`]: {
...getSwitchStyle(prefixCls, token), ...getSwitchStyle(prefixCls, token),
position: 'relative', position: 'relative',
flex: 'none', flex: 'none',
@ -228,14 +232,16 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken, hashId: string
}, },
// >>> Checkbox // >>> Checkbox
'&-checkbox': { [`${treeCls}-checkbox`]: {
top: 'initial', top: 'initial',
marginInlineEnd: treeCheckBoxMarginHorizontal, marginInlineEnd: treeCheckBoxMarginHorizontal,
marginBlockStart: treeCheckBoxMarginVertical, marginBlockStart: treeCheckBoxMarginVertical,
}, },
// >>> Title // >>> Title
'& &-node-content-wrapper': { [`& ${treeCls}-node-content-wrapper`]: {
display: 'flex',
flexWrap: 'nowrap',
position: 'relative', position: 'relative',
zIndex: 'auto', zIndex: 'auto',
minHeight: treeTitleHeight, minHeight: treeTitleHeight,
@ -272,12 +278,12 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken, hashId: string
}, },
// https://github.com/ant-design/ant-design/issues/28217 // https://github.com/ant-design/ant-design/issues/28217
'&-unselectable &-node-content-wrapper:hover': { [`${treeCls}-unselectable ${treeCls}-node-content-wrapper:hover`]: {
backgroundColor: 'transparent', backgroundColor: 'transparent',
}, },
// ==================== Draggable ===================== // ==================== Draggable =====================
'&-node-content-wrapper': { [`${treeCls}-node-content-wrapper`]: {
lineHeight: `${treeTitleHeight}px`, lineHeight: `${treeTitleHeight}px`,
userSelect: 'none', userSelect: 'none',
@ -366,7 +372,7 @@ export const genRTLStyle = (token: TreeToken): CSSObject => {
}, },
// >>> Switcher // >>> Switcher
'&-switcher': { [`${treeCls}-switcher`]: {
'&_close': { '&_close': {
[`${treeCls}-switcher-icon`]: { [`${treeCls}-switcher-icon`]: {
svg: { svg: {
@ -398,6 +404,84 @@ export const genRTLStyle = (token: TreeToken): CSSObject => {
}; };
}; };
// ============================ Directory =============================
export const genDirectoryStyle = (token: TreeToken): CSSObject => {
const { treeCls, treeNodeCls, treeNodePadding } = token;
return {
[`${treeCls}${treeCls}-directory`]: {
// ================== TreeNode ==================
[treeNodeCls]: {
position: 'relative',
// Hover color
'&:before': {
position: 'absolute',
top: 0,
right: 0,
bottom: treeNodePadding,
left: 0,
transition: `background-color ${token.duration}`,
content: '""',
pointerEvents: 'none',
},
'&:hover': {
'&:before': {
background: token.itemHoverBackground,
},
},
// Elements
'> *': {
zIndex: 1,
},
// >>> Switcher
[`${treeCls}-switcher`]: {
transition: `color ${token.duration}`,
},
// >>> Title
[`${treeCls}-node-content-wrapper`]: {
borderRadius: 0,
userSelect: 'none',
'&:hover': {
background: 'transparent',
},
[`&.${treeCls}-node-selected`]: {
color: token.textColorInverse,
background: 'transparent',
},
},
// ============= Selected =============
'&-selected': {
[`
&:hover::before,
&::before
`]: {
background: token.primaryColor,
},
// >>> Switcher
[`${treeCls}-switcher`]: {
color: token.textColorInverse,
},
// >>> Title
[`${treeCls}-node-content-wrapper`]: {
color: token.textColorInverse,
background: 'transparent',
},
},
},
},
};
};
// ============================== Merged ============================== // ============================== Merged ==============================
export const genTreeStyle = ( export const genTreeStyle = (
prefixCls: string, prefixCls: string,
@ -423,16 +507,21 @@ export const genTreeStyle = (
genBaseStyle(prefixCls, treeToken, hashId), genBaseStyle(prefixCls, treeToken, hashId),
// RTL // RTL
genRTLStyle(treeToken), genRTLStyle(treeToken),
// Directory
genDirectoryStyle(treeToken),
]; ];
}; };
// ============================== Export ============================== // ============================== Export ==============================
export default function useStyle(prefixCls: string) { export default function useStyle(prefixCls: string): UseComponentStyleResult {
const [theme, token, hashId] = useToken(); const [theme, token, hashId] = useToken();
return useStyleRegister({ theme, token, hashId, path: [prefixCls] }, () => [ return [
useStyleRegister({ theme, token, hashId, path: [prefixCls] }, () => [
getCheckboxStyle(`${prefixCls}-checkbox`, token, hashId), getCheckboxStyle(`${prefixCls}-checkbox`, token, hashId),
genTreeStyle(prefixCls, token, hashId), genTreeStyle(prefixCls, token, hashId),
treeNodeFX, treeNodeFX,
]); ]),
hashId,
];
} }

View File

@ -113,7 +113,7 @@
], ],
"dependencies": { "dependencies": {
"@ant-design/colors": "^6.0.0", "@ant-design/colors": "^6.0.0",
"@ant-design/cssinjs": "~0.0.0-alpha.10", "@ant-design/cssinjs": "~0.0.0-alpha.12",
"@ant-design/icons": "^4.7.0", "@ant-design/icons": "^4.7.0",
"@ant-design/react-slick": "~0.28.1", "@ant-design/react-slick": "~0.28.1",
"@babel/runtime": "^7.12.5", "@babel/runtime": "^7.12.5",

View File

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import { TinyColor } from '@ctrl/tinycolor'; import { TinyColor } from '@ctrl/tinycolor';
import { Drawer, Form, Input, Button, InputNumber } from 'antd'; import { Drawer, Form, Input, Button, InputNumber, Checkbox } from 'antd';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import { BugOutlined } from '@ant-design/icons'; import { BugOutlined } from '@ant-design/icons';
import { DesignToken } from '../../../../components/_util/theme'; import { DesignToken } from '../../../../components/_util/theme';
@ -95,6 +95,10 @@ export default ({ onChangeTheme, defaultToken }: ThemeConfigProps) => {
</Form.Item> </Form.Item>
); );
})} })}
<Form.Item name="hashed" valuePropName="checked">
<Checkbox>Bind Style on hash className</Checkbox>
</Form.Item>
</Form> </Form>
</Drawer> </Drawer>
</> </>

View File

@ -82,6 +82,7 @@ export default class Layout extends React.Component {
direction: 'ltr', direction: 'ltr',
setIframeTheme: this.setIframeTheme, setIframeTheme: this.setIframeTheme,
designToken: defaultDesignToken, designToken: defaultDesignToken,
hashedStyle: true,
}; };
} }
@ -210,8 +211,16 @@ export default class Layout extends React.Component {
render() { render() {
const { children, helmetContext = {}, ...restProps } = this.props; const { children, helmetContext = {}, ...restProps } = this.props;
const { appLocale, direction, isMobile, theme, setTheme, setIframeTheme, designToken } = const {
this.state; appLocale,
direction,
isMobile,
theme,
setTheme,
setIframeTheme,
designToken,
hashedStyle,
} = this.state;
const title = const title =
appLocale.locale === 'zh-CN' appLocale.locale === 'zh-CN'
? 'Ant Design - 一套企业级 UI 设计语言和 React 组件库' ? 'Ant Design - 一套企业级 UI 设计语言和 React 组件库'
@ -255,17 +264,23 @@ export default class Layout extends React.Component {
direction={direction} direction={direction}
theme={{ theme={{
token: designToken, token: designToken,
hashed: hashedStyle,
}} }}
> >
<Header {...restProps} changeDirection={this.changeDirection} /> <Header {...restProps} changeDirection={this.changeDirection} />
{children} {children}
<DynamicTheme <DynamicTheme
defaultToken={designToken} defaultToken={{
...designToken,
hashed: hashedStyle,
}}
onChangeTheme={newToken => { onChangeTheme={newToken => {
console.log('Change Theme:', newToken); console.log('Change Theme:', newToken);
const { hashed, ...restToken } = newToken;
this.setState({ this.setState({
designToken: newToken, designToken: restToken,
hashedStyle: hashed,
}); });
}} }}
/> />