Skip to content

Commit

Permalink
[CP-2995] Introduce adjustedOffset logic to handle tooltip flipping a…
Browse files Browse the repository at this point in the history
…djustments
  • Loading branch information
dkarski committed Oct 4, 2024
1 parent e1f15ac commit 2de0b77
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,44 @@

import { TooltipPlacement } from "device/models"

type PlacementMap = { [key in TooltipPlacement]: TooltipPlacement }

const VERTICAL_FLIP_MAP: PlacementMap = {
"bottom-right": "top-right",
"bottom-left": "top-left",
"top-right": "bottom-right",
"top-left": "bottom-left",
}

const HORIZONTAL_FLIP_MAP: PlacementMap = {
"bottom-right": "bottom-left",
"bottom-left": "bottom-right",
"top-right": "top-left",
"top-left": "top-right",
}

export const flipVertical = (placement: TooltipPlacement): TooltipPlacement => {
return placement.startsWith("bottom")
? (`top-${placement.split("-")[1]}` as TooltipPlacement)
: (`bottom-${placement.split("-")[1]}` as TooltipPlacement)
return VERTICAL_FLIP_MAP[placement]
}

export const flipHorizontal = (
placement: TooltipPlacement
): TooltipPlacement => {
return placement.endsWith("right")
? (`-${placement.replace("right", "left")}` as TooltipPlacement)
: (`-${placement.replace("left", "right")}` as TooltipPlacement)
return HORIZONTAL_FLIP_MAP[placement]
}

export const flipTooltipPlacement = (
placement: TooltipPlacement
): TooltipPlacement => {
const [vertical, horizontal] = placement.split("-")
const flippedVertical = vertical === "bottom" ? "top" : "bottom"
const flippedHorizontal = horizontal === "right" ? "left" : "right"
return `${flippedVertical}-${flippedHorizontal}` as TooltipPlacement
return flipHorizontal(flipVertical(placement))
}

export const getFlipStatus = (
original: TooltipPlacement,
current: TooltipPlacement
): { isFlippedVertically: boolean; isFlippedHorizontally: boolean } => {
const isFlippedVertically = VERTICAL_FLIP_MAP[original] === current
const isFlippedHorizontally = HORIZONTAL_FLIP_MAP[original] === current

return { isFlippedVertically, isFlippedHorizontally }
}
44 changes: 31 additions & 13 deletions libs/generic-view/ui/src/lib/interactive/tooltip/tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
flipHorizontal,
flipTooltipPlacement,
flipVertical,
getFlipStatus,
} from "./tooltip-helpers"

interface Position {
Expand All @@ -35,6 +36,7 @@ export const Tooltip: BaseGenericComponent<
Content: typeof TooltipContent
} = ({ children, placement = "bottom-right", offset = { x: 0, y: 0 } }) => {
const [contentPosition, setContentPosition] = useState<Partial<Position>>({})
const originalPlacement = useRef<TooltipPlacement>(placement)

const contentRef = useRef<HTMLDivElement>(null)

Expand All @@ -59,30 +61,47 @@ export const Tooltip: BaseGenericComponent<
let top = 0
let left = 0

const adjustedOffset: TooltipOffsetType = { ...offset }
const { isFlippedVertically, isFlippedHorizontally } = getFlipStatus(
originalPlacement.current,
placment
)

if (isFlippedVertically) {
adjustedOffset.y = -offset.y
}
if (isFlippedHorizontally) {
adjustedOffset.x = -offset.x
}

switch (placment) {
case "bottom-right":
top = anchorRect.top + anchorRect.height + offset.y
left = anchorRect.left + offset.x
top = anchorRect.top + anchorRect.height + adjustedOffset.y
left = anchorRect.left + adjustedOffset.x
break
case "bottom-left":
top = anchorRect.top + anchorRect.height + offset.y
top = anchorRect.top + anchorRect.height + adjustedOffset.y
left =
anchorRect.left - contentRect.width + anchorRect.width + offset.x
anchorRect.left -
contentRect.width +
anchorRect.width +
adjustedOffset.x
break
case "top-right":
top =
anchorRect.top - contentRect.height - anchorRect.height - offset.y
left = anchorRect.left + offset.x
top = anchorRect.top + adjustedOffset.y - contentRect.height
left = anchorRect.left + adjustedOffset.x
break
case "top-left":
top =
anchorRect.top - contentRect.height - anchorRect.height - offset.y
top = anchorRect.top + adjustedOffset.y - contentRect.height
left =
anchorRect.left - contentRect.width + anchorRect.width + offset.x
anchorRect.left -
contentRect.width +
anchorRect.width +
adjustedOffset.x
break
default:
top = anchorRect.top + anchorRect.height + offset.y
left = anchorRect.left + offset.x
top = anchorRect.top + anchorRect.height + adjustedOffset.y
left = anchorRect.left + adjustedOffset.x
}

return { top, left }
Expand Down Expand Up @@ -214,7 +233,6 @@ const Content = styled.div<{
${({ $defaultStyles, theme, $placement }) =>
$defaultStyles &&
css`
margin-top: 1rem;
display: flex;
flex-direction: column;
align-items: flex-start;
Expand Down

0 comments on commit 2de0b77

Please sign in to comment.