UNPKG

@carbon/ibm-products

Version:
158 lines (156 loc) 6.7 kB
/** * Copyright IBM Corp. 2020, 2026 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ const require_runtime = require("../../_virtual/_rolldown/runtime.js"); const require_index = require("../../node_modules/classnames/index.js"); const require_settings = require("../../settings.js"); const require_props_helper = require("../../global/js/utils/props-helper.js"); const require_useResizeObserver = require("../../global/js/hooks/useResizeObserver.js"); let react = require("react"); react = require_runtime.__toESM(react); let prop_types = require("prop-types"); prop_types = require_runtime.__toESM(prop_types); let _carbon_react = require("@carbon/react"); //#region src/components/ButtonSetWithOverflow/ButtonSetWithOverflow.jsx var import_classnames = /* @__PURE__ */ require_runtime.__toESM(require_index.default); const blockClass = `${require_settings.pkg.prefix}--button-set-with-overflow`; const componentName = "ButtonSetWithOverflow"; const buttonSize = "md"; const ButtonSetWithOverflow = ({ buttons, className, onWidthChange, buttonSetOverflowLabel, menuOptionsClass, rightAlign }) => { const carbonPrefix = (0, _carbon_react.usePrefix)(); const [showAsOverflow, setShowAsOverflow] = (0, react.useState)(false); const spaceAvailableRef = (0, react.useRef)(null); const sizingContainerRefSet = (0, react.useRef)(null); const sizingContainerRefCombo = (0, react.useRef)(null); const sizes = (0, react.useRef)({}); /** * checkFullyVisibleItems determines display count based on space available and width of pageActions * * ButtonSetWithOverflow switches between a Carbon ButtonSet and use of the ButtonMenu component depending * on the space available. While there is sufficient space to show all of the buttons side by side the * ButtonSet is used, once this is no longer the case it switches to a ButtonMenu. * */ const checkFullyVisibleItems = () => { const spaceAvailable = spaceAvailableRef.current?.offsetWidth; let newShowAsOverflow = true; const sizingSet = sizingContainerRefSet.current?.querySelectorAll(`.${carbonPrefix}--btn`); let sizingSetTotalSize = 0; for (let item of sizingSet) sizingSetTotalSize += item.offsetWidth; const sizingComboSize = sizingContainerRefCombo.current?.offsetWidth; if (onWidthChange && (sizes.current.minWidth !== sizingComboSize || sizes.current.maxWidth !== sizingSetTotalSize)) { sizes.current.minWidth = sizingComboSize; sizes.current.maxWidth = sizingSetTotalSize; onWidthChange({ ...sizes.current }); } if (sizingSetTotalSize <= spaceAvailable) newShowAsOverflow = false; setShowAsOverflow(newShowAsOverflow); }; (0, react.useEffect)(() => { checkFullyVisibleItems(); }, [buttons]); const AButtonSet = react.default.forwardRef(({ isHidden = false, buttons, ...rest }, ref) => { return /* @__PURE__ */ react.default.createElement(_carbon_react.ButtonSet, { ...rest, ref }, buttons.map(({ label, key, kind, id, ...other }) => { const kindFix = kind === "default" ? "primary" : kind; return /* @__PURE__ */ react.default.createElement(_carbon_react.Button, { ...other, key: key && `button-set-${key}`, size: buttonSize, type: "button", kind: kindFix, id: id ? isHidden ? `${id}--hidden` : id : null }, label); })); }); AButtonSet.propTypes = { /** * isHidden - Used to conditionally change id if one is passed to the `AButtonSet` component * in order to avoid duplicate ids between the visible and hidden button set buttons */ isHidden: prop_types.default.bool }; const AButtonMenu = react.default.forwardRef(({ buttons, ...rest }, ref) => { return /* @__PURE__ */ react.default.createElement(_carbon_react.MenuButton, { ...rest, ref, label: buttonSetOverflowLabel }, buttons.map(({ key, kind, ...other }) => { const kindFix = kind === "danger" ? "danger" : "default"; return /* @__PURE__ */ react.default.createElement(_carbon_react.MenuItem, { ...require_props_helper.prepareProps(other, ["iconDescription", "renderIcon"]), key: key && `button-menu-${key}`, kind: kindFix }); }).reverse()); }); require_useResizeObserver.useResizeObserver(sizingContainerRefSet, checkFullyVisibleItems); require_useResizeObserver.useResizeObserver(sizingContainerRefCombo, checkFullyVisibleItems); require_useResizeObserver.useResizeObserver(spaceAvailableRef, checkFullyVisibleItems); return /* @__PURE__ */ react.default.createElement("div", { className: (0, import_classnames.default)([ blockClass, className, { [`${blockClass}--right`]: rightAlign } ]), ref: spaceAvailableRef }, /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__button-container ${blockClass}__button-container--hidden` }, /* @__PURE__ */ react.default.createElement(AButtonSet, { "aria-hidden": true, ref: sizingContainerRefSet, size: buttonSize, buttons, isHidden: true })), /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__button-container ${blockClass}__button-container--hidden`, "aria-hidden": true }, /* @__PURE__ */ react.default.createElement(AButtonMenu, { className: menuOptionsClass, ref: sizingContainerRefCombo, buttons, size: buttonSize })), /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__button-container ${blockClass}__button-container--visible` }, showAsOverflow ? /* @__PURE__ */ react.default.createElement(AButtonMenu, { buttons, size: buttonSize, className: menuOptionsClass }) : /* @__PURE__ */ react.default.createElement(AButtonSet, { className: `${blockClass}__button-container`, size: buttonSize, buttons }))); }; ButtonSetWithOverflow.propTypes = { /** * buttonSetOverflowLabel - used when button set is shown as combo button */ buttonSetOverflowLabel: prop_types.default.node.isRequired, /** * Specifies the buttons for the ButtonSetWithOverflow. Each item is specified as an object * with the properties of a Carbon Button plus a label. * * Carbon Button API https://react.carbondesignsystem.com/?path=/docs/components-button--default#component-api */ buttons: prop_types.default.array.isRequired, /** * className */ className: prop_types.default.string, /** * class name applied to the overflow options */ menuOptionsClass: prop_types.default.string, /** * onResize reports maxSize on resize */ onWidthChange: prop_types.default.func, /** * align buttons to right of available space */ rightAlign: prop_types.default.bool }; ButtonSetWithOverflow.displayName = componentName; //#endregion exports.ButtonSetWithOverflow = ButtonSetWithOverflow;