You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
345 lines
11 KiB
345 lines
11 KiB
// deps-lint-skip-all
|
|
import { CSSObject, Keyframes } from '@ant-design/cssinjs';
|
|
import {
|
|
resetComponent,
|
|
GenerateStyle,
|
|
PresetColors,
|
|
PresetColorType,
|
|
genComponentStyleHook,
|
|
FullToken,
|
|
mergeToken,
|
|
} from '../../_util/theme';
|
|
|
|
interface BadgeToken extends FullToken<'Badge'> {
|
|
badgeZIndex: number | string;
|
|
badgeHeight: number;
|
|
badgeHeightSm: number;
|
|
badgeTextColor: string;
|
|
badgeFontWeight: string;
|
|
badgeFontSize: number;
|
|
badgeColor: string;
|
|
badgeDotSize: number;
|
|
badgeFontSizeSm: number;
|
|
badgeStatusSize: number;
|
|
}
|
|
|
|
const antStatusProcessing = new Keyframes('antStatusProcessing', {
|
|
'0%': { transform: 'scale(0.8)', opacity: 0.5 },
|
|
'100%': { transform: 'scale(2.4)', opacity: 0 },
|
|
});
|
|
|
|
const antZoomBadgeIn = new Keyframes('antZoomBadgeIn', {
|
|
'0%': { transform: 'scale(0) translate(50%, -50%)', opacity: 0 },
|
|
'100%': { transform: 'scale(1) translate(50%, -50%)' },
|
|
});
|
|
|
|
const antZoomBadgeOut = new Keyframes('antZoomBadgeOut', {
|
|
'0%': { transform: 'scale(1) translate(50%, -50%)' },
|
|
'100%': { transform: 'scale(0) translate(50%, -50%)', opacity: 0 },
|
|
});
|
|
|
|
const antNoWrapperZoomBadgeIn = new Keyframes('antNoWrapperZoomBadgeIn', {
|
|
'0%': { transform: 'scale(0)', opacity: 0 },
|
|
'100%': { transform: 'scale(1)' },
|
|
});
|
|
const antNoWrapperZoomBadgeOut = new Keyframes('antNoWrapperZoomBadgeOut', {
|
|
'0%': { transform: 'scale(1)' },
|
|
'100%': { transform: 'scale(0)', opacity: 0 },
|
|
});
|
|
const antBadgeLoadingCircle = new Keyframes('antBadgeLoadingCircle', {
|
|
'0%': { transformOrigin: '50%' },
|
|
'100%': {
|
|
transform: 'translate(50%, -50%) rotate(360deg)',
|
|
transformOrigin: '50%',
|
|
},
|
|
});
|
|
|
|
const genSharedBadgeStyle: GenerateStyle<BadgeToken> = (token: BadgeToken): CSSObject => {
|
|
const { componentCls, iconCls, antCls } = token;
|
|
const numberPrefixCls = `${antCls}-scroll-number`;
|
|
const ribbonPrefixCls = `${antCls}-ribbon`;
|
|
const ribbonWrapperPrefixCls = `${antCls}-ribbon-wrapper`;
|
|
|
|
// FIXME preset color 后面可能要统一重构
|
|
const statusPreset = PresetColors.reduce((prev: CSSObject, colorKey: keyof PresetColorType) => {
|
|
const darkColor = token[`${colorKey}-6`];
|
|
return {
|
|
...prev,
|
|
[`${componentCls}-status-${colorKey}`]: {
|
|
background: darkColor,
|
|
},
|
|
};
|
|
}, {} as CSSObject);
|
|
const statusRibbonPreset = PresetColors.reduce(
|
|
(prev: CSSObject, colorKey: keyof PresetColorType) => {
|
|
const darkColor = token[`${colorKey}-6`];
|
|
return {
|
|
...prev,
|
|
[`&${ribbonPrefixCls}-color-${colorKey}`]: {
|
|
background: darkColor,
|
|
color: darkColor,
|
|
},
|
|
};
|
|
},
|
|
{} as CSSObject,
|
|
);
|
|
|
|
return {
|
|
[componentCls]: {
|
|
...resetComponent(token),
|
|
position: 'relative',
|
|
display: 'inline-block',
|
|
lineHeight: 1,
|
|
|
|
[`${componentCls}-count`]: {
|
|
zIndex: token.badgeZIndex,
|
|
minWidth: token.badgeHeight,
|
|
height: token.badgeHeight,
|
|
padding: '0 6px', // FIXME: hard code, copied from old less file
|
|
color: token.badgeTextColor,
|
|
fontWeight: token.badgeFontWeight,
|
|
fontSize: token.badgeFontSize,
|
|
lineHeight: `${token.badgeHeight}px`,
|
|
whiteSpace: 'nowrap',
|
|
textAlign: 'center',
|
|
background: token.badgeColor,
|
|
borderRadius: token.badgeHeight / 2,
|
|
boxShadow: `0 0 0 1px ${token.colorBgComponent}`,
|
|
a: {
|
|
color: token.badgeTextColor,
|
|
},
|
|
'a:hover': {
|
|
color: token.badgeTextColor,
|
|
},
|
|
},
|
|
[`${componentCls}-count-sm`]: {
|
|
minWidth: token.badgeHeightSm,
|
|
height: token.badgeHeightSm,
|
|
padding: 0,
|
|
fontSize: token.badgeFontSizeSm,
|
|
lineHeight: `${token.badgeHeightSm}px`,
|
|
borderRadius: token.badgeHeightSm / 2,
|
|
},
|
|
|
|
[`${componentCls}-multiple-words`]: {
|
|
padding: `0 ${token.paddingXS}px`,
|
|
},
|
|
|
|
[`${componentCls}-dot`]: {
|
|
zIndex: token.badgeZIndex,
|
|
width: token.badgeDotSize,
|
|
minWidth: token.badgeDotSize,
|
|
height: token.badgeDotSize,
|
|
background: token.badgeColor,
|
|
borderRadius: '100%',
|
|
boxShadow: `0 0 0 1px ${token.colorBgComponent}`,
|
|
},
|
|
[`${componentCls}-dot${numberPrefixCls}`]: {
|
|
transition: 'background 1.5s', // FIXME: hard code, copied from old less file
|
|
},
|
|
[`${componentCls}-count, ${componentCls}-dot, ${numberPrefixCls}-custom-component`]: {
|
|
position: 'absolute',
|
|
top: 0,
|
|
insetInlineEnd: 0,
|
|
transform: 'translate(50%, -50%)',
|
|
transformOrigin: '100% 0%',
|
|
[`${iconCls}-spin`]: {
|
|
animationName: antBadgeLoadingCircle,
|
|
animationDuration: token.motionDurationFast,
|
|
animationIterationCount: 'infinite',
|
|
animationTimingFunction: 'linear',
|
|
},
|
|
},
|
|
[`&${componentCls}-status`]: {
|
|
lineHeight: 'inherit',
|
|
verticalAlign: 'baseline',
|
|
|
|
[`${componentCls}-status-dot`]: {
|
|
position: 'relative',
|
|
top: -1, // FIXME: hard code, copied from old less file
|
|
display: 'inline-block',
|
|
width: token.badgeStatusSize,
|
|
height: token.badgeStatusSize,
|
|
verticalAlign: 'middle',
|
|
borderRadius: '50%',
|
|
},
|
|
|
|
[`${componentCls}-status-success`]: {
|
|
backgroundColor: token.colorSuccess,
|
|
},
|
|
[`${componentCls}-status-processing`]: {
|
|
position: 'relative',
|
|
backgroundColor: token.colorPrimary,
|
|
|
|
'&::after': {
|
|
position: 'absolute',
|
|
top: 0,
|
|
insetInlineStart: 0,
|
|
width: '100%',
|
|
height: '100%',
|
|
border: `1px solid ${token.colorPrimary}`,
|
|
borderRadius: '50%',
|
|
animationName: antStatusProcessing,
|
|
animationDuration: '1.2s',
|
|
animationIterationCount: 'infinite',
|
|
animationTimingFunction: 'ease-in-out',
|
|
content: '""',
|
|
},
|
|
},
|
|
[`${componentCls}-status-default`]: {
|
|
backgroundColor: '#d9d9d9', // FIXME: @normal-color;
|
|
},
|
|
|
|
[`${componentCls}-status-error`]: {
|
|
backgroundColor: token.colorError,
|
|
},
|
|
|
|
[`${componentCls}-status-warning`]: {
|
|
backgroundColor: token.colorWarning,
|
|
},
|
|
...statusPreset,
|
|
[`${componentCls}-status-text`]: {
|
|
marginInlineStart: token.marginXS,
|
|
color: token.colorText,
|
|
fontSize: token.fontSize,
|
|
},
|
|
},
|
|
[`${componentCls}-zoom-appear, ${componentCls}-zoom-enter`]: {
|
|
animationName: antZoomBadgeIn,
|
|
animationDuration: token.motionDurationSlow,
|
|
animationTimingFunction: token.motionEaseOutBack,
|
|
animationFillMode: 'both',
|
|
},
|
|
[`${componentCls}-zoom-leave`]: {
|
|
animationName: antZoomBadgeOut,
|
|
animationDuration: token.motionDurationSlow,
|
|
animationTimingFunction: token.motionEaseOutBack,
|
|
animationFillMode: 'both',
|
|
},
|
|
[`&${componentCls}-not-a-wrapper`]: {
|
|
[`${componentCls}-zoom-appear, ${componentCls}-zoom-enter`]: {
|
|
animationName: antNoWrapperZoomBadgeIn,
|
|
animationDuration: token.motionDurationSlow,
|
|
animationTimingFunction: token.motionEaseOutBack,
|
|
},
|
|
|
|
[`${componentCls}-zoom-leave`]: {
|
|
animationName: antNoWrapperZoomBadgeOut,
|
|
animationDuration: token.motionDurationSlow,
|
|
animationTimingFunction: token.motionEaseOutBack,
|
|
},
|
|
[`&:not(${componentCls}-status)`]: {
|
|
verticalAlign: 'middle',
|
|
},
|
|
[`${numberPrefixCls}-custom-component, ${componentCls}-count`]: {
|
|
transform: 'none',
|
|
},
|
|
[`${numberPrefixCls}-custom-component, ${numberPrefixCls}`]: {
|
|
position: 'relative',
|
|
top: 'auto',
|
|
display: 'block',
|
|
transformOrigin: '50% 50%',
|
|
},
|
|
},
|
|
[`${numberPrefixCls}`]: {
|
|
overflow: 'hidden',
|
|
direction: 'ltr',
|
|
[`${numberPrefixCls}-only`]: {
|
|
position: 'relative',
|
|
display: 'inline-block',
|
|
height: token.badgeHeight,
|
|
transition: `all ${token.motionDurationSlow} ${token.motionEaseOutBack}`,
|
|
WebkitTransformStyle: 'preserve-3d',
|
|
WebkitBackfaceVisibility: 'hidden',
|
|
[`> p${numberPrefixCls}-only-unit`]: {
|
|
height: token.badgeHeight,
|
|
margin: 0,
|
|
WebkitTransformStyle: 'preserve-3d',
|
|
WebkitBackfaceVisibility: 'hidden',
|
|
},
|
|
},
|
|
[`${numberPrefixCls}-symbol`]: { verticalAlign: 'top' },
|
|
},
|
|
},
|
|
[`${ribbonWrapperPrefixCls}`]: { position: 'relative' },
|
|
[`${ribbonPrefixCls}`]: {
|
|
...resetComponent(token),
|
|
position: 'absolute',
|
|
top: 8, // FIXME: hard code, copied from old less file
|
|
height: 22, // FIXME: hard code, copied from old less file
|
|
padding: `0 ${token.paddingXS}px`,
|
|
color: token.badgeTextColor,
|
|
lineHeight: '22px', // colorPrimarycode, copied from old less file
|
|
whiteSpace: 'nowrap',
|
|
backgroundColor: token.colorPrimary,
|
|
borderRadius: token.controlRadius,
|
|
[`${ribbonPrefixCls}-text`]: { color: '#fff' },
|
|
[`${ribbonPrefixCls}-corner`]: {
|
|
position: 'absolute',
|
|
top: '100%',
|
|
width: 8,
|
|
height: 8,
|
|
color: 'currentcolor',
|
|
border: '4px solid', // FIXME: hard code, copied from old less file
|
|
transform: 'scaleY(0.75)', // FIXME: hard code, copied from old less file
|
|
transformOrigin: 'top',
|
|
'&::after': {
|
|
position: 'absolute',
|
|
top: `${-0.5 * token.paddingXS}px`,
|
|
insetInlineStart: `${-0.5 * token.paddingXS}px`,
|
|
width: 'inherit',
|
|
height: 'inherit',
|
|
color: 'rgba(0, 0, 0, 0.25)',
|
|
border: 'inherit',
|
|
content: "''",
|
|
},
|
|
},
|
|
...statusRibbonPreset,
|
|
[`&${ribbonPrefixCls}-placement-end`]: {
|
|
insetInlineEnd: -1 * token.marginXS,
|
|
borderEndEndRadius: 0,
|
|
[`${ribbonPrefixCls}-corner`]: {
|
|
insetInlineEnd: 0,
|
|
borderColor: 'currentcolor transparent transparent currentcolor',
|
|
},
|
|
},
|
|
[`&${ribbonPrefixCls}-placement-start`]: {
|
|
insetInlineStart: -1 * token.marginXS,
|
|
borderEndStartRadius: 0,
|
|
[`${ribbonPrefixCls}-corner`]: {
|
|
insetInlineStart: 0,
|
|
borderColor: 'currentcolor currentcolor transparent transparent',
|
|
},
|
|
},
|
|
},
|
|
};
|
|
};
|
|
|
|
// ============================== Export ==============================
|
|
export default genComponentStyleHook('Badge', token => {
|
|
const badgeZIndex = 'auto';
|
|
const badgeHeight = 20; // FIXME: hard code
|
|
const badgeTextColor = token.colorBgComponent;
|
|
const badgeFontWeight = 'normal';
|
|
const badgeFontSize = token.fontSizeSM;
|
|
const badgeColor = token.colorHighlight;
|
|
const badgeHeightSm = 14; // FIXME: hard code
|
|
const badgeDotSize = 6; // FIXME: hard code
|
|
const badgeFontSizeSm = token.fontSizeSM;
|
|
const badgeStatusSize = 6; // FIXME: hard code
|
|
|
|
const badgeToken = mergeToken<BadgeToken>(token, {
|
|
badgeZIndex,
|
|
badgeHeight,
|
|
badgeTextColor,
|
|
badgeFontWeight,
|
|
badgeFontSize,
|
|
badgeColor,
|
|
badgeHeightSm,
|
|
badgeDotSize,
|
|
badgeFontSizeSm,
|
|
badgeStatusSize,
|
|
});
|
|
|
|
return [genSharedBadgeStyle(badgeToken), { display: 'none' }];
|
|
});
|
|
|