From 75214c3e613a5eb3fdb255cd8dcacfedf28984f3 Mon Sep 17 00:00:00 2001 From: nitin <142569587+ehconitin@users.noreply.github.com> Date: Fri, 1 Aug 2025 20:21:52 +0530 Subject: [PATCH] fix: prevent saving tiny scroll positions in restoration hook (#13554) fixes 1-2px scroll restoration issue - browser reports 1-2px instead of exact 0 when at top - old logic kept saving these tiny values - now clears storage when <= 3px (essentially at top) - prevents weird micro-scroll when returning to pages re: [greptile infinite polling concern](https://github.com/twentyhq/twenty/pull/13363#discussion_r2247232974) - not valid in practice: - restoration only runs if position was previously saved - no scroll = no save = no restore = no polling - tested across all page types, zero infinite loops tested: works perfectly, no side effects --- .../scroll/constants/ScrollRestorationTopThreshold.ts | 1 + .../ui/utilities/scroll/hooks/useScrollRestoration.ts | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 packages/twenty-front/src/modules/ui/utilities/scroll/constants/ScrollRestorationTopThreshold.ts diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/constants/ScrollRestorationTopThreshold.ts b/packages/twenty-front/src/modules/ui/utilities/scroll/constants/ScrollRestorationTopThreshold.ts new file mode 100644 index 0000000000..679b88d5fb --- /dev/null +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/constants/ScrollRestorationTopThreshold.ts @@ -0,0 +1 @@ +export const SCROLL_RESTORATION_TOP_THRESHOLD_PX = 3; diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useScrollRestoration.ts b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useScrollRestoration.ts index 9eceed5c3f..db9ad13a3e 100644 --- a/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useScrollRestoration.ts +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useScrollRestoration.ts @@ -1,3 +1,4 @@ +import { SCROLL_RESTORATION_TOP_THRESHOLD_PX } from '@/ui/utilities/scroll/constants/ScrollRestorationTopThreshold'; import { scrollWrapperScrollTopComponentState } from '@/ui/utilities/scroll/states/scrollWrapperScrollTopComponentState'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useCallback, useEffect, useState } from 'react'; @@ -43,9 +44,14 @@ export const useScrollRestoration = (componentInstanceId: string) => { ); useEffect(() => { - if (scrollTop > 0 && !isRestoring) { - sessionStorage.setItem(storageKey, scrollTop.toString()); + if (isRestoring) return; + + if (scrollTop <= SCROLL_RESTORATION_TOP_THRESHOLD_PX) { + sessionStorage.removeItem(storageKey); + return; } + + sessionStorage.setItem(storageKey, scrollTop.toString()); }, [scrollTop, storageKey, isRestoring]); useEffect(() => {