Files
twenty/packages/twenty-front/src/modules/ui/utilities/scroll/components/ScrollWrapper.tsx
gitstart-app[bot] 0e525caf01 Implement <ScrollRestoration /> (#5086)
### Description

Implement &lt;ScrollRestoration /&gt;

### Refs


[https://github.com/twentyhq/twenty/issues/4357](https://github.com/twentyhq/twenty/issues/4183)

### Demo


https://github.com/twentyhq/twenty/assets/140154534/321242e1-4751-4204-8c86-e9b921c1733e

Fixes #4357

---------

Co-authored-by: gitstart-twenty <gitstart-twenty@users.noreply.github.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: v1b3m <vibenjamin6@gmail.com>
Co-authored-by: RubensRafael <rubensrafael2@live.com>
2024-05-17 16:36:28 +02:00

85 lines
2.2 KiB
TypeScript

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 { 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<RefObject<HTMLDivElement>>({
current: null,
});
const StyledScrollWrapper = styled.div`
display: flex;
height: 100%;
width: 100%;
.os-scrollbar-handle {
background-color: ${({ theme }) => theme.border.color.medium};
}
`;
export type ScrollWrapperProps = {
children: React.ReactNode;
className?: string;
hideY?: boolean;
hideX?: boolean;
};
export const ScrollWrapper = ({
children,
className,
hideX,
hideY,
}: ScrollWrapperProps) => {
const scrollableRef = useRef<HTMLDivElement>(null);
const handleScroll = useRecoilCallback(
({ set }) =>
(overlayScroll: OverlayScrollbars) => {
const target = overlayScroll.elements().scrollOffsetElement;
set(scrollTopState, target.scrollTop);
set(scrollLeftState, target.scrollLeft);
},
[],
);
const setOverlayScrollbars = useSetRecoilState(overlayScrollbarsState);
const [initialize, instance] = useOverlayScrollbars({
options: {
scrollbars: { autoHide: 'scroll' },
overflow: {
y: hideY ? 'hidden' : undefined,
x: hideX ? 'hidden' : undefined,
},
},
events: {
scroll: handleScroll,
},
});
useEffect(() => {
if (scrollableRef?.current !== null) {
initialize(scrollableRef.current);
}
}, [initialize, scrollableRef]);
useEffect(() => {
setOverlayScrollbars(instance());
}, [instance, setOverlayScrollbars]);
return (
<ScrollWrapperContext.Provider value={scrollableRef}>
<StyledScrollWrapper ref={scrollableRef} className={className}>
{children}
</StyledScrollWrapper>
</ScrollWrapperContext.Provider>
);
};