Skip to content

Commit a522fdb

Browse files
fix(SelectPanel): disable body scroll on full screen (#5904)
1 parent 0cd8dd1 commit a522fdb

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

.changeset/tasty-games-trade.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@primer/react": patch
3+
---
4+
5+
fix(SelectPanel): disable body scroll on full screen

packages/react/src/SelectPanel/SelectPanel.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import classes from './SelectPanel.module.css'
2525
import {clsx} from 'clsx'
2626
import {heightMap} from '../Overlay/Overlay'
2727
import {debounce} from '@github/mini-throttle'
28+
import {useResponsiveValue} from '../hooks/useResponsiveValue'
2829

2930
// we add a delay so that it does not interrupt default screen reader announcement and queues after it
3031
const SHORT_DELAY_MS = 500
@@ -170,6 +171,10 @@ export function SelectPanel({
170171
const [inputRef, setInputRef] = React.useState<React.RefObject<HTMLInputElement> | null>(null)
171172
const [listContainerElement, setListContainerElement] = useState<HTMLElement | null>(null)
172173
const [needsNoItemsAnnouncement, setNeedsNoItemsAnnouncement] = useState<boolean>(false)
174+
const isNarrowScreenSize = useResponsiveValue({narrow: true, regular: false, wide: false}, false)
175+
176+
const usingModernActionList = useFeatureFlag('primer_react_select_panel_modern_action_list')
177+
const usingFullScreenOnNarrow = useFeatureFlag('primer_react_select_panel_fullscreen_on_narrow')
173178

174179
const onListContainerRefChanged: FilteredActionListProps['onListContainerRefChanged'] = useCallback(
175180
(node: HTMLElement | null) => {
@@ -234,6 +239,25 @@ export function SelectPanel({
234239
],
235240
)
236241

242+
// disable body scroll when the panel is open on narrow screens
243+
useEffect(() => {
244+
if (open && isNarrowScreenSize && usingFullScreenOnNarrow) {
245+
const bodyOverflowStyle = document.body.style.overflow || ''
246+
// If the body is already set to overflow: hidden, it likely means
247+
// that there is already a modal open. In that case, we should bail
248+
// so we don't re-enable scroll after the second dialog is closed.
249+
if (bodyOverflowStyle === 'hidden') {
250+
return
251+
}
252+
253+
document.body.style.overflow = 'hidden'
254+
255+
return () => {
256+
document.body.style.overflow = bodyOverflowStyle
257+
}
258+
}
259+
}, [isNarrowScreenSize, open, usingFullScreenOnNarrow])
260+
237261
useEffect(() => {
238262
if (open) {
239263
if (items.length === 0 && !(isLoading || loading)) {
@@ -385,9 +409,6 @@ export function SelectPanel({
385409
}
386410
}
387411

388-
const usingModernActionList = useFeatureFlag('primer_react_select_panel_modern_action_list')
389-
const usingFullScreenOnNarrow = useFeatureFlag('primer_react_select_panel_fullscreen_on_narrow')
390-
391412
const iconForNoticeVariant = {
392413
info: <InfoIcon size={16} />,
393414
warning: <AlertIcon size={16} />,

0 commit comments

Comments
 (0)