Skip to content

Commit

Permalink
fix(ui): dnd autoscroll on elements w/ custom scrollbar
Browse files Browse the repository at this point in the history
Have to do a bit of fanagling to get it to work and get `pragmatic-drag-and-drop` to not complain.
  • Loading branch information
psychedelicious committed Nov 7, 2024
1 parent c0c5997 commit 093b6d1
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,27 +1,52 @@
import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element';
import { autoScrollForExternal } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/external';
import type { ChakraProps } from '@invoke-ai/ui-library';
import { Box, Flex } from '@invoke-ai/ui-library';
import { getOverlayScrollbarsParams } from 'common/components/OverlayScrollbars/constants';
import type { OverlayScrollbarsComponentRef } from 'overlayscrollbars-react';
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
import type { CSSProperties, PropsWithChildren } from 'react';
import { memo, useMemo } from 'react';
import { memo, useEffect, useMemo, useState } from 'react';

type Props = PropsWithChildren & {
maxHeight?: ChakraProps['maxHeight'];
overflowX?: 'hidden' | 'scroll';
overflowY?: 'hidden' | 'scroll';
};

const styles: CSSProperties = { height: '100%', width: '100%' };
const styles: CSSProperties = { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 };

const ScrollableContent = ({ children, maxHeight, overflowX = 'hidden', overflowY = 'scroll' }: Props) => {
const overlayscrollbarsOptions = useMemo(
() => getOverlayScrollbarsParams(overflowX, overflowY).options,
[overflowX, overflowY]
);
const [os, osRef] = useState<OverlayScrollbarsComponentRef | null>(null);
useEffect(() => {
const osInstance = os?.osInstance();

if (!osInstance) {
return;
}

const element = osInstance.elements().viewport;

// `pragmatic-drag-and-drop-auto-scroll` requires the element to have `overflow-y: scroll` or `overflow-y: auto`
// else it logs an ugly warning. In our case, using a custom scrollbar library, it will be 'hidden' by default.
// To prevent the erroneous warning, we temporarily set the overflow-y to 'scroll' and then revert it back.
const overflowY = element.style.overflowY; // starts 'hidden'
element.style.setProperty('overflow-y', 'scroll', 'important');
const cleanup = combine(autoScrollForElements({ element }), autoScrollForExternal({ element }));
element.style.setProperty('overflow-y', overflowY);

return cleanup;
}, [os]);

return (
<Flex w="full" h="full" maxHeight={maxHeight} position="relative">
<Box position="absolute" top={0} left={0} right={0} bottom={0}>
<OverlayScrollbarsComponent defer style={styles} options={overlayscrollbarsOptions}>
<OverlayScrollbarsComponent ref={osRef} style={styles} options={overlayscrollbarsOptions}>
{children}
</OverlayScrollbarsComponent>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,23 @@ const BoardsListWrapper = () => {
const allowPrivateBoards = useAppSelector(selectAllowPrivateBoards);
const [os, osRef] = useState<OverlayScrollbarsComponentRef | null>(null);
useEffect(() => {
const element = os?.osInstance()?.elements().viewport;
if (!element) {
const osInstance = os?.osInstance();

if (!osInstance) {
return;
}
return combine(autoScrollForElements({ element }), autoScrollForExternal({ element }));

const element = osInstance.elements().viewport;

// `pragmatic-drag-and-drop-auto-scroll` requires the element to have `overflow-y: scroll` or `overflow-y: auto`
// else it logs an ugly warning. In our case, using a custom scrollbar library, it will be 'hidden' by default.
// To prevent the erroneous warning, we temporarily set the overflow-y to 'scroll' and then revert it back.
const overflowY = element.style.overflowY; // starts 'hidden'
element.style.setProperty('overflow-y', 'scroll', 'important');
const cleanup = combine(autoScrollForElements({ element }), autoScrollForExternal({ element }));
element.style.setProperty('overflow-y', overflowY);

return cleanup;
}, [os]);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const WorkflowLinearTab = () => {
return (
<Box position="relative" w="full" h="full">
<ScrollableContent>
<Flex position="relative" flexDir="column" alignItems="flex-start" p={1} gap={2} h="full" w="full">
<Flex position="relative" flexDir="column" alignItems="flex-start" p={1} py={2} gap={2} h="full" w="full">
<FieldListContent />
</Flex>
</ScrollableContent>
Expand Down

0 comments on commit 093b6d1

Please sign in to comment.