@primer/react
Version:
An implementation of GitHub's Primer Design System using React
84 lines (79 loc) • 2.93 kB
JavaScript
import React, { forwardRef } from 'react';
import { ButtonBase } from './ButtonBase.js';
import { defaultSxProp } from '../utils/defaultSxProp.js';
import { generateCustomSxProp } from './Button.js';
import { TooltipContext, Tooltip } from '../TooltipV2/Tooltip.js';
import { TooltipContext as TooltipContext$1 } from '../Tooltip/Tooltip.js';
import classes from './ButtonBase.module.css.js';
import { clsx } from 'clsx';
import { jsx } from 'react/jsx-runtime';
const IconButton = /*#__PURE__*/forwardRef(({
sx: sxProp = defaultSxProp,
icon: Icon,
'aria-label': ariaLabel,
description,
disabled,
tooltipDirection,
// This is planned to be a temporary prop until the default tooltip on icon buttons are fully rolled out.
unsafeDisableTooltip = false,
keyshortcuts,
keybindingHint,
className,
...props
}, forwardedRef) => {
let sxStyles = sxProp;
// grap the button props that have associated data attributes in the styles
const {
size = 'medium'
} = props;
if (sxProp !== null && Object.keys(sxProp).length > 0) {
sxStyles = generateCustomSxProp({
size
}, sxProp);
}
// If the icon button is already wrapped in a tooltip, do not add one.
const {
tooltipId
} = React.useContext(TooltipContext); // Tooltip v2
const {
tooltipId: tooltipIdV1
} = React.useContext(TooltipContext$1); // Tooltip v1
const hasExternalTooltip = tooltipId || tooltipIdV1;
const withoutTooltip = unsafeDisableTooltip || disabled || ariaLabel === undefined || ariaLabel === '' || hasExternalTooltip;
if (withoutTooltip) {
return /*#__PURE__*/jsx(ButtonBase, {
icon: Icon,
className: clsx(className, classes.IconButton),
"data-component": "IconButton",
sx: sxStyles,
type: "button",
"aria-label": ariaLabel,
disabled: disabled,
...props,
// @ts-expect-error StyledButton wants both Anchor and Button refs
ref: forwardedRef
});
} else {
const tooltipText = description !== null && description !== void 0 ? description : ariaLabel;
return /*#__PURE__*/jsx(Tooltip, {
ref: forwardedRef,
text: tooltipText,
type: description ? undefined : 'label',
direction: tooltipDirection,
keybindingHint: keybindingHint !== null && keybindingHint !== void 0 ? keybindingHint : keyshortcuts,
children: /*#__PURE__*/jsx(ButtonBase, {
icon: Icon,
className: clsx(className, classes.IconButton),
"data-component": "IconButton",
sx: sxStyles,
type: "button",
"aria-keyshortcuts": keyshortcuts !== null && keyshortcuts !== void 0 ? keyshortcuts : undefined
// If description is provided, we will use the tooltip to describe the button, so we need to keep the aria-label to label the button.
,
"aria-label": description ? ariaLabel : undefined,
...props
})
});
}
});
export { IconButton };