import { forwardRef, memo, type AnchorHTMLAttributes, type ButtonHTMLAttributes, type ForwardedRef, type HTMLAttributes, type ElementType, type MouseEvent, } from 'react' import { splitClassNameProp, getMenuButtonStyles, getMenuListStyles, getMenuListItemStyles, getMenuDescriptionStyles, getMenuListContainerStyles, getMenuListItemContentStyles, getMenuListItemLinkStyles, getMenuDividerStyles, } from '@pluralsight/headless-styles' import { useAriaMenuItem, useAriaMenuItemContainer, useAriaMenuList, } from '@pluralsight/react-aria' import { CheckIcon } from '@pluralsight/icons' import { Icon, Show, useMenu, useMenuListInteraction } from '../../index.ts' // export interface MenuList extends HTMLAttributes { value?: string } function MenuListEl(props: MenuList) { const { expanded, triggerId, menuId, floating } = useMenu() const ariaProps = useAriaMenuList({ id: menuId, triggerId, value: props.value, }) const pandoStyles = getMenuListStyles({ classNames: splitClassNameProp(props.className), }) return (
) } // export interface MenuItemProps extends AnchorHTMLAttributes { as?: AnchorHTMLAttributes | ElementType icon?: ElementType } function MenuItemEl( props: MenuItemProps, ref: ForwardedRef, ) { const pandoListStyles = getMenuListItemStyles({ classNames: splitClassNameProp(props.className), }) const pandoListAriaProps = useAriaMenuItem() const pandoListContainerAriaProps = useAriaMenuItemContainer() const Container = (props.as || 'a') as ElementType const IconEl = props.icon as ElementType const { onKeyDown } = useMenuListInteraction() const pandoLinkStyles = getMenuListItemLinkStyles({ classNames: splitClassNameProp(props.className), }) return (
  • {props.children}
  • ) } // export interface MenuOptionProps extends ButtonHTMLAttributes { selected: boolean description?: string } function MenuOptionEl( props: MenuOptionProps, ref: ForwardedRef, ) { const { description, selected, ...nativeProps } = props const { setExpanded } = useMenu() const pandoListStyles = getMenuListItemStyles({ classNames: splitClassNameProp(nativeProps.className), }) const pandoListAriaProps = useAriaMenuItem() const pandoListContainerAriaProps = useAriaMenuItemContainer(selected) const { onKeyDown } = useMenuListInteraction() function handleClick(e: MouseEvent) { e.preventDefault() // ensure the target is always the button e.target = e.currentTarget if (props.onClick) props.onClick(e) setExpanded(false) } return (
  • ) } // export type MenuDividerProps = HTMLAttributes function MenuDividerEl( props: MenuDividerProps, ref: ForwardedRef, ) { const pandoStyles = getMenuDividerStyles({ classNames: splitClassNameProp(props.className), }) return
    } // exports /** * A horizontal line that separates menu items. * @param props anything you can pass to an HTMLHRElement * @see https://design.pluralsight.com/docs/reference/components/menu */ export const MenuDivider = forwardRef( MenuDividerEl, ) /** * Container for a list of menu items. * @param props anything you can pass to an HTMLUListElement * @see https://design.pluralsight.com/docs/reference/components/menu */ export const MenuList = memo(MenuListEl) /** * The clickable item in a menu that is used for navigation. * @param props anything you can pass to an HTMLAnchorElement * @param as an alternative link element type to render (defaults to 'a') * @param icon an icon to display to the left of the content * @see https://design.pluralsight.com/docs/reference/components/menu */ export const MenuItem = forwardRef(MenuItemEl) /** * The clickable item in a menu that is used for selection. * @param props anything you can pass to an HTMLOptionElement * @param description an optional description to display below the content * @see https://design.pluralsight.com/docs/reference/components/menu */ export const MenuOption = forwardRef( MenuOptionEl, )