Files
twenty/packages/twenty-front/src/modules/ui/utilities/scroll/components/ScrollWrapper.tsx
Charles Bochet b6e344e7be Various fixes (#11448)
# Scrollbar fix

Fixes https://github.com/twentyhq/twenty/issues/11403

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/b13fe0f2-8c61-4ea8-9ea1-e61e571a90da"
/>

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-04-09 01:03:43 +02:00

81 lines
2.5 KiB
TypeScript

import styled from '@emotion/styled';
import { ScrollWrapperInitEffect } from '@/ui/utilities/scroll/components/internal/ScrollWrapperInitEffect';
import { ScrollWrapperComponentInstanceContext } from '@/ui/utilities/scroll/states/contexts/ScrollWrapperComponentInstanceContext';
import { scrollWrapperScrollBottomComponentState } from '@/ui/utilities/scroll/states/scrollWrapperScrollBottomComponentState';
import { scrollWrapperScrollLeftComponentState } from '@/ui/utilities/scroll/states/scrollWrapperScrollLeftComponentState';
import { scrollWrapperScrollTopComponentState } from '@/ui/utilities/scroll/states/scrollWrapperScrollTopComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
const StyledScrollWrapper = styled.div`
&.scroll-wrapper-x-enabled {
overflow-x: overlay;
}
&.scroll-wrapper-y-enabled {
overflow-y: overlay;
}
overflow-x: hidden;
overflow-y: hidden;
display: flex;
width: 100%;
height: 100%;
`;
export type ScrollWrapperProps = {
children: React.ReactNode;
className?: string;
defaultEnableXScroll?: boolean;
defaultEnableYScroll?: boolean;
componentInstanceId: string;
};
export const ScrollWrapper = ({
componentInstanceId,
children,
className,
defaultEnableXScroll = true,
defaultEnableYScroll = true,
}: ScrollWrapperProps) => {
const setScrollTop = useSetRecoilComponentStateV2(
scrollWrapperScrollTopComponentState,
componentInstanceId,
);
const setScrollLeft = useSetRecoilComponentStateV2(
scrollWrapperScrollLeftComponentState,
componentInstanceId,
);
const setScrollBottom = useSetRecoilComponentStateV2(
scrollWrapperScrollBottomComponentState,
componentInstanceId,
);
const handleScroll = (event: React.UIEvent<HTMLDivElement>) => {
const target = event.currentTarget;
setScrollTop(target.scrollTop);
setScrollLeft(target.scrollLeft);
setScrollBottom(
target.scrollHeight - target.clientHeight - target.scrollTop,
);
};
return (
<ScrollWrapperComponentInstanceContext.Provider
value={{ instanceId: componentInstanceId }}
>
<ScrollWrapperInitEffect
defaultEnableXScroll={defaultEnableXScroll}
defaultEnableYScroll={defaultEnableYScroll}
/>
<StyledScrollWrapper
id={`scroll-wrapper-${componentInstanceId}`}
className={className}
onScroll={handleScroll}
>
{children}
</StyledScrollWrapper>
</ScrollWrapperComponentInstanceContext.Provider>
);
};