@carbon/ibm-products
Version:
Carbon for IBM Products
173 lines (166 loc) • 6.09 kB
JavaScript
/**
* 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.
*/
'use strict';
var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
var React = require('react');
var index = require('../../_virtual/index.js');
var cx = require('classnames');
var settings = require('../../settings.js');
var react = require('@carbon/react');
var uuidv4 = require('../../global/js/utils/uuidv4.js');
var propsHelper = require('../../global/js/utils/props-helper.js');
var ActionBarItem = require('./ActionBarItem.js');
var ActionBarOverflowItems = require('./ActionBarOverflowItems.js');
var useOverflowItems = require('../../global/js/hooks/useOverflowItems/useOverflowItems.js');
// The block part of our conventional BEM class names (blockClass__E--M).
const blockClass = `${settings.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.
*/
exports.ActionBar = /*#__PURE__*/React.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 = React.useRef(uuidv4.default());
const refDisplayedItems = React.useRef(null);
const backupRef = React.useRef(null);
const localRef = ref || backupRef;
const _offsetRef = React.useRef(null);
const offsetRef = overflowMenuRef || _offsetRef;
const _items = actions.map(action => ({
id: action?.key,
...action
}));
const {
visibleItems,
hiddenItems,
itemRefHandler,
offsetRefHandler
} = useOverflowItems.useOverflowItems(_items, localRef, offsetRef, maxVisible, onWidthChange);
const overflowMenuItems = hiddenItems?.map(_ref2 => {
let {
id: key,
...rest
} = _ref2;
return /*#__PURE__*/React.createElement(ActionBarItem.ActionBarItem, _rollupPluginBabelHelpers.extends({}, rest, {
key: key
}));
});
return /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({}, rest, {
className: cx([blockClass, className]),
ref: localRef
}), /*#__PURE__*/React.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.createElement(ActionBarItem.ActionBarItem, _rollupPluginBabelHelpers.extends({
id
}, rest, {
key: key,
ref: node => {
itemRefHandler(id, node);
}
}));
}), overflowMenuItems?.length > 0 && /*#__PURE__*/React.createElement(ActionBarOverflowItems.ActionBarOverflowItems, {
menuOptionsClass: menuOptionsClass,
overflowAriaLabel: overflowAriaLabel,
overflowMenuRef: node => offsetRef.current = offsetRefHandler(node),
overflowItems: overflowMenuItems,
key: `overflow-menu-${internalId.current}`
})));
});
exports.ActionBar = settings.pkg.checkComponentEnabled(exports.ActionBar, componentName);
exports.ActionBar.displayName = componentName;
exports.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: index.default.arrayOf(index.default.shape({
/**@ts-ignore */
...propsHelper.prepareProps(react.Button.propTypes, [
// props not desired from Button.propTypes
'kind', 'size', 'tooltipPosition', 'tooltipAlignment']),
id: index.default.string,
// Additional props
key: index.default.string.isRequired,
// Redefine as form different to Button and a key prop used by ActionBarItems
iconDescription: index.default.string.isRequired,
label: index.default.string.isRequired,
/**@ts-ignore */
renderIcon: react.Button.propTypes.renderIcon.isRequired,
// We duplicate onClick here to improve DocGen in Storybook
onClick: index.default.func
})),
// expects action bar item as array or in fragment,
/**
* className
*/
className: index.default.string,
/**
* maxVisible : Maximum action bar items visible before going into the overflow menu
*/
maxVisible: index.default.number,
/**
* class name applied to the overflow options
*/
menuOptionsClass: index.default.string,
/**
* onItemCountChange - event reporting maxWidth
*/
onWidthChange: index.default.func,
/**
* overflowAriaLabel label for open close button overflow used for action bar items that do nto fit.
*/
overflowAriaLabel: index.default.string.isRequired,
/**
* overflowMenuRef for the overflow menu width that is needed to calculate the width of the action bar with overflow
*/
/**@ts-ignore */
overflowMenuRef: index.default.oneOfType([index.default.shape({
current: index.default.elementType
}), index.default.object]),
/**
* align tags to right of available space
*/
rightAlign: index.default.bool
};