From 7ecad55bffbc8aad9ed6cbedb4ac3bec666ef8c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 11 Mar 2025 09:16:29 +0100 Subject: [PATCH] Tabs: Reduce active border from 4 px to 2px (#101888) * Tabs: Reduce active border from 4 to 2px * css fixes --- .../src/themes/createComponents.ts | 4 +- .../TabbedContainer/TabbedContainer.tsx | 26 ++--- .../grafana-ui/src/components/Tabs/Tab.tsx | 6 +- .../src/components/Tabs/TabsBar.tsx | 3 +- .../scene/layout-tabs/TabItemRenderer.tsx | 100 +++--------------- .../layout-tabs/TabsLayoutManagerRenderer.tsx | 3 +- 6 files changed, 33 insertions(+), 109 deletions(-) diff --git a/packages/grafana-data/src/themes/createComponents.ts b/packages/grafana-data/src/themes/createComponents.ts index e810a94b86e..6421229640b 100644 --- a/packages/grafana-data/src/themes/createComponents.ts +++ b/packages/grafana-data/src/themes/createComponents.ts @@ -43,9 +43,6 @@ export interface ThemeComponents { sidemenu: { width: number; }; - menuTabs: { - height: number; - }; horizontalDrawer: { defaultHeight: number; }; @@ -96,6 +93,7 @@ export function createComponents(colors: ThemeColors, shadows: ThemeShadows): Th sidemenu: { width: 57, }, + // @ts-expect-error (added here to not crash plugins that might use it) menuTabs: { height: 5, }, diff --git a/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx b/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx index 4bc11a81e5c..5e1cb77957d 100644 --- a/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx +++ b/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx @@ -6,8 +6,9 @@ import { SelectableValue, GrafanaTheme2 } from '@grafana/data'; import { IconButton } from '../../components/IconButton/IconButton'; import { TabsBar, Tab, TabContent } from '../../components/Tabs'; -import { useStyles2, useTheme2 } from '../../themes'; +import { useStyles2 } from '../../themes'; import { IconName } from '../../types/icon'; +import { Box } from '../Layout/Box/Box'; import { ScrollContainer } from '../ScrollContainer/ScrollContainer'; export interface TabConfig { @@ -28,14 +29,11 @@ export interface TabbedContainerProps { export function TabbedContainer({ tabs, defaultTab, closeIconTooltip, onClose, testId }: TabbedContainerProps) { const [activeTab, setActiveTab] = useState(tabs.some((tab) => tab.value === defaultTab) ? defaultTab : tabs[0].value); const styles = useStyles2(getStyles); - const theme = useTheme2(); const onSelectTab = (item: SelectableValue) => { setActiveTab(item.value!); }; - const autoHeight = `calc(100% - (${theme.spacing(theme.components.menuTabs.height)} + ${theme.spacing(1)}))`; - return (
@@ -48,9 +46,11 @@ export function TabbedContainer({ tabs, defaultTab, closeIconTooltip, onClose, t icon={t.icon} /> ))} - + + + - + {tabs.find((t) => t.value === activeTab)?.content}
@@ -60,21 +60,17 @@ export function TabbedContainer({ tabs, defaultTab, closeIconTooltip, onClose, t const getStyles = (theme: GrafanaTheme2) => ({ container: css({ height: '100%', + display: 'flex', + flexDirection: 'column', + flex: '1 1 0', + minHeight: 0, }), tabContent: css({ padding: theme.spacing(2), backgroundColor: theme.colors.background.primary, - height: `100%`, - }), - close: css({ - position: 'absolute', - right: '16px', - top: '5px', - cursor: 'pointer', - fontSize: theme.typography.size.lg, }), tabs: css({ - paddingTop: theme.spacing(1), + paddingTop: theme.spacing(0.5), borderColor: theme.colors.border.weak, ul: { marginLeft: theme.spacing(2), diff --git a/packages/grafana-ui/src/components/Tabs/Tab.tsx b/packages/grafana-ui/src/components/Tabs/Tab.tsx index e866fb4d242..edbe71c965c 100644 --- a/packages/grafana-ui/src/components/Tabs/Tab.tsx +++ b/packages/grafana-ui/src/components/Tabs/Tab.tsx @@ -92,11 +92,11 @@ const getStyles = (theme: GrafanaTheme2) => { position: 'relative', display: 'flex', whiteSpace: 'nowrap', - padding: theme.spacing(0.5), + padding: theme.spacing(0, 0.5), }), link: css({ color: theme.colors.text.secondary, - padding: theme.spacing(1, 1.5, 0.5), + padding: theme.spacing(1, 1.5, 1), borderRadius: theme.shape.radius.default, display: 'block', @@ -114,7 +114,7 @@ const getStyles = (theme: GrafanaTheme2) => { position: 'absolute', left: 0, right: 0, - height: '4px', + height: '2px', borderRadius: theme.shape.radius.default, bottom: 0, }, diff --git a/packages/grafana-ui/src/components/Tabs/TabsBar.tsx b/packages/grafana-ui/src/components/Tabs/TabsBar.tsx index d5d43c51cbd..7ebfaf20c03 100644 --- a/packages/grafana-ui/src/components/Tabs/TabsBar.tsx +++ b/packages/grafana-ui/src/components/Tabs/TabsBar.tsx @@ -36,8 +36,7 @@ const getStyles = (theme: GrafanaTheme2) => ({ tabs: css({ position: 'relative', display: 'flex', - height: theme.spacing(theme.components.menuTabs.height), - alignItems: 'stretch', + alignItems: 'center', }), }); diff --git a/public/app/features/dashboard-scene/scene/layout-tabs/TabItemRenderer.tsx b/public/app/features/dashboard-scene/scene/layout-tabs/TabItemRenderer.tsx index 52f12ffdc7f..69dca7748f1 100644 --- a/public/app/features/dashboard-scene/scene/layout-tabs/TabItemRenderer.tsx +++ b/public/app/features/dashboard-scene/scene/layout-tabs/TabItemRenderer.tsx @@ -1,11 +1,9 @@ -import { css, cx } from '@emotion/css'; +import { cx } from '@emotion/css'; import { useLocation } from 'react-router'; -import { GrafanaTheme2, locationUtil, textUtil } from '@grafana/data'; +import { locationUtil, textUtil } from '@grafana/data'; import { SceneComponentProps, sceneGraph } from '@grafana/scenes'; -import { clearButtonStyles, useElementSelection, useStyles2 } from '@grafana/ui'; -// eslint-disable-next-line no-restricted-imports -import { getFocusStyles } from '@grafana/ui/src/themes/mixins'; +import { Tab, useElementSelection } from '@grafana/ui'; import { TabItem } from './TabItem'; @@ -19,87 +17,19 @@ export function TabItemRenderer({ model }: SceneComponentProps) { const isActive = myIndex === currentTabIndex; const location = useLocation(); const href = textUtil.sanitize(locationUtil.getUrlForPartial(location, { tab: myIndex })); - const styles = useStyles2(getStyles); - const clearStyles = useStyles2(clearButtonStyles); return ( - <> -
- - {titleInterpolated} - -
- + ); } - -function getStyles(theme: GrafanaTheme2) { - return { - container: css({ - listStyle: 'none', - position: 'relative', - display: 'flex', - whiteSpace: 'nowrap', - alignItems: 'center', - }), - checkboxWrapper: css({ - paddingLeft: theme.spacing(1), - }), - label: css({ - color: theme.colors.text.secondary, - padding: theme.spacing(1, 2, 0.5), - borderRadius: theme.shape.radius.default, - userSelect: 'none', - - display: 'block', - height: '100%', - - svg: { - marginRight: theme.spacing(1), - }, - - '&:focus-visible': getFocusStyles(theme), - - '&::before': { - display: 'block', - content: '" "', - position: 'absolute', - left: 0, - right: 0, - height: '4px', - borderRadius: theme.shape.radius.default, - bottom: 0, - }, - }), - labelNotActive: css({ - '&:hover, &:focus': { - color: theme.colors.text.primary, - - '&::before': { - backgroundColor: theme.colors.action.hover, - }, - }, - }), - labelActive: css({ - color: theme.colors.text.primary, - overflow: 'hidden', - - '&::before': { - backgroundImage: theme.colors.gradients.brandHorizontal, - }, - }), - }; -} diff --git a/public/app/features/dashboard-scene/scene/layout-tabs/TabsLayoutManagerRenderer.tsx b/public/app/features/dashboard-scene/scene/layout-tabs/TabsLayoutManagerRenderer.tsx index 8a9e5a6a8f6..624b772db37 100644 --- a/public/app/features/dashboard-scene/scene/layout-tabs/TabsLayoutManagerRenderer.tsx +++ b/public/app/features/dashboard-scene/scene/layout-tabs/TabsLayoutManagerRenderer.tsx @@ -60,12 +60,13 @@ const getStyles = (theme: GrafanaTheme2) => ({ overflowX: 'auto', overflowY: 'hidden', paddingInline: theme.spacing(0.125), + paddingTop: '1px', }), tabContentContainer: css({ backgroundColor: 'transparent', display: 'flex', flex: 1, minHeight: 0, - padding: '2px 2px 0 2px', + paddingTop: theme.spacing(1), }), });