diff --git a/.betterer.results b/.betterer.results index 22be1f2f322..8a02d1a063f 100644 --- a/.betterer.results +++ b/.betterer.results @@ -942,9 +942,7 @@ exports[`better eslint`] = { [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "2"] ], "packages/grafana-ui/src/components/Drawer/Drawer.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"], - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "1"], - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "2"] + [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] ], "packages/grafana-ui/src/components/Dropdown/ButtonSelect.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] diff --git a/e2e/various-suite/inspect-drawer.spec.ts b/e2e/various-suite/inspect-drawer.spec.ts index 155f1c7cd12..7d19f3686b4 100644 --- a/e2e/various-suite/inspect-drawer.spec.ts +++ b/e2e/various-suite/inspect-drawer.spec.ts @@ -41,8 +41,6 @@ e2e.scenario({ expectDrawerTabsAndContent(); - expectDrawerExpandAndContract(viewPortWidth); - expectDrawerClose(); expectSubMenuScenario('Data'); @@ -107,30 +105,6 @@ const expectDrawerClose = () => { e2e.components.Drawer.General.title(`Inspect: ${PANEL_UNDER_TEST}`).should('not.exist'); }; -const expectDrawerExpandAndContract = (viewPortWidth: number) => { - // try expand button - // drawer should take up half the screen - e2e.components.Drawer.General.rcContentWrapper() - .should('be.visible') - .should('have.css', 'width', `${viewPortWidth / 2}px`); - - e2e.components.Drawer.General.expand().click(); - e2e.components.Drawer.General.contract().should('be.visible'); - - // drawer should take up the whole screen - e2e.components.Drawer.General.rcContentWrapper() - .should('be.visible') - .should('have.css', 'width', `${viewPortWidth}px`); - - // try contract button - e2e.components.Drawer.General.contract().click(); - e2e.components.Drawer.General.expand().should('be.visible'); - - e2e.components.Drawer.General.rcContentWrapper() - .should('be.visible') - .should('have.css', 'width', `${viewPortWidth / 2}px`); -}; - const expectSubMenuScenario = (subMenu: string, tabTitle?: string) => { tabTitle = tabTitle ?? subMenu; // testing opening inspect drawer from sub menus under Inspect in header menu diff --git a/packages/grafana-ui/src/components/Drawer/Drawer.tsx b/packages/grafana-ui/src/components/Drawer/Drawer.tsx index 1aad5038d33..80fea394303 100644 --- a/packages/grafana-ui/src/components/Drawer/Drawer.tsx +++ b/packages/grafana-ui/src/components/Drawer/Drawer.tsx @@ -3,14 +3,17 @@ import { useDialog } from '@react-aria/dialog'; import { FocusScope } from '@react-aria/focus'; import { useOverlay } from '@react-aria/overlays'; import RcDrawer from 'rc-drawer'; -import React, { ReactNode, useState, useEffect } from 'react'; +import React, { ReactNode, useEffect } from 'react'; +import { useClickAway } from 'react-use'; import { GrafanaTheme2 } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { useStyles2 } from '../../themes'; +import { Button } from '../Button'; import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; -import { IconButton } from '../IconButton/IconButton'; +//import { IconButton } from '../IconButton/IconButton'; +import { Text } from '../Text/Text'; export interface Props { children: ReactNode; @@ -26,7 +29,9 @@ export interface Props { * @deprecated use the size property instead **/ width?: number | string; - /** Should the Drawer be expandable to full width */ + /** + * @deprecated use a large size instead if high width is needed + **/ expandable?: boolean; /** * Specifies the width and min-width. @@ -52,39 +57,35 @@ export function Drawer({ subtitle, width, size = 'md', - expandable = false, tabs, }: Props) { const styles = useStyles2(getStyles); - const [isExpanded, setIsExpanded] = useState(false); - const [isOpen, setIsOpen] = useState(false); const overlayRef = React.useRef(null); const { dialogProps, titleProps } = useDialog({}, overlayRef); const { overlayProps } = useOverlay( { isDismissable: false, - isOpen, + isOpen: true, onClose, }, overlayRef ); - // RcDrawer v4.x needs to be mounted in advance for animations to play. - useEffect(() => { - setIsOpen(true); - }, []); + // Adds body class while open so the toolbar nav can hide some actions while drawer is open + useBodyClassWhileOpen(); + useClickAway(overlayRef, onClose); - // deprecated width prop now defaults to empty string which make the size prop take over - const fixedWidth = isExpanded ? '100%' : width ?? ''; - const rootClass = cx(styles.drawer, !fixedWidth && styles.sizes[size]); + // Apply size styles (unless deprecated width prop is used) + const rootClass = cx(styles.drawer, !width && styles.sizes[size]); const content =
{children}
; return ( {typeof title === 'string' && ( -
+
- {expandable && !isExpanded && ( - setIsExpanded(true)} - aria-label={selectors.components.Drawer.General.expand} - /> - )} - {expandable && isExpanded && ( - setIsExpanded(false)} - aria-label={selectors.components.Drawer.General.contract} - /> - )} -
-

{title}

- {typeof subtitle === 'string' &&
{subtitle}
} - {typeof subtitle !== 'string' && subtitle} + + {title} + + {subtitle &&
{subtitle}
} {tabs &&
{tabs}
}
@@ -155,6 +142,20 @@ export function Drawer({ ); } +function useBodyClassWhileOpen() { + useEffect(() => { + if (!document.body) { + return; + } + + document.body.classList.add('body-drawer-open'); + + return () => { + document.body.classList.remove('body-drawer-open'); + }; + }, []); +} + const getStyles = (theme: GrafanaTheme2) => { return { container: css` @@ -164,6 +165,14 @@ const getStyles = (theme: GrafanaTheme2) => { flex: 1 1 0; `, drawer: css` + .main-view & { + top: 81px; + } + + .main-view--search-bar-hidden & { + top: 41px; + } + .rc-drawer-content-wrapper { box-shadow: ${theme.shadows.z3}; @@ -185,7 +194,7 @@ const getStyles = (theme: GrafanaTheme2) => { '.rc-drawer-content-wrapper': { label: 'drawer-md', width: '50vw', - minWidth: theme.spacing(66), + minWidth: theme.spacing(60), }, }), lg: css({ @@ -233,21 +242,26 @@ const getStyles = (theme: GrafanaTheme2) => { } } `, - header: css` - background-color: ${theme.colors.background.canvas}; - flex-grow: 0; - padding-top: ${theme.spacing(0.5)}; - `, - actions: css` - display: flex; - align-items: baseline; - justify-content: flex-end; - `, + header: css({ + flexGrow: 0, + padding: theme.spacing(3, 2), + borderBottom: `1px solid ${theme.colors.border.weak}`, + }), + headerWithTabs: css({ + borderBottom: 'none', + }), + actions: css({ + position: 'absolute', + right: theme.spacing(1), + top: theme.spacing(2), + }), titleWrapper: css` - margin-bottom: ${theme.spacing(3)}; - padding: ${theme.spacing(0, 1, 0, 3)}; overflow-wrap: break-word; `, + subtitle: css({ + color: theme.colors.text.secondary, + paddingTop: theme.spacing(1), + }), content: css({ padding: theme.spacing(2), height: '100%', @@ -259,7 +273,7 @@ const getStyles = (theme: GrafanaTheme2) => { }), tabsWrapper: css({ paddingLeft: theme.spacing(2), - margin: theme.spacing(3, -1, -3, -3), + margin: theme.spacing(2, -1, -3, -3), }), }; }; diff --git a/public/app/core/components/AppChrome/AppChrome.tsx b/public/app/core/components/AppChrome/AppChrome.tsx index f140eaa06a9..72489c28fa2 100644 --- a/public/app/core/components/AppChrome/AppChrome.tsx +++ b/public/app/core/components/AppChrome/AppChrome.tsx @@ -1,4 +1,5 @@ import { css, cx } from '@emotion/css'; +import classNames from 'classnames'; import React, { PropsWithChildren } from 'react'; import { GrafanaTheme2, PageLayoutType } from '@grafana/data'; @@ -33,7 +34,7 @@ export function AppChrome({ children }: Props) { // doesn't get re-mounted when chromeless goes from true to false. return ( -
+
{!state.chromeless && (
{!searchBarHidden && } diff --git a/public/app/core/components/AppChrome/NavToolbar/NavToolbar.tsx b/public/app/core/components/AppChrome/NavToolbar/NavToolbar.tsx index fc7f789ca75..2dbb4f82c90 100644 --- a/public/app/core/components/AppChrome/NavToolbar/NavToolbar.tsx +++ b/public/app/core/components/AppChrome/NavToolbar/NavToolbar.tsx @@ -82,7 +82,6 @@ const getStyles = (theme: GrafanaTheme2) => { display: 'flex', padding: theme.spacing(0, 1, 0, 2), alignItems: 'center', - justifyContent: 'space-between', }), menuButton: css({ display: 'flex', @@ -90,6 +89,7 @@ const getStyles = (theme: GrafanaTheme2) => { marginRight: theme.spacing(1), }), actions: css({ + label: 'NavToolbar-actions', display: 'flex', alignItems: 'center', flexWrap: 'nowrap', @@ -98,6 +98,10 @@ const getStyles = (theme: GrafanaTheme2) => { flexGrow: 1, gap: theme.spacing(0.5), minWidth: 0, + + '.body-drawer-open &': { + display: 'none', + }, }), }; }; diff --git a/public/app/features/dashboard/components/HelpWizard/HelpWizard.tsx b/public/app/features/dashboard/components/HelpWizard/HelpWizard.tsx index 541dc7bba11..4f9fa35d360 100644 --- a/public/app/features/dashboard/components/HelpWizard/HelpWizard.tsx +++ b/public/app/features/dashboard/components/HelpWizard/HelpWizard.tsx @@ -74,7 +74,6 @@ export function HelpWizard({ panel, plugin, onClose }: Props) { title={`Get help with this panel`} size="lg" onClose={onClose} - expandable scrollableContent subtitle={ diff --git a/public/app/features/dashboard/components/Inspector/InspectContent.tsx b/public/app/features/dashboard/components/Inspector/InspectContent.tsx index af5446806b9..5b2bbf9956d 100644 --- a/public/app/features/dashboard/components/Inspector/InspectContent.tsx +++ b/public/app/features/dashboard/components/Inspector/InspectContent.tsx @@ -69,7 +69,6 @@ export const InspectContent = ({ title={title} subtitle={data && formatStats(data)} onClose={onClose} - expandable scrollableContent tabs={ diff --git a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardDrawer.tsx b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardDrawer.tsx index 5b02cbd731e..18a2c6157fb 100644 --- a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardDrawer.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardDrawer.tsx @@ -140,7 +140,6 @@ export const SaveDashboardDrawer = ({ dashboard, onDismiss, onSaveSuccess, isCop )} } - expandable scrollableContent > {renderSaveBody()}