fix: responsiveness when resizing window on web/desktop (#1637)

This commit is contained in:
Aman Harwara
2022-09-24 21:24:10 +05:30
committed by GitHub
parent c2a1918843
commit e4b1b64119
8 changed files with 46 additions and 19 deletions

View File

@@ -62,7 +62,7 @@ const Navigation: FunctionComponent<Props> = ({ application }) => {
<div <div
id="navigation" id="navigation"
className={classNames( className={classNames(
'sn-component section app-column h-screen max-h-screen w-[220px] overflow-hidden pt-safe-top md:h-full md:min-h-0 md:py-0 xsm-only:!w-full sm-only:!w-full', 'sn-component section app-column h-screen max-h-screen w-[220px] overflow-hidden pt-safe-top md:h-full md:max-h-full md:min-h-0 md:py-0 xsm-only:!w-full sm-only:!w-full',
isIOS() ? 'pb-safe-bottom' : 'pb-2.5', isIOS() ? 'pb-safe-bottom' : 'pb-2.5',
)} )}
ref={ref} ref={ref}

View File

@@ -1,3 +1,4 @@
import { MediaQueryBreakpoints } from '@/Hooks/useMediaQuery'
import { CSSProperties } from 'react' import { CSSProperties } from 'react'
import { PopoverAlignment, PopoverSide } from './Types' import { PopoverAlignment, PopoverSide } from './Types'
import { OppositeSide, checkCollisions, getNonCollidingSide, getNonCollidingAlignment } from './Utils/Collisions' import { OppositeSide, checkCollisions, getNonCollidingSide, getNonCollidingAlignment } from './Utils/Collisions'
@@ -29,7 +30,7 @@ export const getPositionedPopoverStyles = ({
return [null, side, align] return [null, side, align]
} }
const matchesMediumBreakpoint = matchMedia('(min-width: 768px)').matches const matchesMediumBreakpoint = matchMedia(MediaQueryBreakpoints.md).matches
if (!matchesMediumBreakpoint) { if (!matchesMediumBreakpoint) {
return [null, side, align] return [null, side, align]

View File

@@ -9,8 +9,8 @@ import { getPositionedPopoverStyles } from './GetPositionedPopoverStyles'
import { PopoverContentProps } from './Types' import { PopoverContentProps } from './Types'
import { getPopoverMaxHeight, getAppRect } from './Utils/Rect' import { getPopoverMaxHeight, getAppRect } from './Utils/Rect'
import { usePopoverCloseOnClickOutside } from './Utils/usePopoverCloseOnClickOutside' import { usePopoverCloseOnClickOutside } from './Utils/usePopoverCloseOnClickOutside'
import { fitNodeToMobileScreen } from '@/Utils'
import { useDisableBodyScrollOnMobile } from '@/Hooks/useDisableBodyScrollOnMobile' import { useDisableBodyScrollOnMobile } from '@/Hooks/useDisableBodyScrollOnMobile'
import { MediaQueryBreakpoints, useMediaQuery } from '@/Hooks/useMediaQuery'
const PositionedPopoverContent = ({ const PositionedPopoverContent = ({
align = 'end', align = 'end',
@@ -35,6 +35,7 @@ const PositionedPopoverContent = ({
}) })
const anchorRect = anchorPoint ? anchorPointRect : anchorElementRect const anchorRect = anchorPoint ? anchorPointRect : anchorElementRect
const documentRect = useDocumentRect() const documentRect = useDocumentRect()
const isDesktopScreen = useMediaQuery(MediaQueryBreakpoints.md)
const [styles, positionedSide, positionedAlignment] = getPositionedPopoverStyles({ const [styles, positionedSide, positionedAlignment] = getPositionedPopoverStyles({
align, align,
@@ -63,10 +64,10 @@ const PositionedPopoverContent = ({
style={{ style={{
...styles, ...styles,
maxHeight: getPopoverMaxHeight(getAppRect(documentRect), anchorRect, positionedSide, positionedAlignment), maxHeight: getPopoverMaxHeight(getAppRect(documentRect), anchorRect, positionedSide, positionedAlignment),
top: !isDesktopScreen ? `${document.documentElement.scrollTop}px` : '',
}} }}
ref={(node) => { ref={(node) => {
setPopoverElement(node) setPopoverElement(node)
fitNodeToMobileScreen(node)
}} }}
data-popover={id} data-popover={id}
> >

View File

@@ -1,3 +1,4 @@
import { MediaQueryBreakpoints } from '@/Hooks/useMediaQuery'
import { PopoverSide, PopoverAlignment } from '../Types' import { PopoverSide, PopoverAlignment } from '../Types'
export const getPopoverMaxHeight = ( export const getPopoverMaxHeight = (
@@ -6,7 +7,7 @@ export const getPopoverMaxHeight = (
side: PopoverSide, side: PopoverSide,
alignment: PopoverAlignment, alignment: PopoverAlignment,
): number | 'none' => { ): number | 'none' => {
const matchesMediumBreakpoint = matchMedia('(min-width: 768px)').matches const matchesMediumBreakpoint = matchMedia(MediaQueryBreakpoints.md).matches
if (!matchesMediumBreakpoint) { if (!matchesMediumBreakpoint) {
return 'none' return 'none'

View File

@@ -1,3 +1,4 @@
import { MediaQueryBreakpoints } from '@/Hooks/useMediaQuery'
import { useEffect } from 'react' import { useEffect } from 'react'
type Options = { type Options = {
@@ -15,7 +16,7 @@ export const usePopoverCloseOnClickOutside = ({
}: Options) => { }: Options) => {
useEffect(() => { useEffect(() => {
const closeIfClickedOutside = (event: MouseEvent) => { const closeIfClickedOutside = (event: MouseEvent) => {
const matchesMediumBreakpoint = matchMedia('(min-width: 768px)').matches const matchesMediumBreakpoint = matchMedia(MediaQueryBreakpoints.md).matches
if (!matchesMediumBreakpoint) { if (!matchesMediumBreakpoint) {
return return

View File

@@ -4,11 +4,14 @@ import { observer } from 'mobx-react-lite'
import { PreferencesMenu } from './PreferencesMenu' import { PreferencesMenu } from './PreferencesMenu'
import PreferencesCanvas from './PreferencesCanvas' import PreferencesCanvas from './PreferencesCanvas'
import { PreferencesProps } from './PreferencesProps' import { PreferencesProps } from './PreferencesProps'
import { fitNodeToMobileScreen, isIOS } from '@/Utils' import { isIOS } from '@/Utils'
import { useDisableBodyScrollOnMobile } from '@/Hooks/useDisableBodyScrollOnMobile' import { useDisableBodyScrollOnMobile } from '@/Hooks/useDisableBodyScrollOnMobile'
import { classNames } from '@/Utils/ConcatenateClassNames' import { classNames } from '@/Utils/ConcatenateClassNames'
import { MediaQueryBreakpoints, useMediaQuery } from '@/Hooks/useMediaQuery'
const PreferencesView: FunctionComponent<PreferencesProps> = (props) => { const PreferencesView: FunctionComponent<PreferencesProps> = (props) => {
const isDesktopScreen = useMediaQuery(MediaQueryBreakpoints.md)
const menu = useMemo( const menu = useMemo(
() => new PreferencesMenu(props.application, props.viewControllerManager.enableUnfinishedFeatures), () => new PreferencesMenu(props.application, props.viewControllerManager.enableUnfinishedFeatures),
[props.viewControllerManager.enableUnfinishedFeatures, props.application], [props.viewControllerManager.enableUnfinishedFeatures, props.application],
@@ -33,10 +36,12 @@ const PreferencesView: FunctionComponent<PreferencesProps> = (props) => {
return ( return (
<div <div
className={classNames( className={classNames(
'absolute top-0 left-0 z-preferences flex h-full max-h-screen w-full flex-col bg-default pt-safe-top', 'absolute top-0 left-0 z-preferences flex h-screen max-h-screen w-full flex-col bg-default pt-safe-top md:h-full md:max-h-full',
isIOS() ? 'pb-safe-bottom' : 'pb-2 md:pb-0', isIOS() ? 'pb-safe-bottom' : 'pb-2 md:pb-0',
)} )}
ref={fitNodeToMobileScreen} style={{
top: !isDesktopScreen ? `${document.documentElement.scrollTop}px` : '',
}}
> >
<div className="flex w-full flex-row items-center justify-between border-b border-solid border-border bg-default px-3 py-2 md:p-3"> <div className="flex w-full flex-row items-center justify-between border-b border-solid border-border bg-default px-3 py-2 md:p-3">
<div className="hidden h-8 w-8 md:block" /> <div className="hidden h-8 w-8 md:block" />

View File

@@ -0,0 +1,26 @@
import { useEffect, useState } from 'react'
// Follows https://tailwindcss.com/docs/responsive-design
export const MediaQueryBreakpoints = {
sm: '(min-width: 640px)',
md: '(min-width: 768px)',
lg: '(min-width: 1024px)',
xl: '(min-width: 1280px)',
'2xl': '(min-width: 1536px)',
} as const
export const useMediaQuery = (mediaQuery: string) => {
const [matches, setMatches] = useState(() => window.matchMedia(mediaQuery).matches)
useEffect(() => {
const handler = (event: MediaQueryListEvent) => {
setMatches(event.matches)
}
window.matchMedia(mediaQuery).addEventListener('change', handler)
return () => window.matchMedia(mediaQuery).removeEventListener('change', handler)
}, [mediaQuery])
return matches
}

View File

@@ -1,6 +1,7 @@
import { Platform, platformFromString } from '@standardnotes/snjs' import { Platform, platformFromString } from '@standardnotes/snjs'
import { IsDesktopPlatform, IsWebPlatform } from '@/Constants/Version' import { IsDesktopPlatform, IsWebPlatform } from '@/Constants/Version'
import { EMAIL_REGEX } from '../Constants/Constants' import { EMAIL_REGEX } from '../Constants/Constants'
import { MediaQueryBreakpoints } from '@/Hooks/useMediaQuery'
declare const process: { declare const process: {
env: { env: {
@@ -202,13 +203,4 @@ export const disableIosTextFieldZoom = () => {
} }
} }
export const isMobileScreen = () => !window.matchMedia('(min-width: 768px)').matches export const isMobileScreen = () => !window.matchMedia(MediaQueryBreakpoints.md).matches
export const fitNodeToMobileScreen = (node: HTMLElement | null) => {
if (!node || !isMobileScreen()) {
return
}
node.style.height = `${visualViewport.height}px`
node.style.position = 'absolute'
node.style.top = `${document.documentElement.scrollTop}px`
}