mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-07 09:26:06 +08:00
refactor: ConfigProvider theme API update (#37568)
* refactor: ConfigProvider theme support component alias * test: fix test case * chore: code clean * test: fix lint * test: fix tsx-demo
This commit is contained in:
parent
8bdabe25e0
commit
3515a40706
@ -57,12 +57,10 @@ export default function genPurePanel<ComponentProps extends BaseProps>(
|
||||
return (
|
||||
<ConfigProvider
|
||||
theme={{
|
||||
override: {
|
||||
derivative: {
|
||||
motionDurationFast: '0.01s',
|
||||
motionDurationMid: '0.01s',
|
||||
motionDurationSlow: '0.01s',
|
||||
},
|
||||
token: {
|
||||
motionDurationFast: '0.01s',
|
||||
motionDurationMid: '0.01s',
|
||||
motionDurationSlow: '0.01s',
|
||||
},
|
||||
}}
|
||||
>
|
||||
|
@ -52,10 +52,8 @@ describe('ConfigProvider.DynamicTheme', () => {
|
||||
mount(
|
||||
<ConfigProvider
|
||||
theme={{
|
||||
override: {
|
||||
alias: {
|
||||
colorSplit: 'blue',
|
||||
},
|
||||
token: {
|
||||
colorSplit: 'blue',
|
||||
},
|
||||
}}
|
||||
>
|
||||
|
@ -69,7 +69,7 @@ describe('ConfigProvider.Theme', () => {
|
||||
<Demo />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
expect(tokenRef?.colorPrimary).toBe('#177ddc');
|
||||
expect(tokenRef?.colorPrimaryText).toBe('#177ddc');
|
||||
});
|
||||
|
||||
it('defaultAlgorithmV4 should work', () => {
|
||||
@ -116,12 +116,12 @@ describe('ConfigProvider.Theme', () => {
|
||||
<Demo />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
expect(tokenRef?.colorPrimary).toBe('#177ddc');
|
||||
expect(tokenRef?.colorPrimaryText).toBe('#177ddc');
|
||||
});
|
||||
|
||||
it('overriding component token should work', () => {
|
||||
render(
|
||||
<ConfigProvider theme={{ override: { InputNumber: { handleWidth: 50.1234 } } }}>
|
||||
<ConfigProvider theme={{ components: { InputNumber: { handleWidth: 50.1234 } } }}>
|
||||
<InputNumber />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
|
@ -2,7 +2,7 @@ import * as React from 'react';
|
||||
import type { DerivativeFunc } from '@ant-design/cssinjs';
|
||||
import type { RequiredMark } from '../form/Form';
|
||||
import type { Locale } from '../locale-provider';
|
||||
import type { MapToken, OverrideToken, SeedToken } from '../theme/interface';
|
||||
import type { AliasToken, MapToken, OverrideToken, SeedToken } from '../theme/interface';
|
||||
import type { RenderEmptyHandler } from './defaultRenderEmpty';
|
||||
import type { SizeType } from './SizeContext';
|
||||
|
||||
@ -26,8 +26,8 @@ export type DirectionType = 'ltr' | 'rtl' | undefined;
|
||||
export type MappingAlgorithm = DerivativeFunc<SeedToken, MapToken>;
|
||||
|
||||
export interface ThemeConfig {
|
||||
token?: Partial<SeedToken>;
|
||||
override?: OverrideToken;
|
||||
token?: Partial<AliasToken>;
|
||||
components?: OverrideToken;
|
||||
algorithm?: MappingAlgorithm | MappingAlgorithm[];
|
||||
hashed?: boolean;
|
||||
}
|
||||
|
@ -18,13 +18,13 @@ export default function useTheme(
|
||||
|
||||
// Override
|
||||
const mergedOverride = {
|
||||
...parentThemeConfig.override,
|
||||
...parentThemeConfig.components,
|
||||
};
|
||||
|
||||
Object.keys(theme.override || {}).forEach((componentName: keyof OverrideToken) => {
|
||||
Object.keys(theme.components || {}).forEach((componentName: keyof OverrideToken) => {
|
||||
mergedOverride[componentName] = {
|
||||
...mergedOverride[componentName],
|
||||
...theme.override![componentName],
|
||||
...theme.components![componentName],
|
||||
} as any;
|
||||
});
|
||||
|
||||
|
@ -12,7 +12,7 @@ import { ConfigProvider, InputNumber, Space } from 'antd';
|
||||
export default () => (
|
||||
<ConfigProvider
|
||||
theme={{
|
||||
override: {
|
||||
components: {
|
||||
InputNumber: {
|
||||
handleWidth: 50,
|
||||
},
|
||||
@ -24,7 +24,7 @@ export default () => (
|
||||
|
||||
<ConfigProvider
|
||||
theme={{
|
||||
override: {
|
||||
components: {
|
||||
InputNumber: {
|
||||
handleWidth: 25,
|
||||
},
|
||||
|
@ -78,7 +78,7 @@ const ThemedMenu = forwardRef<MenuRef, MenuProps>(({ theme = 'light', ...rest },
|
||||
}, [theme]);
|
||||
|
||||
return (
|
||||
<ConfigProvider theme={{ override: { Menu: darkThemeToken } }}>
|
||||
<ConfigProvider theme={{ components: { Menu: darkThemeToken } }}>
|
||||
<SiderContext.Consumer>
|
||||
{(context: SiderContextProps) => <InternalMenu ref={menuRef} {...rest} {...context} />}
|
||||
</SiderContext.Consumer>
|
||||
|
@ -48,9 +48,9 @@ export const defaultConfig = {
|
||||
};
|
||||
|
||||
export const DesignTokenContext = React.createContext<{
|
||||
token: Partial<SeedToken>;
|
||||
token: Partial<AliasToken>;
|
||||
theme?: Theme<SeedToken, MapToken>;
|
||||
override?: OverrideToken;
|
||||
components?: OverrideToken;
|
||||
hashed?: string | boolean;
|
||||
}>(defaultConfig);
|
||||
|
||||
@ -61,7 +61,12 @@ const saltPrefix =
|
||||
process.env.NODE_ENV === 'production' ? version : `${version}-${new Date().getHours()}`;
|
||||
|
||||
export function useToken(): [Theme<SeedToken, MapToken>, GlobalToken, string] {
|
||||
const { token: rootDesignToken, override, hashed, theme } = React.useContext(DesignTokenContext);
|
||||
const {
|
||||
token: rootDesignToken,
|
||||
hashed,
|
||||
theme,
|
||||
components,
|
||||
} = React.useContext(DesignTokenContext);
|
||||
|
||||
const salt = `${saltPrefix}-${hashed || ''}`;
|
||||
|
||||
@ -72,7 +77,7 @@ export function useToken(): [Theme<SeedToken, MapToken>, GlobalToken, string] {
|
||||
[defaultSeedToken, rootDesignToken],
|
||||
{
|
||||
salt,
|
||||
override,
|
||||
override: { override: rootDesignToken, ...components },
|
||||
formatToken,
|
||||
},
|
||||
);
|
||||
|
@ -130,16 +130,10 @@ export interface ComponentTokenMap {
|
||||
Progress?: ProgressComponentToken;
|
||||
}
|
||||
|
||||
type OverrideComponentToken = {
|
||||
[key in keyof ComponentTokenMap]: Partial<ComponentTokenMap[key]>;
|
||||
export type OverrideToken = {
|
||||
[key in keyof ComponentTokenMap]: Partial<ComponentTokenMap[key]> & Partial<AliasToken>;
|
||||
};
|
||||
|
||||
export interface OverrideToken extends OverrideComponentToken {
|
||||
derivative?: Partial<MapToken>;
|
||||
/** @private Internal Usage */
|
||||
alias?: Partial<AliasToken>;
|
||||
}
|
||||
|
||||
/** Final token which contains the components level override */
|
||||
export type GlobalToken = AliasToken & ComponentTokenMap;
|
||||
|
||||
|
@ -2,7 +2,7 @@ import { TinyColor } from '@ctrl/tinycolor';
|
||||
import type { AliasToken, MapToken, OverrideToken } from '../interface';
|
||||
|
||||
/** Raw merge of `@ant-design/cssinjs` token. Which need additional process */
|
||||
type RawMergedToken = MapToken & OverrideToken;
|
||||
type RawMergedToken = MapToken & OverrideToken & { override: Partial<AliasToken> };
|
||||
|
||||
/**
|
||||
* Seed (designer) > Derivative (designer) > Alias (developer).
|
||||
@ -10,11 +10,11 @@ type RawMergedToken = MapToken & OverrideToken;
|
||||
* Merge seed & derivative & override token and generate alias token for developer.
|
||||
*/
|
||||
export default function formatToken(derivativeToken: RawMergedToken): AliasToken {
|
||||
const { derivative, alias, ...restToken } = derivativeToken;
|
||||
const { override, ...restToken } = derivativeToken;
|
||||
|
||||
const mergedToken = {
|
||||
...restToken,
|
||||
...derivative,
|
||||
...override,
|
||||
};
|
||||
|
||||
const { fontSizes, lineHeights } = mergedToken;
|
||||
@ -193,7 +193,7 @@ export default function formatToken(derivativeToken: RawMergedToken): AliasToken
|
||||
boxShadowTabsOverflowBottom: `inset 0 -10px 8px -8px rgba(0, 0, 0, 0.08)`,
|
||||
|
||||
// Override AliasToken
|
||||
...alias,
|
||||
...override,
|
||||
};
|
||||
|
||||
return aliasToken;
|
||||
|
@ -77,15 +77,7 @@ export default function genComponentStyleHook<ComponentName extends OverrideComp
|
||||
|
||||
const defaultComponentToken =
|
||||
typeof getDefaultToken === 'function' ? getDefaultToken(proxyToken) : getDefaultToken;
|
||||
const overrideComponentToken = token[component] as any;
|
||||
|
||||
// Only merge token specified in interface
|
||||
const mergedComponentToken = { ...defaultComponentToken } as any;
|
||||
if (overrideComponentToken) {
|
||||
Object.keys(mergedComponentToken).forEach(key => {
|
||||
mergedComponentToken[key] = overrideComponentToken[key] ?? mergedComponentToken[key];
|
||||
});
|
||||
}
|
||||
const mergedComponentToken = { ...defaultComponentToken, ...token[component] };
|
||||
|
||||
const componentCls = `.${prefixCls}`;
|
||||
const mergedToken = mergeToken<
|
||||
|
Loading…
Reference in New Issue
Block a user