refactor: safe area inset fallback (#2329)
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { useMediaQuery, MutuallyExclusiveMediaQueryBreakpoints } from '@/Hooks/useMediaQuery'
|
import { useMediaQuery, MutuallyExclusiveMediaQueryBreakpoints } from '@/Hooks/useMediaQuery'
|
||||||
import { isIOS } from '@/Utils'
|
import { useAvailableSafeAreaPadding } from '@/Hooks/useSafeAreaPadding'
|
||||||
import { classNames } from '@standardnotes/snjs'
|
import { classNames } from '@standardnotes/snjs'
|
||||||
import { ReactNode, useMemo, useRef, useState } from 'react'
|
import { ReactNode, useMemo, useRef, useState } from 'react'
|
||||||
import Button from '../Button/Button'
|
import Button from '../Button/Button'
|
||||||
@@ -92,6 +92,8 @@ const Modal = ({
|
|||||||
const [showAdvanced, setShowAdvanced] = useState(false)
|
const [showAdvanced, setShowAdvanced] = useState(false)
|
||||||
const advancedOptionRef = useRef<HTMLButtonElement>(null)
|
const advancedOptionRef = useRef<HTMLButtonElement>(null)
|
||||||
|
|
||||||
|
const { hasTopInset, hasBottomInset } = useAvailableSafeAreaPadding()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ModalAndroidBackHandler close={close} />
|
<ModalAndroidBackHandler close={close} />
|
||||||
@@ -112,8 +114,8 @@ const Modal = ({
|
|||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'flex w-full flex-shrink-0 items-center justify-between rounded-t border-b border-solid border-border bg-default text-text md:px-4.5 md:py-3',
|
'flex w-full flex-shrink-0 items-center justify-between rounded-t border-b border-solid border-border bg-default px-2 text-text md:px-4.5 md:py-3',
|
||||||
isIOS() ? 'px-2 pt-safe-top pb-1.5' : 'py-1.5 px-2',
|
hasTopInset ? 'pt-safe-top pb-1.5' : 'py-1.5',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<MobileModalHeader className="flex-row items-center justify-between md:flex md:gap-0">
|
<MobileModalHeader className="flex-row items-center justify-between md:flex md:gap-0">
|
||||||
@@ -200,7 +202,7 @@ const Modal = ({
|
|||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'hidden items-center justify-start gap-3 border-t border-border py-2 px-2.5 md:flex md:px-4 md:py-4',
|
'hidden items-center justify-start gap-3 border-t border-border py-2 px-2.5 md:flex md:px-4 md:py-4',
|
||||||
isIOS() && 'pb-safe-bottom',
|
hasBottomInset && 'pb-safe-bottom',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{sortedActions.map((action, index) => (
|
{sortedActions.map((action, index) => (
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { isIOS } from '@/Utils'
|
import { useAvailableSafeAreaPadding } from '@/Hooks/useSafeAreaPadding'
|
||||||
import { classNames } from '@standardnotes/utils'
|
import { classNames } from '@standardnotes/utils'
|
||||||
import { FunctionComponent, ReactNode } from 'react'
|
import { FunctionComponent, ReactNode } from 'react'
|
||||||
|
|
||||||
@@ -7,16 +7,20 @@ type Props = {
|
|||||||
children?: ReactNode
|
children?: ReactNode
|
||||||
}
|
}
|
||||||
|
|
||||||
const ModalDialogButtons: FunctionComponent<Props> = ({ children, className }) => (
|
const ModalDialogButtons: FunctionComponent<Props> = ({ children, className }) => {
|
||||||
<div
|
const { hasBottomInset } = useAvailableSafeAreaPadding()
|
||||||
className={classNames(
|
|
||||||
'flex items-center justify-end gap-3 border-t border-border px-4 py-4',
|
return (
|
||||||
isIOS() && 'pb-safe-bottom',
|
<div
|
||||||
className,
|
className={classNames(
|
||||||
)}
|
'flex items-center justify-end gap-3 border-t border-border px-4 py-4',
|
||||||
>
|
hasBottomInset && 'pb-safe-bottom',
|
||||||
{children}
|
className,
|
||||||
</div>
|
)}
|
||||||
)
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export default ModalDialogButtons
|
export default ModalDialogButtons
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import PreferencesMenuItem from './PreferencesComponents/MenuItem'
|
|||||||
import { PreferencesMenu } from './PreferencesMenu'
|
import { PreferencesMenu } from './PreferencesMenu'
|
||||||
import { PreferenceId } from '@standardnotes/ui-services'
|
import { PreferenceId } from '@standardnotes/ui-services'
|
||||||
import { classNames } from '@standardnotes/snjs'
|
import { classNames } from '@standardnotes/snjs'
|
||||||
import { isIOS } from '@/Utils'
|
import { useAvailableSafeAreaPadding } from '@/Hooks/useSafeAreaPadding'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
menu: PreferencesMenu
|
menu: PreferencesMenu
|
||||||
@@ -25,11 +25,13 @@ const PreferencesMenuView: FunctionComponent<Props> = ({ menu }) => {
|
|||||||
[menuItems],
|
[menuItems],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const { hasBottomInset } = useAvailableSafeAreaPadding()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'border-t border-border bg-default px-5 pt-2 md:border-0 md:bg-contrast md:px-0 md:py-0',
|
'border-t border-border bg-default px-5 pt-2 md:border-0 md:bg-contrast md:px-0 md:py-0',
|
||||||
isIOS() ? 'pb-safe-bottom' : 'pb-2 md:pb-0',
|
hasBottomInset ? 'pb-safe-bottom' : 'pb-2 md:pb-0',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="hidden min-w-55 flex-col overflow-y-auto px-3 py-6 md:flex">
|
<div className="hidden min-w-55 flex-col overflow-y-auto px-3 py-6 md:flex">
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import { useDisableBodyScrollOnMobile } from '@/Hooks/useDisableBodyScrollOnMobi
|
|||||||
import { useAndroidBackHandler } from '@/NativeMobileWeb/useAndroidBackHandler'
|
import { useAndroidBackHandler } from '@/NativeMobileWeb/useAndroidBackHandler'
|
||||||
import Modal from '../Modal/Modal'
|
import Modal from '../Modal/Modal'
|
||||||
import { classNames } from '@standardnotes/snjs'
|
import { classNames } from '@standardnotes/snjs'
|
||||||
import { isIOS } from '@/Utils'
|
|
||||||
import { useCommandService } from '../CommandProvider'
|
import { useCommandService } from '../CommandProvider'
|
||||||
import { ESCAPE_COMMAND } from '@standardnotes/ui-services'
|
import { ESCAPE_COMMAND } from '@standardnotes/ui-services'
|
||||||
|
import { useAvailableSafeAreaPadding } from '@/Hooks/useSafeAreaPadding'
|
||||||
|
|
||||||
const PreferencesView: FunctionComponent<PreferencesProps> = ({
|
const PreferencesView: FunctionComponent<PreferencesProps> = ({
|
||||||
application,
|
application,
|
||||||
@@ -56,6 +56,8 @@ const PreferencesView: FunctionComponent<PreferencesProps> = ({
|
|||||||
})
|
})
|
||||||
}, [commandService, closePreferences])
|
}, [commandService, closePreferences])
|
||||||
|
|
||||||
|
const { hasTopInset } = useAvailableSafeAreaPadding()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
close={closePreferences}
|
close={closePreferences}
|
||||||
@@ -68,7 +70,7 @@ const PreferencesView: FunctionComponent<PreferencesProps> = ({
|
|||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'flex w-full flex-row items-center justify-between border-b border-solid border-border bg-default px-3 pb-2 md:p-3',
|
'flex w-full flex-row items-center justify-between border-b border-solid border-border bg-default px-3 pb-2 md:p-3',
|
||||||
isIOS() ? 'pt-safe-top' : 'pt-2',
|
hasTopInset ? 'pt-safe-top' : 'pt-2',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="hidden h-8 w-8 md:block" />
|
<div className="hidden h-8 w-8 md:block" />
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ import { classNames } from '@standardnotes/utils'
|
|||||||
import { useResponsiveAppPane } from '../Panes/ResponsivePaneProvider'
|
import { useResponsiveAppPane } from '../Panes/ResponsivePaneProvider'
|
||||||
import UpgradeNow from '../Footer/UpgradeNow'
|
import UpgradeNow from '../Footer/UpgradeNow'
|
||||||
import RoundIconButton from '../Button/RoundIconButton'
|
import RoundIconButton from '../Button/RoundIconButton'
|
||||||
import { isIOS } from '@/Utils'
|
|
||||||
import { PanelResizedData } from '@/Types/PanelResizedData'
|
import { PanelResizedData } from '@/Types/PanelResizedData'
|
||||||
import { PANEL_NAME_NAVIGATION } from '@/Constants/Constants'
|
import { PANEL_NAME_NAVIGATION } from '@/Constants/Constants'
|
||||||
import { PaneLayout } from '@/Controllers/PaneController/PaneLayout'
|
import { PaneLayout } from '@/Controllers/PaneController/PaneLayout'
|
||||||
import { usePaneSwipeGesture } from '../Panes/usePaneGesture'
|
import { usePaneSwipeGesture } from '../Panes/usePaneGesture'
|
||||||
import { mergeRefs } from '@/Hooks/mergeRefs'
|
import { mergeRefs } from '@/Hooks/mergeRefs'
|
||||||
|
import { useAvailableSafeAreaPadding } from '@/Hooks/useSafeAreaPadding'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
application: WebApplication
|
application: WebApplication
|
||||||
@@ -55,6 +55,8 @@ const Navigation = forwardRef<HTMLDivElement, Props>(({ application, className,
|
|||||||
'swipe',
|
'swipe',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const { hasBottomInset } = useAvailableSafeAreaPadding()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
id={id}
|
id={id}
|
||||||
@@ -83,7 +85,7 @@ const Navigation = forwardRef<HTMLDivElement, Props>(({ application, className,
|
|||||||
className={classNames(
|
className={classNames(
|
||||||
'fixed bottom-0 flex min-h-[50px] w-full items-center border-t border-border bg-contrast',
|
'fixed bottom-0 flex min-h-[50px] w-full items-center border-t border-border bg-contrast',
|
||||||
'px-3.5 pt-2.5 md:hidden',
|
'px-3.5 pt-2.5 md:hidden',
|
||||||
isIOS() ? 'pb-safe-bottom' : 'pb-2.5',
|
hasBottomInset ? 'pb-safe-bottom' : 'pb-2.5',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<RoundIconButton
|
<RoundIconButton
|
||||||
|
|||||||
15
packages/web/src/javascripts/Hooks/useSafeAreaPadding.ts
Normal file
15
packages/web/src/javascripts/Hooks/useSafeAreaPadding.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
export const useAvailableSafeAreaPadding = () => {
|
||||||
|
const documentStyle = getComputedStyle(document.documentElement)
|
||||||
|
|
||||||
|
const top = parseInt(documentStyle.getPropertyValue('--safe-area-inset-top'))
|
||||||
|
const right = parseInt(documentStyle.getPropertyValue('--safe-area-inset-right'))
|
||||||
|
const bottom = parseInt(documentStyle.getPropertyValue('--safe-area-inset-bottom'))
|
||||||
|
const left = parseInt(documentStyle.getPropertyValue('--safe-area-inset-left'))
|
||||||
|
|
||||||
|
return {
|
||||||
|
hasTopInset: !!top,
|
||||||
|
hasRightInset: !!right,
|
||||||
|
hasBottomInset: !!bottom,
|
||||||
|
hasLeftInset: !!left,
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user