import React, { forwardRef, ButtonHTMLAttributes } from 'react';
import { cx, css } from '@emotion/css';
import { GrafanaTheme } from '@grafana/data';
import { styleMixins, useStyles } from '../../themes';
import { IconName } from '../../types/icon';
import { Tooltip } from '../Tooltip/Tooltip';
import { Icon } from '../Icon/Icon';
import { getPropertiesForVariant } from './Button';
import { isString } from 'lodash';
import { selectors } from '@grafana/e2e-selectors';
export interface Props extends ButtonHTMLAttributes {
/** Icon name */
icon?: IconName | React.ReactNode;
/** Tooltip */
tooltip?: string;
/** For image icons */
imgSrc?: string;
/** if true or false will show angle-down/up */
isOpen?: boolean;
/** Controls flex-grow: 1 */
fullWidth?: boolean;
/** reduces padding to xs */
narrow?: boolean;
/** variant */
variant?: ToolbarButtonVariant;
/** Hide any children and only show icon */
iconOnly?: boolean;
}
export type ToolbarButtonVariant = 'default' | 'primary' | 'destructive' | 'active';
export const ToolbarButton = forwardRef(
(
{
tooltip,
icon,
className,
children,
imgSrc,
fullWidth,
isOpen,
narrow,
variant = 'default',
iconOnly,
'aria-label': ariaLabel,
...rest
},
ref
) => {
const styles = useStyles(getStyles);
const buttonStyles = cx(
'toolbar-button',
{
[styles.button]: true,
[styles.buttonFullWidth]: fullWidth,
[styles.narrow]: narrow,
},
(styles as any)[variant],
className
);
const contentStyles = cx({
[styles.content]: true,
[styles.contentWithIcon]: !!icon,
[styles.contentWithRightIcon]: isOpen !== undefined,
});
const body = (
);
return tooltip ? (
{body}
) : (
body
);
}
);
function getButttonAriaLabel(ariaLabel: string | undefined, tooltip: string | undefined) {
return ariaLabel ? ariaLabel : tooltip ? selectors.components.PageToolbar.item(tooltip) : undefined;
}
function renderIcon(icon: IconName | React.ReactNode) {
if (!icon) {
return null;
}
if (isString(icon)) {
return ;
}
return icon;
}
const getStyles = (theme: GrafanaTheme) => {
const primaryVariant = getPropertiesForVariant(theme.v2, 'primary');
const destructiveVariant = getPropertiesForVariant(theme.v2, 'destructive');
return {
button: css`
label: toolbar-button;
display: flex;
align-items: center;
height: ${theme.height.md}px;
padding: 0 ${theme.spacing.sm};
border-radius: ${theme.border.radius.sm};
line-height: ${theme.height.md - 2}px;
font-weight: ${theme.typography.weight.semibold};
border: 1px solid ${theme.colors.border2};
white-space: nowrap;
&:focus {
outline: none;
}
&[disabled],
&:disabled {
cursor: not-allowed;
opacity: 0.5;
&:hover {
color: ${theme.colors.textWeak};
background: ${theme.colors.bg1};
}
}
`,
default: css`
color: ${theme.colors.textWeak};
background-color: ${theme.colors.bg1};
&:hover {
color: ${theme.colors.text};
background: ${styleMixins.hoverColor(theme.colors.bg1, theme)};
}
`,
active: css`
color: ${theme.palette.orangeDark};
border-color: ${theme.palette.orangeDark};
background-color: transparent;
&:hover {
color: ${theme.colors.text};
background: ${styleMixins.hoverColor(theme.colors.bg1, theme)};
}
`,
primary: css(primaryVariant),
destructive: css(destructiveVariant),
narrow: css`
padding: 0 ${theme.spacing.xs};
`,
img: css`
width: 16px;
height: 16px;
margin-right: ${theme.spacing.sm};
`,
buttonFullWidth: css`
flex-grow: 1;
`,
content: css`
flex-grow: 1;
`,
contentWithIcon: css`
display: none;
padding-left: ${theme.spacing.sm};
@media ${styleMixins.mediaUp(theme.breakpoints.md)} {
display: block;
}
`,
contentWithRightIcon: css`
padding-right: ${theme.spacing.xs};
`,
};
};