@carbon/react
Version:
React components for the Carbon Design System
148 lines (146 loc) • 5.27 kB
JavaScript
/**
* Copyright IBM Corp. 2016, 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_usePrefix = require("../../internal/usePrefix.js");
const require_useIsomorphicEffect = require("../../internal/useIsomorphicEffect.js");
const require_useId = require("../../internal/useId.js");
const require_index = require("../FeatureFlags/index.js");
const require_index$1 = require("../Button/index.js");
const require_mergeRefs = require("../../tools/mergeRefs.js");
const require_Menu = require("../Menu/Menu.js");
const require_useAttachedMenu = require("../../internal/useAttachedMenu.js");
let classnames = require("classnames");
classnames = require_runtime.__toESM(classnames);
let react = require("react");
react = require_runtime.__toESM(react);
let prop_types = require("prop-types");
prop_types = require_runtime.__toESM(prop_types);
let react_jsx_runtime = require("react/jsx-runtime");
let _carbon_icons_react = require("@carbon/icons-react");
let _floating_ui_react = require("@floating-ui/react");
//#region src/components/MenuButton/index.tsx
/**
* Copyright IBM Corp. 2023, 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 validButtonKinds = [
"primary",
"tertiary",
"ghost"
];
const defaultButtonKind = "primary";
const MenuButton = (0, react.forwardRef)(({ children, className, disabled, kind = defaultButtonKind, label, menuBackgroundToken = "layer", menuBorder = false, size = "lg", menuAlignment = "bottom", tabIndex = 0, menuTarget, ...rest }, forwardRef) => {
const enableOnlyFloatingStyles = require_index.useFeatureFlag("enable-v12-dynamic-floating-styles");
const id = require_useId.useId("MenuButton");
const prefix = require_usePrefix.usePrefix();
const triggerRef = (0, react.useRef)(null);
let middlewares = [];
if (!enableOnlyFloatingStyles) middlewares = [(0, _floating_ui_react.flip)({ crossAxis: false })];
if (menuAlignment === "bottom" || menuAlignment === "top") middlewares.push((0, _floating_ui_react.size)({ apply({ rects, elements }) {
Object.assign(elements.floating.style, { width: `${rects.reference.width}px` });
} }));
const { refs, floatingStyles, placement, middlewareData } = (0, _floating_ui_react.useFloating)({
placement: menuAlignment,
strategy: "fixed",
transform: false,
middleware: middlewares,
whileElementsMounted: _floating_ui_react.autoUpdate
});
const ref = require_mergeRefs.mergeRefs(forwardRef, triggerRef);
const { open, handleClick: hookOnClick, handleMousedown, handleClose } = require_useAttachedMenu.useAttachedMenu(triggerRef);
require_useIsomorphicEffect.default(() => {
Object.keys(floatingStyles).forEach((style) => {
if (refs.floating.current) {
let value = floatingStyles[style];
if ([
"top",
"right",
"bottom",
"left"
].includes(style) && Number(value)) value += "px";
refs.floating.current.style[style] = value;
}
});
}, [
floatingStyles,
refs.floating,
middlewareData,
placement,
open
]);
function handleClick() {
if (triggerRef.current) hookOnClick();
}
const containerClasses = (0, classnames.default)(`${prefix}--menu-button__container`, className);
const triggerClasses = (0, classnames.default)(`${prefix}--menu-button__trigger`, { [`${prefix}--menu-button__trigger--open`]: open });
const menuClasses = (0, classnames.default)(`${prefix}--menu-button__${menuAlignment}`);
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
...rest,
ref,
"aria-owns": open ? id : void 0,
className: containerClasses,
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_index$1.default, {
ref: refs.setReference,
className: triggerClasses,
size,
tabIndex,
kind,
renderIcon: _carbon_icons_react.ChevronDown,
disabled,
"aria-haspopup": true,
"aria-expanded": open,
onClick: handleClick,
onMouseDown: handleMousedown,
"aria-controls": open ? id : void 0,
children: label
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Menu.Menu, {
containerRef: triggerRef,
menuAlignment,
className: menuClasses,
ref: refs.setFloating,
id,
legacyAutoalign: false,
label,
size,
open,
onClose: handleClose,
target: menuTarget,
backgroundToken: menuBackgroundToken,
border: menuBorder,
children
})]
});
});
MenuButton.propTypes = {
children: prop_types.default.node.isRequired,
className: prop_types.default.string,
disabled: prop_types.default.bool,
kind: prop_types.default.oneOf(validButtonKinds),
label: prop_types.default.string.isRequired,
menuAlignment: prop_types.default.oneOf([
"top",
"top-start",
"top-end",
"bottom",
"bottom-start",
"bottom-end"
]),
size: prop_types.default.oneOf([
"xs",
"sm",
"md",
"lg"
]),
tabIndex: prop_types.default.number,
menuBackgroundToken: prop_types.default.oneOf(["layer", "background"]),
menuBorder: prop_types.default.bool,
menuTarget: prop_types.default.instanceOf(typeof Element !== "undefined" ? Element : Object)
};
//#endregion
exports.MenuButton = MenuButton;