diff --git a/public/app/features/dashboard-scene/scene/DashboardControls.tsx b/public/app/features/dashboard-scene/scene/DashboardControls.tsx index 5614c57bfd4..e47d048d8dc 100644 --- a/public/app/features/dashboard-scene/scene/DashboardControls.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardControls.tsx @@ -144,8 +144,7 @@ function getStyles(theme: GrafanaTheme2) { gap: theme.spacing(1), flexDirection: 'row', flexWrap: 'nowrap', - position: 'sticky', - top: 0, + position: 'relative', background: theme.colors.background.canvas, zIndex: theme.zIndex.activePanel, width: '100%', @@ -154,6 +153,10 @@ function getStyles(theme: GrafanaTheme2) { flexDirection: 'column-reverse', alignItems: 'stretch', }, + [theme.breakpoints.up('sm')]: { + position: 'sticky', + top: 0, + }, }), embedded: css({ background: 'unset', diff --git a/public/app/features/dashboard-scene/scene/DashboardSceneRenderer.tsx b/public/app/features/dashboard-scene/scene/DashboardSceneRenderer.tsx index 28f75ecffdf..cfb7d8ff713 100644 --- a/public/app/features/dashboard-scene/scene/DashboardSceneRenderer.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardSceneRenderer.tsx @@ -1,11 +1,12 @@ import { css, cx } from '@emotion/css'; import React from 'react'; import { useLocation } from 'react-router-dom'; +import { useMedia } from 'react-use'; import { GrafanaTheme2, PageLayoutType } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { SceneComponentProps } from '@grafana/scenes'; -import { CustomScrollbar, useStyles2 } from '@grafana/ui'; +import { CustomScrollbar, useStyles2, useTheme2 } from '@grafana/ui'; import { Page } from 'app/core/components/Page/Page'; import { getNavModel } from 'app/core/selectors/navModel'; import DashboardEmpty from 'app/features/dashboard/dashgrid/DashboardEmpty'; @@ -63,18 +64,17 @@ export function DashboardSceneRenderer({ model }: SceneComponentProps )} -
<>{isEmpty && emptyState} {withPanels}
-
+ )} {overlay && } @@ -91,6 +91,10 @@ function getStyles(theme: GrafanaTheme2) { gridTemplateColumns: `1fr`, gridTemplateRows: '1fr', height: '100%', + [theme.breakpoints.down('sm')]: { + display: 'flex', + flexDirection: 'column', + }, }), pageContainerWithControls: css({ gridTemplateAreas: ` @@ -110,7 +114,7 @@ function getStyles(theme: GrafanaTheme2) { "scopes controls" "scopes panels"`, }), - scrollbarContainer: css({ + panelsContainer: css({ gridArea: 'panels', }), controlsWrapper: css({ @@ -147,3 +151,34 @@ function getStyles(theme: GrafanaTheme2) { }), }; } + +interface PanelsContainerProps { + id: string; + children: React.ReactNode; + className?: string; + testId?: string; +} +/** + * Removes the scrollbar on mobile and uses a custom scrollbar on desktop + */ +const PanelsContainer = ({ id, children, className, testId }: PanelsContainerProps) => { + const theme = useTheme2(); + const isMobile = useMedia(`(max-width: ${theme.breakpoints.values.sm}px)`); + const styles = useStyles2(() => ({ + nonScrollable: css({ + height: '100%', + display: 'flex', + flexDirection: 'column', + }), + })); + + return isMobile ? ( +
+ {children} +
+ ) : ( + + {children} + + ); +};