import { css, cx } from '@emotion/css' import { ForwardedRef, forwardRef, useRef, useState } from 'react' import Icon from '../Icon' export interface ContextMenuItem { type: 'item' | 'submenu' | 'divider' label?: string onClick?: (e: MouseEvent) => void items?: ContextMenuItem[] } const MenuItem = ({ item, index, onClose, onSubmenuOpen, onSubmenuClose, className, }: { item: ContextMenuItem index: number onClose: (e: MouseEvent) => void onSubmenuOpen: (props: { itemRect: DOMRect; index: number }) => void onSubmenuClose: () => void className?: string }) => { const itemRef = useRef(null) const [isHover, setIsHover] = useState(false) if (item.type === 'divider') { return (
) } return (
{ if (!item.onClick) { return } const event = e as unknown as MouseEvent item.onClick?.(event) onClose(event) }} onMouseOver={() => { if (item.type !== 'submenu') return setIsHover(true) onSubmenuOpen({ itemRect: itemRef.current!.getBoundingClientRect(), index, }) }} onMouseLeave={e => { const relatedTarget = e.relatedTarget as HTMLElement | null if (relatedTarget?.classList?.contains('submenu')) { return } setIsHover(false) onSubmenuClose() }} className={cx( 'relative', className, css` padding-right: 9px; padding-left: 9px; ` )} >
{item.label}
{item.type === 'submenu' && ( <> {/* 将item变宽一点,避免移动鼠标时还没移动到submenu就关闭submenu了 */}
)}
) } export default MenuItem