MenuItem.js 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. "use client";
  2. import * as React from 'react';
  3. import classNames from 'classnames';
  4. import { Item } from 'rc-menu';
  5. import toArray from "rc-util/es/Children/toArray";
  6. import omit from "rc-util/es/omit";
  7. import { cloneElement } from '../_util/reactNode';
  8. import { SiderContext } from '../layout/Sider';
  9. import Tooltip from '../tooltip';
  10. import MenuContext from './MenuContext';
  11. const MenuItem = props => {
  12. var _a;
  13. const {
  14. className,
  15. children,
  16. icon,
  17. title,
  18. danger,
  19. extra
  20. } = props;
  21. const {
  22. prefixCls,
  23. firstLevel,
  24. direction,
  25. disableMenuItemTitleTooltip,
  26. inlineCollapsed: isInlineCollapsed
  27. } = React.useContext(MenuContext);
  28. const renderItemChildren = inlineCollapsed => {
  29. const label = children === null || children === void 0 ? void 0 : children[0];
  30. const wrapNode = /*#__PURE__*/React.createElement("span", {
  31. className: classNames(`${prefixCls}-title-content`, {
  32. [`${prefixCls}-title-content-with-extra`]: !!extra || extra === 0
  33. })
  34. }, children);
  35. // inline-collapsed.md demo 依赖 span 来隐藏文字,有 icon 属性,则内部包裹一个 span
  36. // ref: https://github.com/ant-design/ant-design/pull/23456
  37. if (!icon || /*#__PURE__*/React.isValidElement(children) && children.type === 'span') {
  38. if (children && inlineCollapsed && firstLevel && typeof label === 'string') {
  39. return /*#__PURE__*/React.createElement("div", {
  40. className: `${prefixCls}-inline-collapsed-noicon`
  41. }, label.charAt(0));
  42. }
  43. }
  44. return wrapNode;
  45. };
  46. const {
  47. siderCollapsed
  48. } = React.useContext(SiderContext);
  49. let tooltipTitle = title;
  50. if (typeof title === 'undefined') {
  51. tooltipTitle = firstLevel ? children : '';
  52. } else if (title === false) {
  53. tooltipTitle = '';
  54. }
  55. const tooltipProps = {
  56. title: tooltipTitle
  57. };
  58. if (!siderCollapsed && !isInlineCollapsed) {
  59. tooltipProps.title = null;
  60. // Reset `open` to fix control mode tooltip display not correct
  61. // ref: https://github.com/ant-design/ant-design/issues/16742
  62. tooltipProps.open = false;
  63. }
  64. const childrenLength = toArray(children).length;
  65. let returnNode = /*#__PURE__*/React.createElement(Item, Object.assign({}, omit(props, ['title', 'icon', 'danger']), {
  66. className: classNames({
  67. [`${prefixCls}-item-danger`]: danger,
  68. [`${prefixCls}-item-only-child`]: (icon ? childrenLength + 1 : childrenLength) === 1
  69. }, className),
  70. title: typeof title === 'string' ? title : undefined
  71. }), cloneElement(icon, {
  72. className: classNames(/*#__PURE__*/React.isValidElement(icon) ? (_a = icon.props) === null || _a === void 0 ? void 0 : _a.className : undefined, `${prefixCls}-item-icon`)
  73. }), renderItemChildren(isInlineCollapsed));
  74. if (!disableMenuItemTitleTooltip) {
  75. returnNode = /*#__PURE__*/React.createElement(Tooltip, Object.assign({}, tooltipProps, {
  76. placement: direction === 'rtl' ? 'left' : 'right',
  77. classNames: {
  78. root: `${prefixCls}-inline-collapsed-tooltip`
  79. }
  80. }), returnNode);
  81. }
  82. return returnNode;
  83. };
  84. export default MenuItem;