@carbon/react
Version:
React components for the Carbon Design System
114 lines (110 loc) • 3.25 kB
JavaScript
/**
* Copyright IBM Corp. 2016, 2023
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
import React from 'react';
import cx from 'classnames';
import { usePrefix } from '../../internal/usePrefix.js';
import { useId } from '../../internal/useId.js';
const ButtonBase = /*#__PURE__*/React.forwardRef(function ButtonBase({
as,
children,
className,
dangerDescription = 'danger',
disabled = false,
hasIconOnly = false,
href,
iconDescription,
isExpressive = false,
isSelected,
kind = 'primary',
onBlur,
onClick,
onFocus,
onMouseEnter,
onMouseLeave,
renderIcon: ButtonImageElement,
size,
tabIndex,
type = 'button',
...rest
}, ref) {
const prefix = usePrefix();
const buttonClasses = cx(className, {
[`${prefix}--btn`]: true,
[`${prefix}--btn--xs`]: size === 'xs' && !isExpressive,
// TODO: V12 - Remove this class
[`${prefix}--btn--sm`]: size === 'sm' && !isExpressive,
// TODO: V12 - Remove this class
[`${prefix}--btn--md`]: size === 'md' && !isExpressive,
// TODO: V12 - Remove this class
[`${prefix}--btn--lg`]: size === 'lg' && !isExpressive,
// TODO: V12 - Remove this class
[`${prefix}--btn--xl`]: size === 'xl',
// TODO: V12 - Remove this class
[`${prefix}--btn--2xl`]: size === '2xl',
// TODO: V12 - Remove this class
[`${prefix}--layout--size-${size}`]: size,
[`${prefix}--btn--${kind}`]: kind,
[`${prefix}--btn--disabled`]: disabled,
[`${prefix}--btn--expressive`]: isExpressive,
[`${prefix}--btn--icon-only`]: hasIconOnly,
[`${prefix}--btn--selected`]: hasIconOnly && isSelected && kind === 'ghost'
});
const commonProps = {
tabIndex,
className: buttonClasses,
ref
};
const buttonImage = !ButtonImageElement ? null : /*#__PURE__*/React.createElement(ButtonImageElement, {
"aria-label": iconDescription,
className: `${prefix}--btn__icon`,
"aria-hidden": "true"
});
const dangerButtonVariants = ['danger', 'danger--tertiary', 'danger--ghost'];
let component = 'button';
const assistiveId = useId('danger-description');
const {
'aria-pressed': ariaPressed,
'aria-describedby': ariaDescribedBy
} = rest;
let otherProps = {
disabled,
type,
'aria-describedby': dangerButtonVariants.includes(kind) ? assistiveId : ariaDescribedBy || undefined,
'aria-pressed': ariaPressed ?? (hasIconOnly && kind === 'ghost' ? isSelected : undefined)
};
const anchorProps = {
href
};
let assistiveText = null;
if (dangerButtonVariants.includes(kind)) {
assistiveText = /*#__PURE__*/React.createElement("span", {
id: assistiveId,
className: `${prefix}--visually-hidden`
}, dangerDescription);
}
if (as) {
component = as;
otherProps = {
...otherProps,
...anchorProps
};
} else if (href && !disabled) {
component = 'a';
otherProps = anchorProps;
}
return /*#__PURE__*/React.createElement(component, {
onMouseEnter,
onMouseLeave,
onFocus,
onBlur,
onClick,
...rest,
...commonProps,
...otherProps
}, assistiveText, children, buttonImage);
});
export { ButtonBase as default };