import React, { NamedExoticComponent, ReactElement, useCallback, useEffect, useMemo, useRef, useState, } from "react"; import { VariableSizeList } from "react-window"; import Scrollbar from "@docspace/components/scrollbar"; import CustomScrollbarsVirtualList from "../scrollbar/custom-scrollbars-virtual-list"; type VirtualListProps = { width: number; theme: unknown; isOpen: boolean; itemCount: number; maxHeight: number; calculatedHeight: number; isNoFixedHeightOptions: boolean; cleanChildren: ReactElement[]; children: ReactElement[]; Row: NamedExoticComponent; enableKeyboardEvents: boolean; getItemSize: (index: number) => number; }; function VirtualList({ Row, width, theme, isOpen, children, itemCount, maxHeight, cleanChildren, calculatedHeight, isNoFixedHeightOptions, getItemSize, enableKeyboardEvents, }: VirtualListProps) { const ref = useRef(null); const activeIndex = useMemo(() => { let foundIndex = -1; React.Children.forEach(cleanChildren, (child, index) => { if (child.props.disabled) foundIndex = index; }); return foundIndex; }, [cleanChildren]); const [currentIndex, setCurrentIndex] = useState(activeIndex); const currentIndexRef = useRef(activeIndex); useEffect(() => { if (isOpen && maxHeight && enableKeyboardEvents) { window.addEventListener("keydown", onKeyDown); } return () => { window.removeEventListener("keydown", onKeyDown); if (itemCount > 0 && ref.current) { setCurrentIndex(activeIndex); currentIndexRef.current = activeIndex; ref.current.scrollToItem(activeIndex, "smart"); } }; }, [isOpen, activeIndex, maxHeight, enableKeyboardEvents, children]); const onKeyDown = useCallback( (event: KeyboardEvent) => { if (!ref.current || !isOpen) return; event.preventDefault(); let index = currentIndexRef.current; switch (event.code) { case "ArrowDown": index++; break; case "ArrowUp": index--; break; case "Enter": return children[index]?.props?.onClick(); default: return; } if (index < 0 || index >= React.Children.count(children)) return; setCurrentIndex(index); currentIndexRef.current = index; ref.current.scrollToItem(index, "smart"); }, [isOpen, children] ); const handleMouseMove = useCallback((index: number) => { if (currentIndexRef.current === index) return; setCurrentIndex(index); currentIndexRef.current = index; }, []); if (!maxHeight) return cleanChildren ? cleanChildren : children; return ( <> {isNoFixedHeightOptions ? ( //@ts-ignore {cleanChildren} ) : ( {Row} )} ); } export default VirtualList;