diff --git a/src/components/dropdown-menu/DropdownMenu.tsx b/src/components/dropdown-menu/DropdownMenu.tsx index cd879c1..a9e465b 100644 --- a/src/components/dropdown-menu/DropdownMenu.tsx +++ b/src/components/dropdown-menu/DropdownMenu.tsx @@ -7,7 +7,16 @@ import { SubmenuTrigger, } from "react-aria-components"; import { DropdownMenuItem, DropdownMenuOption } from "./types"; -import { Fragment, PropsWithChildren, ReactNode, useId, useRef } from "react"; +import { + cloneElement, + Fragment, + isValidElement, + PropsWithChildren, + ReactElement, + ReactNode, + useId, + useRef, +} from "react"; import { MenuItemSeparator } from "../menu/types"; import clsx from "clsx"; @@ -59,6 +68,7 @@ export const DropdownMenu = ({ }: PropsWithChildren) => { const id = useId(); const triggerRef = useRef(null); + const menuId = `${id}-menu`; const menuClassName = `c__dropdown-menu${ variant === "tiny" ? " c__dropdown-menu--tiny" : "" }`; @@ -66,6 +76,21 @@ export const DropdownMenu = ({ onOpenChange?.(isOpen); }; + const renderTrigger = (children: ReactNode) => { + if (!isValidElement(children)) { + return children; + } + + const triggerElement = children as ReactElement>; + + return cloneElement(triggerElement, { + ...triggerElement.props, + "aria-controls": isOpen ? menuId : undefined, + "aria-expanded": isOpen, + "aria-haspopup": "menu", + }); + }; + const renderMenuItems = (items: DropdownMenuItem[]) => items.map((option, index) => { if (isSeparator(option)) { @@ -145,7 +170,7 @@ export const DropdownMenu = ({ e.preventDefault(); }} > - {children} + {renderTrigger(children)} - + {topMessage && (