UNPKG

@mskcc/carbon-react

Version:

Carbon react components for the MSKCC DSM

145 lines (141 loc) 4.61 kB
/** * MSKCC 2021, 2024 */ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js'; import React__default, { useRef, useState } from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; import { ChevronDown } from '@carbon/icons-react'; import Button from '../Button/Button.js'; import '../Button/Button.Skeleton.js'; import { IconButton } from '../IconButton/IconButton.js'; import { Menu } from '../Menu/Menu.js'; import { useAttachedMenu } from '../../internal/useAttachedMenu.js'; import { useId } from '../../internal/useId.js'; import { useMergedRefs } from '../../internal/useMergedRefs.js'; import { usePrefix } from '../../internal/usePrefix.js'; var _ChevronDown; const spacing = 4; // top and bottom spacing between the button and the menu. in px const defaultTranslations = { 'carbon.combo-button.additional-actions': 'Additional actions' }; function defaultTranslateWithId(messageId) { return defaultTranslations[messageId]; } const ComboButton = /*#__PURE__*/React__default.forwardRef(function ComboButton(_ref, forwardRef) { let { children, className, disabled, label, onClick, size = 'lg', tooltipAlignment, translateWithId: t = defaultTranslateWithId, ...rest } = _ref; const id = useId('combobutton'); const prefix = usePrefix(); const containerRef = useRef(null); const menuRef = useRef(null); const ref = useMergedRefs([forwardRef, containerRef]); const [width, setWidth] = useState(0); const { open, x, y, handleClick: hookOnClick, handleMousedown: handleTriggerMousedown, handleClose } = useAttachedMenu(containerRef); function handleTriggerClick() { if (containerRef.current) { const { width: w } = containerRef.current.getBoundingClientRect(); setWidth(w); hookOnClick(); } } function handlePrimaryActionClick(e) { if (onClick) { onClick(e); } } function handleOpen() { menuRef.current.style.width = `${width}px`; } const containerClasses = cx(`${prefix}--combo-button__container`, `${prefix}--combo-button__container--${size}`, { [`${prefix}--combo-button__container--open`]: open }, className); const primaryActionClasses = cx(`${prefix}--combo-button__primary-action`); const triggerClasses = cx(`${prefix}--combo-button__trigger`); return /*#__PURE__*/React__default.createElement("div", _extends({}, rest, { className: containerClasses, ref: ref, "aria-owns": open ? id : null }), /*#__PURE__*/React__default.createElement("div", { className: primaryActionClasses }, /*#__PURE__*/React__default.createElement(Button, { size: size, disabled: disabled, onClick: handlePrimaryActionClick }, label)), /*#__PURE__*/React__default.createElement(IconButton, { className: triggerClasses, label: t('carbon.combo-button.additional-actions'), size: size, disabled: disabled, align: tooltipAlignment, "aria-haspopup": true, "aria-expanded": open, onClick: handleTriggerClick, onMouseDown: handleTriggerMousedown, "aria-controls": open ? id : null }, _ChevronDown || (_ChevronDown = /*#__PURE__*/React__default.createElement(ChevronDown, null))), /*#__PURE__*/React__default.createElement(Menu, { ref: menuRef, id: id, label: t('carbon.combo-button.additional-actions'), size: size, open: open, onClose: handleClose, onOpen: handleOpen, x: x, y: [y[0] - spacing, y[1] + spacing] }, children)); }); ComboButton.propTypes = { /** * A collection of MenuItems to be rendered as additional actions for this ComboButton. */ children: PropTypes.node.isRequired, /** * Additional CSS class names. */ className: PropTypes.string, /** * Specify whether the ComboButton should be disabled, or not. */ disabled: PropTypes.bool, /** * Provide the label to be renderd on the primary action button. */ label: PropTypes.string.isRequired, /** * Provide an optional function to be called when the primary action element is clicked. */ onClick: PropTypes.func, /** * Specify the size of the buttons and menu. */ size: PropTypes.oneOf(['sm', 'md', 'lg']), /** * Specify how the trigger tooltip should be aligned. */ tooltipAlignment: PropTypes.oneOf(['top', 'top-left', 'top-right', 'bottom', 'bottom-left', 'bottom-right', 'left', 'right']), /** * Optional method that takes in a message id and returns an * internationalized string. */ translateWithId: PropTypes.func }; export { ComboButton };