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 = ( { onSelect && onSelect(event, value); shouldFocusToggleOnSelect && toggleRef.current.focus(); }} isPlain={isPlain} isScrollable={isScrollable} {...props} {...ouiaProps} > {children} ); return ( ); }; export const Dropdown = React.forwardRef((props: DropdownProps, ref: React.Ref) => ( )); Dropdown.displayName = 'Dropdown';