From e54c141484cd38adea2c833a35cf9fba303d65fd Mon Sep 17 00:00:00 2001 From: Lucas Bordeau Date: Wed, 24 Jan 2024 10:39:04 +0100 Subject: [PATCH] Use scroll left instead of intersection observer (#3522) --- .../RecordTableFirstColumnScrollObserver.tsx | 28 +++++++++---------- .../components/RecordTableWithWrappers.tsx | 4 +-- .../utilities/scroll/hooks/useListenScroll.ts | 11 +++++++- .../scroll/states/scrollLeftState.ts | 6 ++++ .../utilities/scroll/states/scrollTopState.ts | 6 ++++ 5 files changed, 37 insertions(+), 18 deletions(-) create mode 100644 packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollLeftState.ts create mode 100644 packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollTopState.ts diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableFirstColumnScrollObserver.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableFirstColumnScrollObserver.tsx index 5554eef94..6c64644bf 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableFirstColumnScrollObserver.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableFirstColumnScrollObserver.tsx @@ -1,22 +1,20 @@ -import { useContext } from 'react'; -import { useInView } from 'react-intersection-observer'; +import { useContext, useEffect } from 'react'; +import { useRecoilValue } from 'recoil'; import { RecordTableRefContext } from '@/object-record/record-table/contexts/RecordTableRefContext'; -import { ScrollWrapperContext } from '@/ui/utilities/scroll/components/ScrollWrapper'; +import { scrollLeftState } from '@/ui/utilities/scroll/states/scrollLeftState'; -export const RecordTableFirstColumnScrollObserver = () => { - const scrollWrapperRef = useContext(ScrollWrapperContext); +export const RecordTableFirstColumnScrollEffect = () => { const recordTableRef = useContext(RecordTableRefContext); - const { ref: elementRef } = useInView({ - root: scrollWrapperRef.current, - onChange: (inView) => { - recordTableRef.current?.classList.toggle( - 'freeze-first-columns-shadow', - !inView, - ); - }, - }); + const scrollLeft = useRecoilValue(scrollLeftState); - return
; + useEffect(() => { + recordTableRef.current?.classList.toggle( + 'freeze-first-columns-shadow', + scrollLeft > 0, + ); + }, [scrollLeft, recordTableRef]); + + return <>; }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx index f3bccc8d0..4b45219b7 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx @@ -6,7 +6,7 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural'; import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord'; import { RecordTable } from '@/object-record/record-table/components/RecordTable'; -import { RecordTableFirstColumnScrollObserver } from '@/object-record/record-table/components/RecordTableFirstColumnScrollObserver'; +import { RecordTableFirstColumnScrollEffect } from '@/object-record/record-table/components/RecordTableFirstColumnScrollObserver'; import { RecordTableRefContextWrapper } from '@/object-record/record-table/components/RecordTableRefContext'; import { EntityDeleteContext } from '@/object-record/record-table/contexts/EntityDeleteHookContext'; import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates'; @@ -113,7 +113,7 @@ export const RecordTableWithWrappers = ({ - + diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useListenScroll.ts b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useListenScroll.ts index 0948e7348..c6039fc2a 100644 --- a/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useListenScroll.ts +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useListenScroll.ts @@ -2,6 +2,9 @@ import { useEffect } from 'react'; import debounce from 'lodash.debounce'; import { useRecoilCallback } from 'recoil'; +import { scrollLeftState } from '@/ui/utilities/scroll/states/scrollLeftState'; +import { scrollTopState } from '@/ui/utilities/scroll/states/scrollTopState'; + import { isScrollingState } from '../states/isScrollingState'; export const useListenScroll = ({ @@ -11,14 +14,20 @@ export const useListenScroll = ({ }) => { const hideScrollBarsCallback = useRecoilCallback(({ snapshot }) => () => { const isScrolling = snapshot.getLoadable(isScrollingState).getValue(); + if (!isScrolling) { scrollableRef.current?.classList.remove('scrolling'); } }); - const handleScrollStart = useRecoilCallback(({ set }) => () => { + const handleScrollStart = useRecoilCallback(({ set }) => (event: Event) => { set(isScrollingState, true); scrollableRef.current?.classList.add('scrolling'); + + const target = event.target as HTMLElement; + + set(scrollTopState, target.scrollTop); + set(scrollLeftState, target.scrollLeft); }); const handleScrollEnd = useRecoilCallback(({ set }) => () => { diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollLeftState.ts b/packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollLeftState.ts new file mode 100644 index 000000000..97ab75dff --- /dev/null +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollLeftState.ts @@ -0,0 +1,6 @@ +import { atom } from 'recoil'; + +export const scrollLeftState = atom({ + key: 'scroll/scrollLeftState', + default: 0, +}); diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollTopState.ts b/packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollTopState.ts new file mode 100644 index 000000000..cc8ceef32 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollTopState.ts @@ -0,0 +1,6 @@ +import { atom } from 'recoil'; + +export const scrollTopState = atom({ + key: 'scroll/scrollTopState', + default: 0, +});