ant-design-vue
Version:
An enterprise-class UI design language and Vue-based implementation
179 lines • 6.3 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import { roundedArrow } from './roundedArrow';
function connectArrowCls(classList) {
let showArrowCls = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
return classList.map(cls => `${showArrowCls}${cls}`).join(',');
}
export const MAX_VERTICAL_CONTENT_RADIUS = 8;
export function getArrowOffset(options) {
const maxVerticalContentRadius = MAX_VERTICAL_CONTENT_RADIUS;
const {
sizePopupArrow,
contentRadius,
borderRadiusOuter,
limitVerticalRadius
} = options;
const arrowInnerOffset = sizePopupArrow / 2 - Math.ceil(borderRadiusOuter * (Math.sqrt(2) - 1));
const dropdownArrowOffset = (contentRadius > 12 ? contentRadius + 2 : 12) - arrowInnerOffset;
const dropdownArrowOffsetVertical = limitVerticalRadius ? maxVerticalContentRadius - arrowInnerOffset : dropdownArrowOffset;
return {
dropdownArrowOffset,
dropdownArrowOffsetVertical
};
}
export default function getArrowStyle(token, options) {
const {
componentCls,
sizePopupArrow,
marginXXS,
borderRadiusXS,
borderRadiusOuter,
boxShadowPopoverArrow
} = token;
const {
colorBg,
showArrowCls,
contentRadius = token.borderRadiusLG,
limitVerticalRadius
} = options;
const {
dropdownArrowOffsetVertical,
dropdownArrowOffset
} = getArrowOffset({
sizePopupArrow,
contentRadius,
borderRadiusOuter,
limitVerticalRadius
});
const dropdownArrowDistance = sizePopupArrow / 2 + marginXXS;
return {
[componentCls]: {
// ============================ Basic ============================
[`${componentCls}-arrow`]: [_extends(_extends({
position: 'absolute',
zIndex: 1,
display: 'block'
}, roundedArrow(sizePopupArrow, borderRadiusXS, borderRadiusOuter, colorBg, boxShadowPopoverArrow)), {
'&:before': {
background: colorBg
}
})],
// ========================== Placement ==========================
// Here handle the arrow position and rotate stuff
// >>>>> Top
[[`&-placement-top ${componentCls}-arrow`, `&-placement-topLeft ${componentCls}-arrow`, `&-placement-topRight ${componentCls}-arrow`].join(',')]: {
bottom: 0,
transform: 'translateY(100%) rotate(180deg)'
},
[`&-placement-top ${componentCls}-arrow`]: {
left: {
_skip_check_: true,
value: '50%'
},
transform: 'translateX(-50%) translateY(100%) rotate(180deg)'
},
[`&-placement-topLeft ${componentCls}-arrow`]: {
left: {
_skip_check_: true,
value: dropdownArrowOffset
}
},
[`&-placement-topRight ${componentCls}-arrow`]: {
right: {
_skip_check_: true,
value: dropdownArrowOffset
}
},
// >>>>> Bottom
[[`&-placement-bottom ${componentCls}-arrow`, `&-placement-bottomLeft ${componentCls}-arrow`, `&-placement-bottomRight ${componentCls}-arrow`].join(',')]: {
top: 0,
transform: `translateY(-100%)`
},
[`&-placement-bottom ${componentCls}-arrow`]: {
left: {
_skip_check_: true,
value: '50%'
},
transform: `translateX(-50%) translateY(-100%)`
},
[`&-placement-bottomLeft ${componentCls}-arrow`]: {
left: {
_skip_check_: true,
value: dropdownArrowOffset
}
},
[`&-placement-bottomRight ${componentCls}-arrow`]: {
right: {
_skip_check_: true,
value: dropdownArrowOffset
}
},
// >>>>> Left
[[`&-placement-left ${componentCls}-arrow`, `&-placement-leftTop ${componentCls}-arrow`, `&-placement-leftBottom ${componentCls}-arrow`].join(',')]: {
right: {
_skip_check_: true,
value: 0
},
transform: 'translateX(100%) rotate(90deg)'
},
[`&-placement-left ${componentCls}-arrow`]: {
top: {
_skip_check_: true,
value: '50%'
},
transform: 'translateY(-50%) translateX(100%) rotate(90deg)'
},
[`&-placement-leftTop ${componentCls}-arrow`]: {
top: dropdownArrowOffsetVertical
},
[`&-placement-leftBottom ${componentCls}-arrow`]: {
bottom: dropdownArrowOffsetVertical
},
// >>>>> Right
[[`&-placement-right ${componentCls}-arrow`, `&-placement-rightTop ${componentCls}-arrow`, `&-placement-rightBottom ${componentCls}-arrow`].join(',')]: {
left: {
_skip_check_: true,
value: 0
},
transform: 'translateX(-100%) rotate(-90deg)'
},
[`&-placement-right ${componentCls}-arrow`]: {
top: {
_skip_check_: true,
value: '50%'
},
transform: 'translateY(-50%) translateX(-100%) rotate(-90deg)'
},
[`&-placement-rightTop ${componentCls}-arrow`]: {
top: dropdownArrowOffsetVertical
},
[`&-placement-rightBottom ${componentCls}-arrow`]: {
bottom: dropdownArrowOffsetVertical
},
// =========================== Offset ============================
// Offset the popover to account for the dropdown arrow
// >>>>> Top
[connectArrowCls([`&-placement-topLeft`, `&-placement-top`, `&-placement-topRight`].map(cls => cls += ':not(&-arrow-hidden)'), showArrowCls)]: {
paddingBottom: dropdownArrowDistance
},
// >>>>> Bottom
[connectArrowCls([`&-placement-bottomLeft`, `&-placement-bottom`, `&-placement-bottomRight`].map(cls => cls += ':not(&-arrow-hidden)'), showArrowCls)]: {
paddingTop: dropdownArrowDistance
},
// >>>>> Left
[connectArrowCls([`&-placement-leftTop`, `&-placement-left`, `&-placement-leftBottom`].map(cls => cls += ':not(&-arrow-hidden)'), showArrowCls)]: {
paddingRight: {
_skip_check_: true,
value: dropdownArrowDistance
}
},
// >>>>> Right
[connectArrowCls([`&-placement-rightTop`, `&-placement-right`, `&-placement-rightBottom`].map(cls => cls += ':not(&-arrow-hidden)'), showArrowCls)]: {
paddingLeft: {
_skip_check_: true,
value: dropdownArrowDistance
}
}
}
};
}