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,
textColor: new TinyColor('#000').setAlpha(0.85).toRgbString(),
textColorDisabled: new TinyColor('#000').setAlpha(0.25).toRgbString(),
textColorInverse: '#fff',
itemHoverBackground: '#f5f5f5',

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,12 @@
// deps-lint-skip-all
import { CSSObject, Keyframes } from '@ant-design/cssinjs';
import { DerivativeToken, useStyleRegister, useToken, resetComponent } from '../../_util/theme';
import { CSSInterpolation, Keyframes } from '@ant-design/cssinjs';
import {
DerivativeToken,
useStyleRegister,
useToken,
resetComponent,
UseComponentStyleResult,
} from '../../_util/theme';
// ============================== Motion ==============================
const antCheckboxEffect = new Keyframes('antCheckboxEffect', {
@ -20,199 +26,211 @@ export const genCheckboxStyle = (
prefixCls: string,
token: DerivativeToken,
hashId: string,
): CSSObject => {
): CSSInterpolation => {
const checkboxCls = `.${prefixCls}`;
const wrapperCls = `${checkboxCls}-wrapper`;
return {
// Group
[`${checkboxCls}-group`]: {
...resetComponent(token),
return [
// ===================== Basic =====================
{
// Group
[`${checkboxCls}-group`]: {
...resetComponent(token),
display: 'inline-flex',
},
// Wrapper
[wrapperCls]: {
...resetComponent(token),
display: 'inline-flex',
alignItems: 'baseline',
lineHeight: 'unset',
cursor: 'pointer',
// Fix checkbox & radio in flex align #30260
'&:after': {
display: 'inline-block',
width: 0,
overflow: 'hidden',
content: "'\\a0'",
display: 'inline-flex',
},
// Checkbox near checkbox
'& + &': {
marginInlineStart: token.marginXS,
},
},
// Wrapper
[wrapperCls]: {
...resetComponent(token),
// Wrapper > Checkbox
[checkboxCls]: {
...resetComponent(token),
top: '0.2em',
position: 'relative',
whiteSpace: 'nowrap',
lineHeight: 1,
cursor: 'pointer',
// Wrapper > Checkbox > input
'&-input': {
position: 'absolute',
inset: 0,
zIndex: 1,
width: '100%',
height: '100%',
display: 'inline-flex',
alignItems: 'baseline',
lineHeight: 'unset',
cursor: 'pointer',
opacity: 0,
},
// Wrapper > Checkbox > inner
'&-inner': {
position: 'relative',
top: 0,
left: 0,
display: 'block',
width: token.fontSizeLG,
height: token.fontSizeLG,
direction: 'ltr',
backgroundColor: token.componentBackground,
border: `${token.borderWidth}px ${token.borderStyle} ${token.borderColor}`,
borderRadius: token.borderRadius,
borderCollapse: 'separate',
transition: `all ${token.duration}`,
// Fix checkbox & radio in flex align #30260
'&:after': {
position: 'absolute',
top: '50%',
left: '21.5%',
display: 'table',
width: (token.fontSizeLG / 14) * 5,
height: (token.fontSizeLG / 14) * 8,
border: `2px solid ${token.componentBackground}`,
borderTop: 0,
borderLeft: 0,
transform: 'rotate(45deg) scale(0) translate(-50%,-50%)',
opacity: 0,
transition: `all ${token.durationFast} cubic-bezier(.71,-.46,.88,.6), opacity ${token.durationFast}`,
content: '""',
display: 'inline-block',
width: 0,
overflow: 'hidden',
content: "'\\a0'",
},
// Checkbox near checkbox
'& + &': {
marginInlineStart: token.marginXS,
},
},
// Wrapper > Checkbox + Text
'& + span': {
paddingLeft: token.paddingXS,
paddingRight: token.paddingXS,
// Wrapper > Checkbox
[checkboxCls]: {
...resetComponent(token),
top: '0.2em',
position: 'relative',
whiteSpace: 'nowrap',
lineHeight: 1,
cursor: 'pointer',
// Wrapper > Checkbox > input
[`${checkboxCls}-input`]: {
position: 'absolute',
inset: 0,
zIndex: 1,
width: '100%',
height: '100%',
cursor: 'pointer',
opacity: 0,
},
// Wrapper > Checkbox > inner
[`${checkboxCls}-inner`]: {
position: 'relative',
top: 0,
left: 0,
display: 'block',
width: token.fontSizeLG,
height: token.fontSizeLG,
direction: 'ltr',
backgroundColor: token.componentBackground,
border: `${token.borderWidth}px ${token.borderStyle} ${token.borderColor}`,
borderRadius: token.borderRadius,
borderCollapse: 'separate',
transition: `all ${token.duration}`,
'&:after': {
position: 'absolute',
top: '50%',
left: '21.5%',
display: 'table',
width: (token.fontSizeLG / 14) * 5,
height: (token.fontSizeLG / 14) * 8,
border: `2px solid ${token.componentBackground}`,
borderTop: 0,
borderLeft: 0,
transform: 'rotate(45deg) scale(0) translate(-50%,-50%)',
opacity: 0,
transition: `all ${token.durationFast} cubic-bezier(.71,-.46,.88,.6), opacity ${token.durationFast}`,
content: '""',
},
},
// Wrapper > Checkbox + Text
'& + span': {
paddingLeft: token.paddingXS,
paddingRight: token.paddingXS,
},
},
},
// ================= Indeterminate =================
[`${checkboxCls}-indeterminate`]: {
// Wrapper > Checkbox > inner
[`${checkboxCls}-inner`]: {
'&:after': {
top: '50%',
left: '50%',
width: token.fontSizeLG / 2,
height: token.fontSizeLG / 2,
backgroundColor: token.primaryColor,
border: 0,
transform: 'translate(-50%, -50%) scale(1)',
opacity: 1,
content: '""',
{
[checkboxCls]: {
'&-indeterminate': {
// Wrapper > Checkbox > inner
[`${checkboxCls}-inner`]: {
'&:after': {
top: '50%',
left: '50%',
width: token.fontSizeLG / 2,
height: token.fontSizeLG / 2,
backgroundColor: token.primaryColor,
border: 0,
transform: 'translate(-50%, -50%) scale(1)',
opacity: 1,
content: '""',
},
},
},
},
},
// ===================== Hover =====================
// Wrapper
[`${wrapperCls}:hover ${checkboxCls}:after`]: {
visibility: 'visible',
},
{
// Wrapper
[`${wrapperCls}:hover ${checkboxCls}:after`]: {
visibility: 'visible',
},
// Wrapper & Wrapper > Checkbox
[`
// Wrapper & Wrapper > Checkbox
[`
${wrapperCls}:hover:not(${wrapperCls}-disabled),
${checkboxCls}:hover:not(${checkboxCls}-disabled),
${checkboxCls}-input:focus +
`]: {
[`${checkboxCls}-inner`]: {
borderColor: token.primaryColor,
[`${checkboxCls}-inner`]: {
borderColor: token.primaryColor,
},
},
},
// ==================== Checked ====================
{
// Wrapper > Checkbox
[`${checkboxCls}-checked`]: {
[`${checkboxCls}-inner`]: {
backgroundColor: token.primaryColor,
borderColor: token.primaryColor,
// Wrapper > Checkbox
[`${checkboxCls}-checked`]: {
[`${checkboxCls}-inner`]: {
backgroundColor: token.primaryColor,
borderColor: token.primaryColor,
'&:after': {
opacity: 1,
transform: 'rotate(45deg) scale(1) translate(-50%,-50%)',
transition: `all ${token.duration} ${token.easeOutBack} 0.1s`,
'&:after': {
opacity: 1,
transform: 'rotate(45deg) scale(1) translate(-50%,-50%)',
transition: `all ${token.duration} ${token.easeOutBack} 0.1s`,
},
},
},
// Checked Effect
'&:after': {
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
border: `${token.borderWidth}px ${token.borderStyle} ${token.primaryColor}`,
borderRadius: token.borderRadius,
visibility: 'hidden',
animation: `${antCheckboxEffect.getName(hashId)} ${token.duration} ease-in-out`,
animationFillMode: 'backwards',
content: '""',
// Checked Effect
'&:after': {
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
border: `${token.borderWidth}px ${token.borderStyle} ${token.primaryColor}`,
borderRadius: token.borderRadius,
visibility: 'hidden',
animation: `${antCheckboxEffect.getName(hashId)} ${token.duration} ease-in-out`,
animationFillMode: 'backwards',
content: '""',
},
},
},
// ==================== Disable ====================
// Wrapper
[`${wrapperCls}-disabled`]: {
cursor: 'not-allowed',
},
// Wrapper > Checkbox
[`${checkboxCls}-disabled`]: {
// Wrapper > Checkbox > input
[`&, ${checkboxCls}-input`]: {
{
// Wrapper
[`${wrapperCls}-disabled`]: {
cursor: 'not-allowed',
},
// Wrapper > Checkbox > inner
[`${checkboxCls}-inner`]: {
background: token.background,
borderColor: token.borderColor,
// Wrapper > Checkbox
[`${checkboxCls}-disabled`]: {
// Wrapper > Checkbox > input
[`&, ${checkboxCls}-input`]: {
cursor: 'not-allowed',
},
// Wrapper > Checkbox > inner
[`${checkboxCls}-inner`]: {
background: token.background,
borderColor: token.borderColor,
'&:after': {
borderColor: token.borderColor,
},
},
'&:after': {
borderColor: token.borderColor,
display: 'none',
},
'& + span': {
color: token.textColorDisabled,
},
},
'&:after': {
display: 'none',
},
'& + span': {
color: token.textColorDisabled,
},
},
};
];
};
// ============================== Export ==============================
@ -220,10 +238,13 @@ export function getStyle(prefixCls: string, token: DerivativeToken, hashId: stri
return [genCheckboxStyle(prefixCls, token, hashId), antCheckboxEffect];
}
export default function useStyle(prefixCls: string) {
export default function useStyle(prefixCls: string): UseComponentStyleResult {
const [theme, token, hashId] = useToken();
return useStyleRegister({ theme, token, hashId, path: [prefixCls] }, () =>
getStyle(prefixCls, token, hashId),
);
return [
useStyleRegister({ theme, token, hashId, path: [prefixCls] }, () =>
getStyle(prefixCls, token, hashId),
),
hashId,
];
}

View File

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

View File

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

View File

@ -3,7 +3,13 @@
// deps-lint-skip-all
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';
// ============================ Keyframes =============================
@ -80,7 +86,7 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken, hashId: string
},
// =================== Virtual List ===================
'&-list-holder-inner': {
[`${treeCls}-list-holder-inner`]: {
alignItems: 'flex-start',
},
@ -91,8 +97,6 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken, hashId: string
// >>> Title
[`${treeCls}-node-content-wrapper`]: {
flex: 'auto',
display: 'flex',
flexWrap: 'nowrap',
},
// >>> Drag
@ -147,7 +151,7 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken, hashId: string
},
// >>> Indent
'&-indent': {
[`${treeCls}-indent`]: {
alignSelf: 'stretch',
whiteSpace: 'nowrap',
userSelect: 'none',
@ -158,7 +162,7 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken, hashId: string
},
// >>> Drag Handler
'&-draggable-icon': {
[`${treeCls}-draggable-icon`]: {
width: treeTitleHeight,
lineHeight: `${treeTitleHeight}px`,
textAlign: 'center',
@ -171,7 +175,7 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken, hashId: string
},
// >>> Switcher
'&-switcher': {
[`${treeCls}-switcher`]: {
...getSwitchStyle(prefixCls, token),
position: 'relative',
flex: 'none',
@ -228,14 +232,16 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken, hashId: string
},
// >>> Checkbox
'&-checkbox': {
[`${treeCls}-checkbox`]: {
top: 'initial',
marginInlineEnd: treeCheckBoxMarginHorizontal,
marginBlockStart: treeCheckBoxMarginVertical,
},
// >>> Title
'& &-node-content-wrapper': {
[`& ${treeCls}-node-content-wrapper`]: {
display: 'flex',
flexWrap: 'nowrap',
position: 'relative',
zIndex: 'auto',
minHeight: treeTitleHeight,
@ -272,12 +278,12 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken, hashId: string
},
// https://github.com/ant-design/ant-design/issues/28217
'&-unselectable &-node-content-wrapper:hover': {
[`${treeCls}-unselectable ${treeCls}-node-content-wrapper:hover`]: {
backgroundColor: 'transparent',
},
// ==================== Draggable =====================
'&-node-content-wrapper': {
[`${treeCls}-node-content-wrapper`]: {
lineHeight: `${treeTitleHeight}px`,
userSelect: 'none',
@ -366,7 +372,7 @@ export const genRTLStyle = (token: TreeToken): CSSObject => {
},
// >>> Switcher
'&-switcher': {
[`${treeCls}-switcher`]: {
'&_close': {
[`${treeCls}-switcher-icon`]: {
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 ==============================
export const genTreeStyle = (
prefixCls: string,
@ -423,16 +507,21 @@ export const genTreeStyle = (
genBaseStyle(prefixCls, treeToken, hashId),
// RTL
genRTLStyle(treeToken),
// Directory
genDirectoryStyle(treeToken),
];
};
// ============================== Export ==============================
export default function useStyle(prefixCls: string) {
export default function useStyle(prefixCls: string): UseComponentStyleResult {
const [theme, token, hashId] = useToken();
return useStyleRegister({ theme, token, hashId, path: [prefixCls] }, () => [
getCheckboxStyle(`${prefixCls}-checkbox`, token, hashId),
genTreeStyle(prefixCls, token, hashId),
treeNodeFX,
]);
return [
useStyleRegister({ theme, token, hashId, path: [prefixCls] }, () => [
getCheckboxStyle(`${prefixCls}-checkbox`, token, hashId),
genTreeStyle(prefixCls, token, hashId),
treeNodeFX,
]),
hashId,
];
}

View File

@ -113,7 +113,7 @@
],
"dependencies": {
"@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/react-slick": "~0.28.1",
"@babel/runtime": "^7.12.5",

View File

@ -1,6 +1,6 @@
import * as React from 'react';
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 { BugOutlined } from '@ant-design/icons';
import { DesignToken } from '../../../../components/_util/theme';
@ -95,6 +95,10 @@ export default ({ onChangeTheme, defaultToken }: ThemeConfigProps) => {
</Form.Item>
);
})}
<Form.Item name="hashed" valuePropName="checked">
<Checkbox>Bind Style on hash className</Checkbox>
</Form.Item>
</Form>
</Drawer>
</>

View File

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