Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Layout] Scrollbar gutters #6908

Merged
merged 13 commits into from
Dec 4, 2024
21 changes: 1 addition & 20 deletions bskyweb/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,8 @@
font-style: italic;
font-display: swap;
}
:root {
--scrollbar-offset: 0px;
--scrollbar-offset-negative: 0px;
}
html {
background-color: white;
scrollbar-gutter: stable both-edges;
}
@media (prefers-color-scheme: dark) {
html {
Expand Down Expand Up @@ -83,24 +78,10 @@
/* We need this style to prevent web dropdowns from shifting the display when opening */
body {
width: 100%;
overflow-y: scroll;
}
</style>

<script>
try {
var windowWidth = window.innerWidth;
var html = document.documentElement;
var htmlWidth = html.getBoundingClientRect().width;
var scrollbarWidth = (windowWidth - htmlWidth) / 2;
var scrollbarOffset = scrollbarWidth / 2;
var isFF = /firefox/i.test(navigator.userAgent)
if (!isFF) {
html.style.setProperty('--scrollbar-offset', `${scrollbarOffset}px`);
html.style.setProperty('--scrollbar-offset-negative', `-${scrollbarOffset}px`);
}
} catch (error) {}
</script>

{% include "scripts.html" %}
<link rel="apple-touch-icon" sizes="180x180" href="{{ staticCDNHost }}/static/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="{{ staticCDNHost }}/static/favicon-32x32.png">
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@
"react-native-web": "~0.19.11",
"react-native-web-webview": "^1.0.2",
"react-native-webview": "13.10.2",
"react-remove-scroll": "^2.6.0",
"react-responsive": "^9.0.2",
"react-textarea-autosize": "^8.5.3",
"rn-fetch-blob": "^0.12.0",
Expand Down
49 changes: 26 additions & 23 deletions src/components/Dialog/index.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {useLingui} from '@lingui/react'
import {DismissableLayer} from '@radix-ui/react-dismissable-layer'
import {useFocusGuards} from '@radix-ui/react-focus-guards'
import {FocusScope} from '@radix-ui/react-focus-scope'
import {RemoveScroll} from 'react-remove-scroll'

import {logger} from '#/logger'
import {useDialogStateControlContext} from '#/state/dialogs'
Expand Down Expand Up @@ -103,34 +104,36 @@ export function Outer({
{isOpen && (
<Portal>
<Context.Provider value={context}>
<TouchableWithoutFeedback
accessibilityHint={undefined}
accessibilityLabel={_(msg`Close active dialog`)}
onPress={handleBackgroundPress}>
<View
style={[
web(a.fixed),
a.inset_0,
a.z_10,
a.align_center,
gtMobile ? a.p_lg : a.p_md,
{overflowY: 'auto'},
]}>
<Backdrop />
<RemoveScroll>
<TouchableWithoutFeedback
accessibilityHint={undefined}
accessibilityLabel={_(msg`Close active dialog`)}
onPress={handleBackgroundPress}>
<View
style={[
a.w_full,
a.z_20,
a.justify_center,
web(a.fixed),
a.inset_0,
a.z_10,
a.align_center,
{
minHeight: web('calc(90vh - 36px)') || undefined,
},
gtMobile ? a.p_lg : a.p_md,
{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>
</TouchableWithoutFeedback>
</TouchableWithoutFeedback>
</RemoveScroll>
</Context.Provider>
</Portal>
)}
Expand Down
9 changes: 9 additions & 0 deletions src/components/Layout/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
useBreakpoints,
useGutterStyles,
useTheme,
web,
} from '#/alf'
import {Button, ButtonIcon} from '#/components/Button'
import {ArrowLeft_Stroke2_Corner0_Rounded as ArrowLeft} from '#/components/icons/Arrow'
Expand All @@ -39,6 +40,14 @@ export function Outer({children}: {children: React.ReactNode}) {
a.py_sm,
t.atoms.border_contrast_low,
gtMobile && [a.mx_auto, {maxWidth: 600}],
web({
transform: [
{
translateX:
'calc(-1 * var(--removed-body-scroll-bar-size, 0px) / 2)',
},
],
}),
]}>
{children}
</View>
Expand Down
12 changes: 12 additions & 0 deletions src/components/Layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ export const WebCenterBorders = React.forwardRef(function LayoutContent() {
{
translateX: '-50%',
},
{
translateX:
'calc(-1 * var(--removed-body-scroll-bar-size, 0px) / 2)',
},
],
}),
]}
Expand All @@ -165,6 +169,14 @@ export const Center = React.forwardRef(function LayoutContent(
maxWidth: 600,
},
style,
web({
transform: [
{
translateX:
'calc(-1 * var(--removed-body-scroll-bar-size, 0px) / 2)',
},
],
}),
]}
{...props}>
{children}
Expand Down
31 changes: 0 additions & 31 deletions src/lib/hooks/useWebBodyScrollLock.ts

This file was deleted.

15 changes: 8 additions & 7 deletions src/view/com/lightbox/Lightbox.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import {
} from '@fortawesome/react-native-fontawesome'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {RemoveScroll} from 'react-remove-scroll'

import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock'
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import {colors, s} from '#/lib/styles'
import {useLightbox, useLightboxControls} from '#/state/lightbox'
Expand All @@ -28,7 +28,6 @@ export function Lightbox() {
const {activeLightbox} = useLightbox()
const {closeLightbox} = useLightboxControls()
const isActive = !!activeLightbox
useWebBodyScrollLock(isActive)

if (!isActive) {
return null
Expand All @@ -37,11 +36,13 @@ export function Lightbox() {
const initialIndex = activeLightbox.index
const imgs = activeLightbox.images
return (
<LightboxInner
imgs={imgs}
initialIndex={initialIndex}
onClose={closeLightbox}
/>
<RemoveScroll>
<LightboxInner
imgs={imgs}
initialIndex={initialIndex}
onClose={closeLightbox}
/>
</RemoveScroll>
)
}

Expand Down
7 changes: 3 additions & 4 deletions src/view/com/modals/Modal.web.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native'
import Animated, {FadeIn, FadeOut} from 'react-native-reanimated'
import {RemoveScroll} from 'react-remove-scroll'

import {usePalette} from '#/lib/hooks/usePalette'
import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock'
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import type {Modal as ModalIface} from '#/state/modals'
import {useModalControls, useModals} from '#/state/modals'
Expand All @@ -22,18 +22,17 @@ import * as VerifyEmailModal from './VerifyEmail'

export function ModalsContainer() {
const {isModalActive, activeModals} = useModals()
useWebBodyScrollLock(isModalActive)

if (!isModalActive) {
return null
}

return (
<>
<RemoveScroll>
{activeModals.map((modal, i) => (
<Modal key={`modal-${i}`} modal={modal} />
))}
</>
</RemoveScroll>
)
}

Expand Down
10 changes: 6 additions & 4 deletions src/view/shell/Composer.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import {StyleSheet, View} from 'react-native'
import {DismissableLayer} from '@radix-ui/react-dismissable-layer'
import {useFocusGuards} from '@radix-ui/react-focus-guards'
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 {ComposerOpts, useComposerState} from '#/state/shell/composer'
import {
Expand All @@ -20,16 +20,18 @@ export function Composer({}: {winHeight: number}) {
const state = useComposerState()
const isActive = !!state

useWebBodyScrollLock(isActive)

// rendering
// =

if (!isActive) {
return <View />
}

return <Inner state={state} />
return (
<RemoveScroll>
<Inner state={state} />
</RemoveScroll>
)
}

function Inner({state}: {state: ComposerOpts}) {
Expand Down
23 changes: 20 additions & 3 deletions src/view/shell/desktop/LeftNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,14 @@ function NavItem({count, href, icon, iconFilled, label}: NavItemProps) {
accessibilityLabel={_(msg`${count} unread items`)}
accessibilityHint=""
accessible={true}
numberOfLines={1}
style={[
a.absolute,
a.text_xs,
a.font_bold,
a.rounded_full,
a.text_center,
a.leading_tight,
{
top: '-10%',
left: count.length === 1 ? '50%' : '40%',
Expand Down Expand Up @@ -322,9 +324,9 @@ export function DesktopLeftNav() {
<View
role="navigation"
style={[
a.px_xl,
styles.leftNav,
isTablet && styles.leftNavTablet,
pal.view,
pal.border,
]}>
{hasSession ? (
Expand Down Expand Up @@ -479,8 +481,20 @@ const styles = StyleSheet.create({
position: 'fixed',
top: 10,
// @ts-ignore web only
left: 'calc(50vw - 300px - 220px - 20px)',
width: 220,
left: '50%',
transform: [
{
translateX: -300,
},
{
translateX: '-100%',
},
{
// @ts-ignore web only -esb
translateX: 'calc(-1 * var(--removed-body-scroll-bar-size, 0px) / 2)',
},
],
width: 240,
// @ts-ignore web only
maxHeight: 'calc(100vh - 10px)',
overflowY: 'auto',
Expand All @@ -492,7 +506,10 @@ const styles = StyleSheet.create({
borderRightWidth: 1,
height: '100%',
width: 76,
paddingLeft: 0,
paddingRight: 0,
alignItems: 'center',
transform: [],
},

profileCard: {
Expand Down
14 changes: 11 additions & 3 deletions src/view/shell/desktop/RightNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function DesktopRightNav({routeName}: {routeName: string}) {
}

return (
<View style={[styles.rightNav, pal.view]}>
<View style={[a.px_xl, styles.rightNav]}>
<View style={{paddingVertical: 20}}>
{routeName === 'Search' ? (
<View style={{marginBottom: 18}}>
Expand Down Expand Up @@ -122,8 +122,16 @@ const styles = StyleSheet.create({
// @ts-ignore web only
position: 'fixed',
// @ts-ignore web only
left: 'calc(50vw + 300px + 20px)',
width: 300,
left: '50%',
transform: [
{
translateX: 300,
},
{
// @ts-ignore web only -esb
translateX: 'calc(-1 * var(--removed-body-scroll-bar-size, 0px) / 2)',
},
],
maxHeight: '100%',
overflowY: 'auto',
},
Expand Down
Loading
Loading