From 387fefa9466591495da0a73d698487188780e1ed Mon Sep 17 00:00:00 2001 From: Sagi Date: Sun, 16 Oct 2022 22:50:13 +0800 Subject: [PATCH 1/2] fix(tooltip): support adjust the tooltip position that overstep the boundary --- .../src/composition/use-adjust-position.ts | 20 ++++++++- .../src/composition/use-tooltip-position.ts | 6 +-- .../tooltip/src/tooltip.component.tsx | 7 ++-- .../tooltip/src/tooltip.directive.tsx | 2 +- packages/ui-vue/src/components/tooltip.vue | 41 +++++++++++++++---- 5 files changed, 60 insertions(+), 16 deletions(-) diff --git a/packages/ui-vue/components/tooltip/src/composition/use-adjust-position.ts b/packages/ui-vue/components/tooltip/src/composition/use-adjust-position.ts index c353feb1ae..87c0cb5b7e 100644 --- a/packages/ui-vue/components/tooltip/src/composition/use-adjust-position.ts +++ b/packages/ui-vue/components/tooltip/src/composition/use-adjust-position.ts @@ -1,3 +1,4 @@ +import { DomEvent } from "@vue/test-utils/dist/constants/dom-events"; import { SetupContext } from "vue"; import { TooltipPlacement, TooltipProps } from "../tooltip.props"; import { RectPosition, TooltipPosition } from "./types"; @@ -28,10 +29,15 @@ export function useAdjustPosition(props: TooltipProps, context: SetupContext) { placementAndAlignment: TooltipPlacement, originalPosition: TooltipPosition, relativeElementRect: DOMRect, - tooltipRect: DOMRect + hostRect: DOMRect, + tooltipRect: DOMRect, + tooltipContentRect: DOMRect, + arrowRect: DOMRect ): TooltipPosition { let fixedLeft = originalPosition.tooltip.left; let fixedTop = originalPosition.tooltip.top; + let fixedArrowLeft = originalPosition.arrow.left; + let fixedArrowTop = originalPosition.arrow.top; const placementAndAlignmentArray = placementAndAlignment.split('-'); const placement = placementAndAlignmentArray[0]; if (['top', 'bottom'].includes(placement)) { @@ -40,14 +46,24 @@ export function useAdjustPosition(props: TooltipProps, context: SetupContext) { fixedLeft = overLeftBound.overBound ? overLeftBound.fixedValue : (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 overBottomBound = isOverstepBoundary(relativeElementRect, 'bottom', originalPosition.tooltip.top + tooltipRect.height); fixedTop = overTopBound.overBound ? overTopBound.fixedValue : (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 arrow = { left: originalPosition.arrow.left, top: originalPosition.arrow.top }; + const arrow = { left: fixedArrowLeft, top: fixedArrowTop }; return { arrow, tooltip }; } diff --git a/packages/ui-vue/components/tooltip/src/composition/use-tooltip-position.ts b/packages/ui-vue/components/tooltip/src/composition/use-tooltip-position.ts index dcefbb7435..6425f0638e 100644 --- a/packages/ui-vue/components/tooltip/src/composition/use-tooltip-position.ts +++ b/packages/ui-vue/components/tooltip/src/composition/use-tooltip-position.ts @@ -14,8 +14,6 @@ export function useTooltipPosition( tooltipContentRect: DOMRect, arrowRect: DOMRect) { - const { scrollLeft, scrollTop } = document.documentElement; - const placementAndAlignment = ref(props.placement); const { getRelativeElementBound } = useRelative(props, context); @@ -34,7 +32,9 @@ export function useTooltipPosition( const relativeRect = getRelativeElementBound(); placementAndAlignment.value = adjustPlacement(placementAndAlignment.value, relativeRect, hostRect, tooltipRect, 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; }); diff --git a/packages/ui-vue/components/tooltip/src/tooltip.component.tsx b/packages/ui-vue/components/tooltip/src/tooltip.component.tsx index 1f410bc2c8..b0a5662293 100644 --- a/packages/ui-vue/components/tooltip/src/tooltip.component.tsx +++ b/packages/ui-vue/components/tooltip/src/tooltip.component.tsx @@ -24,6 +24,8 @@ export default defineComponent({ return classObject; }); + const { scrollLeft, scrollTop } = document.documentElement; + const shouldShowTooltipText = computed(() => isTextContext.value); const tooltipText = computed(() => props.content); @@ -64,9 +66,8 @@ export default defineComponent({ tooltipInnerRef.value.getBoundingClientRect(), arrowRef.value.getBoundingClientRect() ); - tooltipLeftPosition.value = `${tooltipPosition.value.tooltip.left}px`; - tooltipRightPosition.value = `${tooltipPosition.value.tooltip.right}px`; - tooltipTopPosition.value = `${tooltipPosition.value.tooltip.top}px`; + tooltipLeftPosition.value = `${tooltipPosition.value.tooltip.left + scrollLeft}px`; + tooltipTopPosition.value = `${tooltipPosition.value.tooltip.top + scrollTop}px`; arrowLeftPosition.value = `${tooltipPosition.value.arrow.left}px`; arrowTopPosition.value = `${tooltipPosition.value.arrow.top}px`; placement.value = tooltipPlacement.value; diff --git a/packages/ui-vue/components/tooltip/src/tooltip.directive.tsx b/packages/ui-vue/components/tooltip/src/tooltip.directive.tsx index 817eba7e16..fb309f0ea3 100644 --- a/packages/ui-vue/components/tooltip/src/tooltip.directive.tsx +++ b/packages/ui-vue/components/tooltip/src/tooltip.directive.tsx @@ -43,7 +43,7 @@ const tooltipDirective = { element.addEventListener('mouseleave', ($event: MouseEvent) => { $event.stopPropagation(); if (app) { - // app.unmount(); + app.unmount(); app = null; } }); diff --git a/packages/ui-vue/src/components/tooltip.vue b/packages/ui-vue/src/components/tooltip.vue index 6ecc6606a8..21d5d56c9b 100644 --- a/packages/ui-vue/src/components/tooltip.vue +++ b/packages/ui-vue/src/components/tooltip.vue @@ -10,12 +10,39 @@ const tooltipProps = { placement: 'bottom' }; -
- +
+
+ 1 + +
+
+ +
+
+ +
+
+ +
-- Gitee From e068f1a376661d5f27baeb26faa1d6d6a1e872fb Mon Sep 17 00:00:00 2001 From: Sagi Date: Mon, 17 Oct 2022 14:51:03 +0800 Subject: [PATCH 2/2] chore: add popover demo --- .../components/popover/src/popover.component.tsx | 14 ++++++++------ packages/ui-vue/src/app.vue | 8 ++------ packages/ui-vue/src/components/popover.vue | 11 +++++++++++ packages/ui-vue/src/main.ts | 1 - 4 files changed, 21 insertions(+), 13 deletions(-) create mode 100644 packages/ui-vue/src/components/popover.vue diff --git a/packages/ui-vue/components/popover/src/popover.component.tsx b/packages/ui-vue/components/popover/src/popover.component.tsx index df71c91622..f47ea7e9aa 100644 --- a/packages/ui-vue/components/popover/src/popover.component.tsx +++ b/packages/ui-vue/components/popover/src/popover.component.tsx @@ -1,4 +1,4 @@ -import { computed, defineComponent, ref, SetupContext } from 'vue'; +import { computed, defineComponent, ref, SetupContext, Teleport } from 'vue'; import { PopoverProps, popoverProps } from './popover.props'; import './popover.scss'; @@ -28,11 +28,13 @@ export default defineComponent({ return () => { return ( -
-
- {shouldShowTitle.value &&

{props.title}

} -
{context.slots.default && context.slots?.default()}
-
+ +
+
+ {shouldShowTitle.value &&

{props.title}

} +
{context.slots.default && context.slots?.default()}
+
+
); }; } diff --git a/packages/ui-vue/src/app.vue b/packages/ui-vue/src/app.vue index c2919daf8c..0ae14c621d 100644 --- a/packages/ui-vue/src/app.vue +++ b/packages/ui-vue/src/app.vue @@ -16,6 +16,7 @@ import Accordion from './components/accordion.vue'; import ComboList from './components/combo-list.vue'; import CheckboxGroup from './components/checkbox.vue'; import Tooltip from './components/tooltip.vue'; +import Popover from './components/popover.vue'; const canEdit = ref(true); const disable = ref(false); @@ -32,11 +33,7 @@ const canAutoComplete = ref(false);
- - + @@ -50,7 +47,6 @@ const canAutoComplete = ref(false); -