mirror of
https://github.com/ant-design/ant-design.git
synced 2024-12-24 15:46:10 +08:00
6a62d9e7ea
* fix(dropdown): dropdown menu title content style * chore: update rc-mentions to version 2.17.0 and rc-tabs to version 15.4.0 * test: add extra style debug * test: snap * test: snap * Refactor menu demo: remove extra-style-debug component and rename extra-style-debug files to extra-style * Refactor menu demo: remove extra-style-debug component and rename extra-style-debug files to extra-style * Refactor dropdown and menu styles: Add width to extra-style elements * test: snap * fix: Add Space component to menu demo The Space component was missing from the import statement in the menu demo file. This caused a compilation error. The fix adds the Space component to the import statement, resolving the issue. Refactor the menu demo to use Space component for vertical spacing between menus. This improves the visual layout and readability of the menus. Fixes #51492 * test: snap * refactor: Update dropdown and menu title content class names --------- Co-authored-by: afc163 <afc163@gmail.com>
127 lines
3.8 KiB
TypeScript
127 lines
3.8 KiB
TypeScript
import * as React from 'react';
|
|
import classNames from 'classnames';
|
|
import type { MenuItemProps as RcMenuItemProps } from 'rc-menu';
|
|
import { Item } from 'rc-menu';
|
|
import toArray from 'rc-util/lib/Children/toArray';
|
|
import omit from 'rc-util/lib/omit';
|
|
|
|
import { cloneElement } from '../_util/reactNode';
|
|
import type { SiderContextProps } from '../layout/Sider';
|
|
import { SiderContext } from '../layout/Sider';
|
|
import type { TooltipProps } from '../tooltip';
|
|
import Tooltip from '../tooltip';
|
|
import type { MenuContextProps } from './MenuContext';
|
|
import MenuContext from './MenuContext';
|
|
|
|
export interface MenuItemProps extends Omit<RcMenuItemProps, 'title'> {
|
|
icon?: React.ReactNode;
|
|
danger?: boolean;
|
|
title?: React.ReactNode;
|
|
}
|
|
|
|
type MenuItemComponent = React.FC<MenuItemProps>;
|
|
|
|
type RestArgs<T> = T extends (arg: any, ...args: infer P) => any ? P : never;
|
|
|
|
type GenericProps<T = unknown> = T extends infer U extends MenuItemProps
|
|
? unknown extends U
|
|
? MenuItemProps
|
|
: U
|
|
: MenuItemProps;
|
|
|
|
type GenericComponent = Omit<MenuItemComponent, ''> &
|
|
(<T extends MenuItemProps>(
|
|
props: GenericProps<T>,
|
|
...args: RestArgs<MenuItemComponent>
|
|
) => ReturnType<MenuItemComponent>);
|
|
|
|
const MenuItem: GenericComponent = (props) => {
|
|
const { className, children, icon, title, danger, extra } = props;
|
|
const {
|
|
prefixCls,
|
|
firstLevel,
|
|
direction,
|
|
disableMenuItemTitleTooltip,
|
|
inlineCollapsed: isInlineCollapsed,
|
|
} = React.useContext<MenuContextProps>(MenuContext);
|
|
const renderItemChildren = (inlineCollapsed: boolean) => {
|
|
const label = (children as React.ReactNode[])?.[0];
|
|
|
|
const wrapNode = (
|
|
<span
|
|
className={classNames(`${prefixCls}-title-content`, {
|
|
[`${prefixCls}-title-content-with-extra`]: !!extra || extra === 0,
|
|
})}
|
|
>
|
|
{children}
|
|
</span>
|
|
);
|
|
// inline-collapsed.md demo 依赖 span 来隐藏文字,有 icon 属性,则内部包裹一个 span
|
|
// ref: https://github.com/ant-design/ant-design/pull/23456
|
|
if (!icon || (React.isValidElement(children) && children.type === 'span')) {
|
|
if (children && inlineCollapsed && firstLevel && typeof label === 'string') {
|
|
return <div className={`${prefixCls}-inline-collapsed-noicon`}>{label.charAt(0)}</div>;
|
|
}
|
|
}
|
|
return wrapNode;
|
|
};
|
|
|
|
const { siderCollapsed } = React.useContext<SiderContextProps>(SiderContext);
|
|
|
|
let tooltipTitle = title;
|
|
|
|
if (typeof title === 'undefined') {
|
|
tooltipTitle = firstLevel ? children : '';
|
|
} else if (title === false) {
|
|
tooltipTitle = '';
|
|
}
|
|
|
|
const tooltipProps: TooltipProps = { title: tooltipTitle };
|
|
|
|
if (!siderCollapsed && !isInlineCollapsed) {
|
|
tooltipProps.title = null;
|
|
// Reset `open` to fix control mode tooltip display not correct
|
|
// ref: https://github.com/ant-design/ant-design/issues/16742
|
|
tooltipProps.open = false;
|
|
}
|
|
|
|
const childrenLength = toArray(children).length;
|
|
|
|
let returnNode = (
|
|
<Item
|
|
{...omit(props, ['title', 'icon', 'danger'])}
|
|
className={classNames(
|
|
{
|
|
[`${prefixCls}-item-danger`]: danger,
|
|
[`${prefixCls}-item-only-child`]: (icon ? childrenLength + 1 : childrenLength) === 1,
|
|
},
|
|
className,
|
|
)}
|
|
title={typeof title === 'string' ? title : undefined}
|
|
>
|
|
{cloneElement(icon, {
|
|
className: classNames(
|
|
React.isValidElement(icon) ? icon.props?.className : '',
|
|
`${prefixCls}-item-icon`,
|
|
),
|
|
})}
|
|
{renderItemChildren(isInlineCollapsed)}
|
|
</Item>
|
|
);
|
|
|
|
if (!disableMenuItemTitleTooltip) {
|
|
returnNode = (
|
|
<Tooltip
|
|
{...tooltipProps}
|
|
placement={direction === 'rtl' ? 'left' : 'right'}
|
|
overlayClassName={`${prefixCls}-inline-collapsed-tooltip`}
|
|
>
|
|
{returnNode}
|
|
</Tooltip>
|
|
);
|
|
}
|
|
return returnNode;
|
|
};
|
|
|
|
export default MenuItem;
|