import React, { FunctionComponentElement, useContext, useState } from 'react'; import classNames from 'classnames'; import { MenuContext } from '@/components/menu/menu'; import { MenuItemProps } from '@/components/menu/menuItem'; import Icon from '@/components/icon/icon'; import Transition from '@/components/transition/transition'; export interface SubMenuProps { index?: string; title: string; className?: string; } const SubMenu: React.FunctionComponent = props => { const { index, title, children, className } = props; const context = useContext(MenuContext); const openedSubMenus = context.defaultOpenSubMenus as Array; const isOpened = index && context.mode === 'vertical' ? openedSubMenus.includes(index) : false; const [menuOpen, setOpen] = useState(isOpened); const handleClick = (e: React.MouseEvent) => { e.preventDefault(); setOpen(!menuOpen); }; let timer: any; const handleMouse = (e: React.MouseEvent, toggle: boolean) => { clearTimeout(timer); e.preventDefault(); timer = setTimeout(() => { setOpen(toggle); }, 300); }; const clickEvents = context.mode === 'vertical' ? { onClick: handleClick } : {}; const hoverEvents = context.mode !== 'vertical' ? { onMouseEnter: (e: React.MouseEvent) => handleMouse(e, true), onMouseLeave: (e: React.MouseEvent) => handleMouse(e, false), } : {}; const classes = classNames('gulu-menu-item gulu-submenu-item', className, { active: context.index === index, 'is-opened': menuOpen, 'is-vertical': context.mode === 'vertical', }); const renderChildren = () => { const subMenuClasses = classNames('gulu-submenu', { 'menu-opened': menuOpen, }); const childrenComponent = React.Children.map(children, (child, i) => { const childElement = child as FunctionComponentElement; if (childElement.type.displayName === 'MenuItem') { return React.cloneElement(childElement, { index: `${index}-${i}`, }); } else { console.warn('SubMenu 的子元素至少有一个不是 MenuItem'); } }); return (
    {childrenComponent}
); }; return (
  • {title}
    {renderChildren()}
  • ); }; SubMenu.displayName = 'SubMenu'; export default SubMenu;