diff --git a/web/components/menu.react.js b/web/components/menu.react.js
index dea192da5..fedd647c7 100644
--- a/web/components/menu.react.js
+++ b/web/components/menu.react.js
@@ -1,122 +1,118 @@
// @flow
import classnames from 'classnames';
import * as React from 'react';
import { useRenderMenu } from '../menu-provider.react';
import css from './menu.css';
type MenuVariant = 'thread-actions' | 'member-actions';
type MenuProps = {
+icon: React.Node,
+children?: React.Node,
+variant?: MenuVariant,
+onChange?: boolean => void,
};
function Menu(props: MenuProps): React.Node {
const buttonRef = React.useRef();
const {
renderMenu,
setMenuPosition,
closeMenu,
setCurrentOpenMenu,
currentOpenMenu,
} = useRenderMenu();
const { icon, children, variant = 'thread-actions', onChange } = props;
const ourSymbol = React.useRef(Symbol());
const menuActionListClasses = React.useMemo(
() =>
classnames(css.menuActionList, {
[css.menuActionListThreadActions]: variant === 'thread-actions',
[css.menuActionListMemberActions]: variant === 'member-actions',
}),
[variant],
);
const menuActionList = React.useMemo(
() =>
{children}
,
[children, menuActionListClasses],
);
const isOurMenuOpen = currentOpenMenu === ourSymbol.current;
const updatePosition = React.useCallback(() => {
if (buttonRef.current && isOurMenuOpen) {
const { top, left } = buttonRef.current.getBoundingClientRect();
setMenuPosition({ top, left });
}
}, [isOurMenuOpen, setMenuPosition]);
React.useEffect(() => {
if (!window) {
return undefined;
}
window.addEventListener('resize', updatePosition);
return () => window.removeEventListener('resize', updatePosition);
}, [updatePosition]);
- // useLayoutEffect is necessary so that the menu position is immediately
- // updated in the first render of component
- React.useLayoutEffect(() => {
- updatePosition();
- }, [updatePosition]);
+ React.useEffect(updatePosition, [updatePosition]);
const closeMenuCallback = React.useCallback(() => {
closeMenu(menuActionList);
}, [closeMenu, menuActionList]);
React.useEffect(() => {
onChange?.(isOurMenuOpen);
}, [isOurMenuOpen, onChange]);
React.useEffect(() => {
if (!isOurMenuOpen) {
return undefined;
}
document.addEventListener('click', closeMenuCallback);
return () => {
document.removeEventListener('click', closeMenuCallback);
};
}, [closeMenuCallback, isOurMenuOpen]);
const prevActionListRef = React.useRef(null);
React.useEffect(() => {
if (!isOurMenuOpen) {
prevActionListRef.current = null;
return;
}
if (prevActionListRef.current === menuActionList) {
return;
}
renderMenu(menuActionList);
prevActionListRef.current = menuActionList;
}, [isOurMenuOpen, menuActionList, renderMenu]);
React.useEffect(() => {
return () => closeMenu(prevActionListRef.current);
}, [closeMenu]);
const onClickMenuCallback = React.useCallback(() => {
setCurrentOpenMenu(ourSymbol.current);
}, [setCurrentOpenMenu]);
if (React.Children.count(children) === 0) {
return null;
}
return (
);
}
export default Menu;