Replace scroll-removal handling
This commit is contained in:
@@ -12,6 +12,7 @@ import {useLingui} from '@lingui/react'
|
|||||||
import {DismissableLayer} from '@radix-ui/react-dismissable-layer'
|
import {DismissableLayer} from '@radix-ui/react-dismissable-layer'
|
||||||
import {useFocusGuards} from '@radix-ui/react-focus-guards'
|
import {useFocusGuards} from '@radix-ui/react-focus-guards'
|
||||||
import {FocusScope} from '@radix-ui/react-focus-scope'
|
import {FocusScope} from '@radix-ui/react-focus-scope'
|
||||||
|
import {RemoveScroll} from 'react-remove-scroll'
|
||||||
|
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {useDialogStateControlContext} from '#/state/dialogs'
|
import {useDialogStateControlContext} from '#/state/dialogs'
|
||||||
@@ -103,34 +104,36 @@ export function Outer({
|
|||||||
{isOpen && (
|
{isOpen && (
|
||||||
<Portal>
|
<Portal>
|
||||||
<Context.Provider value={context}>
|
<Context.Provider value={context}>
|
||||||
<TouchableWithoutFeedback
|
<RemoveScroll>
|
||||||
accessibilityHint={undefined}
|
<TouchableWithoutFeedback
|
||||||
accessibilityLabel={_(msg`Close active dialog`)}
|
accessibilityHint={undefined}
|
||||||
onPress={handleBackgroundPress}>
|
accessibilityLabel={_(msg`Close active dialog`)}
|
||||||
<View
|
onPress={handleBackgroundPress}>
|
||||||
style={[
|
|
||||||
web(a.fixed),
|
|
||||||
a.inset_0,
|
|
||||||
a.z_10,
|
|
||||||
a.align_center,
|
|
||||||
gtMobile ? a.p_lg : a.p_md,
|
|
||||||
{overflowY: 'auto'},
|
|
||||||
]}>
|
|
||||||
<Backdrop />
|
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
a.w_full,
|
web(a.fixed),
|
||||||
a.z_20,
|
a.inset_0,
|
||||||
a.justify_center,
|
a.z_10,
|
||||||
a.align_center,
|
a.align_center,
|
||||||
{
|
gtMobile ? a.p_lg : a.p_md,
|
||||||
minHeight: web('calc(90vh - 36px)') || undefined,
|
{overflowY: 'auto'},
|
||||||
},
|
|
||||||
]}>
|
]}>
|
||||||
{children}
|
<Backdrop />
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.w_full,
|
||||||
|
a.z_20,
|
||||||
|
a.justify_center,
|
||||||
|
a.align_center,
|
||||||
|
{
|
||||||
|
minHeight: web('calc(90vh - 36px)') || undefined,
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
{children}
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</TouchableWithoutFeedback>
|
||||||
</TouchableWithoutFeedback>
|
</RemoveScroll>
|
||||||
</Context.Provider>
|
</Context.Provider>
|
||||||
</Portal>
|
</Portal>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
import {useEffect} from 'react'
|
|
||||||
|
|
||||||
import {isWeb} from '#/platform/detection'
|
|
||||||
|
|
||||||
let refCount = 0
|
|
||||||
|
|
||||||
function incrementRefCount() {
|
|
||||||
if (refCount === 0) {
|
|
||||||
document.body.style.overflow = 'hidden'
|
|
||||||
document.documentElement.style.scrollbarGutter = 'auto'
|
|
||||||
}
|
|
||||||
refCount++
|
|
||||||
}
|
|
||||||
|
|
||||||
function decrementRefCount() {
|
|
||||||
refCount--
|
|
||||||
if (refCount === 0) {
|
|
||||||
document.body.style.overflow = ''
|
|
||||||
document.documentElement.style.scrollbarGutter = ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useWebBodyScrollLock(isLockActive: boolean) {
|
|
||||||
useEffect(() => {
|
|
||||||
if (!isWeb || !isLockActive) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
incrementRefCount()
|
|
||||||
return () => decrementRefCount()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -15,8 +15,8 @@ import {
|
|||||||
} from '@fortawesome/react-native-fontawesome'
|
} from '@fortawesome/react-native-fontawesome'
|
||||||
import {msg} from '@lingui/macro'
|
import {msg} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
import {RemoveScroll} from 'react-remove-scroll'
|
||||||
|
|
||||||
import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock'
|
|
||||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||||
import {colors, s} from '#/lib/styles'
|
import {colors, s} from '#/lib/styles'
|
||||||
import {useLightbox, useLightboxControls} from '#/state/lightbox'
|
import {useLightbox, useLightboxControls} from '#/state/lightbox'
|
||||||
@@ -28,7 +28,6 @@ export function Lightbox() {
|
|||||||
const {activeLightbox} = useLightbox()
|
const {activeLightbox} = useLightbox()
|
||||||
const {closeLightbox} = useLightboxControls()
|
const {closeLightbox} = useLightboxControls()
|
||||||
const isActive = !!activeLightbox
|
const isActive = !!activeLightbox
|
||||||
useWebBodyScrollLock(isActive)
|
|
||||||
|
|
||||||
if (!isActive) {
|
if (!isActive) {
|
||||||
return null
|
return null
|
||||||
@@ -37,11 +36,13 @@ export function Lightbox() {
|
|||||||
const initialIndex = activeLightbox.index
|
const initialIndex = activeLightbox.index
|
||||||
const imgs = activeLightbox.images
|
const imgs = activeLightbox.images
|
||||||
return (
|
return (
|
||||||
<LightboxInner
|
<RemoveScroll>
|
||||||
imgs={imgs}
|
<LightboxInner
|
||||||
initialIndex={initialIndex}
|
imgs={imgs}
|
||||||
onClose={closeLightbox}
|
initialIndex={initialIndex}
|
||||||
/>
|
onClose={closeLightbox}
|
||||||
|
/>
|
||||||
|
</RemoveScroll>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native'
|
import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native'
|
||||||
import Animated, {FadeIn, FadeOut} from 'react-native-reanimated'
|
import Animated, {FadeIn, FadeOut} from 'react-native-reanimated'
|
||||||
|
import {RemoveScroll} from 'react-remove-scroll'
|
||||||
|
|
||||||
import {usePalette} from '#/lib/hooks/usePalette'
|
import {usePalette} from '#/lib/hooks/usePalette'
|
||||||
import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock'
|
|
||||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||||
import type {Modal as ModalIface} from '#/state/modals'
|
import type {Modal as ModalIface} from '#/state/modals'
|
||||||
import {useModalControls, useModals} from '#/state/modals'
|
import {useModalControls, useModals} from '#/state/modals'
|
||||||
@@ -22,18 +22,17 @@ import * as VerifyEmailModal from './VerifyEmail'
|
|||||||
|
|
||||||
export function ModalsContainer() {
|
export function ModalsContainer() {
|
||||||
const {isModalActive, activeModals} = useModals()
|
const {isModalActive, activeModals} = useModals()
|
||||||
useWebBodyScrollLock(isModalActive)
|
|
||||||
|
|
||||||
if (!isModalActive) {
|
if (!isModalActive) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<RemoveScroll>
|
||||||
{activeModals.map((modal, i) => (
|
{activeModals.map((modal, i) => (
|
||||||
<Modal key={`modal-${i}`} modal={modal} />
|
<Modal key={`modal-${i}`} modal={modal} />
|
||||||
))}
|
))}
|
||||||
</>
|
</RemoveScroll>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import {StyleSheet, View} from 'react-native'
|
|||||||
import {DismissableLayer} from '@radix-ui/react-dismissable-layer'
|
import {DismissableLayer} from '@radix-ui/react-dismissable-layer'
|
||||||
import {useFocusGuards} from '@radix-ui/react-focus-guards'
|
import {useFocusGuards} from '@radix-ui/react-focus-guards'
|
||||||
import {FocusScope} from '@radix-ui/react-focus-scope'
|
import {FocusScope} from '@radix-ui/react-focus-scope'
|
||||||
|
import {RemoveScroll} from 'react-remove-scroll'
|
||||||
|
|
||||||
import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock'
|
|
||||||
import {useModals} from '#/state/modals'
|
import {useModals} from '#/state/modals'
|
||||||
import {ComposerOpts, useComposerState} from '#/state/shell/composer'
|
import {ComposerOpts, useComposerState} from '#/state/shell/composer'
|
||||||
import {
|
import {
|
||||||
@@ -20,8 +20,6 @@ export function Composer({}: {winHeight: number}) {
|
|||||||
const state = useComposerState()
|
const state = useComposerState()
|
||||||
const isActive = !!state
|
const isActive = !!state
|
||||||
|
|
||||||
useWebBodyScrollLock(isActive)
|
|
||||||
|
|
||||||
// rendering
|
// rendering
|
||||||
// =
|
// =
|
||||||
|
|
||||||
@@ -29,7 +27,11 @@ export function Composer({}: {winHeight: number}) {
|
|||||||
return <View />
|
return <View />
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Inner state={state} />
|
return (
|
||||||
|
<RemoveScroll>
|
||||||
|
<Inner state={state} />
|
||||||
|
</RemoveScroll>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function Inner({state}: {state: ComposerOpts}) {
|
function Inner({state}: {state: ComposerOpts}) {
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native'
|
|||||||
import {msg} from '@lingui/macro'
|
import {msg} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
|
import {RemoveScroll} from 'react-remove-scroll'
|
||||||
|
|
||||||
import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle'
|
import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle'
|
||||||
import {useIntentHandler} from '#/lib/hooks/useIntentHandler'
|
import {useIntentHandler} from '#/lib/hooks/useIntentHandler'
|
||||||
import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock'
|
|
||||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||||
import {NavigationProp} from '#/lib/routes/types'
|
import {NavigationProp} from '#/lib/routes/types'
|
||||||
import {colors} from '#/lib/styles'
|
import {colors} from '#/lib/styles'
|
||||||
@@ -34,7 +34,6 @@ function ShellInner() {
|
|||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const showDrawer = !isDesktop && isDrawerOpen
|
const showDrawer = !isDesktop && isDrawerOpen
|
||||||
|
|
||||||
useWebBodyScrollLock(showDrawer)
|
|
||||||
useComposerKeyboardShortcut()
|
useComposerKeyboardShortcut()
|
||||||
useIntentHandler()
|
useIntentHandler()
|
||||||
|
|
||||||
@@ -58,31 +57,33 @@ function ShellInner() {
|
|||||||
<PortalOutlet />
|
<PortalOutlet />
|
||||||
|
|
||||||
{showDrawer && (
|
{showDrawer && (
|
||||||
<TouchableWithoutFeedback
|
<RemoveScroll>
|
||||||
onPress={ev => {
|
<TouchableWithoutFeedback
|
||||||
// Only close if press happens outside of the drawer
|
onPress={ev => {
|
||||||
if (ev.target === ev.currentTarget) {
|
// Only close if press happens outside of the drawer
|
||||||
setDrawerOpen(false)
|
if (ev.target === ev.currentTarget) {
|
||||||
}
|
setDrawerOpen(false)
|
||||||
}}
|
}
|
||||||
accessibilityLabel={_(msg`Close navigation footer`)}
|
}}
|
||||||
accessibilityHint={_(msg`Closes bottom navigation bar`)}>
|
accessibilityLabel={_(msg`Close navigation footer`)}
|
||||||
<View
|
accessibilityHint={_(msg`Closes bottom navigation bar`)}>
|
||||||
style={[
|
<View
|
||||||
styles.drawerMask,
|
style={[
|
||||||
{
|
styles.drawerMask,
|
||||||
backgroundColor: select(t.name, {
|
{
|
||||||
light: 'rgba(0, 57, 117, 0.1)',
|
backgroundColor: select(t.name, {
|
||||||
dark: 'rgba(1, 82, 168, 0.1)',
|
light: 'rgba(0, 57, 117, 0.1)',
|
||||||
dim: 'rgba(10, 13, 16, 0.8)',
|
dark: 'rgba(1, 82, 168, 0.1)',
|
||||||
}),
|
dim: 'rgba(10, 13, 16, 0.8)',
|
||||||
},
|
}),
|
||||||
]}>
|
},
|
||||||
<View style={styles.drawerContainer}>
|
]}>
|
||||||
<DrawerContent />
|
<View style={styles.drawerContainer}>
|
||||||
|
<DrawerContent />
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</TouchableWithoutFeedback>
|
||||||
</TouchableWithoutFeedback>
|
</RemoveScroll>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user