diff --git a/app/soapbox/components/dropdown-menu/dropdown-menu-item.tsx b/app/soapbox/components/dropdown-menu/dropdown-menu-item.tsx index 8a6c8f531..e236983fc 100644 --- a/app/soapbox/components/dropdown-menu/dropdown-menu-item.tsx +++ b/app/soapbox/components/dropdown-menu/dropdown-menu-item.tsx @@ -87,7 +87,7 @@ const DropdownMenuItem = ({ index, item, onClick }: IDropdownMenuItem) => { title={item.text} className={ clsx({ - 'flex px-4 py-2.5 text-sm text-gray-700 dark:text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none cursor-pointer': true, + 'flex px-4 py-2.5 text-sm text-gray-700 dark:text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 focus:bg-gray-100 dark:focus:bg-gray-800 focus:outline-none cursor-pointer': true, 'text-danger-600 dark:text-danger-400': item.destructive, }) } @@ -106,4 +106,4 @@ const DropdownMenuItem = ({ index, item, onClick }: IDropdownMenuItem) => { ); }; -export default DropdownMenuItem; \ No newline at end of file +export default DropdownMenuItem; diff --git a/app/soapbox/components/dropdown-menu/dropdown-menu.tsx b/app/soapbox/components/dropdown-menu/dropdown-menu.tsx index 9a606bf61..48fff7398 100644 --- a/app/soapbox/components/dropdown-menu/dropdown-menu.tsx +++ b/app/soapbox/components/dropdown-menu/dropdown-menu.tsx @@ -4,12 +4,9 @@ import { supportsPassiveEvents } from 'detect-passive-events'; import React, { useEffect, useMemo, useRef, useState } from 'react'; import { useHistory } from 'react-router-dom'; -import { - closeDropdownMenu as closeDropdownMenuRedux, - openDropdownMenu, -} from 'soapbox/actions/dropdown-menu'; +import { closeDropdownMenu as closeDropdownMenuRedux, openDropdownMenu } from 'soapbox/actions/dropdown-menu'; import { closeModal, openModal } from 'soapbox/actions/modals'; -import { useAppDispatch, useAppSelector } from 'soapbox/hooks'; +import { useAppDispatch } from 'soapbox/hooks'; import { isUserTouching } from 'soapbox/is-mobile'; import { IconButton, Portal } from '../ui'; @@ -53,10 +50,8 @@ const DropdownMenu = (props: IDropdownMenu) => { const history = useHistory(); const [isOpen, setIsOpen] = useState(false); - const isOpenRedux = useAppSelector(state => state.dropdown_menu.isOpen); const arrowRef = useRef(null); - const activeElement = useRef(null); const isOnMobile = isUserTouching(); @@ -116,10 +111,7 @@ const DropdownMenu = (props: IDropdownMenu) => { }; const handleClose = () => { - if (activeElement.current && activeElement.current === refs.reference.current) { - (activeElement.current as any).focus(); - activeElement.current = null; - } + (refs.reference.current as HTMLButtonElement)?.focus(); if (isOnMobile) { dispatch(closeModal('ACTIONS')); @@ -134,24 +126,13 @@ const DropdownMenu = (props: IDropdownMenu) => { }; const closeDropdownMenu = () => { - if (isOpenRedux) { - dispatch(closeDropdownMenuRedux()); - } - }; + dispatch((dispatch, getState) => { + const isOpenRedux = getState().dropdown_menu.isOpen; - const handleMouseDown: React.EventHandler = () => { - if (!isOpen) { - activeElement.current = document.activeElement; - } - }; - - const handleButtonKeyDown: React.EventHandler = (event) => { - switch (event.key) { - case ' ': - case 'Enter': - handleMouseDown(event); - break; - } + if (isOpenRedux) { + dispatch(closeDropdownMenuRedux()); + } + }); }; const handleKeyPress: React.EventHandler> = (event) => { @@ -263,16 +244,22 @@ const DropdownMenu = (props: IDropdownMenu) => { }, []); useEffect(() => { - document.addEventListener('click', handleDocumentClick, false); - document.addEventListener('keydown', handleKeyDown, false); - document.addEventListener('touchend', handleDocumentClick, listenerOptions); + if (isOpen) { + if (refs.floating.current) { + (refs.floating.current?.querySelector('li a[role=\'button\']') as HTMLAnchorElement)?.focus(); + } - return () => { - document.removeEventListener('click', handleDocumentClick); - document.removeEventListener('keydown', handleKeyDown); - document.removeEventListener('touchend', handleDocumentClick); - }; - }, [refs.floating.current]); + document.addEventListener('click', handleDocumentClick, false); + document.addEventListener('keydown', handleKeyDown, false); + document.addEventListener('touchend', handleDocumentClick, listenerOptions); + + return () => { + document.removeEventListener('click', handleDocumentClick); + document.removeEventListener('keydown', handleKeyDown); + document.removeEventListener('touchend', handleDocumentClick); + }; + } + }, [isOpen, refs.floating.current]); if (items.length === 0) { return null; @@ -284,8 +271,6 @@ const DropdownMenu = (props: IDropdownMenu) => { React.cloneElement(children, { disabled, onClick: handleClick, - onMouseDown: handleMouseDown, - onKeyDown: handleButtonKeyDown, onKeyPress: handleKeyPress, ref: refs.setReference, }) @@ -299,8 +284,6 @@ const DropdownMenu = (props: IDropdownMenu) => { title={title} src={src} onClick={handleClick} - onMouseDown={handleMouseDown} - onKeyDown={handleButtonKeyDown} onKeyPress={handleKeyPress} ref={refs.setReference} /> @@ -346,4 +329,4 @@ const DropdownMenu = (props: IDropdownMenu) => { ); }; -export default DropdownMenu; \ No newline at end of file +export default DropdownMenu;