From 369cd6f81e59048d4f8518530ff6ab8b505ff280 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Mon, 12 Aug 2024 13:22:14 +0100 Subject: [PATCH] Chore: Migrate `dashboard_grid` styles to emotion (#91673) migrate dashboard grid styles to emotion --- .../src/themes/GlobalStyles/GlobalStyles.tsx | 2 + .../src/themes/GlobalStyles/dashboardGrid.ts | 68 +++++++++++ .../dashboard/containers/DashboardPage.tsx | 46 +++++++- public/sass/_grafana.scss | 1 - public/sass/components/_dashboard_grid.scss | 106 ------------------ 5 files changed, 112 insertions(+), 111 deletions(-) create mode 100644 packages/grafana-ui/src/themes/GlobalStyles/dashboardGrid.ts delete mode 100644 public/sass/components/_dashboard_grid.scss diff --git a/packages/grafana-ui/src/themes/GlobalStyles/GlobalStyles.tsx b/packages/grafana-ui/src/themes/GlobalStyles/GlobalStyles.tsx index 59587af744d..6434df3cdb6 100644 --- a/packages/grafana-ui/src/themes/GlobalStyles/GlobalStyles.tsx +++ b/packages/grafana-ui/src/themes/GlobalStyles/GlobalStyles.tsx @@ -7,6 +7,7 @@ import { getAlertingStyles } from './alerting'; import { getAgularPanelStyles } from './angularPanelStyles'; import { getCardStyles } from './card'; import { getCodeStyles } from './code'; +import { getDashboardGridStyles } from './dashboardGrid'; import { getDashDiffStyles } from './dashdiff'; import { getElementStyles } from './elements'; import { getExtraStyles } from './extra'; @@ -35,6 +36,7 @@ export function GlobalStyles() { getAlertingStyles(theme), getCodeStyles(theme), getDashDiffStyles(theme), + getDashboardGridStyles(theme), getElementStyles(theme), getExtraStyles(theme), getFilterTableStyles(theme), diff --git a/packages/grafana-ui/src/themes/GlobalStyles/dashboardGrid.ts b/packages/grafana-ui/src/themes/GlobalStyles/dashboardGrid.ts new file mode 100644 index 00000000000..bbd6d6da876 --- /dev/null +++ b/packages/grafana-ui/src/themes/GlobalStyles/dashboardGrid.ts @@ -0,0 +1,68 @@ +import { css } from '@emotion/react'; + +import { GrafanaTheme2 } from '@grafana/data'; + +export function getDashboardGridStyles(theme: GrafanaTheme2) { + return css({ + '.react-resizable-handle': { + // this needs to use visibility and not display none in order not to cause resize flickering + visibility: 'hidden', + }, + + '.react-grid-item, #grafana-portal-container': { + touchAction: 'initial !important', + + '&:hover': { + '.react-resizable-handle': { + visibility: 'visible', + }, + }, + }, + + [theme.breakpoints.down('md')]: { + '.react-grid-item': { + display: 'block !important', + transitionProperty: 'none !important', + // can't avoid type assertion here due to !important + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + position: 'unset !important' as 'unset', + transform: 'translate(0px, 0px) !important', + marginBottom: theme.spacing(2), + }, + '.panel-repeater-grid-item': { + height: 'auto !important', + }, + }, + + '.react-grid-item.react-grid-placeholder': { + boxShadow: `0 0 4px ${theme.colors.primary.border} !important`, + background: `${theme.colors.primary.transparent} !important`, + zIndex: '-1 !important', + opacity: 'unset !important', + }, + + '.react-grid-item > .react-resizable-handle::after': { + borderRight: `2px solid ${theme.isDark ? theme.v1.palette.gray1 : theme.v1.palette.gray3} !important`, + borderBottom: `2px solid ${theme.isDark ? theme.v1.palette.gray1 : theme.v1.palette.gray3} !important`, + }, + + // Hack for preventing panel menu overlapping. + '.react-grid-item.resizing.panel, .react-grid-item.panel.dropdown-menu-open, .react-grid-item.react-draggable-dragging.panel': + { + zIndex: theme.zIndex.dropdown, + }, + + // Disable animation on initial rendering and enable it when component has been mounted. + '.react-grid-item.cssTransforms': { + transitionProperty: 'none !important', + }, + + [theme.transitions.handleMotion('no-preference')]: { + '.react-grid-layout--enable-move-animations': { + '.react-grid-item.cssTransforms': { + transitionProperty: 'transform !important', + }, + }, + }, + }); +} diff --git a/public/app/features/dashboard/containers/DashboardPage.tsx b/public/app/features/dashboard/containers/DashboardPage.tsx index 27e356bb9fa..310bebf2b4b 100644 --- a/public/app/features/dashboard/containers/DashboardPage.tsx +++ b/public/app/features/dashboard/containers/DashboardPage.tsx @@ -1,8 +1,8 @@ -import { cx } from '@emotion/css'; +import { css, cx } from '@emotion/css'; import { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { NavModel, NavModelItem, TimeRange, PageLayoutType, locationUtil } from '@grafana/data'; +import { NavModel, NavModelItem, TimeRange, PageLayoutType, locationUtil, GrafanaTheme2 } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { config, locationService } from '@grafana/runtime'; import { Themeable2, withTheme2 } from '@grafana/ui'; @@ -44,6 +44,9 @@ import { initDashboard } from '../state/initDashboard'; import { DashboardPageRouteParams, DashboardPageRouteSearchParams } from './types'; +import 'react-grid-layout/css/styles.css'; +import 'react-resizable/css/styles.css'; + export const mapStateToProps = (state: StoreState) => ({ initPhase: state.dashboard.initPhase, initError: state.dashboard.initError, @@ -79,6 +82,40 @@ export interface State { sectionNav?: NavModel; } +const getStyles = (theme: GrafanaTheme2) => ({ + fullScreenPanel: css({ + '.react-grid-layout': { + height: 'auto !important', + transitionProperty: 'none', + }, + '.react-grid-item': { + display: 'none !important', + transitionProperty: 'none !important', + + '&--fullscreen': { + display: 'block !important', + // can't avoid type assertion here due to !important + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + position: 'unset !important' as 'unset', + transform: 'translate(0px, 0px) !important', + }, + }, + + // Disable grid interaction indicators in fullscreen panels + '.panel-header:hover': { + backgroundColor: 'inherit', + }, + + '.panel-title-container': { + cursor: 'pointer', + }, + + '.react-resizable-handle': { + display: 'none', + }, + }), +}); + export class UnthemedDashboardPage extends PureComponent { declare context: GrafanaContextType; static contextType = GrafanaContext; @@ -328,9 +365,10 @@ export class UnthemedDashboardPage extends PureComponent { }; render() { - const { dashboard, initError, queryParams } = this.props; + const { dashboard, initError, queryParams, theme } = this.props; const { editPanel, viewPanel, updateScrollTop, pageNav, sectionNav } = this.state; const kioskMode = getKioskMode(this.props.queryParams); + const styles = getStyles(theme); if (!dashboard || !pageNav || !sectionNav) { return ; @@ -342,7 +380,7 @@ export class UnthemedDashboardPage extends PureComponent { const showToolbar = kioskMode !== KioskMode.Full && !queryParams.editview; const pageClassName = cx({ - 'panel-in-fullscreen': Boolean(viewPanel), + [styles.fullScreenPanel]: Boolean(viewPanel), 'page-hidden': Boolean(queryParams.editview || editPanel), }); diff --git a/public/sass/_grafana.scss b/public/sass/_grafana.scss index 6c32eb073a9..f9eedb5bf43 100644 --- a/public/sass/_grafana.scss +++ b/public/sass/_grafana.scss @@ -14,7 +14,6 @@ // COMPONENTS @import 'components/buttons'; @import 'components/dropdown'; -@import 'components/dashboard_grid'; // ANGULAR @import 'angular'; diff --git a/public/sass/components/_dashboard_grid.scss b/public/sass/components/_dashboard_grid.scss deleted file mode 100644 index 7185a2a9be2..00000000000 --- a/public/sass/components/_dashboard_grid.scss +++ /dev/null @@ -1,106 +0,0 @@ -@import 'react-grid-layout/css/styles'; -@import 'react-resizable/css/styles'; - -.react-resizable-handle { - // this needs to use visibility and not display none in order not to cause resize flickering - visibility: hidden; -} - -.react-grid-item, -#grafana-portal-container { - touch-action: initial !important; - - &:hover { - .react-resizable-handle { - visibility: visible; - } - } -} - -.panel-in-fullscreen { - .react-grid-layout { - height: auto !important; - } - .react-grid-item { - display: none !important; - transition-property: none !important; - - &--fullscreen { - display: block !important; - position: unset !important; - transform: translate(0px, 0px) !important; - } - } - - // Disable grid interaction indicators in fullscreen panels - .panel-header:hover { - background-color: inherit; - } - - .panel-title-container { - cursor: pointer; - } - - .react-resizable-handle { - display: none; - } - - // the react-grid has a height transition - .react-grid-layout { - transition-property: none; - } -} - -@include media-breakpoint-down(sm) { - .react-grid-item { - display: block !important; - transition-property: none !important; - position: unset !important; - transform: translate(0px, 0px) !important; - margin-bottom: $space-md; - } - .panel-repeater-grid-item { - height: auto !important; - } -} - -.react-grid-item.react-grid-placeholder { - box-shadow: $panel-grid-placeholder-shadow; - background: $panel-grid-placeholder-bg; - z-index: -1; - opacity: unset; -} - -.theme-dark { - .react-grid-item > .react-resizable-handle::after { - border-right: 2px solid $gray-1; - border-bottom: 2px solid $gray-1; - } -} - -.theme-light { - .react-grid-item > .react-resizable-handle::after { - border-right: 2px solid $gray-3; - border-bottom: 2px solid $gray-3; - } -} - -// Hack for preventing panel menu overlapping. -.react-grid-item.resizing.panel, -.react-grid-item.panel.dropdown-menu-open, -.react-grid-item.react-draggable-dragging.panel { - z-index: $zindex-dropdown; -} - -// Disable animation on initial rendering and enable it when component has been mounted. -.react-grid-item.cssTransforms { - transition-property: none; -} - -@media (prefers-reduced-motion: no-preference) { - .react-grid-layout--enable-move-animations { - .react-grid-item.cssTransforms { - transition-property: transform; - } - } -}