@carbon/react
Version:
React components for the Carbon Design System
110 lines (108 loc) • 3.98 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.
*/
import { usePrefix } from "../../internal/usePrefix.js";
import { Text } from "../Text/Text.js";
import { ArrowDown, ArrowUp } from "../../internal/keyboard/keys.js";
import { match } from "../../internal/keyboard/match.js";
import { useId } from "../../internal/useId.js";
import { warning } from "../../internal/warning.js";
import classNames from "classnames";
import { forwardRef } from "react";
import PropTypes from "prop-types";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
//#region src/components/OverflowMenuItem/OverflowMenuItem.tsx
/**
* 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 OverflowMenuItem = forwardRef((props, ref) => {
const { className, closeMenu, dangerDescription = "danger", disabled = false, handleOverflowMenuItemFocus, hasDivider = false, href, isDelete = false, index, itemText = "Provide itemText", onClick = () => {}, onKeyDown = () => {}, requireTitle, title, wrapperClassName, ...rest } = props;
const prefix = usePrefix();
function setTabFocus(evt) {
if (match(evt, ArrowDown)) handleOverflowMenuItemFocus?.({
currentIndex: index,
direction: 1
});
if (match(evt, ArrowUp)) handleOverflowMenuItemFocus?.({
currentIndex: index,
direction: -1
});
}
function handleClick(evt) {
onClick(evt);
if (closeMenu) closeMenu();
}
warning(!!closeMenu, "`<OverflowMenuItem>` detected missing `closeMenu` prop. `closeMenu` is required to let `<OverflowMenu>` close the menu upon actions on `<OverflowMenuItem>`. Please make sure `<OverflowMenuItem>` is a direct child of `<OverflowMenu>.");
const overflowMenuBtnClasses = classNames(`${prefix}--overflow-menu-options__btn`, className);
const overflowMenuItemClasses = classNames(`${prefix}--overflow-menu-options__option`, {
[`${prefix}--overflow-menu--divider`]: hasDivider,
[`${prefix}--overflow-menu-options__option--danger`]: isDelete,
[`${prefix}--overflow-menu-options__option--disabled`]: disabled
}, wrapperClassName);
const TagToUse = href ? "a" : "button";
const assistiveId = useId("danger-description");
const OverflowMenuItemContent = (() => {
if (typeof itemText !== "string") return itemText;
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
className: `${prefix}--overflow-menu-options__option-content`,
children: itemText
}), isDelete && /* @__PURE__ */ jsx("span", {
id: assistiveId,
className: `${prefix}--visually-hidden`,
children: dangerDescription
})] });
})();
return /* @__PURE__ */ jsx(Text, {
as: "li",
className: overflowMenuItemClasses,
role: "none",
children: /* @__PURE__ */ jsx(TagToUse, {
className: overflowMenuBtnClasses,
disabled,
href,
onClick: handleClick,
onKeyDown: (evt) => {
setTabFocus(evt);
onKeyDown(evt);
},
role: "menuitem",
ref,
tabIndex: -1,
title: requireTitle ? title || itemText : void 0,
...rest,
children: OverflowMenuItemContent
})
});
});
OverflowMenuItem.propTypes = {
className: PropTypes.string,
closeMenu: PropTypes.func,
dangerDescription: PropTypes.string,
disabled: PropTypes.bool,
handleOverflowMenuItemFocus: PropTypes.func,
hasDivider: PropTypes.bool,
href: PropTypes.string,
index: PropTypes.number,
isDelete: PropTypes.bool,
itemText: PropTypes.node.isRequired,
onBlur: PropTypes.func,
onClick: PropTypes.func,
onFocus: PropTypes.func,
onKeyDown: PropTypes.func,
onKeyUp: PropTypes.func,
onMouseDown: PropTypes.func,
onMouseEnter: PropTypes.func,
onMouseLeave: PropTypes.func,
onMouseUp: PropTypes.func,
requireTitle: PropTypes.bool,
title: PropTypes.string,
wrapperClassName: PropTypes.string
};
//#endregion
export { OverflowMenuItem as default };