-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Open
Labels
issue/bug-unconfirmedIssues that describe a bug that hasn't been confirmed by a maintainer yetIssues that describe a bug that hasn't been confirmed by a maintainer yet
Description
Hey,
I tested react-select using Windows Narrator, and I was unable to select any options. I open the select, and when I try to use the Arrow Down key to move to another option, the select closes.
I noticed that the onKeyDown function does not receive the Arrow Down event in the dropdown when Narrator is on.
I created a hook to handle this, but I’d appreciate it if react-select supported this natively.
Here you can check the bug:
react-select.w.narrator.mp4
The hook:
import {useCallback, useEffect, useRef, useState} from 'react';
interface KeyboardNavigation {
initialValue?: any;
onValueChange?: any;
}
export const useSelectKeyboardNavigation = ({
initialValue,
onValueChange,
}: KeyboardNavigation) => {
const [value, setValue] = useState<any>(initialValue);
const [isMenuOpen, setIsMenuOpen] = useState(false);
const selectRef = useRef<any>(null);
const preventCloseRef = useRef(false);
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (selectRef.current?.controlRef) {
if (!selectRef.current.controlRef.contains(event.target as Node)) {
const menu = document.querySelector('[role="listbox"]');
if (menu && !menu.contains(event.target as Node)) {
preventCloseRef.current = false;
setIsMenuOpen(false);
}
}
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
const handleChange = useCallback(
(newValue: any) => {
setValue(newValue);
preventCloseRef.current = false;
setIsMenuOpen(false);
setTimeout(() => {
const firstOption = document.querySelector('[role="option"]') as HTMLElement;
if (firstOption) {
firstOption.setAttribute('tabindex', '0');
firstOption.focus();
}
}, 100);
onValueChange?.(newValue);
},
[onValueChange]
);
const handleMenuClose = useCallback(() => {
if (preventCloseRef.current) {
return;
}
setIsMenuOpen(false);
}, []);
const handleMenuOpen = useCallback(() => {
preventCloseRef.current = true;
setIsMenuOpen(true);
setTimeout(() => {
const firstOption = document.querySelector('[role="option"]') as HTMLElement;
if (firstOption) {
firstOption.setAttribute('tabindex', '0');
firstOption.focus();
}
}, 100);
}, []);
const handleKeyDown = useCallback(
(event: React.KeyboardEvent) => {
if (event.key === 'Escape') {
preventCloseRef.current = false;
setIsMenuOpen(false);
}
},
[]
);
return {
value,
isMenuOpen:isMenuOpen,
selectRef,
handleChange,
handleMenuClose,
handleKeyDown,
handleMenuOpen,
};
};
Metadata
Metadata
Assignees
Labels
issue/bug-unconfirmedIssues that describe a bug that hasn't been confirmed by a maintainer yetIssues that describe a bug that hasn't been confirmed by a maintainer yet