Merge pull request #39 from arapl3y/feature/fix-modal-layout-shift

feat: fix modal and scrollbar layout shift
This commit is contained in:
MAZE ✧ 2024-08-03 21:35:17 +03:30 committed by GitHub
commit f526f97908
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 13 additions and 3 deletions

View file

@ -19,6 +19,8 @@ interface ModalProps {
wide?: boolean; wide?: boolean;
} }
const TRANSITION_DURATION = 300;
export function Modal({ export function Modal({
children, children,
lockBody = true, lockBody = true,
@ -34,9 +36,12 @@ export function Modal({
useEffect(() => { useEffect(() => {
if (show && lockBody) { if (show && lockBody) {
document.body.style.overflow = 'hidden'; document.body.style.overflowY = 'hidden';
} else if (lockBody) { } else if (lockBody) {
document.body.style.overflow = 'auto'; // Wait for transition to finish before allowing scrollbar to return
setTimeout(() => {
document.body.style.overflowY = 'auto';
}, TRANSITION_DURATION);
} }
}, [show, lockBody]); }, [show, lockBody]);
@ -68,6 +73,7 @@ export function Modal({
<motion.div <motion.div
{...animationProps} {...animationProps}
className={styles.overlay} className={styles.overlay}
transition={{ duration: TRANSITION_DURATION / 1000 }}
variants={variants.overlay} variants={variants.overlay}
onClick={onClose} onClick={onClose}
onKeyDown={onClose} onKeyDown={onClose}
@ -76,6 +82,7 @@ export function Modal({
<motion.div <motion.div
{...animationProps} {...animationProps}
className={cn(styles.content, wide && styles.wide)} className={cn(styles.content, wide && styles.wide)}
transition={{ duration: TRANSITION_DURATION / 1000 }}
variants={variants.modal} variants={variants.modal}
> >
<button className={styles.close} onClick={onClose}> <button className={styles.close} onClick={onClose}>

View file

@ -3,7 +3,7 @@
bottom: 20px; bottom: 20px;
left: 0; left: 0;
z-index: 15; z-index: 15;
width: 100%; width: 100vw;
.container { .container {
display: flex; display: flex;

View file

@ -16,6 +16,9 @@ body {
font-size: var(--font-base); font-size: var(--font-base);
color: var(--color-foreground); color: var(--color-foreground);
background-color: var(--color-neutral-50); background-color: var(--color-neutral-50);
/* Workaround for modal and scrollbar layout shifts */
width: 100vw;
overflow-x: hidden;
} }
::selection { ::selection {