From 1030ff43d8ad856b32a31884a5492b13c2c2d5b1 Mon Sep 17 00:00:00 2001 From: nitin <142569587+ehconitin@users.noreply.github.com> Date: Thu, 22 Aug 2024 21:51:14 +0530 Subject: [PATCH] Created a specific scroll wrapper context per scroll wrapper and made ScrollTop and ScrollLeft componentStates (#6645) @lucasbordeau @charlesBochet Issue #4826 Could u review this changes. Let me know what do you think. --------- Co-authored-by: Lucas Bordeau --- .../components/EventList.tsx | 2 +- .../command-menu/components/CommandMenu.tsx | 2 +- .../record-board/components/RecordBoard.tsx | 2 +- .../components/RecordBoardCard.tsx | 6 +- .../components/RecordTableWithWrappers.tsx | 2 +- .../components/RecordTableBodyEffect.tsx | 8 +- .../RecordTableBodyFetchMoreLoader.tsx | 10 ++- .../RecordTableHeaderLastColumn.tsx | 6 +- .../components/RecordTableRowWrapper.tsx | 8 +- .../components/SettingsPageContainer.tsx | 2 +- .../components/DropdownMenuItemsContainer.tsx | 2 +- .../ui/layout/page/ShowPageContainer.tsx | 2 +- .../components/ShowPageLeftContainer.tsx | 4 +- .../ui/layout/tab/components/TabList.tsx | 4 +- .../scroll/components/ScrollWrapper.tsx | 41 +++++----- .../scroll/contexts/ScrollWrapperContexts.tsx | 78 +++++++++++++++++++ .../useScrollWrapperScopedRef.test.tsx | 2 +- .../scroll/hooks/internal/useScrollStates.ts | 32 ++++++++ .../scroll/hooks/useScrollLeftValue.ts | 10 +++ .../scroll/hooks/useScrollTopValue.ts | 8 ++ .../scroll/hooks/useScrollWrapperScopedRef.ts | 12 ++- .../scroll/states/scrollLeftComponentState.ts | 6 ++ .../scroll/states/scrollLeftState.ts | 6 -- .../scroll/states/scrollTopComponentState.ts | 6 ++ .../utilities/scroll/states/scrollTopState.ts | 6 -- .../src/pages/settings/Releases.tsx | 2 +- 26 files changed, 205 insertions(+), 64 deletions(-) create mode 100644 packages/twenty-front/src/modules/ui/utilities/scroll/contexts/ScrollWrapperContexts.tsx create mode 100644 packages/twenty-front/src/modules/ui/utilities/scroll/hooks/internal/useScrollStates.ts create mode 100644 packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useScrollLeftValue.ts create mode 100644 packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useScrollTopValue.ts create mode 100644 packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollLeftComponentState.ts delete 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/scrollTopComponentState.ts delete mode 100644 packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollTopState.ts diff --git a/packages/twenty-front/src/modules/activities/timelineActivities/components/EventList.tsx b/packages/twenty-front/src/modules/activities/timelineActivities/components/EventList.tsx index d6087d825419..bf82cc2a42da 100644 --- a/packages/twenty-front/src/modules/activities/timelineActivities/components/EventList.tsx +++ b/packages/twenty-front/src/modules/activities/timelineActivities/components/EventList.tsx @@ -46,7 +46,7 @@ export const EventList = ({ events, targetableObject }: EventListProps) => { const groupedEvents = groupEventsByMonth(filteredEvents); return ( - + {groupedEvents.map((group, index) => ( { )} - + { > - + {columnIds.map((columnId) => ( diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx index 1e45cbb9fced..8d968c8dd5b2 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx @@ -23,7 +23,7 @@ import { Checkbox, CheckboxVariant } from '@/ui/input/components/Checkbox'; import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState'; import { contextMenuPositionState } from '@/ui/navigation/context-menu/states/contextMenuPositionState'; import { AnimatedEaseInOut } from '@/ui/utilities/animation/components/AnimatedEaseInOut'; -import { ScrollWrapperContext } from '@/ui/utilities/scroll/components/ScrollWrapper'; +import { RecordBoardScrollWrapperContext } from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts'; const StyledBoardCard = styled.div<{ selected: boolean }>` background-color: ${({ theme, selected }) => @@ -199,10 +199,10 @@ export const RecordBoardCard = () => { return [updateEntity, { loading: false }]; }; - const scrollWrapperRef = useContext(ScrollWrapperContext); + const scrollWrapperRef = useContext(RecordBoardScrollWrapperContext); const { ref: cardRef, inView } = useInView({ - root: scrollWrapperRef.current, + root: scrollWrapperRef?.ref.current, rootMargin: '1000px', }); 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 85e860436e93..a9080a4ddd21 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 @@ -70,7 +70,7 @@ export const RecordTableWithWrappers = ({ return ( - + diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyEffect.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyEffect.tsx index 4fe39622def6..d53d6499027b 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyEffect.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyEffect.tsx @@ -10,8 +10,8 @@ import { useRecordTableStates } from '@/object-record/record-table/hooks/interna import { isRecordTableScrolledLeftComponentState } from '@/object-record/record-table/states/isRecordTableScrolledLeftComponentState'; import { isRecordTableScrolledTopComponentState } from '@/object-record/record-table/states/isRecordTableScrolledTopComponentState'; import { isFetchingMoreRecordsFamilyState } from '@/object-record/states/isFetchingMoreRecordsFamilyState'; -import { scrollLeftState } from '@/ui/utilities/scroll/states/scrollLeftState'; -import { scrollTopState } from '@/ui/utilities/scroll/states/scrollTopState'; +import { useScrollLeftValue } from '@/ui/utilities/scroll/hooks/useScrollLeftValue'; +import { useScrollTopValue } from '@/ui/utilities/scroll/hooks/useScrollTopValue'; import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState'; import { isNonEmptyString } from '@sniptt/guards'; import { useScrollToPosition } from '~/hooks/useScrollToPosition'; @@ -38,7 +38,7 @@ export const RecordTableBodyEffect = () => { const tableLastRowVisible = useRecoilValue(tableLastRowVisibleState); - const scrollTop = useRecoilValue(scrollTopState); + const scrollTop = useScrollTopValue('recordTableWithWrappers'); const setIsRecordTableScrolledTop = useSetRecoilComponentState( isRecordTableScrolledTopComponentState, ); @@ -57,7 +57,7 @@ export const RecordTableBodyEffect = () => { } }, [scrollTop, setIsRecordTableScrolledTop]); - const scrollLeft = useRecoilValue(scrollLeftState); + const scrollLeft = useScrollLeftValue('recordTableWithWrappers'); const setIsRecordTableScrolledLeft = useSetRecoilComponentState( isRecordTableScrolledLeftComponentState, diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyFetchMoreLoader.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyFetchMoreLoader.tsx index 17b06e8bdf28..32df8cf268f2 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyFetchMoreLoader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyFetchMoreLoader.tsx @@ -1,13 +1,13 @@ +import styled from '@emotion/styled'; import { useContext } from 'react'; import { useInView } from 'react-intersection-observer'; -import styled from '@emotion/styled'; import { useRecoilCallback, useRecoilValue } from 'recoil'; import { GRAY_SCALE } from 'twenty-ui'; import { useLoadRecordIndexTable } from '@/object-record/record-index/hooks/useLoadRecordIndexTable'; import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; import { isFetchingMoreRecordsFamilyState } from '@/object-record/states/isFetchingMoreRecordsFamilyState'; -import { ScrollWrapperContext } from '@/ui/utilities/scroll/components/ScrollWrapper'; +import { RecordTableWithWrappersScrollWrapperContext } from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts'; type RecordTableBodyFetchMoreLoaderProps = { objectNameSingular: string; @@ -40,12 +40,14 @@ export const RecordTableBodyFetchMoreLoader = ({ [setRecordTableLastRowVisible], ); - const scrollWrapperRef = useContext(ScrollWrapperContext); + const scrollWrapperRef = useContext( + RecordTableWithWrappersScrollWrapperContext, + ); const { ref: tbodyRef } = useInView({ onChange: onLastRowVisible, rootMargin: '1000px', - root: scrollWrapperRef.current?.querySelector( + root: scrollWrapperRef?.ref.current?.querySelector( '[data-overlayscrollbars-viewport="scrollbarHidden"]', ), }); diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderLastColumn.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderLastColumn.tsx index 170ec63f74b9..0a548ae5f8de 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderLastColumn.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderLastColumn.tsx @@ -54,11 +54,11 @@ const HIDDEN_TABLE_COLUMN_DROPDOWN_HOTKEY_SCOPE_ID = export const RecordTableHeaderLastColumn = () => { const { theme } = useContext(ThemeContext); - const scrollWrapper = useScrollWrapperScopedRef(); + const scrollWrapper = useScrollWrapperScopedRef('recordTableWithWrappers'); const isTableWiderThanScreen = - (scrollWrapper.current?.clientWidth ?? 0) < - (scrollWrapper.current?.scrollWidth ?? 0); + (scrollWrapper.ref.current?.clientWidth ?? 0) < + (scrollWrapper.ref.current?.scrollWidth ?? 0); const { hiddenTableColumnsSelector } = useRecordTableStates(); diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableRowWrapper.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableRowWrapper.tsx index 193c852d9e88..1090136fdb1c 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableRowWrapper.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableRowWrapper.tsx @@ -10,7 +10,7 @@ import { RecordTableContext } from '@/object-record/record-table/contexts/Record import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext'; import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates'; import { RecordTableTr } from '@/object-record/record-table/record-table-row/components/RecordTableTr'; -import { ScrollWrapperContext } from '@/ui/utilities/scroll/components/ScrollWrapper'; +import { RecordTableWithWrappersScrollWrapperContext } from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts'; export const RecordTableRowWrapper = ({ recordId, @@ -31,10 +31,12 @@ export const RecordTableRowWrapper = ({ const { isRowSelectedFamilyState } = useRecordTableStates(); const currentRowSelected = useRecoilValue(isRowSelectedFamilyState(recordId)); - const scrollWrapperRef = useContext(ScrollWrapperContext); + const scrollWrapperRef = useContext( + RecordTableWithWrappersScrollWrapperContext, + ); const { ref: elementRef, inView } = useInView({ - root: scrollWrapperRef.current?.querySelector( + root: scrollWrapperRef.ref.current?.querySelector( '[data-overlayscrollbars-viewport="scrollbarHidden"]', ), rootMargin: '1000px', diff --git a/packages/twenty-front/src/modules/settings/components/SettingsPageContainer.tsx b/packages/twenty-front/src/modules/settings/components/SettingsPageContainer.tsx index d25c530762c6..2fc661c7a756 100644 --- a/packages/twenty-front/src/modules/settings/components/SettingsPageContainer.tsx +++ b/packages/twenty-front/src/modules/settings/components/SettingsPageContainer.tsx @@ -34,7 +34,7 @@ export const SettingsPageContainer = ({ }: { children: ReactNode; }) => ( - + {children} ); diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuItemsContainer.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuItemsContainer.tsx index 89c0cef0eae8..652e43f14826 100644 --- a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuItemsContainer.tsx +++ b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuItemsContainer.tsx @@ -45,7 +45,7 @@ export const DropdownMenuItemsContainer = ({ return ( {hasMaxHeight ? ( - + {children} diff --git a/packages/twenty-front/src/modules/ui/layout/page/ShowPageContainer.tsx b/packages/twenty-front/src/modules/ui/layout/page/ShowPageContainer.tsx index c241c44c0183..9a1aa473b987 100644 --- a/packages/twenty-front/src/modules/ui/layout/page/ShowPageContainer.tsx +++ b/packages/twenty-front/src/modules/ui/layout/page/ShowPageContainer.tsx @@ -32,7 +32,7 @@ export const ShowPageContainer = ({ children }: ShowPageContainerProps) => { const isMobile = useIsMobile(); return isMobile ? ( - + {children} diff --git a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageLeftContainer.tsx b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageLeftContainer.tsx index 402bc97dcd2c..2a000fe83aec 100644 --- a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageLeftContainer.tsx +++ b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageLeftContainer.tsx @@ -1,5 +1,5 @@ -import { ReactNode } from 'react'; import styled from '@emotion/styled'; +import { ReactNode } from 'react'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; @@ -46,7 +46,7 @@ export const ShowPageLeftContainer = ({ {children} ) : ( - + {children} diff --git a/packages/twenty-front/src/modules/ui/layout/tab/components/TabList.tsx b/packages/twenty-front/src/modules/ui/layout/tab/components/TabList.tsx index 120d5e720263..349c9cfe3edd 100644 --- a/packages/twenty-front/src/modules/ui/layout/tab/components/TabList.tsx +++ b/packages/twenty-front/src/modules/ui/layout/tab/components/TabList.tsx @@ -1,5 +1,5 @@ -import * as React from 'react'; import styled from '@emotion/styled'; +import * as React from 'react'; import { useRecoilValue } from 'recoil'; import { IconComponent } from 'twenty-ui'; @@ -53,7 +53,7 @@ export const TabList = ({ return ( - + {tabs .filter((tab) => !tab.hide) diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/components/ScrollWrapper.tsx b/packages/twenty-front/src/modules/ui/utilities/scroll/components/ScrollWrapper.tsx index 5f1f24d9069c..d4e5c2e79f78 100644 --- a/packages/twenty-front/src/modules/ui/utilities/scroll/components/ScrollWrapper.tsx +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/components/ScrollWrapper.tsx @@ -1,19 +1,18 @@ -import { createContext, RefObject, useEffect, useRef } from 'react'; import styled from '@emotion/styled'; import { OverlayScrollbars } from 'overlayscrollbars'; import { useOverlayScrollbars } from 'overlayscrollbars-react'; -import { useRecoilCallback, useSetRecoilState } from 'recoil'; +import { useEffect, useRef } from 'react'; +import { useSetRecoilState } from 'recoil'; +import { + ContextProviderName, + getContextByProviderName, +} from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts'; +import { useScrollStates } from '@/ui/utilities/scroll/hooks/internal/useScrollStates'; import { overlayScrollbarsState } from '@/ui/utilities/scroll/states/overlayScrollbarsState'; -import { scrollLeftState } from '@/ui/utilities/scroll/states/scrollLeftState'; -import { scrollTopState } from '@/ui/utilities/scroll/states/scrollTopState'; import 'overlayscrollbars/overlayscrollbars.css'; -export const ScrollWrapperContext = createContext>({ - current: null, -}); - const StyledScrollWrapper = styled.div` display: flex; height: 100%; @@ -29,6 +28,7 @@ export type ScrollWrapperProps = { className?: string; hideY?: boolean; hideX?: boolean; + contextProviderName: ContextProviderName; }; export const ScrollWrapper = ({ @@ -36,18 +36,21 @@ export const ScrollWrapper = ({ className, hideX, hideY, + contextProviderName, }: ScrollWrapperProps) => { const scrollableRef = useRef(null); + const Context = getContextByProviderName(contextProviderName); - const handleScroll = useRecoilCallback( - ({ set }) => - (overlayScroll: OverlayScrollbars) => { - const target = overlayScroll.elements().scrollOffsetElement; - set(scrollTopState, target.scrollTop); - set(scrollLeftState, target.scrollLeft); - }, - [], - ); + const { scrollTopComponentState, scrollLeftComponentState } = + useScrollStates(contextProviderName); + const setScrollTop = useSetRecoilState(scrollTopComponentState); + const setScrollLeft = useSetRecoilState(scrollLeftComponentState); + + const handleScroll = (overlayScroll: OverlayScrollbars) => { + const target = overlayScroll.elements().scrollOffsetElement; + setScrollTop(target.scrollTop); + setScrollLeft(target.scrollLeft); + }; const setOverlayScrollbars = useSetRecoilState(overlayScrollbarsState); @@ -75,10 +78,10 @@ export const ScrollWrapper = ({ }, [instance, setOverlayScrollbars]); return ( - + {children} - + ); }; diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/contexts/ScrollWrapperContexts.tsx b/packages/twenty-front/src/modules/ui/utilities/scroll/contexts/ScrollWrapperContexts.tsx new file mode 100644 index 000000000000..1141b336346e --- /dev/null +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/contexts/ScrollWrapperContexts.tsx @@ -0,0 +1,78 @@ +import { createContext, RefObject } from 'react'; + +type ScrollWrapperContextValue = { + ref: RefObject; + id: string; +}; + +export type ContextProviderName = + | 'eventList' + | 'commandMenu' + | 'recordBoard' + | 'recordTableWithWrappers' + | 'settingsPageContainer' + | 'dropdownMenuItemsContainer' + | 'showPageContainer' + | 'showPageLeftContainer' + | 'tabList' + | 'releases' + | 'test'; + +const createScrollWrapperContext = (id: string) => + createContext({ + ref: { current: null }, + id, + }); + +export const EventListScrollWrapperContext = + createScrollWrapperContext('eventList'); +export const CommandMenuScrollWrapperContext = + createScrollWrapperContext('commandMenu'); +export const RecordBoardScrollWrapperContext = + createScrollWrapperContext('recordBoard'); +export const RecordTableWithWrappersScrollWrapperContext = + createScrollWrapperContext('recordTableWithWrappers'); +export const SettingsPageContainerScrollWrapperContext = + createScrollWrapperContext('settingsPageContainer'); +export const DropdownMenuItemsContainerScrollWrapperContext = + createScrollWrapperContext('dropdownMenuItemsContainer'); +export const ShowPageContainerScrollWrapperContext = + createScrollWrapperContext('showPageContainer'); +export const ShowPageLeftContainerScrollWrapperContext = + createScrollWrapperContext('showPageLeftContainer'); +export const TabListScrollWrapperContext = + createScrollWrapperContext('tabList'); +export const ReleasesScrollWrapperContext = + createScrollWrapperContext('releases'); +export const TestScrollWrapperContext = createScrollWrapperContext('test'); + +export const getContextByProviderName = ( + contextProviderName: ContextProviderName, +) => { + switch (contextProviderName) { + case 'eventList': + return EventListScrollWrapperContext; + case 'commandMenu': + return CommandMenuScrollWrapperContext; + case 'recordBoard': + return RecordBoardScrollWrapperContext; + case 'recordTableWithWrappers': + return RecordTableWithWrappersScrollWrapperContext; + case 'settingsPageContainer': + return SettingsPageContainerScrollWrapperContext; + case 'dropdownMenuItemsContainer': + return DropdownMenuItemsContainerScrollWrapperContext; + case 'showPageContainer': + return ShowPageContainerScrollWrapperContext; + case 'showPageLeftContainer': + return ShowPageLeftContainerScrollWrapperContext; + case 'tabList': + return TabListScrollWrapperContext; + case 'releases': + return ReleasesScrollWrapperContext; + case 'test': + return TestScrollWrapperContext; + default: + throw new Error('Context Provider not available'); + } +}; diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/__tests__/useScrollWrapperScopedRef.test.tsx b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/__tests__/useScrollWrapperScopedRef.test.tsx index f525b47e8308..7048479e036f 100644 --- a/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/__tests__/useScrollWrapperScopedRef.test.tsx +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/__tests__/useScrollWrapperScopedRef.test.tsx @@ -12,7 +12,7 @@ jest.mock('react', () => { describe('useScrollWrapperScopedRef', () => { it('should return the scrollWrapperRef if available', () => { - const { result } = renderHook(() => useScrollWrapperScopedRef()); + const { result } = renderHook(() => useScrollWrapperScopedRef('test')); expect(result.current).toBeDefined(); }); diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/internal/useScrollStates.ts b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/internal/useScrollStates.ts new file mode 100644 index 000000000000..769a17d493d5 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/internal/useScrollStates.ts @@ -0,0 +1,32 @@ +import { + ContextProviderName, + getContextByProviderName, +} from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts'; +import { scrollLeftComponentState } from '@/ui/utilities/scroll/states/scrollLeftComponentState'; +import { scrollTopComponentState } from '@/ui/utilities/scroll/states/scrollTopComponentState'; + +import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; + +import { useContext } from 'react'; + +export const useScrollStates = (contextProviderName: ContextProviderName) => { + const Context = getContextByProviderName(contextProviderName); + const context = useContext(Context); + + if (!context) { + throw new Error('Context not found'); + } + + const { id: scopeId } = context; + + return { + scrollLeftComponentState: extractComponentState( + scrollLeftComponentState, + scopeId, + ), + scrollTopComponentState: extractComponentState( + scrollTopComponentState, + scopeId, + ), + }; +}; diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useScrollLeftValue.ts b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useScrollLeftValue.ts new file mode 100644 index 000000000000..e8ea24cfb323 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useScrollLeftValue.ts @@ -0,0 +1,10 @@ +import { ContextProviderName } from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts'; +import { useScrollStates } from '@/ui/utilities/scroll/hooks/internal/useScrollStates'; +import { useRecoilValue } from 'recoil'; + +export const useScrollLeftValue = ( + contextProviderName: ContextProviderName, +) => { + const { scrollLeftComponentState } = useScrollStates(contextProviderName); + return useRecoilValue(scrollLeftComponentState); +}; diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useScrollTopValue.ts b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useScrollTopValue.ts new file mode 100644 index 000000000000..926d72b00ae7 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useScrollTopValue.ts @@ -0,0 +1,8 @@ +import { ContextProviderName } from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts'; +import { useScrollStates } from '@/ui/utilities/scroll/hooks/internal/useScrollStates'; +import { useRecoilValue } from 'recoil'; + +export const useScrollTopValue = (contextProviderName: ContextProviderName) => { + const { scrollTopComponentState } = useScrollStates(contextProviderName); + return useRecoilValue(scrollTopComponentState); +}; diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useScrollWrapperScopedRef.ts b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useScrollWrapperScopedRef.ts index bbbeecf07059..bc1012c82403 100644 --- a/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useScrollWrapperScopedRef.ts +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/hooks/useScrollWrapperScopedRef.ts @@ -2,10 +2,16 @@ import { useContext } from 'react'; import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; -import { ScrollWrapperContext } from '../components/ScrollWrapper'; +import { + ContextProviderName, + getContextByProviderName, +} from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts'; -export const useScrollWrapperScopedRef = () => { - const scrollWrapperRef = useContext(ScrollWrapperContext); +export const useScrollWrapperScopedRef = ( + contextProviderName: ContextProviderName, +) => { + const Context = getContextByProviderName(contextProviderName); + const scrollWrapperRef = useContext(Context); if (isUndefinedOrNull(scrollWrapperRef)) throw new Error( diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollLeftComponentState.ts b/packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollLeftComponentState.ts new file mode 100644 index 000000000000..1e125cd27bcb --- /dev/null +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollLeftComponentState.ts @@ -0,0 +1,6 @@ +import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; + +export const scrollLeftComponentState = createComponentState({ + key: 'scroll/scrollLeftComponentState', + defaultValue: 0, +}); 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 deleted file mode 100644 index e8acb2be3788..000000000000 --- a/packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollLeftState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createState } from 'twenty-ui'; - -export const scrollLeftState = createState({ - key: 'scroll/scrollLeftState', - defaultValue: 0, -}); diff --git a/packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollTopComponentState.ts b/packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollTopComponentState.ts new file mode 100644 index 000000000000..2bc2365d8e58 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollTopComponentState.ts @@ -0,0 +1,6 @@ +import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; + +export const scrollTopComponentState = createComponentState({ + key: 'scroll/scrollTopComponentState', + defaultValue: 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 deleted file mode 100644 index fdf4a8de154a..000000000000 --- a/packages/twenty-front/src/modules/ui/utilities/scroll/states/scrollTopState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createState } from 'twenty-ui'; - -export const scrollTopState = createState({ - key: 'scroll/scrollTopState', - defaultValue: 0, -}); diff --git a/packages/twenty-front/src/pages/settings/Releases.tsx b/packages/twenty-front/src/pages/settings/Releases.tsx index 72d9732b7ebb..a775bf2466ee 100644 --- a/packages/twenty-front/src/pages/settings/Releases.tsx +++ b/packages/twenty-front/src/pages/settings/Releases.tsx @@ -111,7 +111,7 @@ export const Releases = () => { - + {releases.map((release) => (