fix(TopBar): consistent ToolbarButton styling for sidebar buttons (#113804)

* Remove custom styles from ExtensionToolbarItemButton

* Use active ToolbarButton variant for ExtensionToolbarItemButton

* Use active ToolbarButton variant for HelpTopBarButton

* Simplify ExtensionToolbarItemButton conditional logic

* Replace nested ternary with iife
This commit is contained in:
Matt Cowley
2025-11-13 09:57:27 +00:00
committed by GitHub
parent 73657be5e7
commit 3bd49f6546
2 changed files with 15 additions and 62 deletions
@@ -1,9 +1,7 @@
import { css, cx } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { t } from '@grafana/i18n';
import { ToolbarButton, useStyles2 } from '@grafana/ui';
import { ToolbarButton } from '@grafana/ui';
interface ToolbarItemButtonProps {
isOpen: boolean;
@@ -30,35 +28,24 @@ function ExtensionToolbarItemButtonComponent(
{ isOpen, title, onClick, pluginId }: ToolbarItemButtonProps,
ref: React.ForwardedRef<HTMLButtonElement>
) {
const styles = useStyles2(getStyles);
const icon = getPluginIcon(pluginId);
const tooltip = (() => {
if (isOpen) {
return t('navigation.extension-sidebar.button-tooltip.close', 'Close {{title}}', { title });
}
if (title) {
return t('navigation.extension-sidebar.button-tooltip.open', 'Open {{title}}', { title });
}
return t('navigation.extension-sidebar.button-tooltip.open-all', 'Open AI assistants and sidebar apps');
})();
if (isOpen) {
// render button to close the sidebar
return (
<ToolbarButton
ref={ref}
className={cx(styles.button, styles.buttonActive)}
icon={icon}
data-testid="extension-toolbar-button-close"
variant="default"
onClick={onClick}
tooltip={t('navigation.extension-sidebar.button-tooltip.close', 'Close {{title}}', { title })}
/>
);
}
// if a title is provided, use it in the tooltip
let tooltip = t('navigation.extension-sidebar.button-tooltip.open-all', 'Open AI assistants and sidebar apps');
if (title) {
tooltip = t('navigation.extension-sidebar.button-tooltip.open', 'Open {{title}}', { title });
}
return (
<ToolbarButton
ref={ref}
className={cx(styles.button)}
icon={icon}
data-testid="extension-toolbar-button-open"
variant="default"
iconOnly
data-testid={`extension-toolbar-button-${isOpen ? 'close' : 'open'}`}
variant={isOpen ? 'active' : 'default'}
onClick={onClick}
tooltip={tooltip}
/>
@@ -70,25 +57,3 @@ function ExtensionToolbarItemButtonComponent(
export const ExtensionToolbarItemButton = React.forwardRef<HTMLButtonElement, ToolbarItemButtonProps>(
ExtensionToolbarItemButtonComponent
);
function getStyles(theme: GrafanaTheme2) {
return {
button: css({
// this is needed because with certain breakpoints the button will get `width: auto`
// and the icon will stretch
aspectRatio: '1 / 1 !important',
width: '28px',
height: '28px',
padding: 0,
justifyContent: 'center',
borderRadius: theme.shape.radius.circle,
margin: theme.spacing(0, 0.25),
}),
buttonActive: css({
borderRadius: theme.shape.radius.circle,
backgroundColor: theme.colors.primary.transparent,
border: `1px solid ${theme.colors.primary.borderTransparent}`,
color: theme.colors.text.primary,
}),
};
}
@@ -1,10 +1,8 @@
import { css } from '@emotion/css';
import { memo } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { t } from '@grafana/i18n';
import { getAppEvents } from '@grafana/runtime';
import { Dropdown, ToolbarButton, useStyles2 } from '@grafana/ui';
import { Dropdown, ToolbarButton } from '@grafana/ui';
import { OpenExtensionSidebarEvent } from 'app/types/events';
import {
@@ -23,7 +21,6 @@ interface Props {
export const HelpTopBarButton = memo(function HelpTopBarButton({ isSmallScreen }: Props) {
const enrichedHelpNode = useHelpNode();
const { setDockedComponentId, dockedComponentId, availableComponents } = useExtensionSidebarContext();
const styles = useStyles2(getStyles);
if (!enrichedHelpNode) {
return null;
@@ -52,7 +49,7 @@ export const HelpTopBarButton = memo(function HelpTopBarButton({ isSmallScreen }
iconOnly
icon="question-circle"
aria-label={t('navigation.help.aria-label', 'Help')}
className={isOpen ? styles.helpButtonActive : undefined}
variant={isOpen ? 'active' : 'default'}
tooltip={
isOpen
? t(
@@ -77,12 +74,3 @@ export const HelpTopBarButton = memo(function HelpTopBarButton({ isSmallScreen }
/>
);
});
const getStyles = (theme: GrafanaTheme2) => ({
helpButtonActive: css({
borderRadius: theme.shape.radius.circle,
backgroundColor: theme.colors.primary.transparent,
border: `1px solid ${theme.colors.primary.borderTransparent}`,
color: theme.colors.text.primary,
}),
});