fix(tooltip): fix tooltip arrow position

This commit is contained in:
Sagi 2022-10-13 23:33:03 +08:00
parent 0b807fde1b
commit 0e614d0c74
2 changed files with 27 additions and 8 deletions

View File

@ -6,6 +6,7 @@ export function useTooltipPosition(
props: TooltipProps,
context: SetupContext,
hostBound: DOMRect,
referenceBound: DOMRect,
tooltipBound: DOMRect,
arrowBound: DOMRect) {
@ -160,20 +161,21 @@ export function useTooltipPosition(
arrowBound: DOMRect): RectPosition {
const leftAlignment = placement.indexOf('-left') > 0;
const rightAlignment = placement.indexOf('-right') > 0;
const topAlignment = placement.indexOf('-top') > 0;
const topAlignment = placement.endsWith('top');
const bottomAlignment = placement.indexOf('-bottom') > 0;
const offsetX = leftAlignment ? hostBound.width * 0.4 : (rightAlignment ? 0 - hostBound.width * 0.4 : 0);
const offsetY = topAlignment ? hostBound.height * 0.4 : (bottomAlignment ? 0 - hostBound.height * 0.4 : 0);
const fixedArrowLeft = tooltipPositoin.left - hostBound.left - hostBound.width * 0.5 + arrowBound.width * 0.5 + offsetX;
const fixedArrowTop = tooltipPositoin.top - hostBound.top - hostBound.height * 0.5 + arrowBound.height * 0.5 + offsetY;
// const fixedArrowTop = tooltipPositoin.top - hostBound.top - hostBound.height * 0.5 + arrowBound.height * 0.5 + offsetY;
const fixedArrowTop = (tooltipBound.height - referenceBound.height) / 2 + referenceBound.height;
return { left: Math.abs(fixedArrowLeft), top: Math.abs(fixedArrowTop), right: 0 };
}
const tooltipPlacement = computed<TooltipPlacement>(() => {
const rectifyPlacement = autoRectifyDirection(placement.value, hostBound, hostBound, tooltipBound, arrowBound);
return rectifyPlacement;
// const rectifyPlacement = autoRectifyDirection(placement.value, hostBound, hostBound, tooltipBound, arrowBound);
return placement.value;
});
const tooltipPosition = computed<RectPosition>(() => {
@ -192,7 +194,7 @@ export function useTooltipPosition(
const arrowPosition = computed<RectPosition>(() => {
const { top, left, right } = calculateArrowPosition(placement.value, hostBound, tooltipPosition.value, arrowBound);
return { top: top + scrollTop, left: left + scrollLeft, right };
return { top, left, right };
});
return { arrowPosition, tooltipPlacement, tooltipPosition };

View File

@ -12,6 +12,7 @@ export default defineComponent({
const isTextContext = ref(true);
const arrowRef = ref<HTMLElement>();
const tooltipRef = ref<HTMLElement>();
const tooltipInnerRef = ref<HTMLElement>();
const placement = ref(props.placement);
const tooltipClass = computed(() => {
const classObject = {
@ -41,19 +42,35 @@ export default defineComponent({
return styleObject;
});
const arrowLeftPosition = ref('');
const arrowTopPosition = ref('');
const arrowStyle = computed(() => {
const styleObject = {
left: arrowLeftPosition.value,
top: arrowTopPosition.value
};
return styleObject;
});
onMounted(() => {
if (arrowRef.value && tooltipRef.value && props.reference) {
if (arrowRef.value && tooltipRef.value && tooltipInnerRef.value && props.reference) {
const { arrowPosition, tooltipPlacement, tooltipPosition } = useTooltipPosition(
props,
context,
props.reference.getBoundingClientRect(),
tooltipInnerRef.value.getBoundingClientRect(),
tooltipRef.value.getBoundingClientRect(),
arrowRef.value.getBoundingClientRect()
);
placement.value = tooltipPlacement.value;
arrowLeftPosition.value = `${arrowPosition.value.left}px`;
arrowTopPosition.value = `${arrowPosition.value.top}px`;
tooltipLeftPosition.value = `${tooltipPosition.value.left}px`;
tooltipRightPosition.value = `${tooltipPosition.value.right}px`;
tooltipTopPosition.value = `${tooltipPosition.value.top}px`;
}
});
@ -64,8 +81,8 @@ export default defineComponent({
return () => {
return (
<div ref={tooltipRef} class={tooltipClass.value} style={tooltipStyle.value} onClick={onClick}>
<div class="arrow" ref={arrowRef}></div>
<div class="tooltip-inner">
<div ref={arrowRef} class="arrow" style={arrowStyle.value}></div>
<div ref={tooltipInnerRef} class="tooltip-inner">
<div class="tooltip-tmpl">
{shouldShowTooltipText.value && <div class="tooltip-text" v-html={tooltipText.value}></div>}
</div>