From 44405606f51cf0d16f1746f4a78b295c54f35ec1 Mon Sep 17 00:00:00 2001 From: sirineJ <112706079+sirineJ@users.noreply.github.com> Date: Mon, 23 Dec 2024 00:20:14 +0100 Subject: [PATCH] restore scroll on clean up --- .../hooks/useScrollLock/useScrollLock.spec.ts | 15 ++++++++++++ .../hooks/useScrollLock/useScrollLock.ts | 24 ++++++++++++------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/packages/circuit-ui/hooks/useScrollLock/useScrollLock.spec.ts b/packages/circuit-ui/hooks/useScrollLock/useScrollLock.spec.ts index 4e478c7c3b..2a9733a97e 100644 --- a/packages/circuit-ui/hooks/useScrollLock/useScrollLock.spec.ts +++ b/packages/circuit-ui/hooks/useScrollLock/useScrollLock.spec.ts @@ -58,4 +58,19 @@ describe('useScrollLock', () => { expect(document.body.style.top).toBe(''); expect(window.scrollTo).toHaveBeenCalledWith(0, 100); }); + + it('unlocks the scroll when unmounted', () => { + window.scrollY = 100; + + const { unmount } = renderHook(() => useScrollLock(true), { + initialProps: { isLocked: true }, + }); + expect(document.body.style.position).toBe('fixed'); + + unmount(); + + expect(document.body.style.position).toBe(''); + expect(document.body.style.top).toBe(''); + expect(window.scrollTo).toHaveBeenCalledWith(0, 100); + }); }); diff --git a/packages/circuit-ui/hooks/useScrollLock/useScrollLock.ts b/packages/circuit-ui/hooks/useScrollLock/useScrollLock.ts index 31f79729a8..003c087178 100644 --- a/packages/circuit-ui/hooks/useScrollLock/useScrollLock.ts +++ b/packages/circuit-ui/hooks/useScrollLock/useScrollLock.ts @@ -13,11 +13,20 @@ * limitations under the License. */ -import { useEffect, useRef } from 'react'; +import { useCallback, useEffect, useRef } from 'react'; export const useScrollLock = (isLocked: boolean): void => { const scrollValue = useRef(); + const restoreScroll = useCallback(() => { + // restore scroll to page + const { body } = document; + const scrollY = body.style.top; + body.style.position = ''; + body.style.top = ''; + body.style.width = ''; + window.scrollTo(0, Number.parseInt(scrollY || '0', 10) * -1); + }, []); useEffect(() => { if (isLocked) { scrollValue.current = `${window.scrollY}px`; @@ -31,13 +40,10 @@ export const useScrollLock = (isLocked: boolean): void => { body.style.width = `${bodyWidth}px`; body.style.top = `-${scrollY}`; } else { - // restore scroll to page - const { body } = document; - const scrollY = body.style.top; - body.style.position = ''; - body.style.top = ''; - body.style.width = ''; - window.scrollTo(0, Number.parseInt(scrollY || '0', 10) * -1); + restoreScroll(); } - }, [isLocked]); + return () => { + restoreScroll(); + }; + }, [isLocked, restoreScroll]); };