Client: DropDown: Draft navigation variant
This commit is contained in:
parent
eac40356c7
commit
797f2c83d6
@ -433,6 +433,7 @@ const DropDown = ({
|
|||||||
getItemSize={getItemSize}
|
getItemSize={getItemSize}
|
||||||
isOpen={open || false}
|
isOpen={open || false}
|
||||||
enableKeyboardEvents={enableKeyboardEvents || false}
|
enableKeyboardEvents={enableKeyboardEvents || false}
|
||||||
|
isDropdownReady={state.isDropdownReady}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</VirtualList>
|
</VirtualList>
|
||||||
|
@ -101,6 +101,7 @@ export interface VirtualListProps {
|
|||||||
>;
|
>;
|
||||||
enableKeyboardEvents: boolean;
|
enableKeyboardEvents: boolean;
|
||||||
getItemSize: (index: number) => number;
|
getItemSize: (index: number) => number;
|
||||||
|
isDropdownReady: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RowProps {
|
export interface RowProps {
|
||||||
|
@ -50,14 +50,16 @@ function VirtualList({
|
|||||||
isNoFixedHeightOptions,
|
isNoFixedHeightOptions,
|
||||||
getItemSize,
|
getItemSize,
|
||||||
enableKeyboardEvents,
|
enableKeyboardEvents,
|
||||||
|
isDropdownReady,
|
||||||
}: VirtualListProps) {
|
}: VirtualListProps) {
|
||||||
const ref = useRef<VariableSizeList>(null);
|
const ref = useRef<VariableSizeList>(null);
|
||||||
|
const focusTrapRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const activeIndex = useMemo(() => {
|
const activeIndex = useMemo(() => {
|
||||||
let foundIndex = -1;
|
let foundIndex = -1;
|
||||||
React.Children.forEach(cleanChildren, (child, index) => {
|
React.Children.forEach(cleanChildren, (child, index) => {
|
||||||
const props = child && React.isValidElement(child) && child.props;
|
const props = child && React.isValidElement(child) && child.props;
|
||||||
if (props?.disabled) foundIndex = index;
|
if (props?.isSelected) foundIndex = index;
|
||||||
});
|
});
|
||||||
return foundIndex;
|
return foundIndex;
|
||||||
}, [cleanChildren]);
|
}, [cleanChildren]);
|
||||||
@ -67,9 +69,10 @@ function VirtualList({
|
|||||||
|
|
||||||
const onKeyDown = useCallback(
|
const onKeyDown = useCallback(
|
||||||
(event: KeyboardEvent) => {
|
(event: KeyboardEvent) => {
|
||||||
if (!ref.current || !isOpen) return;
|
if (!focusTrapRef.current || !isOpen) return;
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
let index = currentIndexRef.current;
|
let index = currentIndexRef.current;
|
||||||
|
|
||||||
@ -96,26 +99,27 @@ function VirtualList({
|
|||||||
|
|
||||||
setCurrentIndex(index);
|
setCurrentIndex(index);
|
||||||
currentIndexRef.current = index;
|
currentIndexRef.current = index;
|
||||||
ref.current.scrollToItem(index, "smart");
|
// ref.current.scrollToItem(index, "smart");
|
||||||
},
|
},
|
||||||
[isOpen, children],
|
[isOpen, children],
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isOpen && maxHeight && enableKeyboardEvents) {
|
if (isOpen && isDropdownReady && enableKeyboardEvents) {
|
||||||
window.addEventListener("keydown", onKeyDown);
|
focusTrapRef.current?.focus();
|
||||||
|
focusTrapRef.current?.addEventListener("keydown", onKeyDown);
|
||||||
}
|
}
|
||||||
|
|
||||||
const refVar = ref.current;
|
const refVar = ref.current;
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener("keydown", onKeyDown);
|
focusTrapRef.current?.removeEventListener("keydown", onKeyDown);
|
||||||
|
|
||||||
if (itemCount > 0 && refVar) {
|
if (itemCount > 0 && refVar) {
|
||||||
setCurrentIndex(activeIndex);
|
setCurrentIndex(activeIndex);
|
||||||
currentIndexRef.current = activeIndex;
|
currentIndexRef.current = activeIndex;
|
||||||
|
|
||||||
refVar.scrollToItem(activeIndex, "smart");
|
// refVar.scrollToItem(activeIndex, "smart");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [
|
}, [
|
||||||
@ -126,6 +130,7 @@ function VirtualList({
|
|||||||
children,
|
children,
|
||||||
onKeyDown,
|
onKeyDown,
|
||||||
itemCount,
|
itemCount,
|
||||||
|
isDropdownReady,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const handleMouseMove = useCallback((index: number) => {
|
const handleMouseMove = useCallback((index: number) => {
|
||||||
@ -135,28 +140,62 @@ function VirtualList({
|
|||||||
currentIndexRef.current = index;
|
currentIndexRef.current = index;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (!maxHeight) return cleanChildren || children;
|
const items = cleanChildren || children;
|
||||||
|
|
||||||
return isNoFixedHeightOptions ? (
|
if (!maxHeight)
|
||||||
<Scrollbar style={{ height: maxHeight }}>{cleanChildren}</Scrollbar>
|
return (
|
||||||
) : (
|
<div
|
||||||
<VariableSizeList
|
className="focus-trap"
|
||||||
ref={ref}
|
style={{ outline: "none" }}
|
||||||
width={width}
|
ref={focusTrapRef}
|
||||||
itemCount={itemCount}
|
tabIndex={0}
|
||||||
itemSize={getItemSize}
|
>
|
||||||
height={calculatedHeight}
|
{items?.map((item, index) => (
|
||||||
itemData={{
|
<Row
|
||||||
children: cleanChildren,
|
key={index}
|
||||||
theme,
|
data={{
|
||||||
activeIndex,
|
children: cleanChildren,
|
||||||
activedescendant: currentIndex,
|
theme,
|
||||||
handleMouseMove,
|
activeIndex,
|
||||||
}}
|
activedescendant: currentIndex,
|
||||||
outerElementType={Scrollbar}
|
handleMouseMove,
|
||||||
|
}}
|
||||||
|
index={index}
|
||||||
|
style={{}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="focus-trap"
|
||||||
|
style={{ outline: "none" }}
|
||||||
|
ref={focusTrapRef}
|
||||||
|
tabIndex={0}
|
||||||
>
|
>
|
||||||
{Row}
|
{isNoFixedHeightOptions ? (
|
||||||
</VariableSizeList>
|
<Scrollbar style={{ height: maxHeight }}>{cleanChildren}</Scrollbar>
|
||||||
|
) : (
|
||||||
|
<VariableSizeList
|
||||||
|
ref={ref}
|
||||||
|
width={width}
|
||||||
|
itemCount={itemCount}
|
||||||
|
itemSize={getItemSize}
|
||||||
|
height={calculatedHeight}
|
||||||
|
itemData={{
|
||||||
|
children: cleanChildren,
|
||||||
|
theme,
|
||||||
|
activeIndex,
|
||||||
|
activedescendant: currentIndex,
|
||||||
|
handleMouseMove,
|
||||||
|
}}
|
||||||
|
outerElementType={Scrollbar}
|
||||||
|
>
|
||||||
|
{Row}
|
||||||
|
</VariableSizeList>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user