Adjust useOutsideClick with multi-references (#1059)
This commit is contained in:
@@ -26,7 +26,7 @@ function AddressDropdown ({ allAddresses, className, onSelect, selectedAddress,
|
||||
const _toggleDropdown = useCallback(() => setDropdownVisible(!isDropdownVisible), [isDropdownVisible]);
|
||||
const _selectParent = useCallback((newParent: string) => () => onSelect(newParent), [onSelect]);
|
||||
|
||||
useOutsideClick(ref, _hideDropdown);
|
||||
useOutsideClick([ref], _hideDropdown);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
|
||||
@@ -104,10 +104,11 @@ function Address ({ actions, address, children, className, genesisHash, isExtern
|
||||
|
||||
const [showActionsMenu, setShowActionsMenu] = useState(false);
|
||||
const [moveMenuUp, setIsMovedMenu] = useState(false);
|
||||
const actionsRef = useRef<HTMLDivElement>(null);
|
||||
const actIconRef = useRef<HTMLDivElement>(null);
|
||||
const actMenuRef = useRef<HTMLDivElement>(null);
|
||||
const { show } = useToast();
|
||||
|
||||
useOutsideClick(actionsRef, () => (showActionsMenu && setShowActionsMenu(!showActionsMenu)));
|
||||
useOutsideClick([actIconRef, actMenuRef], () => (showActionsMenu && setShowActionsMenu(!showActionsMenu)));
|
||||
|
||||
useEffect((): void => {
|
||||
if (!address) {
|
||||
@@ -130,8 +131,8 @@ function Address ({ actions, address, children, className, genesisHash, isExtern
|
||||
useEffect(() => {
|
||||
if (!showActionsMenu) {
|
||||
setIsMovedMenu(false);
|
||||
} else if (actionsRef.current) {
|
||||
const { bottom } = actionsRef.current.getBoundingClientRect();
|
||||
} else if (actMenuRef.current) {
|
||||
const { bottom } = actMenuRef.current.getBoundingClientRect();
|
||||
|
||||
if (bottom > ACCOUNTS_SCREEN_HEIGHT) {
|
||||
setIsMovedMenu(true);
|
||||
@@ -283,6 +284,7 @@ function Address ({ actions, address, children, className, genesisHash, isExtern
|
||||
<div
|
||||
className='settings'
|
||||
onClick={_onClick}
|
||||
ref={actIconRef}
|
||||
>
|
||||
<Svg
|
||||
className={`detailsIcon ${showActionsMenu ? 'active' : ''}`}
|
||||
@@ -292,7 +294,7 @@ function Address ({ actions, address, children, className, genesisHash, isExtern
|
||||
{showActionsMenu && (
|
||||
<Menu
|
||||
className={`movableMenu ${moveMenuUp ? 'isMoved' : ''}`}
|
||||
reference={actionsRef}
|
||||
reference={actMenuRef}
|
||||
>
|
||||
{actions}
|
||||
</Menu>
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
|
||||
import { RefObject, useCallback, useEffect } from 'react';
|
||||
|
||||
export default function useOutsideClick (ref: RefObject<HTMLDivElement>, callback: () => void): void {
|
||||
export default function useOutsideClick (refs: RefObject<HTMLDivElement>[], callback: () => void): void {
|
||||
const handleClick = useCallback((e: MouseEvent): void => {
|
||||
if (ref.current && !ref.current.contains(e.target as HTMLInputElement)) {
|
||||
callback();
|
||||
}
|
||||
}, [callback, ref]);
|
||||
refs.every(({ current }) =>
|
||||
current &&
|
||||
!current.contains(e.target as HTMLInputElement)
|
||||
) && callback();
|
||||
}, [callback, refs]);
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener('click', handleClick);
|
||||
|
||||
@@ -34,31 +34,36 @@ function Header ({ children, className = '', onFilter, showAdd, showBackArrow, s
|
||||
const [isSearchOpen, setShowSearch] = useState(false);
|
||||
const [filter, setFilter] = useState('');
|
||||
const { t } = useTranslation();
|
||||
const addRef = useRef(null);
|
||||
const setRef = useRef(null);
|
||||
const addIconRef = useRef(null);
|
||||
const addMenuRef = useRef(null);
|
||||
const setIconRef = useRef(null);
|
||||
const setMenuRef = useRef(null);
|
||||
|
||||
useOutsideClick(addRef, (): void => {
|
||||
useOutsideClick([addIconRef, addMenuRef], (): void => {
|
||||
isAddOpen && setShowAdd(!isAddOpen);
|
||||
});
|
||||
|
||||
useOutsideClick(setRef, (): void => {
|
||||
useOutsideClick([setIconRef, setMenuRef], (): void => {
|
||||
isSettingsOpen && setShowSettings(!isSettingsOpen);
|
||||
});
|
||||
|
||||
const _toggleAdd = useCallback(
|
||||
(): void => setShowAdd((isAddOpen) => !isAddOpen),
|
||||
() => setShowAdd((isAddOpen) => !isAddOpen),
|
||||
[]
|
||||
);
|
||||
|
||||
const _toggleSettings = useCallback(
|
||||
(): void => setShowSettings((isSettingsOpen) => !isSettingsOpen),
|
||||
() => setShowSettings((isSettingsOpen) => !isSettingsOpen),
|
||||
[]
|
||||
);
|
||||
|
||||
const _onChangeFilter = useCallback((filter: string) => {
|
||||
setFilter(filter);
|
||||
onFilter && onFilter(filter);
|
||||
}, [onFilter]);
|
||||
const _onChangeFilter = useCallback(
|
||||
(filter: string) => {
|
||||
setFilter(filter);
|
||||
onFilter && onFilter(filter);
|
||||
},
|
||||
[onFilter]
|
||||
);
|
||||
|
||||
const _toggleSearch = useCallback(
|
||||
(): void => {
|
||||
@@ -120,6 +125,7 @@ function Header ({ children, className = '', onFilter, showAdd, showBackArrow, s
|
||||
<div
|
||||
className='popupToggle'
|
||||
onClick={_toggleAdd}
|
||||
ref={addIconRef}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
className={`plusIcon ${isAddOpen ? 'selected' : ''}`}
|
||||
@@ -133,6 +139,7 @@ function Header ({ children, className = '', onFilter, showAdd, showBackArrow, s
|
||||
className='popupToggle'
|
||||
data-toggle-settings
|
||||
onClick={_toggleSettings}
|
||||
ref={setIconRef}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
className={`cogIcon ${isSettingsOpen ? 'selected' : ''}`}
|
||||
@@ -143,10 +150,10 @@ function Header ({ children, className = '', onFilter, showAdd, showBackArrow, s
|
||||
)}
|
||||
</div>
|
||||
{isAddOpen && (
|
||||
<MenuAdd reference={addRef} />
|
||||
<MenuAdd reference={addMenuRef} />
|
||||
)}
|
||||
{isSettingsOpen && (
|
||||
<MenuSettings reference={setRef} />
|
||||
<MenuSettings reference={setMenuRef} />
|
||||
)}
|
||||
{children}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user