From b4a20724daa939324687560937c679a85795d071 Mon Sep 17 00:00:00 2001 From: Youssef Abelouas Date: Tue, 21 May 2024 11:32:08 +0100 Subject: [PATCH 1/3] fix layout shift and conflicting files --- src/components/Navbar/Navbar.module.scss | 12 ++++++- src/components/Navbar/Navbar.tsx | 36 +++++++++++++++++-- src/components/Navbar/NavbarBody/index.tsx | 5 +-- .../OnboardingChecklist.module.scss | 10 ++++++ .../Onboarding/OnboardingChecklist/index.tsx | 21 ++++++++--- .../QuranReader/ContextMenu.module.scss | 10 ++++++ src/components/QuranReader/ContextMenu.tsx | 9 ++++- src/hooks/usePreventBodyScrolling.ts | 9 +++-- src/styles/theme.scss | 2 ++ 9 files changed, 101 insertions(+), 13 deletions(-) diff --git a/src/components/Navbar/Navbar.module.scss b/src/components/Navbar/Navbar.module.scss index 7f4e7bc1aa..692929b13a 100644 --- a/src/components/Navbar/Navbar.module.scss +++ b/src/components/Navbar/Navbar.module.scss @@ -1,6 +1,16 @@ @use "src/styles/constants"; @use "src/styles/breakpoints"; +body[data-scroll-locked] { + .container { + width: calc(100% - var(--scrollbar-width)) !important; + } +} + +.noScrollbarWidth { + width: calc(100% - var(--scrollbar-width)) !important; +} + .emptySpacePlaceholder { height: var(--navbar-container-height); } @@ -10,7 +20,7 @@ position: fixed; height: var(--navbar-height); width: 100%; - transition: var(--transition-regular); + transition: transform var(--transition-regular); background: var(--color-background-elevated); z-index: var(--z-index-header); will-change: transform; diff --git a/src/components/Navbar/Navbar.tsx b/src/components/Navbar/Navbar.tsx index 9346662950..796886d39d 100644 --- a/src/components/Navbar/Navbar.tsx +++ b/src/components/Navbar/Navbar.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import classNames from 'classnames'; import { useSelector, shallowEqual } from 'react-redux'; @@ -11,13 +11,43 @@ import { selectNavbar } from '@/redux/slices/navbar'; const Navbar = () => { const { isActive } = useOnboarding(); - const { isVisible: isNavbarVisible } = useSelector(selectNavbar, shallowEqual); + const { + isVisible: isNavbarVisible, + isSettingsDrawerOpen, + isNavigationDrawerOpen, + isSearchDrawerOpen, + } = useSelector(selectNavbar, shallowEqual); const showNavbar = isNavbarVisible || isActive; + useEffect(() => { + const getScrollbarWidth = () => { + return window.innerWidth - document.documentElement.clientWidth; + }; + + const setScrollbarWidth = () => { + const scrollbarWidth = getScrollbarWidth(); + document.documentElement.style.setProperty('--scrollbar-width', `${scrollbarWidth}px`); + }; + + setScrollbarWidth(); // Set the scrollbar width initially + + window.addEventListener('resize', setScrollbarWidth); // Update the scrollbar width when the window is resized + + return () => { + window.removeEventListener('resize', setScrollbarWidth); + }; + }, []); + return ( <>
-
diff --git a/src/components/Onboarding/OnboardingChecklist/OnboardingChecklist.module.scss b/src/components/Onboarding/OnboardingChecklist/OnboardingChecklist.module.scss index 1496750563..1a814ac52f 100644 --- a/src/components/Onboarding/OnboardingChecklist/OnboardingChecklist.module.scss +++ b/src/components/Onboarding/OnboardingChecklist/OnboardingChecklist.module.scss @@ -1,5 +1,15 @@ @use "src/styles/breakpoints"; +body[data-scroll-locked] { + .checklistPosition { + margin-right: var(--scrollbar-width); + } +} + +.marginRight { + margin-right: var(--scrollbar-width); +} + .checklistPosition { position: fixed; inset-block-end: var(--spacing-medium); diff --git a/src/components/Onboarding/OnboardingChecklist/index.tsx b/src/components/Onboarding/OnboardingChecklist/index.tsx index 42ffcee89b..41902df69d 100644 --- a/src/components/Onboarding/OnboardingChecklist/index.tsx +++ b/src/components/Onboarding/OnboardingChecklist/index.tsx @@ -2,7 +2,7 @@ import classNames from 'classnames'; import { useRouter } from 'next/router'; import Trans from 'next-translate/Trans'; import useTranslation from 'next-translate/useTranslation'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch, useSelector, shallowEqual } from 'react-redux'; import OnboardingProgress from '../OnboardingProgress'; import { onboardingChecklist } from '../steps'; @@ -16,6 +16,7 @@ import usePersistPreferenceGroup from '@/hooks/auth/usePersistPreferenceGroup'; import CheckIcon from '@/icons/check.svg'; import IconClose from '@/icons/close.svg'; import IconQuestionMark from '@/icons/question-mark-icon.svg'; +import { selectNavbar } from '@/redux/slices/navbar'; import { dismissChecklist, selectOnboarding, @@ -42,6 +43,11 @@ const OnboardingChecklist = () => { const { isChecklistVisible, checklistDismissals, completedGroups } = useSelector(selectOnboarding); + const { isSearchDrawerOpen, isNavigationDrawerOpen, isSettingsDrawerOpen } = useSelector( + selectNavbar, + shallowEqual, + ); + const readingPreferences = useSelector(selectReadingPreferences); const { readingPreference } = readingPreferences; const { @@ -70,7 +76,10 @@ const OnboardingChecklist = () => { return ( - {createPortal(, document.body)} + {isClient && createPortal(, document.body)} <> - {createPortal(, document.body)} + {isClient && createPortal(, document.body)} From e0323ee735d1549b5b443ea6e452ca89824296c1 Mon Sep 17 00:00:00 2001 From: Youssef Abelouas Date: Thu, 23 May 2024 16:06:10 +0100 Subject: [PATCH 3/3] create custom hook that handles changing the scrollbar width css variable --- src/components/Navbar/Navbar.tsx | 22 +++---------------- src/hooks/useScrollBarWidth.ts | 37 ++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 19 deletions(-) create mode 100644 src/hooks/useScrollBarWidth.ts diff --git a/src/components/Navbar/Navbar.tsx b/src/components/Navbar/Navbar.tsx index 796886d39d..78fffadf87 100644 --- a/src/components/Navbar/Navbar.tsx +++ b/src/components/Navbar/Navbar.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React from 'react'; import classNames from 'classnames'; import { useSelector, shallowEqual } from 'react-redux'; @@ -7,6 +7,7 @@ import styles from './Navbar.module.scss'; import NavbarBody from './NavbarBody'; import { useOnboarding } from '@/components/Onboarding/OnboardingProvider'; +import useScrollBarWidth from '@/hooks/useScrollBarWidth'; import { selectNavbar } from '@/redux/slices/navbar'; const Navbar = () => { @@ -19,24 +20,7 @@ const Navbar = () => { } = useSelector(selectNavbar, shallowEqual); const showNavbar = isNavbarVisible || isActive; - useEffect(() => { - const getScrollbarWidth = () => { - return window.innerWidth - document.documentElement.clientWidth; - }; - - const setScrollbarWidth = () => { - const scrollbarWidth = getScrollbarWidth(); - document.documentElement.style.setProperty('--scrollbar-width', `${scrollbarWidth}px`); - }; - - setScrollbarWidth(); // Set the scrollbar width initially - - window.addEventListener('resize', setScrollbarWidth); // Update the scrollbar width when the window is resized - - return () => { - window.removeEventListener('resize', setScrollbarWidth); - }; - }, []); + useScrollBarWidth(); return ( <> diff --git a/src/hooks/useScrollBarWidth.ts b/src/hooks/useScrollBarWidth.ts new file mode 100644 index 0000000000..33af8c22a4 --- /dev/null +++ b/src/hooks/useScrollBarWidth.ts @@ -0,0 +1,37 @@ +import { useEffect } from 'react'; + +const useScrollBarWidth = () => { + useEffect(() => { + const getScrollbarWidth = () => { + return window.innerWidth - document.documentElement.clientWidth; + }; + + const setScrollbarWidth = () => { + const scrollbarWidth = getScrollbarWidth(); + document.documentElement.style.setProperty('--scrollbar-width', `${scrollbarWidth}px`); + }; + + function throttle(fn: () => void, time: number) { + let timeout = null; + return () => { + if (timeout) return; + timeout = setTimeout(() => { + fn(); + timeout = null; + }, time); + }; + } + + const handleResizeThrottled = throttle(setScrollbarWidth, 500); // Throttle the resize event + + setScrollbarWidth(); // Set the scrollbar width initially + + window.addEventListener('resize', handleResizeThrottled); // Update the scrollbar width when the window is resized + + return () => { + window.removeEventListener('resize', handleResizeThrottled); + }; + }, []); +}; + +export default useScrollBarWidth;