@carbon/ibm-security
Version:
Carbon for Cloud & Cognitive IBM Security UI components
159 lines (155 loc) • 6.56 kB
JavaScript
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;