From fc9577b76df5c004a002363c2957400848151a47 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov <80879390+kitsuned@users.noreply.github.com> Date: Wed, 3 Aug 2022 16:08:39 +0500 Subject: [PATCH] MegaMenu: Fix broken hamburger toggle (#52770) * MegaMenu: Fix broken hamburger toggle * oops * MegaMenu: move NavBarToggle to FocusScope --- .../core/components/AppChrome/AppChrome.tsx | 4 +- .../components/AppChrome/AppChromeService.tsx | 4 ++ .../components/MegaMenu/MegaMenu.test.tsx | 17 +++-- .../core/components/MegaMenu/NavBarMenu.tsx | 67 ++++++++++++------- 4 files changed, 59 insertions(+), 33 deletions(-) diff --git a/public/app/core/components/AppChrome/AppChrome.tsx b/public/app/core/components/AppChrome/AppChrome.tsx index 2f987dc1b27..950286821eb 100644 --- a/public/app/core/components/AppChrome/AppChrome.tsx +++ b/public/app/core/components/AppChrome/AppChrome.tsx @@ -20,7 +20,7 @@ export function AppChrome({ children }: Props) { const state = chrome.useState(); if (state.chromeless || !config.featureToggles.topnav) { - return
{children}
; + return
{children}
; } return ( @@ -37,7 +37,7 @@ export function AppChrome({ children }: Props) { />
{children}
- {state.megaMenuOpen && } + chrome.setMegaMenu(false)} /> ); } diff --git a/public/app/core/components/AppChrome/AppChromeService.tsx b/public/app/core/components/AppChrome/AppChromeService.tsx index dd9a6b04a04..f9092690817 100644 --- a/public/app/core/components/AppChrome/AppChromeService.tsx +++ b/public/app/core/components/AppChrome/AppChromeService.tsx @@ -62,6 +62,10 @@ export class AppChromeService { this.update({ megaMenuOpen: !this.state.getValue().megaMenuOpen }); }; + setMegaMenu = (megaMenuOpen: boolean) => { + this.update({ megaMenuOpen }); + }; + toggleSearchBar = () => { const searchBarHidden = !this.state.getValue().searchBarHidden; store.set(this.searchBarStorageKey, searchBarHidden); diff --git a/public/app/core/components/MegaMenu/MegaMenu.test.tsx b/public/app/core/components/MegaMenu/MegaMenu.test.tsx index 04283424de5..e7fab5a8e6a 100644 --- a/public/app/core/components/MegaMenu/MegaMenu.test.tsx +++ b/public/app/core/components/MegaMenu/MegaMenu.test.tsx @@ -2,9 +2,11 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; import { Provider } from 'react-redux'; import { Router } from 'react-router-dom'; +import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock'; import { NavModelItem, NavSection } from '@grafana/data'; import { locationService } from '@grafana/runtime'; +import { GrafanaContext } from 'app/core/context/GrafanaContext'; import { configureStore } from 'app/store/configureStore'; import TestProvider from '../../../../test/helpers/TestProvider'; @@ -31,15 +33,20 @@ const setup = () => { }, ]; + const context = getGrafanaContextMock(); const store = configureStore({ navBarTree }); + context.chrome.toggleMegaMenu(); + return render( - - - {}} /> - - + + + + {}} /> + + + ); }; diff --git a/public/app/core/components/MegaMenu/NavBarMenu.tsx b/public/app/core/components/MegaMenu/NavBarMenu.tsx index 2b2df363de4..5eb41abd64f 100644 --- a/public/app/core/components/MegaMenu/NavBarMenu.tsx +++ b/public/app/core/components/MegaMenu/NavBarMenu.tsx @@ -2,12 +2,13 @@ import { css } from '@emotion/css'; import { useDialog } from '@react-aria/dialog'; import { FocusScope } from '@react-aria/focus'; import { OverlayContainer, useOverlay } from '@react-aria/overlays'; -import React, { useRef } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import CSSTransition from 'react-transition-group/CSSTransition'; import { GrafanaTheme2, NavModelItem } from '@grafana/data'; import { reportInteraction } from '@grafana/runtime'; import { CustomScrollbar, Icon, IconButton, useTheme2 } from '@grafana/ui'; +import { useGrafana } from 'app/core/context/GrafanaContext'; import { TOP_BAR_LEVEL_HEIGHT } from '../AppChrome/types'; import { NavItem } from '../NavBar/NavBarMenu'; @@ -27,29 +28,47 @@ export function NavBarMenu({ activeItem, navItems, searchBarHidden, onClose }: P const styles = getStyles(theme, searchBarHidden); const animationSpeed = theme.transitions.duration.shortest; const animStyles = getAnimStyles(theme, animationSpeed); + const { chrome } = useGrafana(); + const state = chrome.useState(); const ref = useRef(null); + const backdropRef = useRef(null); const { dialogProps } = useDialog({}, ref); + const [isOpen, setIsOpen] = useState(false); + + const onMenuClose = () => setIsOpen(false); const { overlayProps, underlayProps } = useOverlay( { isDismissable: true, isOpen: true, - onClose, + onClose: onMenuClose, }, ref ); + useEffect(() => { + if (state.megaMenuOpen) { + setIsOpen(true); + } + }, [state.megaMenuOpen]); + return ( - - -
+ +
+
@@ -59,24 +78,24 @@ export function NavBarMenu({ activeItem, navItems, searchBarHidden, onClose }: P isExpanded={true} onClick={() => { reportInteraction('grafana_navigation_collapsed'); - onClose(); + onMenuClose(); }} /> -
- - -
- - + +
+
+ +
+ ); } @@ -109,6 +128,7 @@ const getStyles = (theme: GrafanaTheme2, searchBarHidden?: boolean) => { zIndex: theme.zIndex.navbarFixed - 1, position: 'fixed', top: topPosition, + backgroundColor: theme.colors.background.primary, boxSizing: 'content-box', [theme.breakpoints.up('md')]: { borderRight: `1px solid ${theme.colors.border.weak}`, @@ -154,7 +174,7 @@ const getAnimStyles = (theme: GrafanaTheme2, animationDuration: number) => { const overlayTransition = { ...commonTransition, - transitionProperty: 'background-color, box-shadow, width', + transitionProperty: 'box-shadow, width', // this is needed to prevent a horizontal scrollbar during the animation on firefox '.scrollbar-view': { overflow: 'hidden !important', @@ -167,7 +187,6 @@ const getAnimStyles = (theme: GrafanaTheme2, animationDuration: number) => { }; const overlayOpen = { - backgroundColor: theme.colors.background.primary, boxShadow: theme.shadows.z3, width: '100%', [theme.breakpoints.up('md')]: { @@ -178,10 +197,6 @@ const getAnimStyles = (theme: GrafanaTheme2, animationDuration: number) => { const overlayClosed = { boxShadow: 'none', width: 0, - [theme.breakpoints.up('md')]: { - backgroundColor: theme.colors.background.primary, - width: theme.spacing(7), - }, }; const backdropOpen = { @@ -194,16 +209,16 @@ const getAnimStyles = (theme: GrafanaTheme2, animationDuration: number) => { return { backdrop: { - appear: css(backdropClosed), - appearActive: css(backdropTransition, backdropOpen), - appearDone: css(backdropOpen), + enter: css(backdropClosed), + enterActive: css(backdropTransition, backdropOpen), + enterDone: css(backdropOpen), exit: css(backdropOpen), exitActive: css(backdropTransition, backdropClosed), }, overlay: { - appear: css(overlayClosed), - appearActive: css(overlayTransition, overlayOpen), - appearDone: css(overlayOpen), + enter: css(overlayClosed), + enterActive: css(overlayTransition, overlayOpen), + enterDone: css(overlayOpen), exit: css(overlayOpen), exitActive: css(overlayTransition, overlayClosed), },