refactor(tooltip): refactor tooltip add useCalculatePosition and useAdjust-position
This commit is contained in:
parent
f10e8b849d
commit
fbaeb43a8a
|
@ -6,7 +6,11 @@ export type RectSizeProperty = 'height' | 'width';
|
|||
export interface RectPosition {
|
||||
top: number;
|
||||
left: number;
|
||||
right: number;
|
||||
right?: number;
|
||||
}
|
||||
export interface TooltipPosition {
|
||||
arrow: RectPosition;
|
||||
tooltip: RectPosition;
|
||||
}
|
||||
|
||||
export interface UseTooltipPosition {
|
||||
|
@ -14,3 +18,13 @@ export interface UseTooltipPosition {
|
|||
tooltipPosition: ComputedRef<RectPosition>;
|
||||
arrowPosition: ComputedRef<RectPosition>;
|
||||
}
|
||||
|
||||
export interface UseCalculatePosition {
|
||||
calculate: (
|
||||
placementAndAlignment: TooltipPlacement,
|
||||
hostBound: DOMRect,
|
||||
tooltipBound: DOMRect,
|
||||
tooltipContentBound: DOMRect,
|
||||
arrowBound: DOMRect
|
||||
) => TooltipPosition;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { SetupContext } from "vue";
|
||||
import { TooltipProps } from "../tooltip.props";
|
||||
|
||||
export function useTooltipPosition(
|
||||
props: TooltipProps,
|
||||
context: SetupContext,
|
||||
hostBound: DOMRect,
|
||||
tooltipContentBound: DOMRect,
|
||||
tooltipBound: DOMRect,
|
||||
arrowBound: DOMRect) {
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
import { SetupContext } from "vue";
|
||||
import { TooltipPlacement, TooltipProps } from "../tooltip.props";
|
||||
import { RectPosition } from "./types";
|
||||
|
||||
export function useCalculatePosition(
|
||||
props: TooltipProps,
|
||||
context: SetupContext) {
|
||||
|
||||
function calculateArrowPosition(
|
||||
placementAndAlignment: TooltipPlacement,
|
||||
hostBound: DOMRect,
|
||||
tooltipPosition: RectPosition,
|
||||
tooltipContentBound: DOMRect,
|
||||
arrowBound: DOMRect
|
||||
): RectPosition {
|
||||
const placementAndAlignmentArray = placementAndAlignment.split('-');
|
||||
const placement = placementAndAlignmentArray[0];
|
||||
const alignment = placementAndAlignmentArray[1] || 'middle';
|
||||
|
||||
const offsetX = ['top', 'bottom'].includes(placement) ?
|
||||
(
|
||||
alignment === 'middle' ?
|
||||
(tooltipContentBound.width - arrowBound.width) / 2 :
|
||||
(alignment === 'right' ? tooltipContentBound.width - arrowBound.width - space : space)
|
||||
) : 0;
|
||||
|
||||
const offsetY = ['left', 'right'].includes(placement) ?
|
||||
(
|
||||
alignment === 'middle' ?
|
||||
(tooltipContentBound.height - arrowBound.height) / 2 :
|
||||
(alignment === 'bottom' ? tooltipContentBound.height - arrowBound.height - space : space)
|
||||
) : 0;
|
||||
|
||||
const arrowLeft = placement === 'left' ? tooltipContentBound.width + arrowBound.width : 0;
|
||||
const arrowTop = placement === 'top' ? tooltipContentBound.height + arrowBound.height : 0;
|
||||
|
||||
return { left: arrowLeft + offsetX, top: arrowTop + offsetY, right: 0 };
|
||||
}
|
||||
|
||||
function calculateTooltipPosition(
|
||||
placementAndAlignment: TooltipPlacement,
|
||||
hostBound: DOMRect,
|
||||
tooltipBound: DOMRect,
|
||||
tooltipContentBound: DOMRect,
|
||||
arrowBound: DOMRect) {
|
||||
const placementAndAlignmentArray = placementAndAlignment.split('-');
|
||||
const placement = placementAndAlignmentArray[0];
|
||||
const alignment = placementAndAlignmentArray[1] || 'middle';
|
||||
const horizontalMarginSpace = (tooltipBound.width - tooltipContentBound.width) / 2;
|
||||
const verticalMarginSpace = (tooltipBound.height - tooltipContentBound.height) / 2;
|
||||
const originalPositionX = placement === 'right' ? hostBound.right : hostBound.left;
|
||||
const originalPositionY = placement === 'bottom' ? hostBound.bottom : hostBound.top;
|
||||
|
||||
const offsetY = placement === 'top' ?
|
||||
0 - verticalMarginSpace - tooltipContentBound.height - arrowBound.height :
|
||||
(placement === 'bottom' ? (0 - verticalMarginSpace) + arrowBound.height : 0);
|
||||
|
||||
const verticalAlignmentOffset = ['left', 'right'].includes(placement) ?
|
||||
(
|
||||
alignment === 'middle' ?
|
||||
(hostBound.height - tooltipContentBound.height) / 2 :
|
||||
(alignment === 'bottom' ? hostBound.height - tooltipContentBound.height : 0)
|
||||
) : 0;
|
||||
|
||||
const offsetX = placement === 'left' ?
|
||||
0 - horizontalMarginSpace - tooltipContentBound.width - arrowBound.width :
|
||||
(placement === 'right' ? (0 - horizontalMarginSpace) + arrowBound.width : 0);
|
||||
|
||||
const horizontalAlignmentOffset = ['top', 'bottom'].includes(placement) ?
|
||||
(alignment === 'middle' ?
|
||||
(hostBound.width - tooltipContentBound.width) / 2 :
|
||||
(alignment === 'right' ? hostBound.width - tooltipContentBound.width : 0)
|
||||
) : 0;
|
||||
|
||||
const top = originalPositionY + offsetY + verticalAlignmentOffset;
|
||||
const left = originalPositionX + offsetX + horizontalAlignmentOffset;
|
||||
return { left, top };
|
||||
}
|
||||
|
||||
function calculate(
|
||||
placementAndAlignment: TooltipPlacement,
|
||||
hostBound: DOMRect,
|
||||
tooltipBound: DOMRect,
|
||||
tooltipContentBound: DOMRect,
|
||||
arrowBound: DOMRect
|
||||
) {
|
||||
const tooltip = calculateTooltipPosition(placementAndAlignment, hostBound, tooltipBound, tooltipContentBound, arrowBound);
|
||||
const arrow = calculateArrowPosition(placementAndAlignment, hostBound, tooltipBound, tooltipContentBound, arrowBound);
|
||||
return { arrow, tooltip };
|
||||
}
|
||||
|
||||
return { calculate };
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
import { max } from "lodash";
|
||||
import { computed, ref, SetupContext } from "vue";
|
||||
import { TooltipPlacement, TooltipProps } from "../tooltip.props";
|
||||
import { RectDirection, RectPosition, RectSizeProperty } from "./types";
|
||||
|
@ -55,93 +54,7 @@ export function useTooltipPosition(
|
|||
return rectifyPlacement;
|
||||
}
|
||||
|
||||
function calculateTooltipTopPositoin(
|
||||
placementAndAlignment: TooltipPlacement,
|
||||
hostBound: DOMRect,
|
||||
tooltipContentBound: DOMRect,
|
||||
arrowBound: DOMRect
|
||||
) {
|
||||
const placementAndAlignmentArray = placementAndAlignment.split('-');
|
||||
const placement = placementAndAlignmentArray[0];
|
||||
const alignment = placementAndAlignmentArray[1] || 'middle';
|
||||
const marginSpace = (tooltipBound.height - tooltipContentBound.height) / 2;
|
||||
const originalPositionY = placement === 'bottom' ? hostBound.bottom : hostBound.top;
|
||||
|
||||
const offsetY = placement === 'top' ?
|
||||
0 - marginSpace - tooltipContentBound.height - arrowBound.height :
|
||||
(placement === 'bottom' ? (0 - marginSpace) + arrowBound.height : 0);
|
||||
|
||||
const offsetAlignment = ['left', 'right'].includes(placement) ?
|
||||
(
|
||||
alignment === 'middle' ?
|
||||
(hostBound.height - tooltipContentBound.height) / 2 :
|
||||
(alignment === 'bottom' ? hostBound.height - tooltipContentBound.height : 0)
|
||||
) : 0;
|
||||
|
||||
return originalPositionY + offsetY + offsetAlignment;
|
||||
}
|
||||
|
||||
function calculateTooltipLeftPosition(
|
||||
placementAndAlignment: TooltipPlacement,
|
||||
hostBound: DOMRect,
|
||||
tooltipContentBound: DOMRect,
|
||||
arrowBound: DOMRect
|
||||
) {
|
||||
const placementAndAlignmentArray = placementAndAlignment.split('-');
|
||||
const placement = placementAndAlignmentArray[0];
|
||||
const alignment = placementAndAlignmentArray[1] || 'middle';
|
||||
const marginSpace = (tooltipBound.width - tooltipContentBound.width) / 2;
|
||||
const originalPositionX = placement === 'right' ? hostBound.right : hostBound.left;
|
||||
|
||||
const offsetX = placement === 'left' ?
|
||||
0 - marginSpace - tooltipContentBound.width - arrowBound.width :
|
||||
(placement === 'right' ? (0 - marginSpace) + arrowBound.width : 0);
|
||||
|
||||
const offsetAlignment = ['top', 'bottom'].includes(placement) ?
|
||||
(
|
||||
alignment === 'middle' ?
|
||||
(hostBound.width - tooltipContentBound.width) / 2 :
|
||||
(alignment === 'right' ? hostBound.width - tooltipContentBound.width : 0)
|
||||
) : 0;
|
||||
|
||||
// let offsetX = 0;
|
||||
// const horizontalAlignment = placement.indexOf('right') > -1 ? 'right' : (placement.indexOf('left') > -1 ? 'left' : 'center');
|
||||
// const originalPositionX = horizontalAlignment === 'right' ? hostBound.right : hostBound.left;
|
||||
|
||||
// if (['left', 'left-top', 'left-bottom'].includes(placement)) {
|
||||
// offsetX = 0 - tooltipBound.width - space;
|
||||
// } else if (['top', 'bottom'].includes(placement)) {
|
||||
// offsetX = (hostBound.width - tooltipBound.width) / 2;
|
||||
// } else if (['right', 'right-top', 'right-bottom'].includes(placement)) {
|
||||
// offsetX = space;
|
||||
// } else if (['top-right', 'bottom-right'].includes(placement)) {
|
||||
// offsetX = 0 - tooltipBound.width;
|
||||
// } else if (['top-left', 'bottom-left'].includes(placement)) {
|
||||
// offsetX = 0;
|
||||
// } else {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
return originalPositionX + offsetX + offsetAlignment;
|
||||
}
|
||||
|
||||
function calculateTooltipRightPosition(placement: TooltipPlacement, hostBound: DOMRect, tooltipBound: DOMRect, arrowBound: DOMRect) {
|
||||
let offsetX = 0;
|
||||
const horizontalAlignment = placement.indexOf('right') > -1 ? 'right' : (placement.indexOf('left') > -1 ? 'left' : 'center');
|
||||
const originalPositionX = horizontalAlignment === 'right' ? hostBound.right : hostBound.left;
|
||||
|
||||
if (['top', 'bottom'].includes(placement)) {
|
||||
offsetX = (hostBound.width - tooltipBound.width) / 2 + tooltipBound.width;
|
||||
} else if (['top-left', 'bottom-left'].includes(placement)) {
|
||||
offsetX = tooltipBound.width;
|
||||
} else if (['top-right', 'bottom-right'].includes(placement)) {
|
||||
offsetX = 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return originalPositionX + offsetX;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取纠正元素
|
||||
|
@ -222,54 +135,7 @@ export function useTooltipPosition(
|
|||
return { left: fixedLeft, top: fixedTop, right: originalPosition.right };
|
||||
}
|
||||
|
||||
function calculateArrowPosition(
|
||||
placementAndAlignment: TooltipPlacement,
|
||||
hostBound: DOMRect,
|
||||
tooltipPosition: RectPosition,
|
||||
tooltipContentBound: DOMRect,
|
||||
arrowBound: DOMRect
|
||||
): RectPosition {
|
||||
const placementAndAlignmentArray = placementAndAlignment.split('-');
|
||||
const placement = placementAndAlignmentArray[0];
|
||||
const alignment = placementAndAlignmentArray[1] || 'middle';
|
||||
|
||||
const offsetX = ['top', 'bottom'].includes(placement) ?
|
||||
(
|
||||
alignment === 'middle' ?
|
||||
(tooltipContentBound.width - arrowBound.width) / 2 :
|
||||
(alignment === 'right' ? tooltipContentBound.width - arrowBound.width - space : space)
|
||||
) : 0;
|
||||
|
||||
const offsetY = ['left', 'right'].includes(placement) ?
|
||||
(
|
||||
alignment === 'middle' ?
|
||||
(tooltipContentBound.height - arrowBound.height) / 2 :
|
||||
(alignment === 'bottom' ? tooltipContentBound.height - arrowBound.height - space : space)
|
||||
) : 0;
|
||||
|
||||
const arrowLeft = placement === 'left' ? tooltipContentBound.width + arrowBound.width : 0;
|
||||
const arrowTop = placement === 'top' ? tooltipContentBound.height + arrowBound.height : 0;
|
||||
|
||||
return { left: arrowLeft + offsetX, top: arrowTop + offsetY, right: 0 };
|
||||
|
||||
// const leftAlignment = placement.endsWith('left');
|
||||
// const rightAlignment = placement.endsWith('right');
|
||||
// const topAlignment = placement.endsWith('top');
|
||||
// const bottomAlignment = placement.endsWith('bottom');
|
||||
// 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 = tooltipPosition.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 fixedArrowLeft = leftAlignment ?
|
||||
// tooltipContentBound.width + arrowBound.width :
|
||||
// (rightAlignment ? 0 : (tooltipBound.width - arrowBound.width) / 2);
|
||||
// const fixedArrowTop = topAlignment ?
|
||||
// (tooltipBound.height - tooltipContentBound.height) / 2 + tooltipContentBound.height :
|
||||
// (bottomAlignment ? 0 : (tooltipBound.height - arrowBound.height) / 2);
|
||||
|
||||
// return { left: Math.abs(fixedArrowLeft), top: fixedArrowTop, right: 0 };
|
||||
}
|
||||
|
||||
const tooltipPlacement = computed<string>(() => {
|
||||
return placementAndAlignment.value.split('-')[0];
|
||||
|
|
Loading…
Reference in New Issue