Skip to content

Commit

Permalink
fix(clerk-js): Correctly handle scroll lock for multiple modals (#5233)
Browse files Browse the repository at this point in the history
Co-authored-by: Stefanos Anagnostou <[email protected]>
  • Loading branch information
octoper and anagstef authored Feb 26, 2025
1 parent 2817932 commit 250ae5c
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 76 deletions.
5 changes: 5 additions & 0 deletions .changeset/eight-goats-suffer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@clerk/clerk-js": patch
---

Fix issue where scroll lock was not restored correctly when multiple modals were opening
2 changes: 1 addition & 1 deletion packages/clerk-js/bundlewatch.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{ "path": "./dist/clerk.browser.js", "maxSize": "75kB" },
{ "path": "./dist/clerk.headless.js", "maxSize": "48.3KB" },
{ "path": "./dist/ui-common*.js", "maxSize": "89KB" },
{ "path": "./dist/vendors*.js", "maxSize": "25KB" },
{ "path": "./dist/vendors*.js", "maxSize": "25.1KB" },
{ "path": "./dist/coinbase*.js", "maxSize": "35.5KB" },
{ "path": "./dist/createorganization*.js", "maxSize": "5KB" },
{ "path": "./dist/impersonationfab*.js", "maxSize": "5KB" },
Expand Down
89 changes: 43 additions & 46 deletions packages/clerk-js/src/ui/elements/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { createContextAndHook, useSafeLayoutEffect } from '@clerk/shared/react';
import { createContextAndHook } from '@clerk/shared/react';
import { FloatingOverlay } from '@floating-ui/react';
import React, { useRef } from 'react';

import { descriptors, Flex } from '../customizables';
import { usePopover, useScrollLock } from '../hooks';
import { usePopover } from '../hooks';
import type { ThemableCssProp } from '../styledSystem';
import { animations, mqu } from '../styledSystem';
import { withFloatingTree } from './contexts';
Expand All @@ -22,7 +23,6 @@ type ModalProps = React.PropsWithChildren<{

export const Modal = withFloatingTree((props: ModalProps) => {
const { handleClose, handleOpen, contentSx, containerSx, canCloseModal, id, style } = props;
const { disableScroll, enableScroll } = useScrollLock(document.body);
const overlayRef = useRef<HTMLDivElement>(null);
const { floating, isOpen, context, nodeId, toggle } = usePopover({
defaultOpen: true,
Expand All @@ -39,11 +39,6 @@ export const Modal = withFloatingTree((props: ModalProps) => {
}
}, [isOpen]);

useSafeLayoutEffect(() => {
disableScroll();
return () => enableScroll();
});

const modalCtx = React.useMemo(() => ({ value: canCloseModal === false ? {} : { toggle } }), [toggle, canCloseModal]);

return (
Expand All @@ -52,51 +47,53 @@ export const Modal = withFloatingTree((props: ModalProps) => {
context={context}
isOpen={isOpen}
>
<ModalContext.Provider value={modalCtx}>
<Flex
id={id}
ref={overlayRef}
elementDescriptor={descriptors.modalBackdrop}
style={style}
sx={[
t => ({
animation: `${animations.fadeIn} 150ms ${t.transitionTiming.$common}`,
zIndex: t.zIndices.$modal,
backgroundColor: t.colors.$modalBackdrop,
alignItems: 'flex-start',
justifyContent: 'center',
overflow: 'auto',
width: '100vw',
height: ['100vh', '-webkit-fill-available'],
position: 'fixed',
left: 0,
top: 0,
}),
containerSx,
]}
>
<FloatingOverlay lockScroll>
<ModalContext.Provider value={modalCtx}>
<Flex
elementDescriptor={descriptors.modalContent}
ref={floating}
aria-modal='true'
role='dialog'
id={id}
ref={overlayRef}
elementDescriptor={descriptors.modalBackdrop}
style={style}
sx={[
t => ({
position: 'relative',
outline: 0,
animation: `${animations.modalSlideAndFade} 180ms ${t.transitionTiming.$easeOut}`,
margin: `${t.space.$16} 0`,
[mqu.sm]: {
margin: `${t.space.$10} 0`,
},
animation: `${animations.fadeIn} 150ms ${t.transitionTiming.$common}`,
zIndex: t.zIndices.$modal,
backgroundColor: t.colors.$modalBackdrop,
alignItems: 'flex-start',
justifyContent: 'center',
overflow: 'auto',
width: '100vw',
height: ['100vh', '-webkit-fill-available'],
position: 'fixed',
left: 0,
top: 0,
}),
contentSx,
containerSx,
]}
>
{props.children}
<Flex
elementDescriptor={descriptors.modalContent}
ref={floating}
aria-modal='true'
role='dialog'
sx={[
t => ({
position: 'relative',
outline: 0,
animation: `${animations.modalSlideAndFade} 180ms ${t.transitionTiming.$easeOut}`,
margin: `${t.space.$16} 0`,
[mqu.sm]: {
margin: `${t.space.$10} 0`,
},
}),
contentSx,
]}
>
{props.children}
</Flex>
</Flex>
</Flex>
</ModalContext.Provider>
</ModalContext.Provider>
</FloatingOverlay>
</Popover>
);
});
1 change: 0 additions & 1 deletion packages/clerk-js/src/ui/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export * from './useResizeObserver';
export * from './useSafeState';
export * from './useSearchInput';
export * from './useDebounce';
export * from './useScrollLock';
export * from './useClerkModalStateParams';
export * from './useNavigateToFlowStart';
export * from './useEnterpriseSSOLink';
28 changes: 0 additions & 28 deletions packages/clerk-js/src/ui/hooks/useScrollLock.ts

This file was deleted.

0 comments on commit 250ae5c

Please sign in to comment.