@grafana/ui
Version:
Grafana Components Library
1 lines • 10.5 kB
Source Map (JSON)
{"version":3,"file":"IconButton.mjs","sources":["../../../../src/components/IconButton/IconButton.tsx"],"sourcesContent":["import { css, cx } from '@emotion/css';\nimport * as React from 'react';\n\nimport { GrafanaTheme2, deprecationWarning } from '@grafana/data';\n\nimport { useStyles2 } from '../../themes/ThemeContext';\nimport { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins';\nimport { IconName, IconSize, IconType } from '../../types/icon';\nimport { ComponentSize } from '../../types/size';\nimport { getActiveButtonStyles, IconRenderer } from '../Button/Button';\nimport { getSvgSize } from '../Icon/utils';\nimport { Tooltip } from '../Tooltip/Tooltip';\nimport { PopoverContent, TooltipPlacement } from '../Tooltip/types';\n\nexport type IconButtonVariant = 'primary' | 'secondary' | 'destructive';\n\ntype LimitedIconSize = ComponentSize | 'xl';\n\ninterface BaseProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'aria-label'> {\n /** Name of the icon **/\n name: IconName;\n /** Icon size - sizes xxl and xxxl are deprecated and when used being decreased to xl*/\n size?: IconSize;\n /** Type of the icon - mono or default */\n iconType?: IconType;\n /** Variant to change the color of the Icon */\n variant?: IconButtonVariant;\n}\n\nexport interface BasePropsWithTooltip extends BaseProps {\n /** Tooltip content to display on hover and as the aria-label */\n tooltip: PopoverContent;\n /** Position of the tooltip */\n tooltipPlacement?: TooltipPlacement;\n}\n\ninterface BasePropsWithAriaLabel extends BaseProps {\n /** @deprecated use aria-label instead*/\n ariaLabel?: string;\n /** Text available only for screen readers. No tooltip will be set in this case. */\n ['aria-label']: string;\n}\n\ninterface BasePropsWithAriaLabelledBy extends BaseProps {\n /** Reference to an element id that labels the button. No tooltip will be set in this case. */\n ['aria-labelledby']: string;\n}\n\nexport type Props = BasePropsWithTooltip | BasePropsWithAriaLabel | BasePropsWithAriaLabelledBy;\n\n/**\n * This component looks just like an icon but behaves like a button.\n *\n * https://developers.grafana.com/ui/latest/index.html?path=/docs/inputs-iconbutton--docs\n */\nexport const IconButton = React.forwardRef<HTMLButtonElement, Props>((props, ref) => {\n const { size = 'md', variant = 'secondary' } = props;\n let limitedIconSize: LimitedIconSize;\n\n // very large icons (xl to xxxl) are unified to size xl\n if (size === 'xxl' || size === 'xxxl') {\n deprecationWarning('IconButton', 'size=\"xxl\" and size=\"xxxl\"', 'size=\"xl\"');\n limitedIconSize = 'xl';\n } else {\n limitedIconSize = size;\n }\n\n const styles = useStyles2(getStyles, limitedIconSize, variant);\n\n let ariaLabel: string | undefined;\n let buttonRef: typeof ref | undefined;\n\n if ('tooltip' in props) {\n const { tooltip } = props;\n ariaLabel = typeof tooltip === 'string' ? tooltip : undefined;\n } else if ('ariaLabel' in props || 'aria-label' in props) {\n const { ariaLabel: deprecatedAriaLabel, ['aria-label']: ariaLabelProp } = props;\n ariaLabel = ariaLabelProp || deprecatedAriaLabel;\n buttonRef = ref;\n }\n\n // When using tooltip, ref is forwarded to Tooltip component instead for https://github.com/grafana/grafana/issues/65632\n if ('tooltip' in props) {\n const { name, iconType, className, tooltip, tooltipPlacement, ...restProps } = props;\n return (\n <Tooltip ref={ref} content={tooltip} placement={tooltipPlacement}>\n <button\n {...restProps}\n ref={buttonRef}\n aria-label={ariaLabel}\n className={cx(styles.button, className)}\n type=\"button\"\n >\n <IconRenderer icon={name} size={limitedIconSize} className={styles.icon} iconType={iconType} />\n </button>\n </Tooltip>\n );\n } else {\n const { name, iconType, className, ...restProps } = props;\n return (\n <button\n {...restProps}\n ref={buttonRef}\n aria-label={ariaLabel}\n className={cx(styles.button, className)}\n type=\"button\"\n >\n <IconRenderer icon={name} size={limitedIconSize} className={styles.icon} iconType={iconType} />\n </button>\n );\n }\n});\n\nIconButton.displayName = 'IconButton';\n\nconst getStyles = (theme: GrafanaTheme2, size: IconSize, variant: IconButtonVariant) => {\n // overall size of the IconButton on hover\n // theme.spacing.gridSize originates from 2*4px for padding and letting the IconSize generally decide on the hoverSize\n const hoverSize = getSvgSize(size) + theme.spacing.gridSize;\n const activeButtonStyle = getActiveButtonStyles(theme.colors.secondary, 'text');\n\n let iconColor = theme.colors.primary.text;\n let hoverColor = theme.colors.primary.transparent;\n\n if (variant === 'secondary') {\n iconColor = theme.colors.secondary.text;\n hoverColor = theme.colors.secondary.transparent;\n } else if (variant === 'destructive') {\n iconColor = theme.colors.error.text;\n hoverColor = theme.colors.error.transparent;\n }\n\n return {\n button: css({\n zIndex: 0,\n position: 'relative',\n margin: `0 ${theme.spacing.x0_5} 0 0`,\n boxShadow: 'none',\n border: 'none',\n display: 'inline-flex',\n background: 'transparent',\n justifyContent: 'center',\n alignItems: 'center',\n padding: 0,\n color: iconColor,\n borderRadius: theme.shape.radius.default,\n\n '&:active': {\n '&:before, &:hover:before': {\n backgroundColor: activeButtonStyle.background,\n },\n },\n\n '&[disabled], &:disabled': {\n cursor: 'not-allowed',\n color: theme.colors.action.disabledText,\n opacity: 0.65,\n '&:hover:before': {\n backgroundColor: 'transparent',\n },\n },\n\n '&:before': {\n zIndex: -1,\n position: 'absolute',\n opacity: 0,\n width: `${hoverSize}px`,\n height: `${hoverSize}px`,\n borderRadius: theme.shape.radius.default,\n content: '\"\"',\n [theme.transitions.handleMotion('no-preference', 'reduce')]: {\n transitionDuration: '0.2s',\n transitionTimingFunction: 'cubic-bezier(0.4, 0, 0.2, 1)',\n transitionProperty: 'opacity',\n },\n },\n\n '&:focus, &:focus-visible': getFocusStyles(theme),\n\n '&:focus:not(:focus-visible)': getMouseFocusStyles(theme),\n\n '&:hover:before': {\n backgroundColor: hoverColor,\n opacity: 1,\n },\n }),\n icon: css({\n verticalAlign: 'baseline',\n }),\n };\n};\n"],"names":[],"mappings":"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"}