UNPKG

@carbon/react

Version:

React components for the Carbon Design System

166 lines (160 loc) 5.34 kB
/** * 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'); var Text = require('../Text/Text.js'); require('../Text/TextDirection.js'); 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(`${prefix}--overflow-menu-options__btn`, className); const overflowMenuItemClasses = cx(`${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.createElement("div", { className: `${prefix}--overflow-menu-options__option-content` }, itemText); })(); return /*#__PURE__*/React.createElement(Text.Text, { as: "li", className: overflowMenuItemClasses, role: "none" }, /*#__PURE__*/React.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 // eslint-disable-next-line @typescript-eslint/no-explicit-any -- https://github.com/carbon-design-system/carbon/issues/20452 , 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 // eslint-disable-next-line @typescript-eslint/no-explicit-any -- https://github.com/carbon-design-system/carbon/issues/20452 , title: requireTitle ? title || itemText : undefined }, rest), OverflowMenuItemContent)); }); OverflowMenuItem.propTypes = { /** * The CSS class name to be placed on the button element */ className: PropTypes.string, /** * A callback to tell the parent menu component that the menu should be closed. */ closeMenu: PropTypes.func, /** * `true` to make this menu item disabled. */ disabled: PropTypes.bool, handleOverflowMenuItemFocus: PropTypes.func, /** * `true` to make this menu item a divider. */ hasDivider: PropTypes.bool, /** * If given, overflow item will render as a link with the given href */ href: PropTypes.string, index: PropTypes.number, /** * `true` to make this menu item a "danger button". */ isDelete: PropTypes.bool, /** * The text in the menu item. */ itemText: PropTypes.node.isRequired, /** * event handlers */ 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, /** * `true` if this menu item has long text and requires a browser tooltip */ requireTitle: PropTypes.bool, /** * Specify a title for the OverflowMenuItem */ title: PropTypes.string, /** * The CSS class name to be placed on the wrapper list item element */ wrapperClassName: PropTypes.string }; exports.default = OverflowMenuItem;