Page MenuHomePhorge

D3377.1768386142.diff
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

D3377.1768386142.diff

diff --git a/web/components/menu.react.js b/web/components/menu.react.js
--- a/web/components/menu.react.js
+++ b/web/components/menu.react.js
@@ -3,6 +3,7 @@
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';
@@ -11,53 +12,80 @@
+icon: React.Node,
+children?: React.Node,
+variant?: MenuVariant,
+ +onChange?: boolean => void,
};
function Menu(props: MenuProps): React.Node {
- const [isOpen, setIsOpen] = React.useState(false);
+ const buttonRef = React.useRef();
+ const {
+ renderMenu,
+ setMenuPosition,
+ closeMenu,
+ currentMenu,
+ } = useRenderMenu();
+ const { icon, children, variant = 'thread-actions', onChange } = props;
- const { icon, children, variant = 'thread-actions' } = props;
+ const menuActionListClasses = React.useMemo(
+ () =>
+ classnames(css.menuActionList, {
+ [css.menuActionListThreadActions]: variant === 'thread-actions',
+ [css.menuActionListMemberActions]: variant === 'member-actions',
+ }),
+ [variant],
+ );
+
+ const menuActionList = React.useMemo(() => {
+ return <div className={menuActionListClasses}>{children}</div>;
+ }, [children, menuActionListClasses]);
+
+ const updatePosition = React.useCallback(() => {
+ if (buttonRef.current && currentMenu === menuActionList) {
+ const { top, left } = buttonRef.current.getBoundingClientRect();
+ setMenuPosition({ top, left });
+ }
+ }, [currentMenu, menuActionList, setMenuPosition]);
+
+ React.useLayoutEffect(() => {
+ updatePosition();
+ }, [updatePosition]);
const closeMenuCallback = React.useCallback(() => {
document.removeEventListener('click', closeMenuCallback);
- if (isOpen) {
- setIsOpen(false);
- }
- }, [isOpen]);
+ closeMenu(menuActionList);
+ onChange?.(false);
+ }, [closeMenu, menuActionList, onChange]);
React.useEffect(() => {
- if (!document || !isOpen) {
+ if (!window) {
return undefined;
}
- document.addEventListener('click', closeMenuCallback);
- return () => document.removeEventListener('click', closeMenuCallback);
- }, [closeMenuCallback, isOpen]);
- const switchMenuCallback = React.useCallback(() => {
- setIsOpen(isMenuOpen => !isMenuOpen);
- }, []);
+ window.addEventListener('resize', updatePosition);
+ return () => window.removeEventListener('resize', updatePosition);
+ }, [updatePosition]);
- if (React.Children.count(children) === 0) {
- return null;
- }
+ React.useEffect(() => {
+ return closeMenuCallback;
+ }, [closeMenuCallback]);
- let menuActionList = null;
- if (isOpen) {
- const menuActionListClasses = classnames(css.menuActionList, {
- [css.menuActionListThreadActions]: variant === 'thread-actions',
- [css.menuActionListMemberActions]: variant === 'member-actions',
- });
+ const onClickMenuCallback = React.useCallback(() => {
+ renderMenu(menuActionList);
+ document.addEventListener('click', closeMenuCallback);
+ onChange?.(true);
+ }, [closeMenuCallback, menuActionList, onChange, renderMenu]);
- menuActionList = <div className={menuActionListClasses}>{children}</div>;
+ if (React.Children.count(children) === 0) {
+ return null;
}
return (
- <div>
- <button className={css.menuButton} onClick={switchMenuCallback}>
- {icon}
- </button>
- {menuActionList}
- </div>
+ <button
+ ref={buttonRef}
+ className={css.menuButton}
+ onClick={onClickMenuCallback}
+ >
+ {icon}
+ </button>
);
}

File Metadata

Mime Type
text/plain
Expires
Wed, Jan 14, 10:22 AM (3 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5931446
Default Alt Text
D3377.1768386142.diff (3 KB)

Event Timeline