mirror of
https://github.com/ant-design/ant-design.git
synced 2025-07-30 11:26:27 +08:00
feat: menu support css variable theme (#45750)
* feat: layout support cssVar * feat: menu support cssVar * feat: menu support cssVar * feat: menu support cssVar * feat: menu support cssVar * feat: optimize code * feat: optimize code * feat: optimize code * feat: optimize code * feat: optimize code * feat: optimize code
This commit is contained in:
parent
047bc53920
commit
3128539211
@ -18,6 +18,8 @@ import type { MenuContextProps, MenuTheme } from './MenuContext';
|
|||||||
import MenuContext from './MenuContext';
|
import MenuContext from './MenuContext';
|
||||||
import OverrideContext from './OverrideContext';
|
import OverrideContext from './OverrideContext';
|
||||||
import useStyle from './style';
|
import useStyle from './style';
|
||||||
|
import useCSSVar from './style/cssVar';
|
||||||
|
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
|
||||||
|
|
||||||
export interface MenuProps extends Omit<RcMenuProps, 'items'> {
|
export interface MenuProps extends Omit<RcMenuProps, 'items'> {
|
||||||
theme?: MenuTheme;
|
theme?: MenuTheme;
|
||||||
@ -120,7 +122,9 @@ const InternalMenu = forwardRef<RcMenuRef, InternalMenuProps>((props, ref) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const prefixCls = getPrefixCls('menu', customizePrefixCls || overrideObj.prefixCls);
|
const prefixCls = getPrefixCls('menu', customizePrefixCls || overrideObj.prefixCls);
|
||||||
const [wrapSSR, hashId] = useStyle(prefixCls, !override);
|
const [, hashId] = useStyle(prefixCls, !override);
|
||||||
|
const rootCls = useCSSVarCls(prefixCls);
|
||||||
|
const wrapCSSVar = useCSSVar(rootCls);
|
||||||
const menuClassName = classNames(`${prefixCls}-${theme}`, menu?.className, className);
|
const menuClassName = classNames(`${prefixCls}-${theme}`, menu?.className, className);
|
||||||
|
|
||||||
// ====================== Expand Icon ========================
|
// ====================== Expand Icon ========================
|
||||||
@ -156,7 +160,7 @@ const InternalMenu = forwardRef<RcMenuRef, InternalMenuProps>((props, ref) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// ========================= Render ==========================
|
// ========================= Render ==========================
|
||||||
return wrapSSR(
|
return wrapCSSVar(
|
||||||
<OverrideContext.Provider value={null}>
|
<OverrideContext.Provider value={null}>
|
||||||
<MenuContext.Provider value={contextValue}>
|
<MenuContext.Provider value={contextValue}>
|
||||||
<RcMenu
|
<RcMenu
|
||||||
@ -179,7 +183,7 @@ const InternalMenu = forwardRef<RcMenuRef, InternalMenuProps>((props, ref) => {
|
|||||||
defaultMotions={defaultMotions}
|
defaultMotions={defaultMotions}
|
||||||
expandIcon={mergedExpandIcon}
|
expandIcon={mergedExpandIcon}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
rootClassName={classNames(rootClassName, hashId, overrideObj.rootClassName)}
|
rootClassName={classNames(rootClassName, hashId, overrideObj.rootClassName, rootCls)}
|
||||||
>
|
>
|
||||||
{mergedChildren}
|
{mergedChildren}
|
||||||
</RcMenu>
|
</RcMenu>
|
||||||
|
8
components/menu/style/cssVar.ts
Normal file
8
components/menu/style/cssVar.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { genCSSVarRegister } from '../../theme/internal';
|
||||||
|
import { prepareComponentToken } from '.';
|
||||||
|
|
||||||
|
export default genCSSVarRegister('Menu', prepareComponentToken, {
|
||||||
|
unitless: {
|
||||||
|
groupTitleLineHeight: true,
|
||||||
|
},
|
||||||
|
});
|
@ -1,3 +1,4 @@
|
|||||||
|
import { unit } from '@ant-design/cssinjs';
|
||||||
import type { MenuToken } from '.';
|
import type { MenuToken } from '.';
|
||||||
import type { GenerateStyle } from '../../theme/internal';
|
import type { GenerateStyle } from '../../theme/internal';
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ const getHorizontalStyle: GenerateStyle<MenuToken> = (token) => {
|
|||||||
[`${componentCls}-horizontal`]: {
|
[`${componentCls}-horizontal`]: {
|
||||||
lineHeight: horizontalLineHeight,
|
lineHeight: horizontalLineHeight,
|
||||||
border: 0,
|
border: 0,
|
||||||
borderBottom: `${lineWidth}px ${lineType} ${colorSplit}`,
|
borderBottom: `${unit(lineWidth)} ${lineType} ${colorSplit}`,
|
||||||
boxShadow: 'none',
|
boxShadow: 'none',
|
||||||
|
|
||||||
'&::after': {
|
'&::after': {
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
import type { CSSObject } from '@ant-design/cssinjs';
|
import { unit, type CSSObject } from '@ant-design/cssinjs';
|
||||||
import { TinyColor } from '@ctrl/tinycolor';
|
import { TinyColor } from '@ctrl/tinycolor';
|
||||||
import type { CSSProperties } from 'react';
|
import type { CSSProperties } from 'react';
|
||||||
import { clearFix, resetComponent, resetIcon } from '../../style';
|
import { clearFix, resetComponent, resetIcon } from '../../style';
|
||||||
import { genCollapseMotion, initSlideMotion, initZoomMotion } from '../../style/motion';
|
import { genCollapseMotion, initSlideMotion, initZoomMotion } from '../../style/motion';
|
||||||
import type { FullToken, GenerateStyle, UseComponentStyleResult } from '../../theme/internal';
|
import type {
|
||||||
|
FullToken,
|
||||||
|
GenerateStyle,
|
||||||
|
GetDefaultToken,
|
||||||
|
UseComponentStyleResult,
|
||||||
|
} from '../../theme/internal';
|
||||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||||
import getHorizontalStyle from './horizontal';
|
import getHorizontalStyle from './horizontal';
|
||||||
import getRTLStyle from './rtl';
|
import getRTLStyle from './rtl';
|
||||||
import getThemeStyle from './theme';
|
import getThemeStyle from './theme';
|
||||||
import getVerticalStyle from './vertical';
|
import getVerticalStyle from './vertical';
|
||||||
|
import type { CssUtil } from 'antd-style';
|
||||||
|
|
||||||
/** Component only token. Which will handle additional calculation of alias token */
|
/** Component only token. Which will handle additional calculation of alias token */
|
||||||
export interface ComponentToken {
|
export interface ComponentToken {
|
||||||
@ -35,7 +41,7 @@ export interface ComponentToken {
|
|||||||
* @desc 分组标题文字高度
|
* @desc 分组标题文字高度
|
||||||
* @descEN line-height of group title
|
* @descEN line-height of group title
|
||||||
*/
|
*/
|
||||||
groupTitleLineHeight: CSSProperties['lineHeight'];
|
groupTitleLineHeight: string | number;
|
||||||
/**
|
/**
|
||||||
* @desc 分组标题文字大小
|
* @desc 分组标题文字大小
|
||||||
* @descEN font-size of group title
|
* @descEN font-size of group title
|
||||||
@ -357,12 +363,14 @@ export interface ComponentToken {
|
|||||||
* @descEN Background of active danger menu item in dark mode
|
* @descEN Background of active danger menu item in dark mode
|
||||||
*/
|
*/
|
||||||
darkDangerItemActiveBg: string;
|
darkDangerItemActiveBg: string;
|
||||||
|
/** @internal */
|
||||||
|
subMenuTitleWidth: number | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MenuToken extends FullToken<'Menu'> {
|
export interface MenuToken extends FullToken<'Menu'> {
|
||||||
menuHorizontalHeight: number;
|
menuHorizontalHeight: number | string;
|
||||||
menuArrowSize: number;
|
menuArrowSize: number | string;
|
||||||
menuArrowOffset: string;
|
menuArrowOffset: number | string;
|
||||||
menuPanelMaskInset: number;
|
menuPanelMaskInset: number;
|
||||||
menuSubMenuBg: string;
|
menuSubMenuBg: string;
|
||||||
}
|
}
|
||||||
@ -471,8 +479,8 @@ const genSubMenuArrowStyle = (token: MenuToken): CSSObject => {
|
|||||||
// →
|
// →
|
||||||
'&::before, &::after': {
|
'&::before, &::after': {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
width: menuArrowSize * 0.6,
|
width: token.calc(menuArrowSize).mul(0.6).equal(),
|
||||||
height: menuArrowSize * 0.15,
|
height: token.calc(menuArrowSize).mul(0.15).equal(),
|
||||||
backgroundColor: 'currentcolor',
|
backgroundColor: 'currentcolor',
|
||||||
borderRadius,
|
borderRadius,
|
||||||
transition: [
|
transition: [
|
||||||
@ -485,11 +493,13 @@ const genSubMenuArrowStyle = (token: MenuToken): CSSObject => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
'&::before': {
|
'&::before': {
|
||||||
transform: `rotate(45deg) translateY(-${menuArrowOffset})`,
|
transform: `rotate(45deg) translateY(${unit(
|
||||||
|
token.calc(menuArrowOffset).mul(-1).equal(),
|
||||||
|
)})`,
|
||||||
},
|
},
|
||||||
|
|
||||||
'&::after': {
|
'&::after': {
|
||||||
transform: `rotate(-45deg) translateY(${menuArrowOffset})`,
|
transform: `rotate(-45deg) translateY(${unit(menuArrowOffset)})`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -570,7 +580,7 @@ const getBaseStyle: GenerateStyle<MenuToken> = (token) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
[`${componentCls}-item-group-title`]: {
|
[`${componentCls}-item-group-title`]: {
|
||||||
padding: `${paddingXS}px ${padding}px`,
|
padding: `${unit(paddingXS)} ${unit(padding)}`,
|
||||||
fontSize: groupTitleFontSize,
|
fontSize: groupTitleFontSize,
|
||||||
lineHeight: groupTitleLineHeight,
|
lineHeight: groupTitleLineHeight,
|
||||||
transition: `all ${motionDurationSlow}`,
|
transition: `all ${motionDurationSlow}`,
|
||||||
@ -646,7 +656,7 @@ const getBaseStyle: GenerateStyle<MenuToken> = (token) => {
|
|||||||
padding: 0,
|
padding: 0,
|
||||||
|
|
||||||
[`${componentCls}-item, ${componentCls}-submenu-title`]: {
|
[`${componentCls}-item, ${componentCls}-submenu-title`]: {
|
||||||
paddingInline: `${fontSize * 2}px ${padding}px`,
|
paddingInline: `${unit(token.calc(fontSize).mul(2).equal())} ${unit(padding)}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -667,7 +677,7 @@ const getBaseStyle: GenerateStyle<MenuToken> = (token) => {
|
|||||||
// https://github.com/ant-design/ant-design/issues/13955
|
// https://github.com/ant-design/ant-design/issues/13955
|
||||||
'&::before': {
|
'&::before': {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
inset: `${menuPanelMaskInset}px 0 0`,
|
inset: `${unit(menuPanelMaskInset)} 0 0`,
|
||||||
zIndex: -1,
|
zIndex: -1,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
@ -760,25 +770,29 @@ const getBaseStyle: GenerateStyle<MenuToken> = (token) => {
|
|||||||
&-inline ${componentCls}-submenu-arrow`]: {
|
&-inline ${componentCls}-submenu-arrow`]: {
|
||||||
// ↓
|
// ↓
|
||||||
'&::before': {
|
'&::before': {
|
||||||
transform: `rotate(-45deg) translateX(${menuArrowOffset})`,
|
transform: `rotate(-45deg) translateX(${unit(menuArrowOffset)})`,
|
||||||
},
|
},
|
||||||
|
|
||||||
'&::after': {
|
'&::after': {
|
||||||
transform: `rotate(45deg) translateX(-${menuArrowOffset})`,
|
transform: `rotate(45deg) translateX(${unit(
|
||||||
|
token.calc(menuArrowOffset).mul(-1).equal(),
|
||||||
|
)})`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
[`${componentCls}-submenu-open${componentCls}-submenu-inline > ${componentCls}-submenu-title > ${componentCls}-submenu-arrow`]:
|
[`${componentCls}-submenu-open${componentCls}-submenu-inline > ${componentCls}-submenu-title > ${componentCls}-submenu-arrow`]:
|
||||||
{
|
{
|
||||||
// ↑
|
// ↑
|
||||||
transform: `translateY(-${menuArrowSize * 0.2}px)`,
|
transform: `translateY(${unit(token.calc(menuArrowSize).mul(0.2).mul(-1).equal())})`,
|
||||||
|
|
||||||
'&::after': {
|
'&::after': {
|
||||||
transform: `rotate(-45deg) translateX(-${menuArrowOffset})`,
|
transform: `rotate(-45deg) translateX(${unit(
|
||||||
|
token.calc(menuArrowOffset).mul(-1).equal(),
|
||||||
|
)})`,
|
||||||
},
|
},
|
||||||
|
|
||||||
'&::before': {
|
'&::before': {
|
||||||
transform: `rotate(45deg) translateX(${menuArrowOffset})`,
|
transform: `rotate(45deg) translateX(${unit(menuArrowOffset)})`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -795,6 +809,127 @@ const getBaseStyle: GenerateStyle<MenuToken> = (token) => {
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const prepareComponentToken: GetDefaultToken<'Menu'> = (token) => {
|
||||||
|
const {
|
||||||
|
colorPrimary,
|
||||||
|
colorError,
|
||||||
|
colorTextDisabled,
|
||||||
|
colorErrorBg,
|
||||||
|
colorText,
|
||||||
|
colorTextDescription,
|
||||||
|
colorBgContainer,
|
||||||
|
colorFillAlter,
|
||||||
|
colorFillContent,
|
||||||
|
lineWidth,
|
||||||
|
lineWidthBold,
|
||||||
|
controlItemBgActive,
|
||||||
|
colorBgTextHover,
|
||||||
|
controlHeightLG,
|
||||||
|
lineHeight,
|
||||||
|
colorBgElevated,
|
||||||
|
marginXXS,
|
||||||
|
padding,
|
||||||
|
fontSize,
|
||||||
|
controlHeightSM,
|
||||||
|
fontSizeLG,
|
||||||
|
colorTextLightSolid,
|
||||||
|
colorErrorHover,
|
||||||
|
} = token;
|
||||||
|
|
||||||
|
const colorTextDark = new TinyColor(colorTextLightSolid).setAlpha(0.65).toRgbString();
|
||||||
|
|
||||||
|
return {
|
||||||
|
dropdownWidth: 160,
|
||||||
|
zIndexPopup: token.zIndexPopupBase + 50,
|
||||||
|
radiusItem: token.borderRadiusLG,
|
||||||
|
itemBorderRadius: token.borderRadiusLG,
|
||||||
|
radiusSubMenuItem: token.borderRadiusSM,
|
||||||
|
subMenuItemBorderRadius: token.borderRadiusSM,
|
||||||
|
colorItemText: colorText,
|
||||||
|
itemColor: colorText,
|
||||||
|
colorItemTextHover: colorText,
|
||||||
|
itemHoverColor: colorText,
|
||||||
|
colorItemTextHoverHorizontal: colorPrimary,
|
||||||
|
horizontalItemHoverColor: colorPrimary,
|
||||||
|
colorGroupTitle: colorTextDescription,
|
||||||
|
groupTitleColor: colorTextDescription,
|
||||||
|
colorItemTextSelected: colorPrimary,
|
||||||
|
itemSelectedColor: colorPrimary,
|
||||||
|
colorItemTextSelectedHorizontal: colorPrimary,
|
||||||
|
horizontalItemSelectedColor: colorPrimary,
|
||||||
|
colorItemBg: colorBgContainer,
|
||||||
|
itemBg: colorBgContainer,
|
||||||
|
colorItemBgHover: colorBgTextHover,
|
||||||
|
itemHoverBg: colorBgTextHover,
|
||||||
|
colorItemBgActive: colorFillContent,
|
||||||
|
itemActiveBg: controlItemBgActive,
|
||||||
|
colorSubItemBg: colorFillAlter,
|
||||||
|
subMenuItemBg: colorFillAlter,
|
||||||
|
colorItemBgSelected: controlItemBgActive,
|
||||||
|
itemSelectedBg: controlItemBgActive,
|
||||||
|
colorItemBgSelectedHorizontal: 'transparent',
|
||||||
|
horizontalItemSelectedBg: 'transparent',
|
||||||
|
colorActiveBarWidth: 0,
|
||||||
|
activeBarWidth: 0,
|
||||||
|
colorActiveBarHeight: lineWidthBold,
|
||||||
|
activeBarHeight: lineWidthBold,
|
||||||
|
colorActiveBarBorderSize: lineWidth,
|
||||||
|
activeBarBorderWidth: lineWidth,
|
||||||
|
|
||||||
|
// Disabled
|
||||||
|
colorItemTextDisabled: colorTextDisabled,
|
||||||
|
itemDisabledColor: colorTextDisabled,
|
||||||
|
|
||||||
|
// Danger
|
||||||
|
colorDangerItemText: colorError,
|
||||||
|
dangerItemColor: colorError,
|
||||||
|
colorDangerItemTextHover: colorError,
|
||||||
|
dangerItemHoverColor: colorError,
|
||||||
|
colorDangerItemTextSelected: colorError,
|
||||||
|
dangerItemSelectedColor: colorError,
|
||||||
|
colorDangerItemBgActive: colorErrorBg,
|
||||||
|
dangerItemActiveBg: colorErrorBg,
|
||||||
|
colorDangerItemBgSelected: colorErrorBg,
|
||||||
|
dangerItemSelectedBg: colorErrorBg,
|
||||||
|
|
||||||
|
itemMarginInline: token.marginXXS,
|
||||||
|
|
||||||
|
horizontalItemBorderRadius: 0,
|
||||||
|
horizontalItemHoverBg: 'transparent',
|
||||||
|
itemHeight: controlHeightLG,
|
||||||
|
groupTitleLineHeight: lineHeight,
|
||||||
|
collapsedWidth: controlHeightLG * 2,
|
||||||
|
popupBg: colorBgElevated,
|
||||||
|
itemMarginBlock: marginXXS,
|
||||||
|
itemPaddingInline: padding,
|
||||||
|
horizontalLineHeight: `${controlHeightLG * 1.15}px`,
|
||||||
|
iconSize: fontSize,
|
||||||
|
iconMarginInlineEnd: controlHeightSM - fontSize,
|
||||||
|
collapsedIconSize: fontSizeLG,
|
||||||
|
groupTitleFontSize: fontSize,
|
||||||
|
|
||||||
|
// Disabled
|
||||||
|
darkItemDisabledColor: new TinyColor(colorTextLightSolid).setAlpha(0.25).toRgbString(),
|
||||||
|
|
||||||
|
// Dark
|
||||||
|
darkItemColor: colorTextDark,
|
||||||
|
darkDangerItemColor: colorError,
|
||||||
|
darkItemBg: '#001529',
|
||||||
|
darkSubMenuItemBg: '#000c17',
|
||||||
|
darkItemSelectedColor: colorTextLightSolid,
|
||||||
|
darkItemSelectedBg: colorPrimary,
|
||||||
|
darkDangerItemSelectedBg: colorError,
|
||||||
|
darkItemHoverBg: 'transparent',
|
||||||
|
darkGroupTitleColor: colorTextDark,
|
||||||
|
darkItemHoverColor: colorTextLightSolid,
|
||||||
|
darkDangerItemHoverColor: colorErrorHover,
|
||||||
|
darkDangerItemSelectedColor: colorTextLightSolid,
|
||||||
|
darkDangerItemActiveBg: colorError,
|
||||||
|
|
||||||
|
subMenuTitleWidth: `calc(100% - ${token.marginXXS * 2}px)`,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// ============================== Export ==============================
|
// ============================== Export ==============================
|
||||||
export default (prefixCls: string, injectStyle: boolean): UseComponentStyleResult => {
|
export default (prefixCls: string, injectStyle: boolean): UseComponentStyleResult => {
|
||||||
const useOriginHook = genComponentStyleHook(
|
const useOriginHook = genComponentStyleHook(
|
||||||
@ -827,15 +962,20 @@ export default (prefixCls: string, injectStyle: boolean): UseComponentStyleResul
|
|||||||
darkDangerItemActiveBg,
|
darkDangerItemActiveBg,
|
||||||
} = token;
|
} = token;
|
||||||
|
|
||||||
const menuArrowSize = (fontSize / 7) * 5;
|
const menuArrowSize = token.calc(fontSize).div(7).mul(5).equal();
|
||||||
|
|
||||||
// Menu Token
|
// Menu Token
|
||||||
const menuToken = mergeToken<MenuToken>(token, {
|
const menuToken = mergeToken<MenuToken & CssUtil>(token, {
|
||||||
menuArrowSize,
|
menuArrowSize,
|
||||||
menuHorizontalHeight: controlHeightLG * 1.15,
|
menuHorizontalHeight: token.calc(controlHeightLG).mul(1.15).equal(),
|
||||||
menuArrowOffset: `${menuArrowSize * 0.25}px`,
|
menuArrowOffset: token.calc(menuArrowSize).mul(0.25).equal(),
|
||||||
menuPanelMaskInset: -7, // Still a hardcode here since it's offset by rc-align
|
menuPanelMaskInset: -7, // Still a hardcode here since it's offset by rc-align
|
||||||
menuSubMenuBg: colorBgElevated,
|
menuSubMenuBg: colorBgElevated,
|
||||||
|
calc: token.calc,
|
||||||
|
subMenuTitleWidth:
|
||||||
|
token.activeBarWidth && token.activeBarBorderWidth
|
||||||
|
? `calc(100% + ${token.activeBarBorderWidth}px)`
|
||||||
|
: `calc(100% - ${token.marginXXS * 2}px)`,
|
||||||
});
|
});
|
||||||
|
|
||||||
const menuDarkToken = mergeToken<MenuToken>(menuToken, {
|
const menuDarkToken = mergeToken<MenuToken>(menuToken, {
|
||||||
@ -894,124 +1034,7 @@ export default (prefixCls: string, injectStyle: boolean): UseComponentStyleResul
|
|||||||
initZoomMotion(menuToken, 'zoom-big'),
|
initZoomMotion(menuToken, 'zoom-big'),
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
(token) => {
|
prepareComponentToken,
|
||||||
const {
|
|
||||||
colorPrimary,
|
|
||||||
colorError,
|
|
||||||
colorTextDisabled,
|
|
||||||
colorErrorBg,
|
|
||||||
colorText,
|
|
||||||
colorTextDescription,
|
|
||||||
colorBgContainer,
|
|
||||||
colorFillAlter,
|
|
||||||
colorFillContent,
|
|
||||||
lineWidth,
|
|
||||||
lineWidthBold,
|
|
||||||
controlItemBgActive,
|
|
||||||
colorBgTextHover,
|
|
||||||
controlHeightLG,
|
|
||||||
lineHeight,
|
|
||||||
colorBgElevated,
|
|
||||||
marginXXS,
|
|
||||||
padding,
|
|
||||||
fontSize,
|
|
||||||
controlHeightSM,
|
|
||||||
fontSizeLG,
|
|
||||||
colorTextLightSolid,
|
|
||||||
colorErrorHover,
|
|
||||||
} = token;
|
|
||||||
|
|
||||||
const colorTextDark = new TinyColor(colorTextLightSolid).setAlpha(0.65).toRgbString();
|
|
||||||
|
|
||||||
return {
|
|
||||||
dropdownWidth: 160,
|
|
||||||
zIndexPopup: token.zIndexPopupBase + 50,
|
|
||||||
radiusItem: token.borderRadiusLG,
|
|
||||||
itemBorderRadius: token.borderRadiusLG,
|
|
||||||
radiusSubMenuItem: token.borderRadiusSM,
|
|
||||||
subMenuItemBorderRadius: token.borderRadiusSM,
|
|
||||||
colorItemText: colorText,
|
|
||||||
itemColor: colorText,
|
|
||||||
colorItemTextHover: colorText,
|
|
||||||
itemHoverColor: colorText,
|
|
||||||
colorItemTextHoverHorizontal: colorPrimary,
|
|
||||||
horizontalItemHoverColor: colorPrimary,
|
|
||||||
colorGroupTitle: colorTextDescription,
|
|
||||||
groupTitleColor: colorTextDescription,
|
|
||||||
colorItemTextSelected: colorPrimary,
|
|
||||||
itemSelectedColor: colorPrimary,
|
|
||||||
colorItemTextSelectedHorizontal: colorPrimary,
|
|
||||||
horizontalItemSelectedColor: colorPrimary,
|
|
||||||
colorItemBg: colorBgContainer,
|
|
||||||
itemBg: colorBgContainer,
|
|
||||||
colorItemBgHover: colorBgTextHover,
|
|
||||||
itemHoverBg: colorBgTextHover,
|
|
||||||
colorItemBgActive: colorFillContent,
|
|
||||||
itemActiveBg: controlItemBgActive,
|
|
||||||
colorSubItemBg: colorFillAlter,
|
|
||||||
subMenuItemBg: colorFillAlter,
|
|
||||||
colorItemBgSelected: controlItemBgActive,
|
|
||||||
itemSelectedBg: controlItemBgActive,
|
|
||||||
colorItemBgSelectedHorizontal: 'transparent',
|
|
||||||
horizontalItemSelectedBg: 'transparent',
|
|
||||||
colorActiveBarWidth: 0,
|
|
||||||
activeBarWidth: 0,
|
|
||||||
colorActiveBarHeight: lineWidthBold,
|
|
||||||
activeBarHeight: lineWidthBold,
|
|
||||||
colorActiveBarBorderSize: lineWidth,
|
|
||||||
activeBarBorderWidth: lineWidth,
|
|
||||||
|
|
||||||
// Disabled
|
|
||||||
colorItemTextDisabled: colorTextDisabled,
|
|
||||||
itemDisabledColor: colorTextDisabled,
|
|
||||||
|
|
||||||
// Danger
|
|
||||||
colorDangerItemText: colorError,
|
|
||||||
dangerItemColor: colorError,
|
|
||||||
colorDangerItemTextHover: colorError,
|
|
||||||
dangerItemHoverColor: colorError,
|
|
||||||
colorDangerItemTextSelected: colorError,
|
|
||||||
dangerItemSelectedColor: colorError,
|
|
||||||
colorDangerItemBgActive: colorErrorBg,
|
|
||||||
dangerItemActiveBg: colorErrorBg,
|
|
||||||
colorDangerItemBgSelected: colorErrorBg,
|
|
||||||
dangerItemSelectedBg: colorErrorBg,
|
|
||||||
|
|
||||||
itemMarginInline: token.marginXXS,
|
|
||||||
|
|
||||||
horizontalItemBorderRadius: 0,
|
|
||||||
horizontalItemHoverBg: 'transparent',
|
|
||||||
itemHeight: controlHeightLG,
|
|
||||||
groupTitleLineHeight: lineHeight,
|
|
||||||
collapsedWidth: controlHeightLG * 2,
|
|
||||||
popupBg: colorBgElevated,
|
|
||||||
itemMarginBlock: marginXXS,
|
|
||||||
itemPaddingInline: padding,
|
|
||||||
horizontalLineHeight: `${controlHeightLG * 1.15}px`,
|
|
||||||
iconSize: fontSize,
|
|
||||||
iconMarginInlineEnd: controlHeightSM - fontSize,
|
|
||||||
collapsedIconSize: fontSizeLG,
|
|
||||||
groupTitleFontSize: fontSize,
|
|
||||||
|
|
||||||
// Disabled
|
|
||||||
darkItemDisabledColor: new TinyColor(colorTextLightSolid).setAlpha(0.25).toRgbString(),
|
|
||||||
|
|
||||||
// Dark
|
|
||||||
darkItemColor: colorTextDark,
|
|
||||||
darkDangerItemColor: colorError,
|
|
||||||
darkItemBg: '#001529',
|
|
||||||
darkSubMenuItemBg: '#000c17',
|
|
||||||
darkItemSelectedColor: colorTextLightSolid,
|
|
||||||
darkItemSelectedBg: colorPrimary,
|
|
||||||
darkDangerItemSelectedBg: colorError,
|
|
||||||
darkItemHoverBg: 'transparent',
|
|
||||||
darkGroupTitleColor: colorTextDark,
|
|
||||||
darkItemHoverColor: colorTextLightSolid,
|
|
||||||
darkDangerItemHoverColor: colorErrorHover,
|
|
||||||
darkDangerItemSelectedColor: colorTextLightSolid,
|
|
||||||
darkDangerItemActiveBg: colorError,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
deprecatedTokens: [
|
deprecatedTokens: [
|
||||||
['colorGroupTitle', 'groupTitleColor'],
|
['colorGroupTitle', 'groupTitleColor'],
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
|
import type { CssUtil } from 'antd-style';
|
||||||
import type { MenuToken } from '.';
|
import type { MenuToken } from '.';
|
||||||
import type { GenerateStyle } from '../../theme/internal';
|
import type { GenerateStyle } from '../../theme/internal';
|
||||||
|
import { unit } from '@ant-design/cssinjs';
|
||||||
|
|
||||||
const getRTLStyle: GenerateStyle<MenuToken> = ({ componentCls, menuArrowOffset }) => ({
|
const getRTLStyle: GenerateStyle<MenuToken & CssUtil> = ({
|
||||||
|
componentCls,
|
||||||
|
menuArrowOffset,
|
||||||
|
calc,
|
||||||
|
}) => ({
|
||||||
[`${componentCls}-rtl`]: {
|
[`${componentCls}-rtl`]: {
|
||||||
direction: 'rtl',
|
direction: 'rtl',
|
||||||
},
|
},
|
||||||
@ -15,11 +21,11 @@ const getRTLStyle: GenerateStyle<MenuToken> = ({ componentCls, menuArrowOffset }
|
|||||||
${componentCls}-submenu-rtl ${componentCls}-vertical`]: {
|
${componentCls}-submenu-rtl ${componentCls}-vertical`]: {
|
||||||
[`${componentCls}-submenu-arrow`]: {
|
[`${componentCls}-submenu-arrow`]: {
|
||||||
'&::before': {
|
'&::before': {
|
||||||
transform: `rotate(-45deg) translateY(-${menuArrowOffset})`,
|
transform: `rotate(-45deg) translateY(${unit(calc(menuArrowOffset).mul(-1).equal())})`,
|
||||||
},
|
},
|
||||||
|
|
||||||
'&::after': {
|
'&::after': {
|
||||||
transform: `rotate(45deg) translateY(${menuArrowOffset})`,
|
transform: `rotate(45deg) translateY(${unit(menuArrowOffset)})`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import type { CSSInterpolation } from '@ant-design/cssinjs';
|
import { unit, type CSSInterpolation } from '@ant-design/cssinjs';
|
||||||
|
|
||||||
import type { MenuToken } from '.';
|
import type { MenuToken } from '.';
|
||||||
import { genFocusOutline } from '../../style';
|
import { genFocusOutline } from '../../style';
|
||||||
|
|
||||||
@ -172,7 +173,7 @@ const getThemeStyle = (token: MenuToken, themeSuffix: string): CSSInterpolation
|
|||||||
|
|
||||||
[`> ${componentCls}-item, > ${componentCls}-submenu`]: {
|
[`> ${componentCls}-item, > ${componentCls}-submenu`]: {
|
||||||
top: activeBarBorderWidth,
|
top: activeBarBorderWidth,
|
||||||
marginTop: -activeBarBorderWidth,
|
marginTop: token.calc(activeBarBorderWidth).mul(-1).equal(),
|
||||||
marginBottom: 0,
|
marginBottom: 0,
|
||||||
borderRadius: horizontalItemBorderRadius,
|
borderRadius: horizontalItemBorderRadius,
|
||||||
|
|
||||||
@ -180,7 +181,7 @@ const getThemeStyle = (token: MenuToken, themeSuffix: string): CSSInterpolation
|
|||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
insetInline: itemPaddingInline,
|
insetInline: itemPaddingInline,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
borderBottom: `${activeBarHeight}px solid transparent`,
|
borderBottom: `${unit(activeBarHeight)} solid transparent`,
|
||||||
transition: `border-color ${motionDurationSlow} ${motionEaseInOut}`,
|
transition: `border-color ${motionDurationSlow} ${motionEaseInOut}`,
|
||||||
content: '""',
|
content: '""',
|
||||||
},
|
},
|
||||||
@ -210,7 +211,7 @@ const getThemeStyle = (token: MenuToken, themeSuffix: string): CSSInterpolation
|
|||||||
//
|
//
|
||||||
[`&${componentCls}-root`]: {
|
[`&${componentCls}-root`]: {
|
||||||
[`&${componentCls}-inline, &${componentCls}-vertical`]: {
|
[`&${componentCls}-inline, &${componentCls}-vertical`]: {
|
||||||
borderInlineEnd: `${activeBarBorderWidth}px ${lineType} ${colorSplit}`,
|
borderInlineEnd: `${unit(activeBarBorderWidth)} ${lineType} ${colorSplit}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -222,12 +223,9 @@ const getThemeStyle = (token: MenuToken, themeSuffix: string): CSSInterpolation
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Item
|
// Item
|
||||||
[`${componentCls}-item, ${componentCls}-submenu-title`]:
|
[`${componentCls}-item, ${componentCls}-submenu-title`]: {
|
||||||
activeBarBorderWidth && activeBarWidth
|
width: token.subMenuTitleWidth,
|
||||||
? {
|
},
|
||||||
width: `calc(100% + ${activeBarBorderWidth}px)`,
|
|
||||||
}
|
|
||||||
: {},
|
|
||||||
|
|
||||||
[`${componentCls}-item`]: {
|
[`${componentCls}-item`]: {
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
@ -236,7 +234,7 @@ const getThemeStyle = (token: MenuToken, themeSuffix: string): CSSInterpolation
|
|||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
insetBlock: 0,
|
insetBlock: 0,
|
||||||
insetInlineEnd: 0,
|
insetInlineEnd: 0,
|
||||||
borderInlineEnd: `${activeBarWidth}px solid ${itemSelectedColor}`,
|
borderInlineEnd: `${unit(activeBarWidth)} solid ${itemSelectedColor}`,
|
||||||
transform: 'scaleY(0.0001)',
|
transform: 'scaleY(0.0001)',
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
transition: [
|
transition: [
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { CSSObject } from '@ant-design/cssinjs';
|
import { unit, type CSSObject } from '@ant-design/cssinjs';
|
||||||
import type { MenuToken } from '.';
|
import type { MenuToken } from '.';
|
||||||
import { textEllipsis } from '../../style';
|
import { textEllipsis } from '../../style';
|
||||||
import type { GenerateStyle } from '../../theme/internal';
|
import type { GenerateStyle } from '../../theme/internal';
|
||||||
@ -14,7 +14,7 @@ const getVerticalInlineStyle: GenerateStyle<MenuToken, CSSObject> = (token) => {
|
|||||||
itemMarginBlock,
|
itemMarginBlock,
|
||||||
} = token;
|
} = token;
|
||||||
|
|
||||||
const paddingWithArrow = padding + menuArrowSize + marginXS;
|
const paddingWithArrow = token.calc(menuArrowSize).add(padding).add(marginXS).equal();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[`${componentCls}-item`]: {
|
[`${componentCls}-item`]: {
|
||||||
@ -24,19 +24,19 @@ const getVerticalInlineStyle: GenerateStyle<MenuToken, CSSObject> = (token) => {
|
|||||||
|
|
||||||
[`${componentCls}-item, ${componentCls}-submenu-title`]: {
|
[`${componentCls}-item, ${componentCls}-submenu-title`]: {
|
||||||
height: itemHeight,
|
height: itemHeight,
|
||||||
lineHeight: `${itemHeight}px`,
|
lineHeight: `${unit(itemHeight)}`,
|
||||||
paddingInline: padding,
|
paddingInline: padding,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
textOverflow: 'ellipsis',
|
textOverflow: 'ellipsis',
|
||||||
marginInline: itemMarginInline,
|
marginInline: itemMarginInline,
|
||||||
marginBlock: itemMarginBlock,
|
marginBlock: itemMarginBlock,
|
||||||
width: `calc(100% - ${itemMarginInline * 2}px)`,
|
width: token.subMenuTitleWidth,
|
||||||
},
|
},
|
||||||
|
|
||||||
[`> ${componentCls}-item,
|
[`> ${componentCls}-item,
|
||||||
> ${componentCls}-submenu > ${componentCls}-submenu-title`]: {
|
> ${componentCls}-submenu > ${componentCls}-submenu-title`]: {
|
||||||
height: itemHeight,
|
height: itemHeight,
|
||||||
lineHeight: `${itemHeight}px`,
|
lineHeight: `${unit(itemHeight)}`,
|
||||||
},
|
},
|
||||||
|
|
||||||
[`${componentCls}-item-group-list ${componentCls}-submenu-title,
|
[`${componentCls}-item-group-list ${componentCls}-submenu-title,
|
||||||
@ -68,7 +68,7 @@ const getVerticalStyle: GenerateStyle<MenuToken> = (token) => {
|
|||||||
|
|
||||||
const inlineItemStyle: CSSObject = {
|
const inlineItemStyle: CSSObject = {
|
||||||
height: itemHeight,
|
height: itemHeight,
|
||||||
lineHeight: `${itemHeight}px`,
|
lineHeight: `${unit(itemHeight)}`,
|
||||||
listStylePosition: 'inside',
|
listStylePosition: 'inside',
|
||||||
listStyleType: 'disc',
|
listStyleType: 'disc',
|
||||||
};
|
};
|
||||||
@ -97,7 +97,7 @@ const getVerticalStyle: GenerateStyle<MenuToken> = (token) => {
|
|||||||
{
|
{
|
||||||
[`${componentCls}-submenu-popup ${componentCls}-vertical${componentCls}-sub`]: {
|
[`${componentCls}-submenu-popup ${componentCls}-vertical${componentCls}-sub`]: {
|
||||||
minWidth: dropdownWidth,
|
minWidth: dropdownWidth,
|
||||||
maxHeight: `calc(100vh - ${controlHeightLG * 2.5}px)`,
|
maxHeight: `calc(100vh - ${unit(token.calc(controlHeightLG).mul(2.5).equal())})`,
|
||||||
padding: '0',
|
padding: '0',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
borderInlineEnd: 0,
|
borderInlineEnd: 0,
|
||||||
@ -178,7 +178,9 @@ const getVerticalStyle: GenerateStyle<MenuToken> = (token) => {
|
|||||||
> ${componentCls}-item-group > ${componentCls}-item-group-list > ${componentCls}-submenu > ${componentCls}-submenu-title,
|
> ${componentCls}-item-group > ${componentCls}-item-group-list > ${componentCls}-submenu > ${componentCls}-submenu-title,
|
||||||
> ${componentCls}-submenu > ${componentCls}-submenu-title`]: {
|
> ${componentCls}-submenu > ${componentCls}-submenu-title`]: {
|
||||||
insetInlineStart: 0,
|
insetInlineStart: 0,
|
||||||
paddingInline: `calc(50% - ${fontSizeLG / 2}px - ${itemMarginInline}px)`,
|
paddingInline: `calc(50% - ${unit(token.calc(fontSizeLG).div(2).equal())} - ${unit(
|
||||||
|
itemMarginInline,
|
||||||
|
)})`,
|
||||||
textOverflow: 'clip',
|
textOverflow: 'clip',
|
||||||
|
|
||||||
[`
|
[`
|
||||||
@ -191,7 +193,7 @@ const getVerticalStyle: GenerateStyle<MenuToken> = (token) => {
|
|||||||
[`${componentCls}-item-icon, ${iconCls}`]: {
|
[`${componentCls}-item-icon, ${iconCls}`]: {
|
||||||
margin: 0,
|
margin: 0,
|
||||||
fontSize: collapsedIconSize,
|
fontSize: collapsedIconSize,
|
||||||
lineHeight: `${itemHeight}px`,
|
lineHeight: `${unit(itemHeight)}`,
|
||||||
|
|
||||||
'+ span': {
|
'+ span': {
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
|
Loading…
Reference in New Issue
Block a user