Client: DropDown: Draft navigation variant

This commit is contained in:
Aleksandr Lushkin 2024-08-30 16:30:35 +02:00
parent eac40356c7
commit 797f2c83d6
3 changed files with 68 additions and 27 deletions

View File

@ -433,6 +433,7 @@ const DropDown = ({
getItemSize={getItemSize}
isOpen={open || false}
enableKeyboardEvents={enableKeyboardEvents || false}
isDropdownReady={state.isDropdownReady}
>
{children}
</VirtualList>

View File

@ -101,6 +101,7 @@ export interface VirtualListProps {
>;
enableKeyboardEvents: boolean;
getItemSize: (index: number) => number;
isDropdownReady: boolean;
}
export interface RowProps {

View File

@ -50,14 +50,16 @@ function VirtualList({
isNoFixedHeightOptions,
getItemSize,
enableKeyboardEvents,
isDropdownReady,
}: VirtualListProps) {
const ref = useRef<VariableSizeList>(null);
const focusTrapRef = useRef<HTMLDivElement>(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,9 +140,41 @@ function VirtualList({
currentIndexRef.current = index;
}, []);
if (!maxHeight) return cleanChildren || children;
const items = cleanChildren || children;
return isNoFixedHeightOptions ? (
if (!maxHeight)
return (
<div
className="focus-trap"
style={{ outline: "none" }}
ref={focusTrapRef}
tabIndex={0}
>
{items?.map((item, index) => (
<Row
key={index}
data={{
children: cleanChildren,
theme,
activeIndex,
activedescendant: currentIndex,
handleMouseMove,
}}
index={index}
style={{}}
/>
))}
</div>
);
return (
<div
className="focus-trap"
style={{ outline: "none" }}
ref={focusTrapRef}
tabIndex={0}
>
{isNoFixedHeightOptions ? (
<Scrollbar style={{ height: maxHeight }}>{cleanChildren}</Scrollbar>
) : (
<VariableSizeList
@ -157,6 +194,8 @@ function VirtualList({
>
{Row}
</VariableSizeList>
)}
</div>
);
}