UNPKG

@carbon/ibm-security

Version:

Carbon for Cloud & Cognitive IBM Security UI components

159 lines (155 loc) 6.56 kB
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; import _extends from "@babel/runtime/helpers/extends"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; var _excluded = ["children", "className", "disabled", "href", "iconDescription", "id", "onClick", "renderIcon"]; /** * @file Combo button. * @copyright IBM Security 2019 - 2021 */ import { ChevronDown16, ChevronUp16 } from '@carbon/icons-react'; import classnames from 'classnames'; import PropTypes from 'prop-types'; import React, { createElement, useState } from 'react'; import { carbonPrefix, getComponentNamespace } from '../../globals/namespace'; import Button from '../Button'; import OverflowMenu from '../OverflowMenu'; import OverflowMenuItem from '../OverflowMenuItem'; import { TooltipDirection } from '../IconButton/IconButton'; import { namespace as buttonNamespace } from '../Button/Button'; export var namespace = getComponentNamespace('combo-button'); var ComboButton = function ComboButton(_ref) { var children = _ref.children, className = _ref.className, direction = _ref.direction, menuOffset = _ref.menuOffset, menuOffsetFlip = _ref.menuOffsetFlip, selectorPrimaryFocus = _ref.selectorPrimaryFocus; var _useState = useState(false), _useState2 = _slicedToArray(_useState, 2), isOpen = _useState2[0], setIsOpen = _useState2[1]; var childrenArray = React.Children.toArray(children).filter(Boolean); // Save first child (e.g., primary action) to use as a `Button`: var buttonProps = childrenArray[0].props; // Need to explicitly define props, versus using `...rest`, // because otherwise unused `OverflowMenuItem`-related props from // may trigger invalid DOM warnings. var primaryActionWithProps = /*#__PURE__*/React.createElement(Button, _extends({}, buttonProps, { className: classnames(buttonProps.className, "".concat(namespace, "--primary")), disabled: buttonProps.disabled, href: buttonProps.href, iconDescription: buttonProps.iconDescription, kind: "primary", id: buttonProps.id, onClick: buttonProps.onClick, renderIcon: buttonProps.renderIcon, type: "button" }), /*#__PURE__*/React.createElement("span", { className: "".concat(carbonPrefix, "--text-truncate--end"), title: buttonProps.children }, buttonProps.children)); // Save remaining children to be displayed in the `OverflowMenu`: var overflowItems; var overflowMenuItemWithProps; if (childrenArray.length > 1) { overflowItems = childrenArray.slice(1); // Create `OverflowMenuItem` components: overflowMenuItemWithProps = overflowItems.map(function (item, index) { // Need to explicitly define props, versus using `...rest`, // because otherwise unused `Button`-related props from // may trigger invalid DOM warnings. var _item$props = item.props, children = _item$props.children, className = _item$props.className, disabled = _item$props.disabled, href = _item$props.href, iconDescription = _item$props.iconDescription, id = _item$props.id, onClick = _item$props.onClick, Icon = _item$props.renderIcon, other = _objectWithoutProperties(_item$props, _excluded); return /*#__PURE__*/React.createElement(OverflowMenuItem, _extends({ className: classnames(className, "".concat(namespace, "-item__wrapper")), disabled: disabled, href: href, itemText: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", { className: "".concat(carbonPrefix, "--text-truncate--end"), title: children }, children), Icon && /*#__PURE__*/React.createElement(Icon, { "aria-label": iconDescription })), id: id, key: id || index, onClick: onClick }, other)); }); } var renderOverflowMenuIcon = function renderOverflowMenuIcon() { return /*#__PURE__*/createElement(isOpen ? ChevronUp16 : ChevronDown16, { className: "".concat(namespace, "__icon") }); }; return /*#__PURE__*/React.createElement("div", { className: classnames(namespace, className), "data-floating-menu-container": true }, /*#__PURE__*/React.createElement("div", { className: "".concat(namespace, "__group") }, primaryActionWithProps, overflowMenuItemWithProps !== undefined && /*#__PURE__*/React.createElement(OverflowMenu, { className: classnames( // Button-specific classes for styling: buttonNamespace, "".concat(carbonPrefix, "--btn"), "".concat(carbonPrefix, "--btn--primary"), // Button as a child of combo button: "".concat(namespace, "__button"), // Overflow menu as a child of combo button: "".concat(namespace, "__overflow-menu")), direction: direction, menuOffset: menuOffset, menuOffsetFlip: menuOffsetFlip, menuOptionsClass: "".concat(carbonPrefix, "--list-box__menu"), onClick: function onClick() { return setIsOpen(!isOpen); }, onClose: function onClose() { return setIsOpen(false); }, renderIcon: renderOverflowMenuIcon, selectorPrimaryFocus: selectorPrimaryFocus }, overflowMenuItemWithProps))); }; ComboButton.propTypes = { /** @type {node} The child nodes. */ children: PropTypes.node.isRequired, /** @type {string} Extra classes to add. */ className: PropTypes.string, /** @type {string} Overflow menu direction. */ direction: PropTypes.oneOf([TooltipDirection.TOP, TooltipDirection.BOTTOM]), /** * The adjustment in position applied to the floating menu. */ menuOffset: PropTypes.oneOfType([PropTypes.shape({ top: PropTypes.oneOf([PropTypes.number, PropTypes.string]), left: PropTypes.oneOf([PropTypes.number, PropTypes.string]) }), PropTypes.func]), /** * The adjustment in position applied to the floating menu. */ menuOffsetFlip: PropTypes.oneOfType([PropTypes.shape({ top: PropTypes.oneOf([PropTypes.number, PropTypes.string]), left: PropTypes.oneOf([PropTypes.number, PropTypes.string]) }), PropTypes.func]), /** * Specify a CSS selector that matches the DOM element that should * be focused when the OverflowMenu opens */ selectorPrimaryFocus: PropTypes.string }; ComboButton.defaultProps = { className: '', direction: TooltipDirection.TOP, menuOffset: function menuOffset() { return { left: 'auto' }; }, menuOffsetFlip: undefined, selectorPrimaryFocus: '[data-overflow-menu-primary-focus]' }; export default ComboButton;