Refacto scroll + Aggregate queries for view groups (#9089)
Closes https://github.com/twentyhq/private-issues/issues/217. Refactoring scroll not to cause table-wide re-render when opening a dropdown (triggering a scroll lock) in the table.
This commit is contained in:
@ -1,9 +1,10 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useLocation, useNavigation } from 'react-router-dom';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { useNavigation } from 'react-router-dom';
|
||||
|
||||
import { overlayScrollbarsState } from '@/ui/utilities/scroll/states/overlayScrollbarsState';
|
||||
import { scrollPositionState } from '@/ui/utilities/scroll/states/scrollPositionState';
|
||||
import { scrollWrapperInstanceComponentState } from '@/ui/utilities/scroll/states/scrollWrapperInstanceComponentState';
|
||||
import { scrollWrapperScrollTopComponentState } from '@/ui/utilities/scroll/states/scrollWrapperScrollTopComponentState';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
/**
|
||||
@ -13,23 +14,24 @@ import { isDefined } from '~/utils/isDefined';
|
||||
* not share the same scroll position.
|
||||
*/
|
||||
export const useScrollRestoration = (viewportHeight?: number) => {
|
||||
const key = `scroll-position-${useLocation().key}`;
|
||||
const { state } = useNavigation();
|
||||
|
||||
const [scrollPosition, setScrollPosition] = useRecoilState(
|
||||
scrollPositionState(key),
|
||||
const [scrollTop, setScrollTop] = useRecoilComponentStateV2(
|
||||
scrollWrapperScrollTopComponentState,
|
||||
);
|
||||
|
||||
const overlayScrollbars = useRecoilValue(overlayScrollbarsState);
|
||||
const overlayScrollbars = useRecoilComponentValueV2(
|
||||
scrollWrapperInstanceComponentState,
|
||||
);
|
||||
|
||||
const scrollWrapper = overlayScrollbars?.elements().viewport;
|
||||
const skip = isDefined(viewportHeight) && scrollPosition > viewportHeight;
|
||||
const skip = isDefined(viewportHeight) && scrollTop > viewportHeight;
|
||||
|
||||
useEffect(() => {
|
||||
if (state === 'loading') {
|
||||
setScrollPosition(scrollWrapper?.scrollTop ?? 0);
|
||||
setScrollTop(scrollWrapper?.scrollTop ?? 0);
|
||||
} else if (state === 'idle' && isDefined(scrollWrapper) && !skip) {
|
||||
scrollWrapper.scrollTo({ top: scrollPosition });
|
||||
scrollWrapper.scrollTo({ top: scrollTop });
|
||||
}
|
||||
}, [key, state, scrollWrapper, skip, scrollPosition, setScrollPosition]);
|
||||
}, [state, scrollWrapper, skip, scrollTop, setScrollTop]);
|
||||
};
|
||||
|
||||
@ -1,19 +1,24 @@
|
||||
import { overlayScrollbarsState } from '@/ui/utilities/scroll/states/overlayScrollbarsState';
|
||||
import { scrollWrapperInstanceComponentState } from '@/ui/utilities/scroll/states/scrollWrapperInstanceComponentState';
|
||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
export const useScrollToPosition = () => {
|
||||
const scrollWrapperInstanceState = useRecoilComponentCallbackStateV2(
|
||||
scrollWrapperInstanceComponentState,
|
||||
);
|
||||
|
||||
const scrollToPosition = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
(scrollPositionInPx: number) => {
|
||||
const overlayScrollbars = snapshot
|
||||
.getLoadable(overlayScrollbarsState)
|
||||
.getLoadable(scrollWrapperInstanceState)
|
||||
.getValue();
|
||||
|
||||
const scrollWrapper = overlayScrollbars?.elements().viewport;
|
||||
|
||||
scrollWrapper?.scrollTo({ top: scrollPositionInPx });
|
||||
},
|
||||
[],
|
||||
[scrollWrapperInstanceState],
|
||||
);
|
||||
|
||||
return { scrollToPosition };
|
||||
|
||||
Reference in New Issue
Block a user