Drawer: Clicking a `Select` arrow within a `Drawer` no longer causes it to close (#73557)

ensure drawer doesn't close when clicking dropdown arrow
This commit is contained in:
Ashley Harrison 2023-08-22 16:11:18 +01:00 committed by GitHub
parent cf9da12975
commit 1f49d480a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 10 deletions

View File

@ -4,7 +4,6 @@ import { FocusScope } from '@react-aria/focus';
import { useOverlay } from '@react-aria/overlays'; import { useOverlay } from '@react-aria/overlays';
import RcDrawer from 'rc-drawer'; import RcDrawer from 'rc-drawer';
import React, { ReactNode, useEffect } from 'react'; import React, { ReactNode, useEffect } from 'react';
import { useClickAway } from 'react-use';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
@ -73,8 +72,6 @@ export function Drawer({
// Adds body class while open so the toolbar nav can hide some actions while drawer is open // Adds body class while open so the toolbar nav can hide some actions while drawer is open
useBodyClassWhileOpen(); useBodyClassWhileOpen();
// Close when we click outside mask (topnav) but only if closeOnMaskClick is true
useClickAway(overlayRef, closeOnMaskClick ? onClose : doNothing);
// Apply size styles (unless deprecated width prop is used) // Apply size styles (unless deprecated width prop is used)
const rootClass = cx(styles.drawer, !width && styles.sizes[size]); const rootClass = cx(styles.drawer, !width && styles.sizes[size]);
@ -143,8 +140,6 @@ export function Drawer({
); );
} }
function doNothing() {}
function useBodyClassWhileOpen() { function useBodyClassWhileOpen() {
useEffect(() => { useEffect(() => {
if (!document.body) { if (!document.body) {
@ -170,11 +165,15 @@ const getStyles = (theme: GrafanaTheme2) => {
}), }),
drawer: css({ drawer: css({
'.main-view &': { '.main-view &': {
top: '81px', top: 81,
}, },
'.main-view--search-bar-hidden &': { '.main-view--search-bar-hidden &': {
top: '41px', top: 41,
},
'.main-view--chrome-hidden &': {
top: 0,
}, },
'.rc-drawer-content-wrapper': { '.rc-drawer-content-wrapper': {
@ -232,9 +231,35 @@ const getStyles = (theme: GrafanaTheme2) => {
}, },
}, },
}), }),
// we want the mask itself to span the whole page including the top bar
// this ensures trying to click something in the top bar will close the drawer correctly
// but we don't want the backdrop styling to apply over the top bar as it looks weird
// instead have a child pseudo element to apply the backdrop styling below the top bar
mask: css({ mask: css({
backgroundColor: 'transparent',
position: 'fixed',
'&:before': {
backgroundColor: `${theme.components.overlay.background} !important`, backgroundColor: `${theme.components.overlay.background} !important`,
backdropFilter: 'blur(1px)', backdropFilter: 'blur(1px)',
bottom: 0,
content: '""',
left: 0,
position: 'fixed',
right: 0,
'.main-view &': {
top: 81,
},
'.main-view--search-bar-hidden &': {
top: 41,
},
'.main-view--chrome-hidden &': {
top: 0,
},
},
}), }),
maskMotion: css({ maskMotion: css({
'&-appear': { '&-appear': {

View File

@ -34,7 +34,12 @@ export function AppChrome({ children }: Props) {
// doesn't get re-mounted when chromeless goes from true to false. // doesn't get re-mounted when chromeless goes from true to false.
return ( return (
<div className={classNames('main-view', searchBarHidden && 'main-view--search-bar-hidden')}> <div
className={classNames('main-view', {
'main-view--search-bar-hidden': searchBarHidden && !state.chromeless,
'main-view--chrome-hidden': state.chromeless,
})}
>
{!state.chromeless && ( {!state.chromeless && (
<> <>
<LinkButton className={styles.skipLink} href="#pageContent"> <LinkButton className={styles.skipLink} href="#pageContent">