fix: don't hide sidebar when menu is open (#3203)
This commit is contained in:
@@ -1,10 +1,13 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
import { Portal } from "react-portal";
|
import { Portal } from "react-portal";
|
||||||
import { Menu } from "reakit/Menu";
|
import { Menu } from "reakit/Menu";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import breakpoint from "styled-components-breakpoint";
|
import breakpoint from "styled-components-breakpoint";
|
||||||
|
import useMenuContext from "~/hooks/useMenuContext";
|
||||||
import useMenuHeight from "~/hooks/useMenuHeight";
|
import useMenuHeight from "~/hooks/useMenuHeight";
|
||||||
import usePrevious from "~/hooks/usePrevious";
|
import usePrevious from "~/hooks/usePrevious";
|
||||||
|
import useStores from "~/hooks/useStores";
|
||||||
import {
|
import {
|
||||||
fadeIn,
|
fadeIn,
|
||||||
fadeAndSlideUp,
|
fadeAndSlideUp,
|
||||||
@@ -50,20 +53,38 @@ export default function ContextMenu({
|
|||||||
const previousVisible = usePrevious(rest.visible);
|
const previousVisible = usePrevious(rest.visible);
|
||||||
const maxHeight = useMenuHeight(rest.visible, rest.unstable_disclosureRef);
|
const maxHeight = useMenuHeight(rest.visible, rest.unstable_disclosureRef);
|
||||||
const backgroundRef = React.useRef<HTMLDivElement>(null);
|
const backgroundRef = React.useRef<HTMLDivElement>(null);
|
||||||
|
const { ui } = useStores();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { setIsMenuOpen } = useMenuContext();
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (rest.visible && !previousVisible) {
|
if (rest.visible && !previousVisible) {
|
||||||
if (onOpen) {
|
if (onOpen) {
|
||||||
onOpen();
|
onOpen();
|
||||||
}
|
}
|
||||||
|
if (rest["aria-label"] !== t("Submenu")) {
|
||||||
|
setIsMenuOpen(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rest.visible && previousVisible) {
|
if (!rest.visible && previousVisible) {
|
||||||
if (onClose) {
|
if (onClose) {
|
||||||
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
|
// Perf win – don't render anything until the menu has been opened
|
||||||
if (!rest.visible && !previousVisible) {
|
if (!rest.visible && !previousVisible) {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { LoadingIndicatorBar } from "~/components/LoadingIndicator";
|
|||||||
import SkipNavContent from "~/components/SkipNavContent";
|
import SkipNavContent from "~/components/SkipNavContent";
|
||||||
import SkipNavLink from "~/components/SkipNavLink";
|
import SkipNavLink from "~/components/SkipNavLink";
|
||||||
import useKeyDown from "~/hooks/useKeyDown";
|
import useKeyDown from "~/hooks/useKeyDown";
|
||||||
|
import { MenuProvider } from "~/hooks/useMenuContext";
|
||||||
import useStores from "~/hooks/useStores";
|
import useStores from "~/hooks/useStores";
|
||||||
import { isModKey } from "~/utils/keyboard";
|
import { isModKey } from "~/utils/keyboard";
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ function Layout({ title, children, sidebar, rightRail }: Props) {
|
|||||||
{ui.progressBarVisible && <LoadingIndicatorBar />}
|
{ui.progressBarVisible && <LoadingIndicatorBar />}
|
||||||
|
|
||||||
<Container auto>
|
<Container auto>
|
||||||
{sidebar}
|
<MenuProvider>{sidebar}</MenuProvider>
|
||||||
|
|
||||||
<SkipNavContent />
|
<SkipNavContent />
|
||||||
<Content
|
<Content
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { useLocation } from "react-router-dom";
|
|||||||
import styled, { useTheme } from "styled-components";
|
import styled, { useTheme } from "styled-components";
|
||||||
import breakpoint from "styled-components-breakpoint";
|
import breakpoint from "styled-components-breakpoint";
|
||||||
import Flex from "~/components/Flex";
|
import Flex from "~/components/Flex";
|
||||||
|
import useMenuContext from "~/hooks/useMenuContext";
|
||||||
import usePrevious from "~/hooks/usePrevious";
|
import usePrevious from "~/hooks/usePrevious";
|
||||||
import useStores from "~/hooks/useStores";
|
import useStores from "~/hooks/useStores";
|
||||||
import { fadeIn } from "~/styles/animations";
|
import { fadeIn } from "~/styles/animations";
|
||||||
@@ -26,8 +27,9 @@ const Sidebar = React.forwardRef<HTMLDivElement, Props>(
|
|||||||
const { ui } = useStores();
|
const { ui } = useStores();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const previousLocation = usePrevious(location);
|
const previousLocation = usePrevious(location);
|
||||||
|
const { isMenuOpen } = useMenuContext();
|
||||||
const width = ui.sidebarWidth;
|
const width = ui.sidebarWidth;
|
||||||
const collapsed = ui.isEditing || ui.sidebarCollapsed;
|
const collapsed = (ui.isEditing || ui.sidebarCollapsed) && !isMenuOpen;
|
||||||
const maxWidth = theme.sidebarMaxWidth;
|
const maxWidth = theme.sidebarMaxWidth;
|
||||||
const minWidth = theme.sidebarMinWidth + 16; // padding
|
const minWidth = theme.sidebarMinWidth + 16; // padding
|
||||||
|
|
||||||
|
|||||||
31
app/hooks/useMenuContext.tsx
Normal file
31
app/hooks/useMenuContext.tsx
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { noop } from "lodash";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
type MenuContextType = {
|
||||||
|
isMenuOpen: boolean;
|
||||||
|
setIsMenuOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const MenuContext = React.createContext<MenuContextType | null>(null);
|
||||||
|
|
||||||
|
export const MenuProvider: React.FC = ({ children }) => {
|
||||||
|
const [isMenuOpen, setIsMenuOpen] = React.useState(false);
|
||||||
|
const memoized = React.useMemo(
|
||||||
|
() => ({
|
||||||
|
isMenuOpen,
|
||||||
|
setIsMenuOpen,
|
||||||
|
}),
|
||||||
|
[isMenuOpen, setIsMenuOpen]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MenuContext.Provider value={memoized}>{children}</MenuContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const useMenuContext: () => MenuContextType = () => {
|
||||||
|
const value = React.useContext(MenuContext);
|
||||||
|
return value ? value : { isMenuOpen: false, setIsMenuOpen: noop };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useMenuContext;
|
||||||
Reference in New Issue
Block a user