2023-05-06 15:49:37 +08:00
|
|
|
import * as React from 'react';
|
|
|
|
import { forwardRef, useImperativeHandle, useRef } from 'react';
|
2023-12-29 16:49:57 +08:00
|
|
|
import type { MenuRef as RcMenuRef } from 'rc-menu';
|
|
|
|
import { ItemGroup } from 'rc-menu';
|
|
|
|
|
2022-05-07 14:31:54 +08:00
|
|
|
import { SiderContext } from '../layout/Sider';
|
2024-05-18 15:07:26 +08:00
|
|
|
import type { ItemType, MenuItemType } from './interface';
|
2023-12-29 16:49:57 +08:00
|
|
|
import type { MenuProps } from './menu';
|
|
|
|
import InternalMenu from './menu';
|
2022-11-09 12:28:04 +08:00
|
|
|
import type { MenuTheme } from './MenuContext';
|
2022-06-21 15:48:29 +08:00
|
|
|
import MenuDivider from './MenuDivider';
|
2024-04-08 14:04:08 +08:00
|
|
|
import Item from './MenuItem';
|
|
|
|
import type { MenuItemProps } from './MenuItem';
|
|
|
|
import SubMenu from './SubMenu';
|
|
|
|
import type { SubMenuProps } from './SubMenu';
|
2015-08-06 16:49:54 +08:00
|
|
|
|
2022-11-09 12:28:04 +08:00
|
|
|
export type { MenuItemGroupProps } from 'rc-menu';
|
|
|
|
export type { MenuDividerProps } from './MenuDivider';
|
2023-07-15 12:57:03 +08:00
|
|
|
export type { MenuItemProps, MenuProps, MenuTheme, SubMenuProps };
|
2016-08-15 12:00:05 +08:00
|
|
|
|
2022-07-28 20:33:10 +08:00
|
|
|
export type MenuRef = {
|
|
|
|
menu: RcMenuRef | null;
|
|
|
|
focus: (options?: FocusOptions) => void;
|
|
|
|
};
|
|
|
|
|
2023-05-10 10:20:17 +08:00
|
|
|
type ComponentProps = MenuProps & React.RefAttributes<MenuRef>;
|
|
|
|
|
|
|
|
type GenericItemType<T = unknown> = T extends infer U extends MenuItemType
|
|
|
|
? unknown extends U
|
|
|
|
? ItemType
|
|
|
|
: ItemType<U>
|
|
|
|
: ItemType;
|
|
|
|
|
|
|
|
type GenericComponentProps<T = unknown> = Omit<ComponentProps, 'items'> & {
|
|
|
|
items?: GenericItemType<T>[];
|
|
|
|
};
|
|
|
|
|
|
|
|
type CompoundedComponent = React.ForwardRefExoticComponent<GenericComponentProps> & {
|
2022-07-28 20:33:10 +08:00
|
|
|
Item: typeof Item;
|
|
|
|
SubMenu: typeof SubMenu;
|
2022-11-21 09:52:33 +08:00
|
|
|
Divider: typeof MenuDivider;
|
2022-07-28 20:33:10 +08:00
|
|
|
ItemGroup: typeof ItemGroup;
|
2022-11-19 16:56:23 +08:00
|
|
|
};
|
2016-08-15 12:00:05 +08:00
|
|
|
|
2023-05-10 10:20:17 +08:00
|
|
|
interface GenericComponent extends Omit<CompoundedComponent, ''> {
|
|
|
|
<T extends MenuItemType>(props: GenericComponentProps<T>): ReturnType<CompoundedComponent>;
|
|
|
|
}
|
|
|
|
|
2022-09-19 22:17:26 +08:00
|
|
|
const Menu = forwardRef<MenuRef, MenuProps>((props, ref) => {
|
2022-07-28 20:33:10 +08:00
|
|
|
const menuRef = useRef<RcMenuRef>(null);
|
2022-09-19 22:17:26 +08:00
|
|
|
const context = React.useContext(SiderContext);
|
2022-07-28 20:33:10 +08:00
|
|
|
|
|
|
|
useImperativeHandle(ref, () => ({
|
2022-11-21 09:52:33 +08:00
|
|
|
menu: menuRef.current,
|
|
|
|
focus: (options) => {
|
2022-07-28 20:33:10 +08:00
|
|
|
menuRef.current?.focus(options);
|
|
|
|
},
|
|
|
|
}));
|
2022-09-19 22:17:26 +08:00
|
|
|
return <InternalMenu ref={menuRef} {...props} {...context} />;
|
2023-05-10 10:20:17 +08:00
|
|
|
}) as GenericComponent;
|
2019-08-05 18:38:10 +08:00
|
|
|
|
2022-07-28 20:33:10 +08:00
|
|
|
Menu.Item = Item;
|
|
|
|
Menu.SubMenu = SubMenu;
|
2022-11-21 09:52:33 +08:00
|
|
|
Menu.Divider = MenuDivider;
|
2022-07-28 20:33:10 +08:00
|
|
|
Menu.ItemGroup = ItemGroup;
|
2021-01-24 23:24:06 +08:00
|
|
|
|
2023-01-08 21:30:41 +08:00
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
|
|
Menu.displayName = 'Menu';
|
|
|
|
}
|
|
|
|
|
2021-01-24 23:24:06 +08:00
|
|
|
export default Menu;
|