@carbon/react
Version:
React components for the Carbon Design System
168 lines (166 loc) • 5.78 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_useId = require("../../../internal/useId.js");
const require_deprecateValuesWithin = require("../../../prop-types/deprecateValuesWithin.js");
const require_mapPopoverAlign = require("../../../tools/mapPopoverAlign.js");
const require_index = require("../../FeatureFlags/index.js");
const require_index$1 = require("../../IconButton/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/OverflowMenu/next/index.tsx
/**
* 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.
*/
const defaultSize = "md";
const OverflowMenu = react.default.forwardRef(({ autoAlign = false, children, className, label = "Options", renderIcon: IconElement = _carbon_icons_react.OverflowMenuVertical, size = defaultSize, menuAlignment = "bottom-start", tooltipAlignment, menuTarget, ...rest }, forwardRef) => {
const enableFloatingStyles = require_index.useFeatureFlag("enable-v12-dynamic-floating-styles") || autoAlign;
const { refs, floatingStyles, placement, middlewareData } = (0, _floating_ui_react.useFloating)(enableFloatingStyles ? {
placement: menuAlignment,
strategy: "fixed",
middleware: [autoAlign && (0, _floating_ui_react.flip)({ fallbackPlacements: menuAlignment.includes("bottom") ? [
"bottom-start",
"bottom-end",
"top-start",
"top-end"
] : [
"top-start",
"top-end",
"bottom-start",
"bottom-end"
] })],
whileElementsMounted: _floating_ui_react.autoUpdate
} : {});
const id = require_useId.useId("overflowmenu");
const prefix = require_usePrefix.usePrefix();
const triggerRef = (0, react.useRef)(null);
const { open, x, y, handleClick: hookOnClick, handleMousedown, handleClose } = require_useAttachedMenu.useAttachedMenu(triggerRef);
(0, react.useEffect)(() => {
if (enableFloatingStyles) Object.keys(floatingStyles).forEach((style) => {
if (refs.floating.current) refs.floating.current.style[style] = floatingStyles[style];
});
}, [
floatingStyles,
enableFloatingStyles,
refs.floating,
open,
placement,
middlewareData
]);
function handleTriggerClick() {
if (triggerRef.current) hookOnClick();
}
const containerClasses = (0, classnames.default)(className, `${prefix}--overflow-menu__container`, { [`${prefix}--autoalign`]: enableFloatingStyles });
const menuClasses = (0, classnames.default)(`${prefix}--overflow-menu__${menuAlignment}`);
const triggerClasses = (0, classnames.default)(`${prefix}--overflow-menu`, { [`${prefix}--overflow-menu--open`]: open }, size !== defaultSize && `${prefix}--overflow-menu--${size}`);
const floatingRef = require_mergeRefs.mergeRefs(triggerRef, refs.setReference);
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
...rest,
className: containerClasses,
"aria-owns": open ? id : void 0,
ref: forwardRef,
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_index$1.IconButton, {
"aria-controls": open ? id : void 0,
"aria-haspopup": true,
"aria-expanded": open,
className: triggerClasses,
onClick: handleTriggerClick,
onMouseDown: handleMousedown,
ref: floatingRef,
label,
align: tooltipAlignment,
kind: "ghost",
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconElement, { className: `${prefix}--overflow-menu__icon` })
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Menu.Menu, {
containerRef: triggerRef,
ref: refs.setFloating,
menuAlignment,
className: menuClasses,
id,
size,
legacyAutoalign: !enableFloatingStyles,
open,
onClose: handleClose,
x,
y,
label,
target: menuTarget,
children
})]
});
});
OverflowMenu.propTypes = {
autoAlign: prop_types.default.bool,
children: prop_types.default.node,
className: prop_types.default.string,
label: prop_types.default.string,
menuAlignment: prop_types.default.oneOf([
"top-start",
"top-end",
"bottom-start",
"bottom-end"
]),
renderIcon: prop_types.default.oneOfType([prop_types.default.func, prop_types.default.object]),
size: prop_types.default.oneOf([
"xs",
"sm",
"md",
"lg"
]),
tooltipAlignment: require_deprecateValuesWithin.deprecateValuesWithin(prop_types.default.oneOf([
"top",
"top-left",
"top-right",
"bottom",
"bottom-left",
"bottom-right",
"left",
"left-bottom",
"left-top",
"right",
"right-bottom",
"right-top",
"top-start",
"top-end",
"bottom-start",
"bottom-end",
"left-end",
"left-start",
"right-end",
"right-start"
]), [
"top",
"top-start",
"top-end",
"bottom",
"bottom-start",
"bottom-end",
"left",
"left-start",
"left-end",
"right",
"right-start",
"right-end"
], require_mapPopoverAlign.mapPopoverAlign),
menuTarget: prop_types.default.instanceOf(typeof Element !== "undefined" ? Element : Object)
};
//#endregion
exports.OverflowMenu = OverflowMenu;