import { CSSProperties, useCallback, useRef } from "react"; import { DragDropContext, Draggable, DraggableProvided, DropResult, Droppable } from "react-beautiful-dnd"; import { ListChildComponentProps, VariableSizeList } from "react-window"; import { cn } from "renderer/helpers/css-class.helpers"; import { useObserveSize } from "renderer/hooks/use-observe-size.hook"; import equal from "fast-deep-equal"; import { typedMemo } from "renderer/helpers/typed-memo"; type DraggableVirtualScrollClassNames = { mainDiv?: string; variableList?: string; rows?: string; } type Props = { className?: string; classNames?: DraggableVirtualScrollClassNames; itemHeight: number; items: T[]; isDragDisabled?: boolean; renderItem: (item: T) => JSX.Element; onDragEnd?: (fromIndex: number, toIndex: number) => void; } export function DraggableVirtualScroll({ className, classNames, items, itemHeight, isDragDisabled, renderItem, onDragEnd }: Props) { const ref = useRef(null); const { height } = useObserveSize({ ref, debounce: 100 }); const handleOnDragEnd = useCallback((result: DropResult) => { if(!onDragEnd){ return; } if (!result.destination || result.destination.index === result.source.index) { return; } onDragEnd(result.source.index, result.destination.index); }, [onDragEnd]); const renderDraggedItem = useCallback((renderItem: (item: T) => JSX.Element, itemProps: T, provided: DraggableProvided) => { return (
{renderItem(itemProps)}
) }, [renderItem]); const renderRow = useCallback((props: ListChildComponentProps) => { return ( ) }, [renderItem, isDragDisabled]); return (
{ return renderDraggedItem(renderItem, items[rubric.source.index], provided) }}> {provided => ( itemHeight} itemData={items} style={{ scrollbarGutter: "stable both-edges" }} direction="vertical" > {renderRow} )}
) } type DraggableRowProps = { className?: string; style?: CSSProperties; item: T; index: number; isDragDisabled?: boolean; renderItem: (item: T) => JSX.Element; } function DraggableRowComponent({ item, renderItem, className, style, index, isDragDisabled }: DraggableRowProps) { const innerRender = useCallback((provided: DraggableProvided) => { return (
{renderItem(item)}
) }, [item]); return ( {innerRender} ) } const DraggableRow = typedMemo(DraggableRowComponent, equal);