UNPKG

@mskcc/carbon-react

Version:

Carbon react components for the MSKCC DSM

145 lines (140 loc) 4.39 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 { usePrefix } from '../../internal/usePrefix.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'; var _aside; const spacing = 4; // top and bottom spacing between the button and the menu. in px // const validButtonKinds = ['primary', 'tertiary', 'ghost']; // const defaultButtonKind = 'primary'; const MenuButton = /*#__PURE__*/React__default.forwardRef(function MenuButton(_ref, forwardRef) { let { children, className, disabled, icon = '', label = '', size = 'lg', target, disableFocus = false, ...rest } = _ref; const id = useId('MenuButton'); const prefix = usePrefix(); const triggerRef = useRef(null); const menuRef = useRef(null); const ref = useMergedRefs([forwardRef, triggerRef]); const [width, setWidth] = useState(0); const { open, x, y, handleClick: hookOnClick, handleMousedown, handleClose } = useAttachedMenu(triggerRef); function handleClick() { if (triggerRef.current) { const { width: w } = triggerRef.current.getBoundingClientRect(); setWidth(w); hookOnClick(); } } function handleOpen() { menuRef.current.style.width = `${width}px`; } const triggerClasses = cx(`${prefix}--btn ${prefix}--btn--ghost msk-menu-button`, { [`active`]: open }); const iconSizeClass = `msk-icon msk-menu-button-top-icon ${size}`.trim(); const parentClass = `msk-menu-button-container ${className ?? ''}`.trim(); const mobileIconClass = `msk-menu-button-mobile-icon ${open ? 'open' : ''}`.trim(); return /*#__PURE__*/React__default.createElement("div", _extends({}, rest, { ref: ref, "aria-owns": open ? id : null, className: parentClass }), /*#__PURE__*/React__default.createElement("button", { disabled: disabled, type: "button", className: triggerClasses, "aria-haspopup": true, "aria-expanded": open, onClick: handleClick, onMouseDown: handleMousedown, "aria-controls": open ? id : null }, /*#__PURE__*/React__default.createElement("div", { className: 'msk-menu-button-content' }, /*#__PURE__*/React__default.createElement("div", { className: "msk-menu-button-label-container" }, /*#__PURE__*/React__default.createElement("span", { className: mobileIconClass }), /*#__PURE__*/React__default.createElement("span", { className: iconSizeClass }, icon), label ? /*#__PURE__*/React__default.createElement("span", { className: "msk-menu-button-label" }, label) : null), _aside || (_aside = /*#__PURE__*/React__default.createElement("aside", { className: "msk-menu-button-expand" }, /*#__PURE__*/React__default.createElement("span", { className: "msk-icon msk-menu-button-expand-icon" }, "arrow_drop_down"))))), /*#__PURE__*/React__default.createElement(Menu, { target: target, ref: menuRef, id: id, label: label, size: size, open: open, onClose: handleClose, onOpen: handleOpen, x: x, y: [y[0] - spacing, y[1] + spacing], disableFocus: disableFocus }, children)); }); MenuButton.propTypes = { /** * A collection of MenuItems to be rendered as actions for this MenuButton. */ children: PropTypes.node.isRequired, /** * Additional CSS class names. */ className: PropTypes.string, /** * disable focus */ disableFocus: PropTypes.bool, /** * Specify whether the MenuButton should be disabled, or not. */ disabled: PropTypes.bool, /** * Specify the icon to render on top of the label. */ icon: PropTypes.string, /** * Provide the label to be renderd on the trigger button. */ label: PropTypes.node, /** * Provide a prefix, default is 'cds'. */ // prefix: PropTypes.string, /** * Specify the size of the button and menu. */ size: PropTypes.oneOf(['md', 'lg']), /** * Specify a DOM node where the Menu should be rendered in. Defaults to document.body. */ target: PropTypes.object }; export { MenuButton };