import * as React from 'react' import { motion } from 'framer-motion' import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu' import { cva, type VariantProps } from 'class-variance-authority' import { cn } from '@/lib/utils' import { MOTION_SCALE_IN } from '@/lib/motion' import { ArrowRightLine, CheckLine } from './icons-inline' import { getThemeFromDocument } from './theme-from-document' const DropdownMenu = DropdownMenuPrimitive.Root const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger const DropdownMenuGroup = DropdownMenuPrimitive.Group const DropdownMenuPortal = DropdownMenuPrimitive.Portal const DropdownMenuSub = DropdownMenuPrimitive.Sub const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup const contentClasses = 'min-w-32 overflow-hidden rounded-lg border border-border-tertiary bg-bg-container p-1 text-text shadow-lg z-50 outline-none focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:!outline-none focus-visible:!ring-0' export interface DropdownMenuContentProps extends React.ComponentPropsWithoutRef { /** When provided (e.g. from ThemeStyleProvider), used for portal wrapper */ dataStyle?: string dataTheme?: string } const DropdownMenuContent = React.forwardRef< React.ElementRef, DropdownMenuContentProps >(({ className, sideOffset = 4, children, dataStyle, dataTheme, ...props }, ref) => { const fromDoc = getThemeFromDocument() const dataProps = dataStyle !== undefined ? { 'data-style': dataStyle, 'data-theme': dataTheme ?? fromDoc['data-theme'] ?? '' } : fromDoc return (
{children}
) }) DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName const subTriggerVariants = cva( 'flex h-[var(--select-item-height)] w-full cursor-pointer select-none items-center gap-2 rounded-sm px-[var(--select-item-padding-x)] text-[length:var(--control-font-size-md)] leading-[var(--control-line-height-md)] outline-none focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:!outline-none hover:bg-fill-secondary focus:bg-fill-secondary data-[highlighted]:bg-fill-secondary data-[state=open]:bg-fill-secondary', { variants: { inset: { true: 'pl-8 pr-3', false: '' }, }, defaultVariants: { inset: false }, } ) const DropdownMenuSubTrigger = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef & VariantProps & { subTriggerIcon?: React.ReactNode } >(({ className, inset = false, children, subTriggerIcon, ...rest }, ref) => ( {children} {subTriggerIcon ?? } )) DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName export interface DropdownMenuSubContentProps extends React.ComponentPropsWithoutRef { /** When provided (e.g. from ThemeStyleProvider), used for portal wrapper */ dataStyle?: string dataTheme?: string } const DropdownMenuSubContent = React.forwardRef< React.ElementRef, DropdownMenuSubContentProps >(({ className, sideOffset = 4, dataStyle, dataTheme, ...props }, ref) => { const fromDoc = getThemeFromDocument() const dataProps = dataStyle !== undefined ? { 'data-style': dataStyle, 'data-theme': dataTheme ?? fromDoc['data-theme'] ?? '' } : fromDoc return (
) }) DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName const itemVariants = cva( 'relative flex h-[var(--select-item-height)] w-full min-w-0 cursor-pointer select-none items-center gap-2 rounded-sm px-[var(--select-item-padding-x)] text-[length:var(--control-font-size-md)] leading-[var(--control-line-height-md)] outline-none focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:!outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50', { variants: { variant: { default: 'hover:bg-fill-secondary focus:bg-fill-secondary focus:text-text data-[highlighted]:bg-fill-secondary data-[highlighted]:text-text', destructive: 'text-error hover:bg-error-bg focus:bg-error-bg focus:text-error data-[highlighted]:bg-error-bg data-[highlighted]:text-error', }, inset: { true: 'pl-8 pr-3', false: '' }, }, defaultVariants: { variant: 'default', inset: false }, } ) const DropdownMenuItem = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef & VariantProps >(({ className, inset = false, variant = 'default', ...props }, ref) => ( )) DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName const itemIndicatorClasses = 'relative flex h-[var(--select-item-height)] w-full min-w-0 cursor-pointer select-none items-center gap-2 rounded-sm pl-8 pr-3 text-[length:var(--control-font-size-md)] leading-[var(--control-line-height-md)] outline-none transition-colors hover:bg-fill-secondary focus:bg-fill-secondary focus:text-text data-[highlighted]:bg-fill-secondary data-[highlighted]:text-text data-[disabled]:pointer-events-none data-[disabled]:opacity-50' const DropdownMenuCheckboxItem = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef & { checkIcon?: React.ReactNode } >(({ className, children, checked, checkIcon, ...rest }, ref) => ( {checkIcon ?? } {children} )) DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName const DropdownMenuRadioItem = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => (
{children} )) DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName const labelVariants = cva( 'flex h-[var(--select-item-height)] items-center px-[var(--select-item-padding-x)] text-[length:var(--control-font-size-md)] leading-[var(--control-line-height-md)] font-semibold text-text-secondary', { variants: { inset: { true: 'pl-8 pr-3', false: '' }, }, defaultVariants: { inset: false }, } ) const DropdownMenuLabel = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef & VariantProps >(({ className, inset = false, ...props }, ref) => ( )) DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName const DropdownMenuSeparator = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes) => ( ) DropdownMenuShortcut.displayName = 'DropdownMenuShortcut' export { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuGroup, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuRadioGroup, }