Merge branch 'dropdown-menu-improvements' into 'develop'
Dropdown menu improvements and fixes See merge request soapbox-pub/soapbox!2541
This commit is contained in:
commit
ea298472a8
2 changed files with 27 additions and 44 deletions
|
@ -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;
|
||||
export default DropdownMenuItem;
|
||||
|
|
|
@ -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<boolean>(false);
|
||||
const isOpenRedux = useAppSelector(state => state.dropdown_menu.isOpen);
|
||||
|
||||
const arrowRef = useRef<HTMLDivElement>(null);
|
||||
const activeElement = useRef<Element | null>(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<React.MouseEvent | React.KeyboardEvent> = () => {
|
||||
if (!isOpen) {
|
||||
activeElement.current = document.activeElement;
|
||||
}
|
||||
};
|
||||
|
||||
const handleButtonKeyDown: React.EventHandler<React.KeyboardEvent> = (event) => {
|
||||
switch (event.key) {
|
||||
case ' ':
|
||||
case 'Enter':
|
||||
handleMouseDown(event);
|
||||
break;
|
||||
}
|
||||
if (isOpenRedux) {
|
||||
dispatch(closeDropdownMenuRedux());
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleKeyPress: React.EventHandler<React.KeyboardEvent<HTMLButtonElement>> = (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;
|
||||
export default DropdownMenu;
|
||||
|
|
Loading…
Reference in a new issue