From 797f2c83d6f97db2b60565b94fce775703d3c678 Mon Sep 17 00:00:00 2001 From: Aleksandr Lushkin Date: Fri, 30 Aug 2024 16:30:35 +0200 Subject: [PATCH] Client: DropDown: Draft navigation variant --- .../shared/components/drop-down/DropDown.tsx | 1 + .../components/drop-down/DropDown.types.ts | 1 + .../drop-down/sub-components/VirtualList.tsx | 93 +++++++++++++------ 3 files changed, 68 insertions(+), 27 deletions(-) diff --git a/packages/shared/components/drop-down/DropDown.tsx b/packages/shared/components/drop-down/DropDown.tsx index 9acff7a8d9..6d7be6dec2 100644 --- a/packages/shared/components/drop-down/DropDown.tsx +++ b/packages/shared/components/drop-down/DropDown.tsx @@ -433,6 +433,7 @@ const DropDown = ({ getItemSize={getItemSize} isOpen={open || false} enableKeyboardEvents={enableKeyboardEvents || false} + isDropdownReady={state.isDropdownReady} > {children} diff --git a/packages/shared/components/drop-down/DropDown.types.ts b/packages/shared/components/drop-down/DropDown.types.ts index 50b5d0877c..cb4eefb9ad 100644 --- a/packages/shared/components/drop-down/DropDown.types.ts +++ b/packages/shared/components/drop-down/DropDown.types.ts @@ -101,6 +101,7 @@ export interface VirtualListProps { >; enableKeyboardEvents: boolean; getItemSize: (index: number) => number; + isDropdownReady: boolean; } export interface RowProps { diff --git a/packages/shared/components/drop-down/sub-components/VirtualList.tsx b/packages/shared/components/drop-down/sub-components/VirtualList.tsx index 819c98f7ab..9c6e682f02 100644 --- a/packages/shared/components/drop-down/sub-components/VirtualList.tsx +++ b/packages/shared/components/drop-down/sub-components/VirtualList.tsx @@ -50,14 +50,16 @@ function VirtualList({ isNoFixedHeightOptions, getItemSize, enableKeyboardEvents, + isDropdownReady, }: VirtualListProps) { const ref = useRef(null); + const focusTrapRef = useRef(null); const activeIndex = useMemo(() => { let foundIndex = -1; React.Children.forEach(cleanChildren, (child, index) => { const props = child && React.isValidElement(child) && child.props; - if (props?.disabled) foundIndex = index; + if (props?.isSelected) foundIndex = index; }); return foundIndex; }, [cleanChildren]); @@ -67,9 +69,10 @@ function VirtualList({ const onKeyDown = useCallback( (event: KeyboardEvent) => { - if (!ref.current || !isOpen) return; + if (!focusTrapRef.current || !isOpen) return; event.preventDefault(); + event.stopPropagation(); let index = currentIndexRef.current; @@ -96,26 +99,27 @@ function VirtualList({ setCurrentIndex(index); currentIndexRef.current = index; - ref.current.scrollToItem(index, "smart"); + // ref.current.scrollToItem(index, "smart"); }, [isOpen, children], ); useEffect(() => { - if (isOpen && maxHeight && enableKeyboardEvents) { - window.addEventListener("keydown", onKeyDown); + if (isOpen && isDropdownReady && enableKeyboardEvents) { + focusTrapRef.current?.focus(); + focusTrapRef.current?.addEventListener("keydown", onKeyDown); } const refVar = ref.current; return () => { - window.removeEventListener("keydown", onKeyDown); + focusTrapRef.current?.removeEventListener("keydown", onKeyDown); if (itemCount > 0 && refVar) { setCurrentIndex(activeIndex); currentIndexRef.current = activeIndex; - refVar.scrollToItem(activeIndex, "smart"); + // refVar.scrollToItem(activeIndex, "smart"); } }; }, [ @@ -126,6 +130,7 @@ function VirtualList({ children, onKeyDown, itemCount, + isDropdownReady, ]); const handleMouseMove = useCallback((index: number) => { @@ -135,28 +140,62 @@ function VirtualList({ currentIndexRef.current = index; }, []); - if (!maxHeight) return cleanChildren || children; + const items = cleanChildren || children; - return isNoFixedHeightOptions ? ( - {cleanChildren} - ) : ( - + {items?.map((item, index) => ( + + ))} + + ); + + return ( +
- {Row} - + {isNoFixedHeightOptions ? ( + {cleanChildren} + ) : ( + + {Row} + + )} +
); }