refactor: close menus when clicking outside

This commit is contained in:
Tim 2024-02-20 07:43:26 +01:00
parent 63da56b4a0
commit 6a4ac35b0e
2 changed files with 7 additions and 5 deletions

View file

@ -4,6 +4,7 @@ import React, { useLayoutEffect, useMemo, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import classNames from 'classnames';
import useKeyboardEvent from '../useKeyboardEvent';
import useOnClickOutside from '../useOnClickOutside';
import MenuContext from './MenuContext';
import { type Menu } from './types';
@ -70,6 +71,7 @@ const MenuProvider = ({ children, className }: Props) => {
}, [active]);
useKeyboardEvent('Escape', closeAll);
useOnClickOutside([container.current, active?.parent], closeAll);
return (
<MenuContext.Provider value={{ active, create, remove, render, toggle }}>

View file

@ -2,17 +2,17 @@
import { useEffect } from 'react';
const useOnClickOutside = (ref: React.MutableRefObject<HTMLElement>, handler: () => void, ignore?: boolean) => {
const useOnClickOutside = (elements: HTMLElement[], handler: () => void) => {
useEffect(() => {
const onClickOutside = (event: MouseEvent) => {
const element = event.target as Node;
if (ref.current && !ref.current.contains(element)) {
!ignore && handler();
if (!elements.some((el) => el && el.contains(element))) {
handler();
}
};
document.addEventListener('mouseup', onClickOutside);
return () => document.removeEventListener('mouseup', onClickOutside);
document.addEventListener('click', onClickOutside);
return () => document.removeEventListener('click', onClickOutside);
}, [handler]);
};