@carbon/react
Version:
React components for the Carbon Design System
170 lines (162 loc) • 5.91 kB
JavaScript
/**
* Copyright IBM Corp. 2016, 2023
*
* 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';
Object.defineProperty(exports, '__esModule', { value: true });
var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
var cx = require('classnames');
var PropTypes = require('prop-types');
var React = require('react');
var keys = require('../../internal/keyboard/keys.js');
var match = require('../../internal/keyboard/match.js');
var usePrefix = require('../../internal/usePrefix.js');
var warning = require('../../internal/warning.js');
require('../Text/index.js');
var Text = require('../Text/Text.js');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
const frFn = React.forwardRef;
const OverflowMenuItem = frFn((props, ref) => {
const {
className,
closeMenu,
disabled = false,
handleOverflowMenuItemFocus,
hasDivider = false,
href,
isDelete = false,
index,
itemText = 'Provide itemText',
onClick = () => {},
onKeyDown = () => {},
requireTitle,
title,
wrapperClassName,
...rest
} = props;
const prefix = usePrefix.usePrefix();
function setTabFocus(evt) {
if (match.match(evt, keys.ArrowDown)) {
handleOverflowMenuItemFocus?.({
currentIndex: index,
direction: 1
});
}
if (match.match(evt, keys.ArrowUp)) {
handleOverflowMenuItemFocus?.({
currentIndex: index,
direction: -1
});
}
}
function handleClick(evt) {
onClick(evt);
if (closeMenu) {
closeMenu();
}
}
process.env.NODE_ENV !== "production" ? warning.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>.') : void 0;
const overflowMenuBtnClasses = cx__default["default"](`${prefix}--overflow-menu-options__btn`, className);
const overflowMenuItemClasses = cx__default["default"](`${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 OverflowMenuItemContent = (() => {
if (typeof itemText !== 'string') {
return itemText;
}
return /*#__PURE__*/React__default["default"].createElement("div", {
className: `${prefix}--overflow-menu-options__option-content`
}, itemText);
})();
return /*#__PURE__*/React__default["default"].createElement(Text.Text, {
as: "li",
className: overflowMenuItemClasses,
role: "none"
}, /*#__PURE__*/React__default["default"].createElement(TagToUse, _rollupPluginBabelHelpers["extends"]({
className: overflowMenuBtnClasses,
disabled: disabled,
href: href,
onClick: handleClick,
onKeyDown: evt => {
setTabFocus(evt);
onKeyDown(evt);
},
role: "menuitem"
// ref as any: the type of `ref` is `ForwardedRef<HTMLButtonElement>` in `Button` component
// but `OverflowMenuItem` can be rendered as `a` tag as well, which is `HTMLAnchorElement`
// so we have to use `any` here
,
ref: ref,
tabIndex: -1
// itemText as any: itemText may be a ReactNode, but `title` only accepts string
// to avoid compatibility issue, we use `any` here. Consider to enforce `itemText` to be `string?`
// in the next major release
,
title: requireTitle ? title || itemText : undefined
}, rest), OverflowMenuItemContent));
});
OverflowMenuItem.propTypes = {
/**
* The CSS class name to be placed on the button element
*/
className: PropTypes__default["default"].string,
/**
* A callback to tell the parent menu component that the menu should be closed.
*/
closeMenu: PropTypes__default["default"].func,
/**
* `true` to make this menu item disabled.
*/
disabled: PropTypes__default["default"].bool,
handleOverflowMenuItemFocus: PropTypes__default["default"].func,
/**
* `true` to make this menu item a divider.
*/
hasDivider: PropTypes__default["default"].bool,
/**
* If given, overflow item will render as a link with the given href
*/
href: PropTypes__default["default"].string,
index: PropTypes__default["default"].number,
/**
* `true` to make this menu item a "danger button".
*/
isDelete: PropTypes__default["default"].bool,
/**
* The text in the menu item.
*/
itemText: PropTypes__default["default"].node.isRequired,
/**
* event handlers
*/
onBlur: PropTypes__default["default"].func,
onClick: PropTypes__default["default"].func,
onFocus: PropTypes__default["default"].func,
onKeyDown: PropTypes__default["default"].func,
onKeyUp: PropTypes__default["default"].func,
onMouseDown: PropTypes__default["default"].func,
onMouseEnter: PropTypes__default["default"].func,
onMouseLeave: PropTypes__default["default"].func,
onMouseUp: PropTypes__default["default"].func,
/**
* `true` if this menu item has long text and requires a browser tooltip
*/
requireTitle: PropTypes__default["default"].bool,
/**
* Specify a title for the OverflowMenuItem
*/
title: PropTypes__default["default"].string,
/**
* The CSS class name to be placed on the wrapper list item element
*/
wrapperClassName: PropTypes__default["default"].string
};
exports["default"] = OverflowMenuItem;