import * as React from 'react' ; import { composeEventHandlers } from '@radix-ui/primitive' ; import { composeRefs } from '@radix-ui/react-compose-refs' ; import { createContextScope } from '@radix-ui/react-context' ; import { useControllableState } from '@radix-ui/react-use-controllable-state' ; import { Primitive } from '@radix-ui/react-primitive' ; import * as MenuPrimitive from '@radix-ui/react-menu' ; import { createMenuScope } from '@radix-ui/react-menu' ; import { useId } from '@radix-ui/react-id' ; import type * as Radix from '@radix-ui/react-primitive' ; import type { Scope } from '@radix-ui/react-context' ; type Direction = 'ltr' | 'rtl' ; const DROPDOWN_MENU_NAME = 'DropdownMenu' ; type ScopedProps < P > = P & { __scopeDropdownMenu ? : Scope ; } ; const [ createDropdownMenuContext , createDropdownMenuScope ] = createContextScope ( DROPDOWN_MENU_NAME , [ createMenuScope ] ) ; const useMenuScope = createMenuScope ( ) ; type DropdownMenuRootContextValue = { isRootMenu : true ; triggerId : string ; triggerRef : React . RefObject < HTMLButtonElement > ; contentId : string ; open : boolean ; onOpenChange ( open ) : void ; onOpenToggle ( ) : void ; modal : boolean ; } ; type DropdownMenuSubContextValue = { isRootMenu : false ; open : boolean ; onOpenChange ( open ) : void ; onOpenToggle ( ) : void ; } ; const [ DropdownMenuProvider , useDropdownMenuContext ] = createDropdownMenuContext < DropdownMenuRootContextValue | DropdownMenuSubContextValue > ( DROPDOWN_MENU_NAME ) ; interface DropdownMenuProps { dir ? : Direction ; open ? : boolean ; defaultOpen ? : boolean ; onOpenChange ? ( open ) : void ; modal ? : boolean ; children ? : React . ReactNode ; } const DropdownMenu = ( props ) => { const { __scopeDropdownMenu , children , open : openProp , defaultOpen , onOpenChange } = props ; const contentContext = useContentContext ( DROPDOWN_MENU_NAME , __scopeDropdownMenu ) ; const menuScope = useMenuScope ( __scopeDropdownMenu ) ; const [ open = false , setOpen ] = useControllableState ( { prop : openProp , defaultProp : defaultOpen , onChange : onOpenChange , } ) ; const handleOpenToggle = React . useCallback ( ( ) => setOpen ( ( prevOpen ) => ! prevOpen ) , [ setOpen ] ) ; return contentContext . isInsideContent ? ( < DropdownMenuProvider scope = { __scopeDropdownMenu } isRootMenu = { false } open = { open } onOpenChange = { setOpen } onOpenToggle = { handleOpenToggle } > < MenuPrimitive . Sub { ... menuScope } open = { open } onOpenChange = { setOpen } > { children } < /MenuPrimitive.Sub> < /DropdownMenuProvider>) : (<DropdownMenuRoot {...props} open={open} onOpenChange={setOpen} onOpenToggle={handleOpenToggle}> { children } < /DropdownMenuRoot>); } ; DropdownMenu . displayName = DROPDOWN_MENU_NAME ; interface DropdownMenuRootProps { dir ? : Direction ; open : boolean ; onOpenChange ( open ) : void ; onOpenToggle ( ) : void ; modal ? : boolean ; children ? : React . ReactNode ; } const DropdownMenuRoot = ( props ) => { const { __scopeDropdownMenu , children , dir , open , onOpenChange , onOpenToggle , modal = true , } = props ; const menuScope = useMenuScope ( __scopeDropdownMenu ) ; const triggerRef = React . useRef < HTMLButtonElement > ( null ) ; return ( < DropdownMenuProvider scope = { __scopeDropdownMenu } isRootMenu = { true } triggerId = { useId ( ) } triggerRef = { triggerRef } contentId = { useId ( ) } open = { open } onOpenChange = { onOpenChange } onOpenToggle = { onOpenToggle } modal = { modal } > < MenuPrimitive . Root { ... menuScope } open = { open } onOpenChange = { onOpenChange } dir = { dir } modal = { modal } > { children } < /MenuPrimitive.Root> < /DropdownMenuProvider>); } ; const TRIGGER_NAME = 'DropdownMenuTrigger' ; type DropdownMenuTriggerElement = React . ElementRef < typeof Primitive . button > ; type PrimitiveButtonProps = Radix . ComponentPropsWithoutRef < typeof Primitive . button > ; interface DropdownMenuTriggerProps extends PrimitiveButtonProps { } const DropdownMenuTrigger = React . forwardRef < DropdownMenuTriggerElement , DropdownMenuTriggerProps > ( ( props , forwardedRef ) => { const { __scopeDropdownMenu , disabled = false , ... triggerProps } = props ; const context = useDropdownMenuContext ( TRIGGER_NAME , __scopeDropdownMenu ) ; const menuScope = useMenuScope ( __scopeDropdownMenu ) ; return context . isRootMenu ? ( < MenuPrimitive . Anchor asChild { ... menuScope } > < Primitive . button type = "button" id = { context . triggerId } aria - haspopup = "menu" aria - expanded = { context . open ? true : undefined } aria - controls = { context . open ? context . contentId : undefined } data - state = { context . open ? 'open' : 'closed' } data - disabled = { disabled ? '' : undefined } disabled = { disabled } { ... triggerProps } ref = { composeRefs ( forwardedRef , context . triggerRef ) } onClick = { composeEventHandlers ( props . onClick , ( ) => context . onOpenChange ( true ) ) } onPointerDown = { composeEventHandlers ( props . onPointerDown , ( event ) => { if ( ! disabled && event . button === 0 && event . ctrlKey === false ) { if ( ! context . open ) event . preventDefault ( ) ; context . onOpenToggle ( ) ; } } ) } onKeyDown = { composeEventHandlers ( props . onKeyDown , ( event ) => { if ( ! disabled && event . key === 'ArrowDown' ) { event . preventDefault ( ) ; context . onOpenChange ( true ) ; } } ) } /> < /MenuPrimitive.Anchor>) : null; } ) ; DropdownMenuTrigger . displayName = TRIGGER_NAME ; const CONTENT_NAME = 'DropdownMenuContent' ; const [ ContentProvider , useContentContext ] = createDropdownMenuContext ( CONTENT_NAME , { isInsideContent : false , } ) ; type DropdownMenuContentElement = DropdownMenuRootContentElement | React . ElementRef < typeof MenuPrimitive . Content > ; type MenuContentProps = Radix . ComponentPropsWithoutRef < typeof MenuPrimitive . Content > ; interface DropdownMenuContentProps extends DropdownMenuRootContentProps , MenuContentProps { } const DropdownMenuContent = React . forwardRef < DropdownMenuContentElement , DropdownMenuContentProps > ( ( props , forwardedRef ) => { const { __scopeDropdownMenu , ... contentProps } = props ; const context = useDropdownMenuContext ( CONTENT_NAME , __scopeDropdownMenu ) ; const menuScope = useMenuScope ( __scopeDropdownMenu ) ; const commonProps = { ... contentProps , style : { ... props . style , [ '--radix-dropdown-menu-content-transform-origin' as any ] : 'var(--radix-popper-transform-origin)' , } , } ; return ( < ContentProvider scope = { __scopeDropdownMenu } isInsideContent = { true } > { context . isRootMenu ? ( < DropdownMenuRootContent __scopeDropdownMenu = { __scopeDropdownMenu } { ... commonProps } ref = { forwardedRef } / > ) : ( < MenuPrimitive . Content { ... menuScope } { ... commonProps } ref = { forwardedRef } / > ) } < /ContentProvider>); } ) ; DropdownMenuContent . displayName = CONTENT_NAME ; type DropdownMenuRootContentElement = React . ElementRef < typeof MenuPrimitive . Content > ; interface DropdownMenuRootContentProps extends ScopedProps < MenuContentProps > { } const DropdownMenuRootContent = React . forwardRef < DropdownMenuRootContentElement , DropdownMenuRootContentProps > ( ( props , forwardedRef ) => { const { __scopeDropdownMenu , portalled = true , ... contentProps } = props ; const context = useDropdownMenuContext ( CONTENT_NAME , __scopeDropdownMenu ) ; const menuScope = useMenuScope ( __scopeDropdownMenu ) ; const hasInteractedOutsideRef = React . useRef ( false ) ; return context . isRootMenu ? ( < MenuPrimitive . Content id = { context . contentId } aria - labelledby = { context . triggerId } { ... menuScope } { ... contentProps } ref = { forwardedRef } portalled = { portalled } onCloseAutoFocus = { ( event ) => { props . onCloseAutoFocus ?. ( event ) ; if ( ! event . defaultPrevented ) { if ( ! hasInteractedOutsideRef . current ) context . triggerRef . current ?. focus ( ) ; event . preventDefault ( ) ; } hasInteractedOutsideRef . current = false ; } } onInteractOutside = { ( event ) => { props . onInteractOutside ?. ( event ) ; if ( ! event . defaultPrevented ) { const originalEvent = event . detail . originalEvent as PointerEvent ; const ctrlLeftClick = originalEvent . button === 0 && originalEvent . ctrlKey === true ; const isRightClick = originalEvent . button === 2 || ctrlLeftClick ; if ( ! context . modal || isRightClick ) hasInteractedOutsideRef . current = true ; } const target = event . target as HTMLElement ; const targetIsTrigger = context . triggerRef . current ?. contains ( target ) ; if ( targetIsTrigger ) event . preventDefault ( ) ; } } />) : null; } ) ; const GROUP_NAME = 'DropdownMenuGroup' ; type DropdownMenuGroupElement = React . ElementRef < typeof MenuPrimitive . Group > ; type MenuGroupProps = Radix . ComponentPropsWithoutRef < typeof MenuPrimitive . Group > ; interface DropdownMenuGroupProps extends MenuGroupProps { } const DropdownMenuGroup = React . forwardRef < DropdownMenuGroupElement , DropdownMenuGroupProps > ( ( props , forwardedRef ) => { const { __scopeDropdownMenu , ... groupProps } = props ; const menuScope = useMenuScope ( __scopeDropdownMenu ) ; return < MenuPrimitive . Group { ... menuScope } { ... groupProps } ref = { forwardedRef } / > ; } ) ; DropdownMenuGroup . displayName = GROUP_NAME ; const LABEL_NAME = 'DropdownMenuLabel' ; type DropdownMenuLabelElement = React . ElementRef < typeof MenuPrimitive . Label > ; type MenuLabelProps = Radix . ComponentPropsWithoutRef < typeof MenuPrimitive . Label > ; interface DropdownMenuLabelProps extends MenuLabelProps { } const DropdownMenuLabel = React . forwardRef < DropdownMenuLabelElement , DropdownMenuLabelProps > ( ( props , forwardedRef ) => { const { __scopeDropdownMenu , ... labelProps } = props ; const menuScope = useMenuScope ( __scopeDropdownMenu ) ; return < MenuPrimitive . Label { ... menuScope } { ... labelProps } ref = { forwardedRef } / > ; } ) ; DropdownMenuLabel . displayName = LABEL_NAME ; const ITEM_NAME = 'DropdownMenuItem' ; type DropdownMenuItemElement = React . ElementRef < typeof MenuPrimitive . Item > ; type MenuItemProps = Radix . ComponentPropsWithoutRef < typeof MenuPrimitive . Item > ; interface DropdownMenuItemProps extends MenuItemProps { } const DropdownMenuItem = React . forwardRef < DropdownMenuItemElement , DropdownMenuItemProps > ( ( props , forwardedRef ) => { const { __scopeDropdownMenu , ... itemProps } = props ; const menuScope = useMenuScope ( __scopeDropdownMenu ) ; return < MenuPrimitive . Item { ... menuScope } { ... itemProps } ref = { forwardedRef } / > ; } ) ; DropdownMenuItem . displayName = ITEM_NAME ; const TRIGGER_ITEM_NAME = 'DropdownMenuTriggerItem' ; type DropdownMenuTriggerItemElement = React . ElementRef < typeof MenuPrimitive . SubTrigger > ; type MenuSubTriggerProps = Radix . ComponentPropsWithoutRef < typeof MenuPrimitive . SubTrigger > ; interface DropdownMenuTriggerItemProps extends MenuSubTriggerProps { } const DropdownMenuTriggerItem = React . forwardRef < DropdownMenuTriggerItemElement , DropdownMenuTriggerItemProps > ( ( props , forwardedRef ) => { const { __scopeDropdownMenu , ... triggerItemProps } = props ; const menuScope = useMenuScope ( __scopeDropdownMenu ) ; return < MenuPrimitive . SubTrigger { ... menuScope } { ... triggerItemProps } ref = { forwardedRef } / > ; } ) ; DropdownMenuTriggerItem . displayName = TRIGGER_ITEM_NAME ; const CHECKBOX_ITEM_NAME = 'DropdownMenuCheckboxItem' ; type DropdownMenuCheckboxItemElement = React . ElementRef < typeof MenuPrimitive . CheckboxItem > ; type MenuCheckboxItemProps = Radix . ComponentPropsWithoutRef < typeof MenuPrimitive . CheckboxItem > ; interface DropdownMenuCheckboxItemProps extends MenuCheckboxItemProps { } const DropdownMenuCheckboxItem = React . forwardRef < DropdownMenuCheckboxItemElement , DropdownMenuCheckboxItemProps > ( ( props , forwardedRef ) => { const { __scopeDropdownMenu , ... checkboxItemProps } = props ; const menuScope = useMenuScope ( __scopeDropdownMenu ) ; return < MenuPrimitive . CheckboxItem { ... menuScope } { ... checkboxItemProps } ref = { forwardedRef } / > ; } ) ; DropdownMenuCheckboxItem . displayName = CHECKBOX_ITEM_NAME ; const RADIO_GROUP_NAME = 'DropdownMenuRadioGroup' ; type DropdownMenuRadioGroupElement = React . ElementRef < typeof MenuPrimitive . RadioGroup > ; type MenuRadioGroupProps = Radix . ComponentPropsWithoutRef < typeof MenuPrimitive . RadioGroup > ; interface DropdownMenuRadioGroupProps extends MenuRadioGroupProps { } const DropdownMenuRadioGroup = React . forwardRef < DropdownMenuRadioGroupElement , DropdownMenuRadioGroupProps > ( ( props , forwardedRef ) => { const { __scopeDropdownMenu , ... radioGroupProps } = props ; const menuScope = useMenuScope ( __scopeDropdownMenu ) ; return < MenuPrimitive . RadioGroup { ... menuScope } { ... radioGroupProps } ref = { forwardedRef } / > ; } ) ; DropdownMenuRadioGroup . displayName = RADIO_GROUP_NAME ; const RADIO_ITEM_NAME = 'DropdownMenuRadioItem' ; type DropdownMenuRadioItemElement = React . ElementRef < typeof MenuPrimitive . RadioItem > ; type MenuRadioItemProps = Radix . ComponentPropsWithoutRef < typeof MenuPrimitive . RadioItem > ; interface DropdownMenuRadioItemProps extends MenuRadioItemProps { } const DropdownMenuRadioItem = React . forwardRef < DropdownMenuRadioItemElement , DropdownMenuRadioItemProps > ( ( props , forwardedRef ) => { const { __scopeDropdownMenu , ... radioItemProps } = props ; const menuScope = useMenuScope ( __scopeDropdownMenu ) ; return < MenuPrimitive . RadioItem { ... menuScope } { ... radioItemProps } ref = { forwardedRef } / > ; } ) ; DropdownMenuRadioItem . displayName = RADIO_ITEM_NAME ; const INDICATOR_NAME = 'DropdownMenuItemIndicator' ; type DropdownMenuItemIndicatorElement = React . ElementRef < typeof MenuPrimitive . ItemIndicator > ; type MenuItemIndicatorProps = Radix . ComponentPropsWithoutRef < typeof MenuPrimitive . ItemIndicator > ; interface DropdownMenuItemIndicatorProps extends MenuItemIndicatorProps { } const DropdownMenuItemIndicator = React . forwardRef < DropdownMenuItemIndicatorElement , DropdownMenuItemIndicatorProps > ( ( props , forwardedRef ) => { const { __scopeDropdownMenu , ... itemIndicatorProps } = props ; const menuScope = useMenuScope ( __scopeDropdownMenu ) ; return < MenuPrimitive . ItemIndicator { ... menuScope } { ... itemIndicatorProps } ref = { forwardedRef } / > ; } ) ; DropdownMenuItemIndicator . displayName = INDICATOR_NAME ; const SEPARATOR_NAME = 'DropdownMenuSeparator' ; type DropdownMenuSeparatorElement = React . ElementRef < typeof MenuPrimitive . Separator > ; type MenuSeparatorProps = Radix . ComponentPropsWithoutRef < typeof MenuPrimitive . Separator > ; interface DropdownMenuSeparatorProps extends MenuSeparatorProps { } const DropdownMenuSeparator = React . forwardRef < DropdownMenuSeparatorElement , DropdownMenuSeparatorProps > ( ( props , forwardedRef ) => { const { __scopeDropdownMenu , ... separatorProps } = props ; const menuScope = useMenuScope ( __scopeDropdownMenu ) ; return < MenuPrimitive . Separator { ... menuScope } { ... separatorProps } ref = { forwardedRef } / > ; } ) ; DropdownMenuSeparator . displayName = SEPARATOR_NAME ; const ARROW_NAME = 'DropdownMenuArrow' ; type DropdownMenuArrowElement = React . ElementRef < typeof MenuPrimitive . Arrow > ; type MenuArrowProps = Radix . ComponentPropsWithoutRef < typeof MenuPrimitive . Arrow > ; interface DropdownMenuArrowProps extends MenuArrowProps { } const DropdownMenuArrow = React . forwardRef < DropdownMenuArrowElement , DropdownMenuArrowProps > ( ( props , forwardedRef ) => { const { __scopeDropdownMenu , ... arrowProps } = props ; const menuScope = useMenuScope ( __scopeDropdownMenu ) ; return < MenuPrimitive . Arrow { ... menuScope } { ... arrowProps } ref = { forwardedRef } / > ; } ) ; DropdownMenuArrow . displayName = ARROW_NAME ; const Root = DropdownMenu ; const Trigger = DropdownMenuTrigger ; const Content = DropdownMenuContent ; const Group = DropdownMenuGroup ; const Label = DropdownMenuLabel ; const Item = DropdownMenuItem ; const TriggerItem = DropdownMenuTriggerItem ; const CheckboxItem = DropdownMenuCheckboxItem ; const RadioGroup = DropdownMenuRadioGroup ; const RadioItem = DropdownMenuRadioItem ; const ItemIndicator = DropdownMenuItemIndicator ; const Separator = DropdownMenuSeparator ; const Arrow = DropdownMenuArrow ; export { createDropdownMenuScope , DropdownMenu , DropdownMenuTrigger , DropdownMenuContent , DropdownMenuGroup , DropdownMenuLabel , DropdownMenuItem , DropdownMenuTriggerItem , DropdownMenuCheckboxItem , DropdownMenuRadioGroup , DropdownMenuRadioItem , DropdownMenuItemIndicator , DropdownMenuSeparator , DropdownMenuArrow , Root , Trigger , Content , Group , Label , Item , TriggerItem , CheckboxItem , RadioGroup , RadioItem , ItemIndicator , Separator , Arrow , } ; export type { DropdownMenuProps , DropdownMenuTriggerProps , DropdownMenuContentProps , DropdownMenuGroupProps , DropdownMenuLabelProps , DropdownMenuItemProps , DropdownMenuTriggerItemProps , DropdownMenuCheckboxItemProps , DropdownMenuRadioGroupProps , DropdownMenuRadioItemProps , DropdownMenuItemIndicatorProps , DropdownMenuSeparatorProps , DropdownMenuArrowProps , } ;