diff --git a/web/chat/thread-menu.css b/web/chat/thread-menu.css --- a/web/chat/thread-menu.css +++ b/web/chat/thread-menu.css @@ -1,58 +1,6 @@ -button.topBarMenuButton { - background-color: transparent; - border: none; - cursor: pointer; - color: var(--thread-top-bar-menu-color); -} - -div.topBarMenuActionList { - position: absolute; - right: 10px; - top: 55px; - z-index: 1; - display: flex; - flex-direction: column; - background-color: var(--thread-menu-bg); - border-radius: 4px; - padding: 4px 0; -} - -button.topBarMenuAction { - z-index: 1; - background-color: transparent; - padding: 12px 16px; - color: var(--thread-menu-color); - background-color: var(--thread-menu-bg); - font-size: var(--m-font-16); - line-height: 1.5; - border: none; - cursor: pointer; - display: flex; - align-items: center; -} - -button.topBarMenuAction:hover { - color: var(--thread-menu-color-hover); -} - -div.topBarMenuActionIcon { - font-size: var(--l-font-18); - display: flex; - justify-content: center; - margin-right: 8px; - width: 20px; -} - -button.topBarMenuActionDangerous { - color: var(--thread-menu-color-dangerous); -} -button.topBarMenuActionDangerous:hover { - color: var(--thread-menu-color-dangerous-hover); -} - hr.separator { height: 1px; - background: var(--thread-menu-separator-color); + background: var(--menu-separator-color); margin: 10px 16px; max-width: 130px; border: none; diff --git a/web/chat/thread-menu.react.js b/web/chat/thread-menu.react.js --- a/web/chat/thread-menu.react.js +++ b/web/chat/thread-menu.react.js @@ -31,13 +31,14 @@ useDispatchActionPromise, } from 'lib/utils/action-utils'; +import MenuItem from '../components/menu-item.react'; +import Menu from '../components/menu.react'; import SidebarListModal from '../modals/chat/sidebar-list-modal.react'; import { useModalContext } from '../modals/modal-provider.react'; import ConfirmLeaveThreadModal from '../modals/threads/confirm-leave-thread-modal.react'; import ThreadSettingsModal from '../modals/threads/thread-settings-modal.react'; import { useSelector } from '../redux/redux-utils'; import SWMansionIcon from '../SWMansionIcon.react'; -import ThreadMenuItem from './thread-menu-item.react'; import css from './thread-menu.css'; type ThreadMenuProps = { @@ -45,8 +46,6 @@ }; function ThreadMenu(props: ThreadMenuProps): React.Node { - const [isOpen, setIsOpen] = React.useState(false); - const { setModal, clearModal } = useModalContext(); const { threadInfo } = props; @@ -58,7 +57,7 @@ const settingsItem = React.useMemo(() => { return ( - ; + return ; }, [threadInfo.type]); const childThreads = useSelector( @@ -94,7 +93,7 @@ return null; } return ( - + ); }, [canCreateSubchannels, hasSubchannels]); @@ -130,7 +125,7 @@ return null; } return ( - { const notificationsItem = ( - + ); const separator =
; @@ -211,45 +206,11 @@ createSubchannelsItem, leaveThreadItem, ]); - - const closeMenuCallback = React.useCallback(() => { - document.removeEventListener('click', closeMenuCallback); - if (isOpen) { - setIsOpen(false); - } - }, [isOpen]); - - React.useEffect(() => { - if (!document || !isOpen) { - return undefined; - } - document.addEventListener('click', closeMenuCallback); - return () => document.removeEventListener('click', closeMenuCallback); - }, [closeMenuCallback, isOpen]); - - const switchMenuCallback = React.useCallback(() => { - setIsOpen(isMenuOpen => !isMenuOpen); - }, []); - - if (menuItems.length === 0) { - return null; - } - - let menuActionList = null; - if (isOpen) { - menuActionList = ( -
{menuItems}
- ); - } - - return ( - <> - - {menuActionList} - + const icon = React.useMemo( + () => , + [], ); + return {menuItems}; } export default ThreadMenu; diff --git a/web/chat/thread-menu-item.react.js b/web/components/menu-item.react.js rename from web/chat/thread-menu-item.react.js rename to web/components/menu-item.react.js --- a/web/chat/thread-menu-item.react.js +++ b/web/components/menu-item.react.js @@ -5,24 +5,24 @@ import classNames from 'classnames'; import * as React from 'react'; -import css from './thread-menu.css'; +import css from './menu.css'; -type ThreadMenuItemProps = { +type MenuItemProps = { +onClick?: () => mixed, +icon: IconDefinition, +text: string, +dangerous?: boolean, }; -function ThreadMenuItem(props: ThreadMenuItemProps): React.Node { +function MenuItem(props: MenuItemProps): React.Node { const { onClick, icon, text, dangerous } = props; - const itemClasses = classNames(css.topBarMenuAction, { - [css.topBarMenuActionDangerous]: dangerous, + const itemClasses = classNames(css.menuAction, { + [css.menuActionDangerous]: dangerous, }); return ( + {menuActionList} + + ); +} + +export default Menu; diff --git a/web/theme.css b/web/theme.css --- a/web/theme.css +++ b/web/theme.css @@ -104,12 +104,12 @@ --thread-ancestor-separator-color: var(--shades-white-60); --text-message-default-background: var(--shades-black-80); --message-action-tooltip-bg: var(--shades-black-90); - --thread-menu-bg: var(--shades-black-90); - --thread-menu-separator-color: var(--shades-black-80); - --thread-menu-color: var(--shades-black-60); - --thread-menu-color-hover: var(--shades-white-100); - --thread-menu-color-dangerous: var(--error-primary); - --thread-menu-color-dangerous-hover: var(--error-light-50); + --menu-bg: var(--shades-black-90); + --menu-separator-color: var(--shades-black-80); + --menu-color: var(--shades-black-60); + --menu-color-hover: var(--shades-white-100); + --menu-color-dangerous: var(--error-primary); + --menu-color-dangerous-hover: var(--error-light-50); --app-list-icon-read-only-color: var(--shades-black-60); --app-list-icon-enabled-color: var(--success-primary); --app-list-icon-disabled-color: var(--shades-white-80);