fix(desktop): Fixed issue where preferences header & tooltips are overlapped by custom titlebar

This commit is contained in:
Aman Harwara
2023-04-27 15:57:56 +05:30
parent 76bd995c9a
commit ef27a21fb1
6 changed files with 79 additions and 28 deletions

View File

@@ -41,6 +41,7 @@ type Options = {
side: PopoverSide
disableMobileFullscreenTakeover?: boolean
maxHeightFunction?: (calculatedMaxHeight: number) => number
offset?: number
}
export const getPositionedPopoverStyles = ({
@@ -51,6 +52,7 @@ export const getPositionedPopoverStyles = ({
side,
disableMobileFullscreenTakeover,
maxHeightFunction,
offset,
}: Options): CSSProperties | null => {
if (!popoverRect || !anchorRect) {
return null
@@ -71,12 +73,21 @@ export const getPositionedPopoverStyles = ({
const oppositeSideOverflows = getOverflows(rectForOppositeSide, documentRect)
const sideWithLessOverflows = preferredSideOverflows[side] < oppositeSideOverflows[oppositeSide] ? side : oppositeSide
const finalAlignment = getNonCollidingAlignment(sideWithLessOverflows, align, preferredSideRectCollisions, {
const finalAlignment = getNonCollidingAlignment({
finalSide: sideWithLessOverflows,
preferredAlignment: align,
collisions: preferredSideRectCollisions,
popoverRect,
buttonRect: anchorRect,
documentRect,
})
const finalPositionedRect = getPositionedPopoverRect(popoverRect, anchorRect, sideWithLessOverflows, finalAlignment)
const finalPositionedRect = getPositionedPopoverRect(
popoverRect,
anchorRect,
sideWithLessOverflows,
finalAlignment,
offset,
)
let maxHeight = getPopoverMaxHeight(
getAppRect(),

View File

@@ -45,20 +45,21 @@ const OppositeAlignment: Record<Exclude<PopoverAlignment, 'center'>, PopoverAlig
end: 'start',
}
export const getNonCollidingAlignment = (
finalSide: PopoverSide,
preferredAlignment: PopoverAlignment,
collisions: RectCollisions,
{
popoverRect,
buttonRect,
documentRect,
}: {
popoverRect: DOMRect
buttonRect: DOMRect
documentRect: DOMRect
},
): PopoverAlignment => {
export const getNonCollidingAlignment = ({
finalSide,
preferredAlignment,
collisions,
popoverRect,
buttonRect,
documentRect,
}: {
finalSide: PopoverSide
preferredAlignment: PopoverAlignment
collisions: RectCollisions
popoverRect: DOMRect
buttonRect: DOMRect
documentRect: DOMRect
}): PopoverAlignment => {
const isHorizontalSide = finalSide === 'top' || finalSide === 'bottom'
const boundToCheckForStart = isHorizontalSide ? 'right' : 'bottom'
const boundToCheckForEnd = isHorizontalSide ? 'left' : 'top'

View File

@@ -68,49 +68,52 @@ export const getPositionedPopoverRect = (
buttonRect: DOMRect,
side: PopoverSide,
align: PopoverAlignment,
offset?: number,
): DOMRect => {
const { width, height } = popoverRect
const positionPopoverRect = DOMRect.fromRect(popoverRect)
const finalOffset = offset ? offset : 0
switch (side) {
case 'top': {
positionPopoverRect.y = buttonRect.top - height
positionPopoverRect.y = buttonRect.top - height - finalOffset
break
}
case 'bottom':
positionPopoverRect.y = buttonRect.bottom
positionPopoverRect.y = buttonRect.bottom + finalOffset
break
case 'left':
positionPopoverRect.x = buttonRect.left - width
positionPopoverRect.x = buttonRect.left - width - finalOffset
break
case 'right':
positionPopoverRect.x = buttonRect.right
positionPopoverRect.x = buttonRect.right + finalOffset
break
}
if (side === 'top' || side === 'bottom') {
switch (align) {
case 'start':
positionPopoverRect.x = buttonRect.left
positionPopoverRect.x = buttonRect.left - finalOffset
break
case 'center':
positionPopoverRect.x = buttonRect.left - width / 2 + buttonRect.width / 2
positionPopoverRect.x = buttonRect.left - width / 2 + buttonRect.width / 2 - finalOffset
break
case 'end':
positionPopoverRect.x = buttonRect.right - width
positionPopoverRect.x = buttonRect.right - width + finalOffset
break
}
} else {
switch (align) {
case 'start':
positionPopoverRect.y = buttonRect.top
positionPopoverRect.y = buttonRect.top - finalOffset
break
case 'center':
positionPopoverRect.y = buttonRect.top - height / 2 + buttonRect.height / 2
positionPopoverRect.y = buttonRect.top - height / 2 + buttonRect.height / 2 - finalOffset
break
case 'end':
positionPopoverRect.y = buttonRect.bottom - height
positionPopoverRect.y = buttonRect.bottom - height + finalOffset
break
}
}

View File

@@ -3,6 +3,7 @@ import { ReactNode } from 'react'
import { Tooltip, TooltipAnchor, TooltipStoreProps, useTooltipStore } from '@ariakit/react'
import { Slot } from '@radix-ui/react-slot'
import { MutuallyExclusiveMediaQueryBreakpoints, useMediaQuery } from '@/Hooks/useMediaQuery'
import { getPositionedPopoverStyles } from '../Popover/GetPositionedPopoverStyles'
const StyledTooltip = ({
children,
@@ -16,7 +17,31 @@ const StyledTooltip = ({
} & Partial<TooltipStoreProps>) => {
const tooltip = useTooltipStore({
timeout: 350,
gutter: 6,
renderCallback(props) {
const { popoverElement, anchorElement } = props
const documentElement = document.querySelector('.main-ui-view')
if (!popoverElement || !anchorElement || !documentElement) {
return
}
const anchorRect = anchorElement.getBoundingClientRect()
const popoverRect = popoverElement.getBoundingClientRect()
const documentRect = documentElement.getBoundingClientRect()
const styles = getPositionedPopoverStyles({
align: 'center',
side: 'bottom',
anchorRect,
popoverRect,
documentRect,
disableMobileFullscreenTakeover: true,
offset: 6,
})
Object.assign(popoverElement.style, styles)
},
...props,
})
const isMobile = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm)