import React, { useRef, useState } from "react"; import { AriaMenuOptions, useMenu, useMenuItem } from "@react-aria/menu"; import { TreeState, useTreeState } from "@react-stately/tree"; import { mergeProps } from "@react-aria/utils"; import { useFocus } from "@react-aria/interactions"; import classNames from "classnames"; import { Node } from "@react-types/shared"; import styles from "./Menu.module.css"; interface MenuProps extends AriaMenuOptions { className: String; onAction: () => void; onClose: () => void; } export function Menu({ className, onAction, onClose, ...rest }: MenuProps) { const state = useTreeState({ ...rest, selectionMode: "none" }); const menuRef = useRef(); const { menuProps } = useMenu(rest, state, menuRef); return (
    {[...state.collection].map((item) => ( ))}
); } interface MenuItemProps { item: Node; state: TreeState; onAction: () => void; onClose: () => void; } function MenuItem({ item, state, onAction, onClose }: MenuItemProps) { const ref = useRef(); const { menuItemProps } = useMenuItem( { key: item.key, onAction, onClose, }, state, ref ); const [isFocused, setFocused] = useState(false); const { focusProps } = useFocus({ onFocusChange: setFocused }); return (
  • {item.rendered}
  • ); }