Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ module.exports = {
'@typescript-eslint/no-explicit-any': 0,
'jsx-a11y/label-has-associated-control': 0,
'jsx-a11y/label-has-for': 0,
'@typescript-eslint/no-empty-interface': "off",
},
};
3 changes: 3 additions & 0 deletions docs/demo/options.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## options

<code src="../examples/options.tsx">
68 changes: 68 additions & 0 deletions docs/examples/options.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/* eslint no-console:0 */

import React from 'react';
import Menu from '../../src';
import '../../assets/index.less';

export default () => (
<Menu
options={[
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

items?

{
// MenuItem
title: 'Top Menu Item',
key: 'top',
},
{
// MenuGroup
type: 'group',
title: 'Top Menu Group without children',
},
{
// MenuGroup
type: 'group',
title: 'Top Menu Group with children',
children: [
{
// MenuItem
title: 'Menu Item 1',
key: 'inner1',
},
{
// Divider
type: 'divider',
},
{
// MenuItem
title: 'Menu Item 2',
key: 'inner2',
},
],
},
{
// SubMenu
title: 'SubMenu',
key: 'sub1',
children: [
{
// MenuItem
title: 'Menu Item 1-1',
key: 'inner11',
},

{
// SubMenu
title: 'SubMenu inner',
key: 'sub1-1',
children: [
{
// MenuItem
title: 'Menu Item 111',
key: 'inner1-1-1',
},
],
},
],
},
]}
/>
);
6 changes: 2 additions & 4 deletions src/Divider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ import * as React from 'react';
import classNames from 'classnames';
import { MenuContext } from './context/MenuContext';
import { useMeasure } from './context/PathContext';
import type { MenuDividerType } from './interface';

export interface DividerProps {
className?: string;
style?: React.CSSProperties;
}
export type DividerProps = Omit<MenuDividerType, 'type'>;

export default function Divider({ className, style }: DividerProps) {
const { prefixCls } = React.useContext(MenuContext);
Expand Down
12 changes: 10 additions & 2 deletions src/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import type {
TriggerSubMenuAction,
SelectInfo,
RenderIconType,
ItemType,
} from './interface';
import MenuItem from './MenuItem';
import { parseChildren } from './utils/nodeUtil';
import { parseItems } from './utils/nodeUtil';
import MenuContextProvider from './context/MenuContext';
import useMemoCallback from './hooks/useMemoCallback';
import { warnItemProp } from './utils/warnUtil';
Expand Down Expand Up @@ -52,6 +53,8 @@ export interface MenuProps
> {
prefixCls?: string;

items?: ItemType[];
/** @deprecated Please use `items` instead */
children?: React.ReactNode;

disabled?: boolean;
Expand Down Expand Up @@ -152,6 +155,7 @@ const Menu = React.forwardRef<HTMLUListElement, MenuProps>((props, ref) => {
style,
className,
tabIndex = 0,
items,
children,
direction,

Expand Down Expand Up @@ -220,7 +224,11 @@ const Menu = React.forwardRef<HTMLUListElement, MenuProps>((props, ref) => {
...restProps
} = props as LegacyMenuProps;

const childList: React.ReactElement[] = parseChildren(children, EMPTY_LIST);
const childList: React.ReactElement[] = parseItems(
children,
items,
EMPTY_LIST,
);
const [mounted, setMounted] = React.useState(false);

const containerRef = React.useRef<HTMLUListElement>();
Expand Down
26 changes: 6 additions & 20 deletions src/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,7 @@ import Overflow from 'rc-overflow';
import warning from 'rc-util/lib/warning';
import KeyCode from 'rc-util/lib/KeyCode';
import omit from 'rc-util/lib/omit';
import type {
MenuClickEventHandler,
MenuInfo,
MenuHoverEventHandler,
RenderIconType,
} from './interface';
import type { MenuInfo, MenuItemType } from './interface';
import { MenuContext } from './context/MenuContext';
import useActive from './hooks/useActive';
import { warnItemProp } from './utils/warnUtil';
Expand All @@ -20,10 +15,11 @@ import { useMenuId } from './context/IdContext';
import PrivateContext from './context/PrivateContext';

export interface MenuItemProps
extends Omit<
React.HTMLAttributes<HTMLLIElement>,
'onClick' | 'onMouseEnter' | 'onMouseLeave' | 'onSelect'
> {
extends Omit<MenuItemType, 'title' | 'key'>,
Omit<
React.HTMLAttributes<HTMLLIElement>,
'onClick' | 'onMouseEnter' | 'onMouseLeave' | 'onSelect'
> {
children?: React.ReactNode;

/** @private Internal filled key. Do not set it directly */
Expand All @@ -32,18 +28,8 @@ export interface MenuItemProps
/** @private Do not use. Private warning empty usage */
warnKey?: boolean;

disabled?: boolean;

itemIcon?: RenderIconType;

/** @deprecated No place to use this. Should remove */
attribute?: Record<string, string>;
// >>>>> Active
onMouseEnter?: MenuHoverEventHandler;
onMouseLeave?: MenuHoverEventHandler;

// >>>>> Events
onClick?: MenuClickEventHandler;
}

// Since Menu event provide the `info.item` which point to the MenuItem node instance.
Expand Down
6 changes: 3 additions & 3 deletions src/MenuItemGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import omit from 'rc-util/lib/omit';
import { parseChildren } from './utils/nodeUtil';
import { MenuContext } from './context/MenuContext';
import { useFullPath, useMeasure } from './context/PathContext';
import type { MenuItemGroupType } from './interface';

export interface MenuItemGroupProps {
className?: string;
title?: React.ReactNode;
export interface MenuItemGroupProps
extends Omit<MenuItemGroupType, 'type' | 'children'> {
children?: React.ReactNode;

/** @private Internal filled key. Do not set it directly */
Expand Down
33 changes: 2 additions & 31 deletions src/SubMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,7 @@ import Overflow from 'rc-overflow';
import warning from 'rc-util/lib/warning';
import SubMenuList from './SubMenuList';
import { parseChildren } from '../utils/nodeUtil';
import type {
MenuClickEventHandler,
MenuHoverEventHandler,
MenuInfo,
MenuTitleInfo,
RenderIconType,
} from '../interface';
import type { MenuInfo, SubMenuType } from '../interface';
import MenuContextProvider, { MenuContext } from '../context/MenuContext';
import useMemoCallback from '../hooks/useMemoCallback';
import PopupTrigger from './PopupTrigger';
Expand All @@ -28,14 +22,9 @@ import {
import { useMenuId } from '../context/IdContext';
import PrivateContext from '../context/PrivateContext';

export interface SubMenuProps {
style?: React.CSSProperties;
className?: string;

title?: React.ReactNode;
export interface SubMenuProps extends Omit<SubMenuType, 'key' | 'children'> {
children?: React.ReactNode;

disabled?: boolean;
/** @private Used for rest popup. Do not use in your prod */
internalPopupClose?: boolean;

Expand All @@ -45,24 +34,6 @@ export interface SubMenuProps {
/** @private Do not use. Private warning empty usage */
warnKey?: boolean;

// >>>>> Icon
itemIcon?: RenderIconType;
expandIcon?: RenderIconType;

// >>>>> Active
onMouseEnter?: MenuHoverEventHandler;
onMouseLeave?: MenuHoverEventHandler;

// >>>>> Popup
popupClassName?: string;
popupOffset?: number[];

// >>>>> Events
onClick?: MenuClickEventHandler;
onTitleClick?: (info: MenuTitleInfo) => void;
onTitleMouseEnter?: MenuHoverEventHandler;
onTitleMouseLeave?: MenuHoverEventHandler;

// >>>>>>>>>>>>>>>>>>>>> Next Round <<<<<<<<<<<<<<<<<<<<<<<
// onDestroy?: DestroyEventHandler;
}
Expand Down
69 changes: 69 additions & 0 deletions src/interface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,74 @@
import type * as React from 'react';

// ========================= Options =========================
interface ItemSharedProps {
style?: React.CSSProperties;
className?: string;
}

export interface SubMenuType extends ItemSharedProps {
title?: React.ReactNode;

children: ItemType[];

disabled?: boolean;

key: string;

// >>>>> Icon
itemIcon?: RenderIconType;
expandIcon?: RenderIconType;

// >>>>> Active
onMouseEnter?: MenuHoverEventHandler;
onMouseLeave?: MenuHoverEventHandler;

// >>>>> Popup
popupClassName?: string;
popupOffset?: number[];

// >>>>> Events
onClick?: MenuClickEventHandler;
onTitleClick?: (info: MenuTitleInfo) => void;
onTitleMouseEnter?: MenuHoverEventHandler;
onTitleMouseLeave?: MenuHoverEventHandler;
}

export interface MenuItemType extends ItemSharedProps {
title?: React.ReactNode;

disabled?: boolean;

itemIcon?: RenderIconType;

key: string;

// >>>>> Active
onMouseEnter?: MenuHoverEventHandler;
onMouseLeave?: MenuHoverEventHandler;

// >>>>> Events
onClick?: MenuClickEventHandler;
}

export interface MenuItemGroupType extends ItemSharedProps {
type: 'group';

title?: React.ReactNode;

children?: ItemType[];
}

export interface MenuDividerType extends ItemSharedProps {
type: 'divider';
}

export type ItemType =
| SubMenuType
| MenuItemType
| MenuItemGroupType
| MenuDividerType;

// ========================== Basic ==========================
export type MenuMode = 'horizontal' | 'vertical' | 'inline';

Expand Down
30 changes: 0 additions & 30 deletions src/utils/nodeUtil.ts

This file was deleted.

Loading