diff --git a/src/browser.ts b/src/browser.ts new file mode 100644 index 0000000..8c76a7c --- /dev/null +++ b/src/browser.ts @@ -0,0 +1,36 @@ +export function isMobileFirefox(): boolean | undefined { + const userAgent = navigator.userAgent; + return ( + typeof window !== 'undefined' && + ((/Firefox/.test(userAgent) && /Mobile/.test(userAgent)) || // Android Firefox + /FxiOS/.test(userAgent)) // iOS Firefox + ); +} + +export function isMac(): boolean | undefined { + return testPlatform(/^Mac/); +} + +export function isIPhone(): boolean | undefined { + return testPlatform(/^iPhone/); +} + +export function isSafari(): boolean | undefined { + return /^((?!chrome|android).)*safari/i.test(navigator.userAgent); +} + +export function isIPad(): boolean | undefined { + return ( + testPlatform(/^iPad/) || + // iPadOS 13 lies and says it's a Mac, but we can distinguish by detecting touch support. + (isMac() && navigator.maxTouchPoints > 1) + ); +} + +export function isIOS(): boolean | undefined { + return isIPhone() || isIPad(); +} + +export function testPlatform(re: RegExp): boolean | undefined { + return typeof window !== 'undefined' && window.navigator != null ? re.test(window.navigator.platform) : undefined; +} diff --git a/src/index.tsx b/src/index.tsx index 9372d36..76aad6d 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,7 +4,7 @@ import * as DialogPrimitive from '@radix-ui/react-dialog'; import React from 'react'; import { DrawerContext, useDrawerContext } from './context'; import './style.css'; -import { usePreventScroll, isInput, isIOS } from './use-prevent-scroll'; +import { usePreventScroll, isInput } from './use-prevent-scroll'; import { useComposedRefs } from './use-composed-refs'; import { useSnapPoints } from './use-snap-points'; import { set, getTranslate, dampenValue, isVertical, reset } from './helpers'; @@ -22,6 +22,7 @@ import { DrawerDirection } from './types'; import { useControllableState } from './use-controllable-state'; import { useScaleBackground } from './use-scale-background'; import { usePositionFixed } from './use-position-fixed'; +import { isIOS, isMobileFirefox } from './browser'; export interface WithFadeFromProps { /** @@ -500,7 +501,6 @@ export function Root({ const activeSnapPointHeight = snapPointsOffset[activeSnapPointIndex] || 0; diffFromInitial += activeSnapPointHeight; } - previousDiffFromInitial.current = diffFromInitial; // We don't have to change the height if the input is in view, when we are here we are in the opened keyboard state so we can correctly check if the input is in view if (drawerHeight > visualViewportHeight || keyboardIsOpen.current) { @@ -516,7 +516,7 @@ export function Root({ } else { drawerRef.current.style.height = `${Math.max(newDrawerHeight, visualViewportHeight - offsetFromTop)}px`; } - } else { + } else if (!isMobileFirefox()) { drawerRef.current.style.height = `${initialDrawerHeight.current}px`; } diff --git a/src/use-position-fixed.ts b/src/use-position-fixed.ts index 59bbcfb..513fc0d 100644 --- a/src/use-position-fixed.ts +++ b/src/use-position-fixed.ts @@ -1,5 +1,5 @@ import React from 'react'; -import { isSafari } from './use-prevent-scroll'; +import { isSafari } from './browser'; let previousBodyPosition: Record | null = null; diff --git a/src/use-prevent-scroll.ts b/src/use-prevent-scroll.ts index 2ed43a7..a0099fc 100644 --- a/src/use-prevent-scroll.ts +++ b/src/use-prevent-scroll.ts @@ -1,6 +1,7 @@ // This code comes from https://github.com/adobe/react-spectrum/blob/main/packages/%40react-aria/overlays/src/usePreventScroll.ts import { useEffect, useLayoutEffect } from 'react'; +import { isIOS } from './browser'; const KEYBOARD_BUFFER = 24; @@ -22,34 +23,6 @@ function chain(...callbacks: any[]): (...args: any[]) => void { }; } -function isMac(): boolean | undefined { - return testPlatform(/^Mac/); -} - -function isIPhone(): boolean | undefined { - return testPlatform(/^iPhone/); -} - -export function isSafari(): boolean | undefined { - return /^((?!chrome|android).)*safari/i.test(navigator.userAgent); -} - -function isIPad(): boolean | undefined { - return ( - testPlatform(/^iPad/) || - // iPadOS 13 lies and says it's a Mac, but we can distinguish by detecting touch support. - (isMac() && navigator.maxTouchPoints > 1) - ); -} - -export function isIOS(): boolean | undefined { - return isIPhone() || isIPad(); -} - -function testPlatform(re: RegExp): boolean | undefined { - return typeof window !== 'undefined' && window.navigator != null ? re.test(window.navigator.platform) : undefined; -} - // @ts-ignore const visualViewport = typeof document !== 'undefined' && window.visualViewport;