Skip to content

Commit

Permalink
fix: poc with overlayscrollbars
Browse files Browse the repository at this point in the history
  • Loading branch information
dougfabris committed Oct 25, 2024
1 parent e04a112 commit 9f92f88
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 61 deletions.
103 changes: 54 additions & 49 deletions apps/meteor/client/components/CustomScrollbars/CustomScrollbars.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,65 @@
import { Palette } from '@rocket.chat/fuselage';
import type { ScrollValues } from 'rc-scrollbars';
import { Scrollbars } from 'rc-scrollbars';
import type { MutableRefObject, CSSProperties, ReactNode } from 'react';
import React, { memo, forwardRef, useCallback, useMemo } from 'react';
import { css } from '@rocket.chat/css-in-js';
import { Box, Palette } from '@rocket.chat/fuselage';
import { useMergedRefs } from '@rocket.chat/fuselage-hooks';
import { useOverlayScrollbars } from 'overlayscrollbars-react';
import type { HTMLAttributes, ReactElement } from 'react';
import React, { useEffect, useState, useRef, cloneElement, forwardRef, memo } from 'react';

export type CustomScrollbarsProps = {
import 'overlayscrollbars/styles/overlayscrollbars.css';

type CustomScrollbarsProps = {
children: ReactElement;
virtualized?: boolean;
overflowX?: boolean;
style?: CSSProperties;
children?: ReactNode;
onScroll?: (values: ScrollValues) => void;
renderView?: typeof Scrollbars.defaultProps.renderView;
renderTrackHorizontal?: typeof Scrollbars.defaultProps.renderTrackHorizontal;
autoHide?: boolean;
};

const styleDefault: CSSProperties = {
flexGrow: 1,
overflowY: 'hidden',
};

const CustomScrollbars = forwardRef<HTMLElement, CustomScrollbarsProps>(function CustomScrollbars(
{ children, style, onScroll, overflowX, renderView, ...props },
} & Omit<HTMLAttributes<HTMLDivElement>, 'is'>;

const CustomScrollbars = forwardRef<HTMLElement, CustomScrollbarsProps>(function Virtualized(
{ virtualized = false, overflowX, ...props },
ref,
) {
const scrollbarsStyle = useMemo(() => ({ ...style, ...styleDefault }), [style]);

const refSetter = useCallback(
(scrollbarRef) => {
if (ref && scrollbarRef) {
if (typeof ref === 'function') {
ref(scrollbarRef.view ?? null);
return;
}
const rootRef = useRef(null);
const mergedRefs = useMergedRefs(rootRef, ref);
const [scroller, setScroller] = useState(null);
const [initialize, osInstance] = useOverlayScrollbars({
options: { scrollbars: { autoHide: 'scroll' }, overflow: { x: overflowX ? 'scroll' : 'hidden' } },
defer: true,
});

(ref as MutableRefObject<HTMLElement | undefined>).current = scrollbarRef.view;
}
},
[ref],
);
useEffect(() => {
const { current: root } = rootRef;

if (scroller && root) {
return initialize({
target: root,
elements: {
viewport: scroller,
},
});
}

if (root) {
initialize(root);
}

return () => osInstance()?.destroy();
}, [scroller, initialize, osInstance]);

return (
<Scrollbars
<Box
className={css`
.os-scrollbar {
--os-handle-bg: ${Palette.stroke['stroke-dark']};
--os-handle-bg-hover: ${Palette.stroke['stroke-dark']};
--os-handle-bg-active: ${Palette.stroke['stroke-dark']};
}
`}
height='full'
data-overlayscrollbars-initialize=''
ref={mergedRefs}
{...props}
autoHide
autoHideTimeout={2000}
autoHideDuration={500}
style={scrollbarsStyle}
onScrollFrame={onScroll}
renderView={renderView}
renderTrackHorizontal={overflowX ? undefined : (props) => <div {...props} className='track-horizontal' style={{ display: 'none' }} />}
renderThumbVertical={({ style, ...props }) => (
<div {...props} style={{ ...style, backgroundColor: Palette.stroke['stroke-dark'].toString(), borderRadius: '4px' }} />
)}
children={children}
ref={refSetter}
/>
>
{cloneElement(props.children, virtualized ? { scrollerRef: setScroller } : undefined)}
</Box>
);
});

Expand Down
6 changes: 2 additions & 4 deletions apps/meteor/client/components/Page/PageScrollableContent.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import type { Scrollable } from '@rocket.chat/fuselage';
import { Box } from '@rocket.chat/fuselage';
import type { ComponentProps } from 'react';
import React, { forwardRef } from 'react';

import type { CustomScrollbarsProps } from '../CustomScrollbars';
import { CustomScrollbars } from '../CustomScrollbars';

type PageScrollableContentProps = {
onScrollContent?: ComponentProps<typeof Scrollable>['onScrollContent'];
onScrollContent?: ComponentProps<typeof CustomScrollbars>['onScroll'];
} & ComponentProps<typeof Box>;

const PageScrollableContent = forwardRef<HTMLElement, PageScrollableContentProps>(function PageScrollableContent(
Expand All @@ -24,7 +22,7 @@ const PageScrollableContent = forwardRef<HTMLElement, PageScrollableContentProps
overflow='hidden'
borderBlockEndColor={borderBlockEndColor}
>
<CustomScrollbars onScroll={onScrollContent as CustomScrollbarsProps['onScroll']} ref={ref}>
<CustomScrollbars onScroll={onScrollContent} ref={ref}>
<Box paddingBlock={16} paddingInline={24} display='flex' flexDirection='column' {...props} />
</CustomScrollbars>
</Box>
Expand Down
21 changes: 13 additions & 8 deletions apps/meteor/client/sidebar/RoomList/RoomList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { Virtuoso } from 'react-virtuoso';

import { VirtuosoScrollbars } from '../../components/CustomScrollbars';
import { CustomScrollbars } from '../../components/CustomScrollbars';
import { useOpenedRoom } from '../../lib/RoomManager';
import { useAvatarTemplate } from '../hooks/useAvatarTemplate';
import { usePreventDefault } from '../hooks/usePreventDefault';
Expand Down Expand Up @@ -121,13 +121,18 @@ const RoomList = (): ReactElement => {
return (
<Box className={[roomsListStyle, 'sidebar--custom-colors'].filter(Boolean)}>
<Box h='full' w='full' ref={ref}>
<Virtuoso
totalCount={roomsList.length}
data={roomsList}
components={{ Item: RoomListRowWrapper, List: RoomListWrapper, Scroller: VirtuosoScrollbars }}
computeItemKey={computeItemKey}
itemContent={(_, data): ReactElement => <RoomListRow data={itemData} item={data} />}
/>
<CustomScrollbars virtualized>
<Virtuoso
totalCount={roomsList.length}
data={roomsList}
components={{
Item: RoomListRowWrapper,
List: RoomListWrapper,
}}
computeItemKey={computeItemKey}
itemContent={(_, data): ReactElement => <RoomListRow data={itemData} item={data} />}
/>
</CustomScrollbars>
</Box>
</Box>
);
Expand Down
2 changes: 2 additions & 0 deletions apps/meteor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,8 @@
"nodemailer": "^6.9.15",
"oauth2-server": "3.1.1",
"object-path": "^0.11.8",
"overlayscrollbars": "^2.10.0",
"overlayscrollbars-react": "^0.5.6",
"path": "^0.12.7",
"path-to-regexp": "^6.3.0",
"pdfjs-dist": "^2.16.105",
Expand Down
19 changes: 19 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9227,6 +9227,8 @@ __metadata:
oauth2-server: "npm:3.1.1"
object-path: "npm:^0.11.8"
outdent: "npm:~0.8.0"
overlayscrollbars: "npm:^2.10.0"
overlayscrollbars-react: "npm:^0.5.6"
path: "npm:^0.12.7"
path-to-regexp: "npm:^6.3.0"
pdfjs-dist: "npm:^2.16.105"
Expand Down Expand Up @@ -29820,6 +29822,23 @@ __metadata:
languageName: node
linkType: hard

"overlayscrollbars-react@npm:^0.5.6":
version: 0.5.6
resolution: "overlayscrollbars-react@npm:0.5.6"
peerDependencies:
overlayscrollbars: ^2.0.0
react: ">=16.8.0"
checksum: 10/473f5af860feab4b5418f9adc8e356fb201e9de61286443ff64002b9c997bc19bf17cf60e314c502c14ca41fa213c12f18111e6fe913be86ad68a15c32e66789
languageName: node
linkType: hard

"overlayscrollbars@npm:^2.10.0":
version: 2.10.0
resolution: "overlayscrollbars@npm:2.10.0"
checksum: 10/d9bc907d722f730f17b2ff6fd678ae6679edd677c431c876bde918838f4a3e08d75bdeec62a9b018d29c0e14c8287277612a2a5cab73afcced4769f1bcb74cfd
languageName: node
linkType: hard

"ow@npm:^0.17.0":
version: 0.17.0
resolution: "ow@npm:0.17.0"
Expand Down

0 comments on commit 9f92f88

Please sign in to comment.