mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-27 20:49:53 +08:00
863f61d908
Co-authored-by: afc163 <afc163@gmail.com>
94 lines
2.7 KiB
TypeScript
94 lines
2.7 KiB
TypeScript
import type { CSSObject } from '@ant-design/cssinjs';
|
|
import { unit } from '@ant-design/cssinjs';
|
|
|
|
import type { AliasToken } from '../theme/interface';
|
|
import type { CSSUtil } from '../theme/internal';
|
|
|
|
export interface ArrowToken {
|
|
/** @internal */
|
|
arrowShadowWidth: number;
|
|
/** @internal */
|
|
arrowPath: string;
|
|
/** @internal */
|
|
arrowPolygon: string;
|
|
}
|
|
|
|
export function getArrowToken(token: AliasToken): ArrowToken {
|
|
const { sizePopupArrow, borderRadiusXS, borderRadiusOuter } = token;
|
|
|
|
const unitWidth = sizePopupArrow / 2;
|
|
|
|
const ax = 0;
|
|
const ay = unitWidth;
|
|
const bx = (borderRadiusOuter * 1) / Math.sqrt(2);
|
|
const by = unitWidth - borderRadiusOuter * (1 - 1 / Math.sqrt(2));
|
|
const cx = unitWidth - borderRadiusXS * (1 / Math.sqrt(2));
|
|
const cy = borderRadiusOuter * (Math.sqrt(2) - 1) + borderRadiusXS * (1 / Math.sqrt(2));
|
|
const dx = 2 * unitWidth - cx;
|
|
const dy = cy;
|
|
const ex = 2 * unitWidth - bx;
|
|
const ey = by;
|
|
const fx = 2 * unitWidth - ax;
|
|
const fy = ay;
|
|
|
|
const shadowWidth = unitWidth * Math.sqrt(2) + borderRadiusOuter * (Math.sqrt(2) - 2);
|
|
const polygonOffset = borderRadiusOuter * (Math.sqrt(2) - 1);
|
|
|
|
const arrowPolygon = `polygon(${polygonOffset}px 100%, 50% ${polygonOffset}px, ${
|
|
2 * unitWidth - polygonOffset
|
|
}px 100%, ${polygonOffset}px 100%)`;
|
|
const arrowPath = `path('M ${ax} ${ay} A ${borderRadiusOuter} ${borderRadiusOuter} 0 0 0 ${bx} ${by} L ${cx} ${cy} A ${borderRadiusXS} ${borderRadiusXS} 0 0 1 ${dx} ${dy} L ${ex} ${ey} A ${borderRadiusOuter} ${borderRadiusOuter} 0 0 0 ${fx} ${fy} Z')`;
|
|
|
|
return {
|
|
arrowShadowWidth: shadowWidth,
|
|
arrowPath,
|
|
arrowPolygon,
|
|
};
|
|
}
|
|
|
|
export const genRoundedArrow = <T extends AliasToken & ArrowToken & CSSUtil>(
|
|
token: T,
|
|
bgColor: string,
|
|
boxShadow: string,
|
|
): CSSObject => {
|
|
const { sizePopupArrow, arrowPolygon, arrowPath, arrowShadowWidth, borderRadiusXS, calc } = token;
|
|
return {
|
|
pointerEvents: 'none',
|
|
width: sizePopupArrow,
|
|
height: sizePopupArrow,
|
|
overflow: 'hidden',
|
|
|
|
'&::before': {
|
|
position: 'absolute',
|
|
bottom: 0,
|
|
insetInlineStart: 0,
|
|
width: sizePopupArrow,
|
|
height: calc(sizePopupArrow).div(2).equal(),
|
|
background: bgColor,
|
|
clipPath: {
|
|
_multi_value_: true,
|
|
value: [arrowPolygon, arrowPath],
|
|
},
|
|
content: '""',
|
|
},
|
|
|
|
'&::after': {
|
|
content: '""',
|
|
position: 'absolute',
|
|
width: arrowShadowWidth,
|
|
height: arrowShadowWidth,
|
|
bottom: 0,
|
|
insetInline: 0,
|
|
margin: 'auto',
|
|
borderRadius: {
|
|
_skip_check_: true,
|
|
value: `0 0 ${unit(borderRadiusXS)} 0`,
|
|
},
|
|
transform: 'translateY(50%) rotate(-135deg)',
|
|
boxShadow,
|
|
zIndex: 0,
|
|
background: 'transparent',
|
|
},
|
|
};
|
|
};
|