'use client' import { button } from './button' import { separator } from './separator' import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu' import type * as _A from '@radix-ui/react-menu' import { IconCheck, IconChevronRight, IconPoint } from '@tabler/icons-react' import { forwardRef } from 'react' import type { VariantProps } from 'tailwind-variants' import { tv } from 'tailwind-variants' import type { Merge } from 'type-fest' const baseItem = button({ size: 'sm', variant: 'ghost' }).root({ className: [ 'flex justify-start', 'w-full px-2 text-sm font-medium', 'outline-none focus:bg-bg--active data-[state=open]:bg-bg--active', 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50', ], }) const baseContent = [ 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-bg--contrast p-1 shadow-md', 'data-[state=open]:animate-in data-[state=closed]:animate-out', 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0', 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95', 'data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2', 'data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', ] const dropdownMenu = tv({ slots: { subTrigger: baseItem, subTriggerIcon: button({ size: 'sm', variant: 'ghost' }).rightIcon({ className: 'ml-auto' }), subContent: [baseContent, 'shadow-lg'], content: [baseContent, 'min-w-[12rem]'], item: baseItem, itemShortcut: 'ml-auto text-xs tracking-widest text-fg-weaker', checkboxItem: [baseItem, 'relative pl-8'], checkboxItemIndicatorIcon: 'absolute left-2 size-4', radioItem: [baseItem, 'relative pl-8'], radioItemIndicatorIcon: 'absolute left-2 size-4 fill-current', label: 'px-2 py-1.5 text-sm font-semibold', separator: separator({ variant: 'weak' }).root({ className: '-mx-1 my-1' }), }, variants: { inset: { true: { subTrigger: 'pl-8', item: 'pl-8', label: 'pl-8', }, }, }, }) const DropdownMenuSubTrigger = forwardRef< React.ElementRef, Merge< Merge< React.ComponentPropsWithoutRef, VariantProps >, { iconProps?: React.ComponentProps } > >(({ iconProps, inset, children, ...props }, ref) => { const { subTrigger, subTriggerIcon } = dropdownMenu({ inset }) return ( {children} ) }) DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName const DropdownMenuSubContent = forwardRef< React.ElementRef, Merge< React.ComponentPropsWithoutRef, { portalProps?: React.ComponentProps } > >(({ portalProps, ...props }, ref) => { const { subContent } = dropdownMenu() return ( ) }) DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName const DropdownMenuContent = forwardRef< React.ElementRef, Merge< React.ComponentPropsWithoutRef, { portalProps?: React.ComponentProps } > >(({ portalProps, ...props }, ref) => { const { content } = dropdownMenu() return ( ) }) DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName const DropdownMenuItem = forwardRef< React.ElementRef, Merge< React.ComponentPropsWithoutRef, VariantProps > >(({ inset, ...props }, ref) => { const { item } = dropdownMenu({ inset }) return ( ) }) DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName const DropdownMenuCheckboxItem = forwardRef< React.ElementRef, Merge< React.ComponentPropsWithoutRef, { indicatorIconProps?: React.ComponentProps } > >(({ indicatorIconProps, children, ...props }, ref) => { const { checkboxItem, checkboxItemIndicatorIcon } = dropdownMenu() return ( {children} ) }) DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName const DropdownMenuRadioItem = forwardRef< React.ElementRef, Merge< React.ComponentPropsWithoutRef, { indicatorIconProps?: React.ComponentProps } > >(({ indicatorIconProps, children, ...props }, ref) => { const { radioItem, radioItemIndicatorIcon } = dropdownMenu() return ( {children} ) }) DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName const DropdownMenuLabel = forwardRef< React.ElementRef, Merge< React.ComponentPropsWithoutRef, VariantProps > >(({ inset, ...props }, ref) => { const { label } = dropdownMenu({ inset }) return ( ) }) DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName const DropdownMenuSeparator = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >((props, ref) => { const { separator } = dropdownMenu() return ( ) }) DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName function DropdownMenuItemShortcut(props: React.ComponentProps<'span'>) { const { itemShortcut } = dropdownMenu() return } const DropdownMenu = Object.assign(DropdownMenuPrimitive.Root, { Trigger: DropdownMenuPrimitive.Trigger, Content: DropdownMenuContent, Group: DropdownMenuPrimitive.Group, Label: DropdownMenuLabel, Separator: DropdownMenuSeparator, Item: Object.assign(DropdownMenuItem, { Shortcut: DropdownMenuItemShortcut, }), Radio: Object.assign(DropdownMenuPrimitive.RadioGroup, { Item: DropdownMenuRadioItem, }), CheckboxItem: DropdownMenuCheckboxItem, Sub: Object.assign(DropdownMenuPrimitive.Sub, { Trigger: DropdownMenuSubTrigger, Content: DropdownMenuSubContent, }), }) export default DropdownMenu export { dropdownMenu, DropdownMenuPrimitive }