nuRef = React.useRef();
const localToggleRef = React.useRef();
const ouiaProps = useOUIAProps(Dropdown.displayName, ouiaId, ouiaSafe);
const menuRef = (innerRef as React.RefObject) || localMenuRef;
const toggleRef =
typeof toggle === 'function' || (typeof toggle !== 'function' && !toggle.toggleRef)
? localToggleRef
: (toggle?.toggleRef as React.RefObject);
React.useEffect(() => {
const handleMenuKeys = (event: KeyboardEvent) => {
// Close the menu on tab or escape if onOpenChange is provided
if (
isOpen &&
onOpenChange &&
(menuRef.current?.contains(event.target as Node) || toggleRef.current?.contains(event.target as Node))
) {
if (onOpenChangeKeys.includes(event.key)) {
onOpenChange(false);
toggleRef.current?.focus();
}
}
};
const handleClick = (event: MouseEvent) => {
// toggle was clicked open via keyboard, focus on first menu item
if (isOpen && toggleRef.current?.contains(event.target as Node) && event.detail === 0) {
setTimeout(() => {
const firstElement = menuRef?.current?.querySelector(
'li button:not(:disabled),li input:not(:disabled),li a:not([aria-disabled="true"])'
);
firstElement && (firstElement as HTMLElement).focus();
}, 0);
}
// If the event is not on the toggle and onOpenChange callback is provided, close the menu
if (isOpen && onOpenChange && !toggleRef?.current?.contains(event.target as Node)) {
if (isOpen && !menuRef.current?.contains(event.target as Node)) {
onOpenChange(false);
}
}
};
window.addEventListener('keydown', handleMenuKeys);
window.addEventListener('click', handleClick);
return () => {
window.removeEventListener('keydown', handleMenuKeys);
window.removeEventListener('click', handleClick);
};
}, [isOpen, menuRef, toggleRef, onOpenChange, onOpenChangeKeys]);
const menu = (
);
return (
);
};
export const Dropdown = React.forwardRef((props: DropdownProps, ref: React.Ref) => (
));
Dropdown.displayName = 'Dropdown';