UNPKG

@mskcc/carbon-react

Version:

Carbon react components for the MSKCC DSM

333 lines (322 loc) 11 kB
/** * MSKCC 2021, 2024 */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js'); var PropTypes = require('prop-types'); var React = require('react'); var cx = require('classnames'); var IconButton = require('../IconButton/IconButton.js'); var events = require('../../tools/events.js'); var usePrefix = require('../../internal/usePrefix.js'); var useId = require('../../internal/useId.js'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes); var React__default = /*#__PURE__*/_interopDefaultLegacy(React); var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx); const ButtonKinds = ['primary', 'secondary', 'danger', 'ghost', 'danger--primary', 'danger--ghost', 'danger--tertiary', 'tertiary']; // export const ButtonSizes = ['field', 'sm', 'md', 'lg', 'xl', '2xl'] as const; const ButtonSizes = ['sm', 'md', 'lg']; const ButtonTooltipAlignments = ['start', 'center', 'end']; const ButtonTooltipPositions = ['top', 'right', 'bottom', 'left']; const ButtonIconPositions = ['top', 'right', 'left']; const Button = /*#__PURE__*/React__default["default"].forwardRef(function Button(_ref, // ref: React.Ref<unknown>, ref) { let { as, children, className, dangerDescription = 'danger', disabled = false, hasIconOnly = false, href, iconDescription, icon, iconPosition, isExpressive = false, isSelected, kind = 'primary', width = 'content', onBlur, onClick, onFocus, onMouseEnter, onMouseLeave, // renderIcon: ButtonImageElement, renderIcon, size = 'md', tabIndex, tooltipAlignment = 'center', tooltipPosition = 'top', type = 'button', wrapperClasses, disableTooltip, disableFocus, ...rest } = _ref; const tooltipRef = React.useRef(null); const prefix = usePrefix.usePrefix(); const handleClick = evt => { // Prevent clicks on the tooltip from triggering the button click event if (evt.target === tooltipRef.current) { evt.preventDefault(); return; } }; const buttonClasses = cx__default["default"](className, { [`msk-btn`]: true, [`msk-btn--${size}`]: size, [`msk-btn--${kind}`]: kind, [`msk-btn--icon-only`]: hasIconOnly, [`msk-btn--icon-${iconPosition}`]: iconPosition && !hasIconOnly, [`msk-btn--disabled`]: disabled, [`msk-btn--${width}`]: width, [`msk-btn--disable-focus`]: disableFocus // [`${prefix}--btn--sm`]: size === 'sm' && !isExpressive, // TODO: V12 - Remove this class // [`${prefix}--btn--md`]: size === 'md' && !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--expressive`]: isExpressive, // [`${prefix}--btn--icon-only`]: hasIconOnly, // [`${prefix}--btn--selected`]: hasIconOnly && isSelected && kind === 'ghost', }); const commonProps = { tabIndex, className: buttonClasses, ref }; // const iconOnlyImage = !ButtonImageElement ? null : <ButtonImageElement />; // const iconOnlyImage = null; const dangerButtonVariants = ['danger', 'danger--tertiary', 'danger--ghost']; let component = 'button'; const assistiveId = useId.useId('danger-description'); const { 'aria-pressed': ariaPressed } = rest; let otherProps = { disabled, type, 'aria-describedby': dangerButtonVariants.includes(kind) ? assistiveId : undefined, 'aria-pressed': ariaPressed ?? undefined }; const anchorProps = { href }; let assistiveText = null; if (dangerButtonVariants.includes(kind)) { assistiveText = /*#__PURE__*/React__default["default"].createElement("span", { id: assistiveId, className: `${prefix}--visually-hidden` }, dangerDescription); } if (as) { component = as; otherProps = { ...otherProps, ...anchorProps }; } else if (href && !disabled) { component = 'a'; otherProps = anchorProps; } if (hasIconOnly) { let align = undefined; if (tooltipPosition === 'top' || tooltipPosition === 'bottom') { if (tooltipAlignment === 'center') { align = tooltipPosition; } if (tooltipAlignment === 'end') { align = `${tooltipPosition}-right`; } if (tooltipAlignment === 'start') { align = `${tooltipPosition}-left`; } } if (tooltipPosition === 'right' || tooltipPosition === 'left') { align = tooltipPosition; } return /*#__PURE__*/React__default["default"].createElement(IconButton.IconButton, _rollupPluginBabelHelpers["extends"]({ as: as, align: align, label: iconDescription, kind: kind, size: size, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onFocus: onFocus, onBlur: onBlur, onClick: events.composeEventHandlers([onClick, handleClick]), wrapperClasses: wrapperClasses, disableTooltip: disableTooltip }, rest, commonProps, otherProps), icon); } if (!hasIconOnly) { const Button = /*#__PURE__*/React__default["default"].createElement(component, { onMouseEnter, onMouseLeave, onFocus, onBlur, onClick, ...rest, ...commonProps, ...otherProps }, assistiveText, (!!icon && iconPosition === 'left' || iconPosition === 'top') && /*#__PURE__*/React__default["default"].createElement("span", { className: "msk-icon msk-btn--icon", "aria-label": iconDescription }, icon), children, !!icon && iconPosition === 'right' && /*#__PURE__*/React__default["default"].createElement("span", { className: "msk-icon msk-btn--icon", "aria-label": iconDescription }, icon)); return Button; } return /*#__PURE__*/React__default["default"].createElement(component, { onMouseEnter, onMouseLeave, onFocus, onBlur, onClick, ...rest, ...commonProps, ...otherProps }, assistiveText, children); }); Button.displayName = 'Button'; Button.propTypes = { /** * Specify how the button itself should be rendered. * Make sure to apply all props to the root node and render children appropriately */ as: PropTypes__default["default"].oneOfType([PropTypes__default["default"].func, PropTypes__default["default"].string, PropTypes__default["default"].elementType]), /** * Specify the content of your Button */ children: PropTypes__default["default"].node, /** * Specify an optional className to be added to your Button */ className: PropTypes__default["default"].string, /** * Specify the message read by screen readers for the danger button variant */ dangerDescription: PropTypes__default["default"].string, /** * Specify whether the button should be disabled from focus */ disableFocus: PropTypes__default["default"].bool, /** * Specify whether the tooltip should be disabled */ disableTooltip: PropTypes__default["default"].bool, /** * Specify whether the Button should be disabled, or not */ disabled: PropTypes__default["default"].bool, /** * Specify if the button is an icon-only button */ hasIconOnly: PropTypes__default["default"].bool, /** * Optionally specify an href for your Button to become an `<a>` element */ href: PropTypes__default["default"].string, /* render a msk icon from types MskIcon */ icon: PropTypes__default["default"].string, /** * If specifying the `renderIcon` prop, provide a description for that icon that can * be read by screen readers */ iconDescription: props => { if (props.renderIcon && !props.children && !props.iconDescription) { return new Error('renderIcon property specified without also providing an iconDescription property.'); } return null; }, /** * Specify whether the Button is expressive, or not */ isExpressive: PropTypes__default["default"].bool, /** * Specify whether the Button is currently selected. Only applies to the Ghost variant. */ isSelected: PropTypes__default["default"].bool, /** * Specify the kind of Button you want to create */ kind: PropTypes__default["default"].oneOf(ButtonKinds), /** * Provide an optional function to be called when the button element * loses focus */ onBlur: PropTypes__default["default"].func, /** * Provide an optional function to be called when the button element * is clicked */ onClick: PropTypes__default["default"].func, /** * Provide an optional function to be called when the button element * receives focus */ onFocus: PropTypes__default["default"].func, /** * Provide an optional function to be called when the mouse * enters the button element */ onMouseEnter: PropTypes__default["default"].func, /** * Provide an optional function to be called when the mouse * leaves the button element */ onMouseLeave: PropTypes__default["default"].func, /** * Optional prop to allow overriding the icon rendering. * Can be a React component class */ renderIcon: PropTypes__default["default"].oneOfType([PropTypes__default["default"].func, PropTypes__default["default"].object]), /** * Optional prop to specify the role of the Button */ role: PropTypes__default["default"].string, /** * Specify the size of the button, from the following list of sizes: */ size: PropTypes__default["default"].oneOf(['sm', 'md', 'lg']), /** * Optional prop to specify the tabIndex of the Button */ tabIndex: PropTypes__default["default"].number, /** * Specify the alignment of the tooltip to the icon-only button. * Can be one of: start, center, or end. */ tooltipAlignment: PropTypes__default["default"].oneOf(['start', 'center', 'end']), /** * Specify the direction of the tooltip for icon-only buttons. * Can be either top, right, bottom, or left. */ tooltipPosition: PropTypes__default["default"].oneOf(['top', 'right', 'bottom', 'left']), /** * Optional prop to specify the type of the Button */ type: PropTypes__default["default"].oneOf(['button', 'reset', 'submit']), /** * Specify the width of the button */ width: PropTypes__default["default"].oneOf(['content', 'full']), /** * Specify an optional className to be added to your Icon Only Tooltip wrapper */ wrapperClasses: PropTypes__default["default"].string }; exports.ButtonIconPositions = ButtonIconPositions; exports.ButtonKinds = ButtonKinds; exports.ButtonSizes = ButtonSizes; exports.ButtonTooltipAlignments = ButtonTooltipAlignments; exports.ButtonTooltipPositions = ButtonTooltipPositions; exports["default"] = Button;