UNPKG

@carbon/ibm-products

Version:

Carbon for IBM Products

173 lines (166 loc) 5.85 kB
/** * Copyright IBM Corp. 2020, 2025 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js'; import React__default, { useRef } from 'react'; import PropTypes from '../../_virtual/index.js'; import cx from 'classnames'; import { pkg } from '../../settings.js'; import { Button } from '@carbon/react'; import uuidv4 from '../../global/js/utils/uuidv4.js'; import { prepareProps } from '../../global/js/utils/props-helper.js'; import { ActionBarItem } from './ActionBarItem.js'; import { ActionBarOverflowItems } from './ActionBarOverflowItems.js'; import { useOverflowItems } from '../../global/js/hooks/useOverflowItems/useOverflowItems.js'; // The block part of our conventional BEM class names (blockClass__E--M). const blockClass = `${pkg.prefix}--action-bar`; const componentName = 'ActionBar'; // Default values for props const defaults = { actions: Object.freeze([]) }; // NOTE: the component SCSS is not imported here: it is rolled up separately. /** * The ActionBar is used internally by the PageHeader to wrap ActionBarItems. */ let ActionBar = /*#__PURE__*/React__default.forwardRef((_ref, ref) => { let { // The component props, in alphabetical order (for consistency). actions = defaults.actions, className, maxVisible, menuOptionsClass, onWidthChange, overflowAriaLabel, overflowMenuRef, rightAlign, // Collect any other property values passed in. ...rest } = _ref; const internalId = useRef(uuidv4()); const refDisplayedItems = useRef(null); const backupRef = useRef(null); const localRef = ref || backupRef; const _offsetRef = useRef(null); const offsetRef = overflowMenuRef || _offsetRef; const _items = actions.map(action => ({ id: action?.key, ...action })); const { visibleItems, hiddenItems, itemRefHandler, offsetRefHandler } = useOverflowItems(_items, localRef, offsetRef, maxVisible, onWidthChange); const overflowMenuItems = hiddenItems?.map(_ref2 => { let { id: key, ...rest } = _ref2; return /*#__PURE__*/React__default.createElement(ActionBarItem, _extends({}, rest, { key: key })); }); return /*#__PURE__*/React__default.createElement("div", _extends({}, rest, { className: cx([blockClass, className]), ref: localRef }), /*#__PURE__*/React__default.createElement("div", { ref: refDisplayedItems, className: cx([`${blockClass}__displayed-items`, { [`${blockClass}__displayed-items--right`]: rightAlign }]) }, visibleItems.map(_ref3 => { let { key, id, ...rest } = _ref3; return /*#__PURE__*/React__default.createElement(ActionBarItem, _extends({ id }, rest, { key: key, ref: node => { itemRefHandler(id, node); } })); }), overflowMenuItems?.length > 0 && /*#__PURE__*/React__default.createElement(ActionBarOverflowItems, { menuOptionsClass: menuOptionsClass, overflowAriaLabel: overflowAriaLabel, overflowMenuRef: node => offsetRef.current = offsetRefHandler(node), overflowItems: overflowMenuItems, key: `overflow-menu-${internalId.current}` }))); }); ActionBar = pkg.checkComponentEnabled(ActionBar, componentName); ActionBar.displayName = componentName; ActionBar.propTypes = { /** * Specifies the action bar items. Each item is specified as an object * with required fields: key for array rendering, renderIcon, iconDescription and * label to provide the icon to display, * and optional 'onClick' to receive notifications when the button is clicked. * Additional fields in the object will be passed to the * Button component, and these can include 'disabled', 'ref', 'className', * and any other Button props. * * Note that the Button props 'kind', 'size', * 'tooltipPosition', 'tooltipAlignment' and 'type' are ignored, as these * cannot be used for an action bar item. * * Carbon Button API https://react.carbondesignsystem.com/?path=/docs/components-button--default#component-api */ /**@ts-ignore */ actions: PropTypes.arrayOf(PropTypes.shape({ /**@ts-ignore */ ...prepareProps(Button.propTypes, [ // props not desired from Button.propTypes 'kind', 'size', 'tooltipPosition', 'tooltipAlignment']), id: PropTypes.string, // Additional props key: PropTypes.string.isRequired, // Redefine as form different to Button and a key prop used by ActionBarItems iconDescription: PropTypes.string.isRequired, label: PropTypes.string.isRequired, /**@ts-ignore */ renderIcon: Button.propTypes.renderIcon.isRequired, // We duplicate onClick here to improve DocGen in Storybook onClick: PropTypes.func })), // expects action bar item as array or in fragment, /** * className */ className: PropTypes.string, /** * maxVisible : Maximum action bar items visible before going into the overflow menu */ maxVisible: PropTypes.number, /** * class name applied to the overflow options */ menuOptionsClass: PropTypes.string, /** * onItemCountChange - event reporting maxWidth */ onWidthChange: PropTypes.func, /** * overflowAriaLabel label for open close button overflow used for action bar items that do nto fit. */ overflowAriaLabel: PropTypes.string.isRequired, /** * overflowMenuRef for the overflow menu width that is needed to calculate the width of the action bar with overflow */ /**@ts-ignore */ overflowMenuRef: PropTypes.oneOfType([PropTypes.shape({ current: PropTypes.elementType }), PropTypes.object]), /** * align tags to right of available space */ rightAlign: PropTypes.bool }; export { ActionBar };