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

@@ -156,7 +156,7 @@ export function createSpellcheckerManager(
const firstOutlier = session.availableSpellCheckerLanguages.find( const firstOutlier = session.availableSpellCheckerLanguages.find(
(language, index) => availableSpellCheckerLanguages[index] !== language, (language, index) => availableSpellCheckerLanguages[index] !== language,
) )
throw new Error(`Found unsupported language code: ${firstOutlier}`) console.error(`Found unsupported language code: ${firstOutlier}`)
} }
setSpellcheckerLanguages() setSpellcheckerLanguages()

View File

@@ -114,6 +114,17 @@ async function configureWindow(remoteBridge: CrossProcessBridge) {
if (isMacOS || useSystemMenuBar) { if (isMacOS || useSystemMenuBar) {
// !important is important here because #desktop-title-bar has display: flex. // !important is important here because #desktop-title-bar has display: flex.
sheet.insertRule('#desktop-title-bar { display: none !important; }', sheet.cssRules.length) sheet.insertRule('#desktop-title-bar { display: none !important; }', sheet.cssRules.length)
} else {
/* Use custom title bar. Take the sn-titlebar-height off of
the app content height so its not overflowing */
sheet.insertRule(
'[data-dialog] { position: relative; height: calc(100vh - var(--sn-desktop-titlebar-height)) !important; margin-top: var(--sn-desktop-titlebar-height) !important; }',
sheet.cssRules.length,
)
sheet.insertRule(
'[data-mobile-popover] { padding-top: var(--sn-desktop-titlebar-height) !important; }',
sheet.cssRules.length,
)
} }
} }

View File

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

View File

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

View File

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

View File

@@ -3,6 +3,7 @@ import { ReactNode } from 'react'
import { Tooltip, TooltipAnchor, TooltipStoreProps, useTooltipStore } from '@ariakit/react' import { Tooltip, TooltipAnchor, TooltipStoreProps, useTooltipStore } from '@ariakit/react'
import { Slot } from '@radix-ui/react-slot' import { Slot } from '@radix-ui/react-slot'
import { MutuallyExclusiveMediaQueryBreakpoints, useMediaQuery } from '@/Hooks/useMediaQuery' import { MutuallyExclusiveMediaQueryBreakpoints, useMediaQuery } from '@/Hooks/useMediaQuery'
import { getPositionedPopoverStyles } from '../Popover/GetPositionedPopoverStyles'
const StyledTooltip = ({ const StyledTooltip = ({
children, children,
@@ -16,7 +17,31 @@ const StyledTooltip = ({
} & Partial<TooltipStoreProps>) => { } & Partial<TooltipStoreProps>) => {
const tooltip = useTooltipStore({ const tooltip = useTooltipStore({
timeout: 350, 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, ...props,
}) })
const isMobile = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm) const isMobile = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm)