import * as Ariakit from '@ariakit/react' import clsx, { ClassValue } from 'clsx' import React from 'react' import { Button as OriginalButton, ButtonProps as ButtonProps, } from '../Button/Button' import { ButtonIcon, Props as ButtonIconProps } from '../ButtonIcon/ButtonIcon' import * as styles from './styles.css' const MenuContext = React.createContext( {} as Ariakit.MenuStore, ) export const useMenu = () => React.useContext(MenuContext) type Props = React.PropsWithChildren> type MenuComponent = React.FC & { Button: typeof Button List: typeof List Item: typeof Item Divider: typeof Divider Heading: typeof Heading } export const Menu: MenuComponent = ({ children, ...props }: Props) => { const menu = Ariakit.useMenuStore(props) return {children} } export type MenuButtonProps = React.PropsWithChildren<{ cssClass?: ClassValue | ClassValue[] }> & Omit & Pick & { emphasis?: ButtonProps['emphasis'] icon?: ButtonIconProps['icon'] kind?: ButtonProps['kind'] size?: ButtonProps['size'] | ButtonIconProps['size'] } const Button: React.FC> = ({ children, ...props }) => { const menu = useMenu() const Component = props.icon && !children ? ButtonIcon : OriginalButton return ( {children} ) } type ListProps = React.PropsWithChildren<{ cssClass?: ClassValue | ClassValue[] }> & Partial const List: React.FC = ({ children, cssClass, ...props }) => { const menu = useMenu() return ( {/* There is a bug in v0.2.17 of Ariakit where you need to have this arrow rendered or else positioning of the popover breaks. We render it, but hide it by setting size={0}. This is an issue with anything using a popover coming from the floating-ui library. */} {children} ) } const Item: React.FC = ({ children, ...props }) => ( {children} ) const Divider: React.FC = ({ children, ...props }) => ( {children} ) const Heading: React.FC = ({ children, className, ...props }) => ( <> {children} ) Menu.Button = Button Menu.List = List Menu.Item = Item Menu.Divider = Divider Menu.Heading = Heading