feat(ui): abstract out the global menu close trigger

This logic is moved into a hook.

This is needed for our context menus to close when the user clicks something in reactflow. It needed to be extended to support menus also.
This commit is contained in:
psychedelicious
2023-12-06 18:54:23 +11:00
parent 3423b5848f
commit 61060f032a
7 changed files with 43 additions and 17 deletions

View File

@@ -22,7 +22,7 @@ import {
PortalProps,
useEventListener,
} from '@chakra-ui/react';
import { useAppSelector } from 'app/store/storeHooks';
import { useGlobalMenuCloseTrigger } from 'common/hooks/useGlobalMenuCloseTrigger';
import * as React from 'react';
import {
MutableRefObject,
@@ -49,10 +49,6 @@ export function IAIContextMenu<T extends HTMLElement = HTMLElement>(
const [position, setPosition] = useState<[number, number]>([0, 0]);
const targetRef = useRef<T>(null);
const globalContextMenuCloseTrigger = useAppSelector(
(state) => state.ui.globalContextMenuCloseTrigger
);
useEffect(() => {
if (isOpen) {
setTimeout(() => {
@@ -70,11 +66,12 @@ export function IAIContextMenu<T extends HTMLElement = HTMLElement>(
}
}, [isOpen]);
useEffect(() => {
const onClose = useCallback(() => {
setIsOpen(false);
setIsDeferredOpen(false);
setIsRendered(false);
}, [globalContextMenuCloseTrigger]);
}, []);
useGlobalMenuCloseTrigger(onClose);
useEventListener('contextmenu', (e) => {
if (

View File

@@ -0,0 +1,25 @@
import { useAppSelector } from 'app/store/storeHooks';
import { useEffect } from 'react';
/**
* The reactflow background element somehow prevents the chakra `useOutsideClick()` hook from working.
* With a menu open, clicking on the reactflow background element doesn't close the menu.
*
* Reactflow does provide an `onPaneClick` to handle clicks on the background element, but it is not
* straightforward to programatically close the menu.
*
* As a (hopefully temporary) workaround, we will use a dirty hack:
* - create `globalMenuCloseTrigger: number` in `ui` slice
* - increment it in `onPaneClick`
* - `useEffect()` to close the menu when `globalMenuCloseTrigger` changes
*/
export const useGlobalMenuCloseTrigger = (onClose: () => void) => {
const globalMenuCloseTrigger = useAppSelector(
(state) => state.ui.globalMenuCloseTrigger
);
useEffect(() => {
onClose();
}, [globalMenuCloseTrigger, onClose]);
};