1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- // @flow
-
- import { useCallback, useRef, useState } from 'react';
-
- import { findAncestorByClass } from '../../../participants-pane/functions';
-
- type RaiseContext = {|
-
- /**
- * Target elements against which positioning calculations are made.
- */
- offsetTarget?: HTMLElement,
-
- /**
- * The entity for which the menu is context menu is raised.
- */
- entity?: string | Object,
- |};
-
- const initialState = Object.freeze({});
-
- const useContextMenu = () => {
- const [ raiseContext, setRaiseContext ] = useState < RaiseContext >(initialState);
- const isMouseOverMenu = useRef(false);
-
- const lowerMenu = useCallback((force: boolean | Object = false) => {
- /**
- * We are tracking mouse movement over the active participant item and
- * the context menu. Due to the order of enter/leave events, we need to
- * defer checking if the mouse is over the context menu with
- * queueMicrotask.
- */
- window.queueMicrotask(() => {
- if (isMouseOverMenu.current && !(force === true)) {
- return;
- }
-
- if (raiseContext !== initialState) {
- setRaiseContext(initialState);
- }
- });
- }, [ raiseContext ]);
-
- const raiseMenu = useCallback((entity: string | Object, target: EventTarget) => {
- setRaiseContext({
- entity,
- offsetTarget: findAncestorByClass(target, 'list-item-container')
- });
- }, [ raiseContext ]);
-
- const toggleMenu = useCallback((entity: string | Object) => (e: MouseEvent) => {
- e.stopPropagation();
- const { entity: raisedEntity } = raiseContext;
-
- if (raisedEntity && raisedEntity === entity) {
- lowerMenu();
- } else {
- raiseMenu(entity, e.target);
- }
- }, [ raiseContext ]);
-
- const menuEnter = useCallback(() => {
- isMouseOverMenu.current = true;
- }, []);
-
- const menuLeave = useCallback(() => {
- isMouseOverMenu.current = false;
- lowerMenu();
- }, [ lowerMenu ]);
-
- return [ lowerMenu, raiseMenu, toggleMenu, menuEnter, menuLeave, raiseContext ];
- };
-
- export default useContextMenu;
|