From 8b0b383e9ec1326efbc4c3c3f742f0b01732a0d2 Mon Sep 17 00:00:00 2001 From: Saumya Pandey Date: Sat, 5 Mar 2022 23:00:41 +0530 Subject: [PATCH] fix: don't hide sidebar when menu is open (#3203) --- app/components/ContextMenu/index.tsx | 23 ++++++++++++++++++++- app/components/Layout.tsx | 3 ++- app/components/Sidebar/Sidebar.tsx | 4 +++- app/hooks/useMenuContext.tsx | 31 ++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 app/hooks/useMenuContext.tsx diff --git a/app/components/ContextMenu/index.tsx b/app/components/ContextMenu/index.tsx index 9d2612219..3c1f71358 100644 --- a/app/components/ContextMenu/index.tsx +++ b/app/components/ContextMenu/index.tsx @@ -1,10 +1,13 @@ import * as React from "react"; +import { useTranslation } from "react-i18next"; import { Portal } from "react-portal"; import { Menu } from "reakit/Menu"; import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; +import useMenuContext from "~/hooks/useMenuContext"; import useMenuHeight from "~/hooks/useMenuHeight"; import usePrevious from "~/hooks/usePrevious"; +import useStores from "~/hooks/useStores"; import { fadeIn, fadeAndSlideUp, @@ -50,20 +53,38 @@ export default function ContextMenu({ const previousVisible = usePrevious(rest.visible); const maxHeight = useMenuHeight(rest.visible, rest.unstable_disclosureRef); const backgroundRef = React.useRef(null); + const { ui } = useStores(); + const { t } = useTranslation(); + const { setIsMenuOpen } = useMenuContext(); React.useEffect(() => { if (rest.visible && !previousVisible) { if (onOpen) { onOpen(); } + if (rest["aria-label"] !== t("Submenu")) { + setIsMenuOpen(true); + } } if (!rest.visible && previousVisible) { if (onClose) { onClose(); } + if (rest["aria-label"] !== t("Submenu")) { + setIsMenuOpen(false); + } } - }, [onOpen, onClose, previousVisible, rest.visible]); + }, [ + onOpen, + onClose, + previousVisible, + rest.visible, + ui.sidebarCollapsed, + setIsMenuOpen, + rest, + t, + ]); // Perf win – don't render anything until the menu has been opened if (!rest.visible && !previousVisible) { diff --git a/app/components/Layout.tsx b/app/components/Layout.tsx index 043699351..a0f6303e2 100644 --- a/app/components/Layout.tsx +++ b/app/components/Layout.tsx @@ -8,6 +8,7 @@ import { LoadingIndicatorBar } from "~/components/LoadingIndicator"; import SkipNavContent from "~/components/SkipNavContent"; import SkipNavLink from "~/components/SkipNavLink"; import useKeyDown from "~/hooks/useKeyDown"; +import { MenuProvider } from "~/hooks/useMenuContext"; import useStores from "~/hooks/useStores"; import { isModKey } from "~/utils/keyboard"; @@ -40,7 +41,7 @@ function Layout({ title, children, sidebar, rightRail }: Props) { {ui.progressBarVisible && } - {sidebar} + {sidebar} ( const { ui } = useStores(); const location = useLocation(); const previousLocation = usePrevious(location); + const { isMenuOpen } = useMenuContext(); const width = ui.sidebarWidth; - const collapsed = ui.isEditing || ui.sidebarCollapsed; + const collapsed = (ui.isEditing || ui.sidebarCollapsed) && !isMenuOpen; const maxWidth = theme.sidebarMaxWidth; const minWidth = theme.sidebarMinWidth + 16; // padding diff --git a/app/hooks/useMenuContext.tsx b/app/hooks/useMenuContext.tsx new file mode 100644 index 000000000..7df90f7c1 --- /dev/null +++ b/app/hooks/useMenuContext.tsx @@ -0,0 +1,31 @@ +import { noop } from "lodash"; +import React from "react"; + +type MenuContextType = { + isMenuOpen: boolean; + setIsMenuOpen: React.Dispatch>; +}; + +const MenuContext = React.createContext(null); + +export const MenuProvider: React.FC = ({ children }) => { + const [isMenuOpen, setIsMenuOpen] = React.useState(false); + const memoized = React.useMemo( + () => ({ + isMenuOpen, + setIsMenuOpen, + }), + [isMenuOpen, setIsMenuOpen] + ); + + return ( + {children} + ); +}; + +const useMenuContext: () => MenuContextType = () => { + const value = React.useContext(MenuContext); + return value ? value : { isMenuOpen: false, setIsMenuOpen: noop }; +}; + +export default useMenuContext;