fix(tooltip): support adjust the tooltip position that overstep the boundary
This commit is contained in:
parent
879c3c9dc2
commit
7f142a71af
|
@ -1,3 +1,4 @@
|
||||||
|
import { DomEvent } from "@vue/test-utils/dist/constants/dom-events";
|
||||||
import { SetupContext } from "vue";
|
import { SetupContext } from "vue";
|
||||||
import { TooltipPlacement, TooltipProps } from "../tooltip.props";
|
import { TooltipPlacement, TooltipProps } from "../tooltip.props";
|
||||||
import { RectPosition, TooltipPosition } from "./types";
|
import { RectPosition, TooltipPosition } from "./types";
|
||||||
|
@ -28,10 +29,15 @@ export function useAdjustPosition(props: TooltipProps, context: SetupContext) {
|
||||||
placementAndAlignment: TooltipPlacement,
|
placementAndAlignment: TooltipPlacement,
|
||||||
originalPosition: TooltipPosition,
|
originalPosition: TooltipPosition,
|
||||||
relativeElementRect: DOMRect,
|
relativeElementRect: DOMRect,
|
||||||
tooltipRect: DOMRect
|
hostRect: DOMRect,
|
||||||
|
tooltipRect: DOMRect,
|
||||||
|
tooltipContentRect: DOMRect,
|
||||||
|
arrowRect: DOMRect
|
||||||
): TooltipPosition {
|
): TooltipPosition {
|
||||||
let fixedLeft = originalPosition.tooltip.left;
|
let fixedLeft = originalPosition.tooltip.left;
|
||||||
let fixedTop = originalPosition.tooltip.top;
|
let fixedTop = originalPosition.tooltip.top;
|
||||||
|
let fixedArrowLeft = originalPosition.arrow.left;
|
||||||
|
let fixedArrowTop = originalPosition.arrow.top;
|
||||||
const placementAndAlignmentArray = placementAndAlignment.split('-');
|
const placementAndAlignmentArray = placementAndAlignment.split('-');
|
||||||
const placement = placementAndAlignmentArray[0];
|
const placement = placementAndAlignmentArray[0];
|
||||||
if (['top', 'bottom'].includes(placement)) {
|
if (['top', 'bottom'].includes(placement)) {
|
||||||
|
@ -40,14 +46,24 @@ export function useAdjustPosition(props: TooltipProps, context: SetupContext) {
|
||||||
fixedLeft = overLeftBound.overBound ?
|
fixedLeft = overLeftBound.overBound ?
|
||||||
overLeftBound.fixedValue :
|
overLeftBound.fixedValue :
|
||||||
(overRightBound.overBound ? overRightBound.fixedValue - tooltipRect.width : originalPosition.tooltip.left);
|
(overRightBound.overBound ? overRightBound.fixedValue - tooltipRect.width : originalPosition.tooltip.left);
|
||||||
|
fixedArrowLeft = overLeftBound.overBound ?
|
||||||
|
tooltipRect.width - ((fixedLeft + tooltipRect.width) - hostRect.right) - arrowRect.width :
|
||||||
|
(overRightBound.overBound ? hostRect.left - fixedLeft : originalPosition.arrow.left);
|
||||||
}
|
}
|
||||||
const overTopBound = isOverstepBoundary(relativeElementRect, 'top', originalPosition.tooltip.top);
|
const overTopBound = isOverstepBoundary(relativeElementRect, 'top', originalPosition.tooltip.top);
|
||||||
const overBottomBound = isOverstepBoundary(relativeElementRect, 'bottom', originalPosition.tooltip.top + tooltipRect.height);
|
const overBottomBound = isOverstepBoundary(relativeElementRect, 'bottom', originalPosition.tooltip.top + tooltipRect.height);
|
||||||
fixedTop = overTopBound.overBound ?
|
fixedTop = overTopBound.overBound ?
|
||||||
overTopBound.fixedValue :
|
overTopBound.fixedValue :
|
||||||
(overBottomBound.overBound ? overBottomBound.fixedValue - tooltipRect.height : originalPosition.tooltip.top);
|
(overBottomBound.overBound ? overBottomBound.fixedValue - tooltipRect.height : originalPosition.tooltip.top);
|
||||||
|
fixedArrowTop = overTopBound.overBound ?
|
||||||
|
(originalPosition.arrow.top) :
|
||||||
|
(overBottomBound.overBound ?
|
||||||
|
(
|
||||||
|
tooltipRect.height - ((fixedTop + tooltipRect.height) - hostRect.top)
|
||||||
|
) :
|
||||||
|
originalPosition.arrow.top);
|
||||||
const tooltip = { left: fixedLeft, top: fixedTop };
|
const tooltip = { left: fixedLeft, top: fixedTop };
|
||||||
const arrow = { left: originalPosition.arrow.left, top: originalPosition.arrow.top };
|
const arrow = { left: fixedArrowLeft, top: fixedArrowTop };
|
||||||
return { arrow, tooltip };
|
return { arrow, tooltip };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,6 @@ export function useTooltipPosition(
|
||||||
tooltipContentRect: DOMRect,
|
tooltipContentRect: DOMRect,
|
||||||
arrowRect: DOMRect) {
|
arrowRect: DOMRect) {
|
||||||
|
|
||||||
const { scrollLeft, scrollTop } = document.documentElement;
|
|
||||||
|
|
||||||
const placementAndAlignment = ref(props.placement);
|
const placementAndAlignment = ref(props.placement);
|
||||||
|
|
||||||
const { getRelativeElementBound } = useRelative(props, context);
|
const { getRelativeElementBound } = useRelative(props, context);
|
||||||
|
@ -34,7 +32,9 @@ export function useTooltipPosition(
|
||||||
const relativeRect = getRelativeElementBound();
|
const relativeRect = getRelativeElementBound();
|
||||||
placementAndAlignment.value = adjustPlacement(placementAndAlignment.value, relativeRect, hostRect, tooltipRect, arrowRect);
|
placementAndAlignment.value = adjustPlacement(placementAndAlignment.value, relativeRect, hostRect, tooltipRect, arrowRect);
|
||||||
const originalPosition = calculate(placementAndAlignment.value, hostRect, tooltipRect, tooltipContentRect, arrowRect);
|
const originalPosition = calculate(placementAndAlignment.value, hostRect, tooltipRect, tooltipContentRect, arrowRect);
|
||||||
const position = adjustPosition(placementAndAlignment.value, originalPosition, relativeRect, tooltipRect);
|
const position = adjustPosition(
|
||||||
|
placementAndAlignment.value, originalPosition, relativeRect, hostRect, tooltipRect, tooltipContentRect, arrowRect
|
||||||
|
);
|
||||||
return position;
|
return position;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ export default defineComponent({
|
||||||
return classObject;
|
return classObject;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { scrollLeft, scrollTop } = document.documentElement;
|
||||||
|
|
||||||
const shouldShowTooltipText = computed(() => isTextContext.value);
|
const shouldShowTooltipText = computed(() => isTextContext.value);
|
||||||
|
|
||||||
const tooltipText = computed(() => props.content);
|
const tooltipText = computed(() => props.content);
|
||||||
|
@ -64,9 +66,8 @@ export default defineComponent({
|
||||||
tooltipInnerRef.value.getBoundingClientRect(),
|
tooltipInnerRef.value.getBoundingClientRect(),
|
||||||
arrowRef.value.getBoundingClientRect()
|
arrowRef.value.getBoundingClientRect()
|
||||||
);
|
);
|
||||||
tooltipLeftPosition.value = `${tooltipPosition.value.tooltip.left}px`;
|
tooltipLeftPosition.value = `${tooltipPosition.value.tooltip.left + scrollLeft}px`;
|
||||||
tooltipRightPosition.value = `${tooltipPosition.value.tooltip.right}px`;
|
tooltipTopPosition.value = `${tooltipPosition.value.tooltip.top + scrollTop}px`;
|
||||||
tooltipTopPosition.value = `${tooltipPosition.value.tooltip.top}px`;
|
|
||||||
arrowLeftPosition.value = `${tooltipPosition.value.arrow.left}px`;
|
arrowLeftPosition.value = `${tooltipPosition.value.arrow.left}px`;
|
||||||
arrowTopPosition.value = `${tooltipPosition.value.arrow.top}px`;
|
arrowTopPosition.value = `${tooltipPosition.value.arrow.top}px`;
|
||||||
placement.value = tooltipPlacement.value;
|
placement.value = tooltipPlacement.value;
|
||||||
|
|
|
@ -43,7 +43,7 @@ const tooltipDirective = {
|
||||||
element.addEventListener('mouseleave', ($event: MouseEvent) => {
|
element.addEventListener('mouseleave', ($event: MouseEvent) => {
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
if (app) {
|
if (app) {
|
||||||
// app.unmount();
|
app.unmount();
|
||||||
app = null;
|
app = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,12 +10,39 @@ const tooltipProps = { placement: 'bottom' };
|
||||||
|
|
||||||
<Button v-tooltip="{ placement: 'top-right' }"> 显示提示信息 </Button>
|
<Button v-tooltip="{ placement: 'top-right' }"> 显示提示信息 </Button>
|
||||||
|
|
||||||
<div id="tooltipContainer" style="width: 200px; height: 200px; background: antiquewhite; display: flex">
|
<div>
|
||||||
<Button
|
<div id="tooltipContainer1" style="width: 250px; height: 250px; background: antiquewhite; display: inline-flex">
|
||||||
style="margin: auto 0 auto auto"
|
1
|
||||||
v-tooltip="{ placement: 'top-left', referenceV: '#tooltipContainer', referenceH: '#tooltipContainer' }"
|
<Button
|
||||||
>
|
style="margin: auto 0 auto auto"
|
||||||
显示提示信息
|
v-tooltip="{ placement: 'right', verticalRelative: '#tooltipContainer1', horizontalRelative: '#tooltipContainer1' }"
|
||||||
</Button>
|
>
|
||||||
|
显示提示信息
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div id="tooltipContainer2" style="width: 250px; height: 250px; background: antiquewhite; display: inline-flex">
|
||||||
|
<Button
|
||||||
|
style="margin: auto auto auto 0px"
|
||||||
|
v-tooltip="{ placement: 'left', verticalRelative: '#tooltipContainer2', horizontalRelative: '#tooltipContainer2' }"
|
||||||
|
>
|
||||||
|
显示提示信息
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div id="tooltipContainer3" style="width: 250px; height: 250px; background: antiquewhite; display: inline-flex">
|
||||||
|
<Button
|
||||||
|
style="margin: 0px auto auto auto"
|
||||||
|
v-tooltip="{ placement: 'bottom', verticalRelative: '#tooltipContainer3', horizontalRelative: '#tooltipContainer3' }"
|
||||||
|
>
|
||||||
|
显示提示信息
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div id="tooltipContainer4" style="width: 250px; height: 250px; background: antiquewhite; display: inline-flex">
|
||||||
|
<Button
|
||||||
|
style="margin: auto auto 0px auto"
|
||||||
|
v-tooltip="{ placement: 'top', verticalRelative: '#tooltipContainer4', horizontalRelative: '#tooltipContainer4' }"
|
||||||
|
>
|
||||||
|
显示提示信息
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Reference in New Issue