"use client"; import clsx from "clsx"; import { PointerEventHandler, forwardRef, useId, useRef } from "react"; import { IconSizeContext } from "../../contexts/IconSizeContext"; import classes from "./Menu.module.css"; import { useMenu } from "./menu-context"; interface MenuItemInnerProps { children?: any; Component?: any; href?: string; "aria-disabled": boolean | "true" | "false"; "aria-labelledby"?: string; onPointerUp: () => void; onPointerMove: PointerEventHandler; "data-selected"?: ""; className: string; } export const MenuItemInner: React.ForwardRefExoticComponent< MenuItemInnerProps & React.RefAttributes > = forwardRef( ( { children, className, onPointerMove, onPointerUp, href, Component, ...props }, ref, ) => { const { setOpen } = useMenu(); if (Component) { return (
  • setTimeout(() => setOpen(false), 0)} onMouseUp={() => setTimeout(() => setOpen(false), 0)} > {children}
  • ); } return (
  • {children}
  • ); }, ); MenuItemInner.displayName = "MenuItemInner"; export interface MenuItemProps { disabled?: boolean; onClick?: () => void; value?: any; // fixme isLink?: boolean; type?: "error"; error?: boolean; prefix?: JSX.Element; suffix?: JSX.Element; } export const MenuItem: React.ComponentType< React.PropsWithChildren > = ({ children, onClick, type, error, disabled, prefix, suffix }) => { const { setOpen, selected, setSelected, listElement } = useMenu(); const itemRef = useRef(); // https://stackoverflow.com/a/23528539/9823455 const idx = Array.from(listElement?.childNodes.values() ?? []).indexOf( itemRef.current, ); const id = useId(); return ( { if (disabled) return; onClick?.(); setOpen(false); }} onPointerMove={() => { if (disabled) return; setSelected(idx); }} > {prefix && ( {prefix} )} {children} {suffix && ( {suffix} )} ); }; export const MenuLink = ({ href, children, disabled, type, error, onClick, }) => { const { setOpen, selected, setSelected, listElement } = useMenu(); const itemRef = useRef(); // https://stackoverflow.com/a/23528539/9823455 const idx = Array.from(listElement?.childNodes.values() ?? []).indexOf( itemRef.current, ); const id = useId(); return ( { return ; }} ref={itemRef} aria-disabled={disabled ? "true" : undefined} aria-labelledby={`menu-item-${id}`} data-selected={selected === idx ? "" : undefined} className={clsx(classes.item, classes[type], { [classes.error]: error, [classes.disabled]: disabled, })} onPointerUp={() => { if (disabled) return; onClick?.(); setOpen(false); }} onPointerMove={() => { if (disabled) return; setSelected(idx); }} > {children} ); };