refactor(tooltip): refactor tooltip types
This commit is contained in:
parent
4367870061
commit
7a107b1f06
|
@ -0,0 +1,16 @@
|
|||
import { ComputedRef } from "vue";
|
||||
import { TooltipPlacement } from "../tooltip.props";
|
||||
|
||||
export type RectDirection = 'top' | 'bottom' | 'right' | 'left';
|
||||
export type RectSizeProperty = 'height' | 'width';
|
||||
export interface RectPosition {
|
||||
top: number;
|
||||
left: number;
|
||||
right: number;
|
||||
}
|
||||
|
||||
export interface UseTooltipPosition {
|
||||
tooltipPlacement: ComputedRef<TooltipPlacement>;
|
||||
tooltipPosition: ComputedRef<RectPosition>;
|
||||
arrowPosition: ComputedRef<RectPosition>;
|
||||
}
|
|
@ -1,13 +1,6 @@
|
|||
import { computed, ref, SetupContext } from "vue";
|
||||
import { TooltipPlacement, TooltipProps } from "../tooltip.props";
|
||||
|
||||
type RectDirection = 'top' | 'bottom' | 'right' | 'left';
|
||||
type RectSizeProperty = 'height' | 'width';
|
||||
interface RectPosition {
|
||||
top: number;
|
||||
left: number;
|
||||
right: number;
|
||||
}
|
||||
import { RectDirection, RectPosition, RectSizeProperty } from "./types";
|
||||
|
||||
export function useTooltipPosition(
|
||||
props: TooltipProps,
|
||||
|
@ -30,14 +23,10 @@ export function useTooltipPosition(
|
|||
|
||||
const placement = ref(props.placement);
|
||||
|
||||
const tooltipPlacement = computed(() => {
|
||||
return props.placement;
|
||||
});
|
||||
|
||||
function revertPlacement(placement: string, direction: RectDirection) {
|
||||
function revertPlacement(placement: string, direction: RectDirection): TooltipPlacement {
|
||||
const revertDirection: RectDirection = revertDirectionMap.get(direction) || direction;
|
||||
const revertedPlacement = placement.replace(direction, revertDirection);
|
||||
return revertDirection;
|
||||
const revertedPlacement = placement.replace(direction, revertDirection) as TooltipPlacement;
|
||||
return revertedPlacement;
|
||||
}
|
||||
|
||||
function autoRectifyDirection(
|
||||
|
@ -165,8 +154,8 @@ export function useTooltipPosition(
|
|||
function calculateArrowPosition(
|
||||
placement: TooltipPlacement,
|
||||
hostBound: DOMRect,
|
||||
fixedTooltipBound: DOMRect,
|
||||
arrowBound: DOMRect): DOMRect {
|
||||
tooltipPositoin: RectPosition,
|
||||
arrowBound: DOMRect): RectPosition {
|
||||
const leftAlignment = placement.indexOf('-left') > 0;
|
||||
const rightAlignment = placement.indexOf('-right') > 0;
|
||||
const topAlignment = placement.indexOf('-top') > 0;
|
||||
|
@ -174,12 +163,17 @@ export function useTooltipPosition(
|
|||
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 = fixedTooltipBound.left - hostBound.left - hostBound.width * 0.5 + arrowBound.width * 0.5 + offsetX;
|
||||
const fixedArrowTop = fixedTooltipBound.top - hostBound.top - hostBound.height * 0.5 + arrowBound.height * 0.5 + offsetY;
|
||||
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;
|
||||
|
||||
return Object.assign({}, arrowBound, { left: Math.abs(fixedArrowLeft), top: Math.abs(fixedArrowTop) });
|
||||
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 tooltipPosition = computed<RectPosition>(() => {
|
||||
const originalTop = calculateTooltipTopPositoin(placement.value, hostBound, tooltipBound, arrowBound);
|
||||
const originalLeft = calculateTooltipLeftPosition(placement.value, hostBound, tooltipBound, arrowBound);
|
||||
|
@ -194,119 +188,10 @@ export function useTooltipPosition(
|
|||
return { top, left, right };
|
||||
});
|
||||
|
||||
/* 计算tooltip最新位置 */
|
||||
function calculatePosition(hostBound: DOMRect, tooltipBound: DOMRect, arrowBound: DOMRect) {
|
||||
let top = 0;
|
||||
let left = 0;
|
||||
let right = 0;
|
||||
const arrowPosition = computed<RectPosition>(() => {
|
||||
const { top, left, right } = calculateArrowPosition(placement.value, hostBound, tooltipPosition.value, arrowBound);
|
||||
return { top, left, right };
|
||||
});
|
||||
|
||||
switch (this.rectifyPlacement) {
|
||||
case 'top':
|
||||
top = hostPosition.top - tooltipSize.height - 2;
|
||||
left = hostPosition.left + (hostPosition.width - tooltipSize.width) / 2;
|
||||
right = left + tooltipSize.width;
|
||||
break;
|
||||
case 'left':
|
||||
top = hostPosition.top + (hostPosition.height - tooltipSize.height) / 2;
|
||||
left = hostPosition.left - tooltipSize.width - 2;
|
||||
break;
|
||||
case 'right':
|
||||
top = hostPosition.top + (hostPosition.height - tooltipSize.height) / 2;
|
||||
left = hostPosition.right + 2;
|
||||
break;
|
||||
case 'bottom':
|
||||
top = hostPosition.bottom + arrowSize.height + 2;
|
||||
left = hostPosition.left + (hostPosition.width - tooltipSize.width) / 2;
|
||||
right = left + tooltipSize.width;
|
||||
break;
|
||||
case 'top-left':
|
||||
top = hostPosition.top - tooltipSize.height - 2;
|
||||
left = hostPosition.left;
|
||||
right = left + tooltipSize.width;
|
||||
break;
|
||||
case 'top-right':
|
||||
top = hostPosition.top - tooltipSize.height - 2;
|
||||
left = hostPosition.right - tooltipSize.width;
|
||||
right = hostPosition.right;
|
||||
break;
|
||||
case 'right-top':
|
||||
top = hostPosition.top;
|
||||
left = hostPosition.right + 2;
|
||||
this.arrowNode.nativeElement.style.top = '10%';
|
||||
break;
|
||||
case 'right-bottom':
|
||||
top = hostPosition.bottom - tooltipSize.height;
|
||||
left = hostPosition.right + 2;
|
||||
this.arrowNode.nativeElement.style.bottom = '10%';
|
||||
break;
|
||||
case 'bottom-left':
|
||||
top = hostPosition.bottom + arrowSize.height + 2;
|
||||
left = hostPosition.left;
|
||||
right = left + tooltipSize.width;
|
||||
break;
|
||||
case 'bottom-right':
|
||||
top = hostPosition.bottom + arrowSize.height + 2;
|
||||
left = hostPosition.right - tooltipSize.width;
|
||||
right = hostPosition.right;
|
||||
break;
|
||||
case 'left-top':
|
||||
top = hostPosition.top;
|
||||
left = hostPosition.left - tooltipSize.width - 2;
|
||||
this.arrowNode.nativeElement.style.top = '10%';
|
||||
break;
|
||||
case 'left-bottom':
|
||||
top = hostPosition.bottom - tooltipSize.height;
|
||||
left = hostPosition.left - tooltipSize.width - 2;
|
||||
this.arrowNode.nativeElement.style.bottom = '10%';
|
||||
}
|
||||
let overResult;
|
||||
let arrowLeft = 0;
|
||||
let arrowTop = 0
|
||||
switch (this.rectifyPlacement) {
|
||||
case 'top':
|
||||
case 'top-left':
|
||||
case 'top-right':
|
||||
case 'bottom':
|
||||
case 'bottom-left':
|
||||
case 'bottom-right':
|
||||
overResult = this.isOverBounding('left', left);
|
||||
if (overResult.isOver) {
|
||||
left = overResult.newValue;
|
||||
} else {
|
||||
overResult = this.isOverBounding('right', right);
|
||||
if (overResult.isOver) {
|
||||
left = overResult.newValue - tooltipSize.width;
|
||||
}
|
||||
}
|
||||
arrowLeft = left - hostPosition.left - hostPosition.width * 0.5 + arrowSize.width * 0.5;
|
||||
if (this.rectifyPlacement.indexOf('-left') > 0) {
|
||||
arrowLeft += hostPosition.width * 0.4;
|
||||
} else if (this.rectifyPlacement.indexOf('-right') > 0) {
|
||||
arrowLeft -= hostPosition.width * 0.4;
|
||||
}
|
||||
this.arrowNode.nativeElement.style.left = Math.abs(arrowLeft) + 'px';
|
||||
break;
|
||||
default:
|
||||
overResult = this.isOverBounding('top', top);
|
||||
|
||||
if (overResult.isOver) {
|
||||
top = overResult.newValue;
|
||||
} else {
|
||||
overResult = this.isOverBounding('bottom', bottom);
|
||||
if (overResult.isOver) {
|
||||
top = overResult.newValue - tooltipSize.height;
|
||||
}
|
||||
}
|
||||
arrowTop = top - hostPosition.top - hostPosition.height * 0.5 + arrowSize.height * 0.5;;
|
||||
if (this.rectifyPlacement.indexOf('-top') > 0) {
|
||||
arrowTop += hostPosition.height * 0.4;
|
||||
} else if (this.rectifyPlacement.indexOf('-bottom') > 0) {
|
||||
arrowTop -= hostPosition.height * 0.4;
|
||||
}
|
||||
this.arrowNode.nativeElement.style.top = Math.abs(arrowTop) + 'px';
|
||||
}
|
||||
this.tooltipNode.nativeElement.style.top = top + 'px';
|
||||
this.tooltipNode.nativeElement.style.left = left + 'px';
|
||||
|
||||
}
|
||||
return { arrowPosition, tooltipPlacement, tooltipPosition };
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ export default defineComponent({
|
|||
tooltip: true,
|
||||
show: true
|
||||
} as any;
|
||||
const tooltipClassName = `bs-tooltip-${props.position}`;
|
||||
const tooltipClassName = `bs-tooltip-${props.placement}`;
|
||||
classObject[tooltipClassName] = true;
|
||||
return classObject;
|
||||
});
|
||||
|
|
|
@ -32,7 +32,7 @@ const tooltipDirective = {
|
|||
content: 'This is a tooltip',
|
||||
width: 100,
|
||||
customClass: '',
|
||||
position: 'top',
|
||||
placement: 'top',
|
||||
referenceBoundingRect: element.getBoundingClientRect()
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue