{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "dropdown-menu-glass", "type": "registry:ui", "title": "Dropdown Menu Glass", "description": "DropdownMenuGlass - Compound Component", "dependencies": [ "@radix-ui/react-dropdown-menu", "lucide-react", "react", "shadcn-glass-ui" ], "registryDependencies": [ "cn", "variants" ], "files": [ { "path": "components/glass/ui/dropdown-menu-glass.tsx", "type": "registry:component", "content": "/**\n * DropdownMenuGlass - Compound Component\n *\n * Glass-themed dropdown menu following shadcn/ui compound component pattern.\n * Built on Radix UI primitives with unified glass styling and full keyboard navigation.\n *\n * ## Features\n * - **Compound Component API** - Root, Trigger, Content, Item, and more sub-components\n * - **Radix UI Primitives** - Built on @radix-ui/react-dropdown-menu for robust accessibility\n * - **Glassmorphism Styling** - Backdrop blur, glow effects, CSS variables\n * - **Theme Support** - Works with all 3 themes (glass, light, aurora)\n * - **shadcn/ui Compatible** - 100% API compatibility with shadcn/ui DropdownMenu\n * - **Rich Features** - Checkboxes, radio groups, sub-menus, labels, separators, shortcuts\n * - **Keyboard Accessible** - Full keyboard navigation (Tab, Arrow keys, Enter, Escape)\n * - **Variant Support** - Default and destructive item variants\n *\n * ## Sub-Components\n * - `DropdownMenuGlass` - Root context provider\n * - `DropdownMenuGlassTrigger` - Opens menu when clicked (supports asChild)\n * - `DropdownMenuGlassContent` - Main menu container with glass styling\n * - `DropdownMenuGlassItem` - Individual menu item (supports variant prop)\n * - `DropdownMenuGlassCheckboxItem` - Checkbox menu item with checked state\n * - `DropdownMenuGlassRadioItem` - Radio button menu item\n * - `DropdownMenuGlassRadioGroup` - Container for radio items\n * - `DropdownMenuGlassLabel` - Label for menu sections\n * - `DropdownMenuGlassSeparator` - Visual divider\n * - `DropdownMenuGlassGroup` - Groups related items\n * - `DropdownMenuGlassSub` - Sub-menu context\n * - `DropdownMenuGlassSubTrigger` - Opens sub-menu\n * - `DropdownMenuGlassSubContent` - Sub-menu content\n * - `DropdownMenuGlassShortcut` - Keyboard shortcut display\n *\n * ## CSS Variables\n * Customize styling via theme CSS variables:\n * - `--dropdown-bg` - Menu background color\n * - `--dropdown-border` - Menu border color\n * - `--dropdown-glow` - Menu box shadow\n * - `--dropdown-item-hover` - Item hover background\n * - `--dropdown-item-danger` - Destructive item color\n * - `--dropdown-item-danger-hover` - Destructive item hover background\n * - `--text-primary`, `--text-secondary`, `--text-muted` - Text colors\n * - `--blur-md` (16px) - Backdrop blur for menu\n *\n * @example Basic usage\n * ```tsx\n * import { DropdownMenuGlass, DropdownMenuGlassTrigger, DropdownMenuGlassContent, DropdownMenuGlassItem } from 'shadcn-glass-ui'\n *\n * \n * \n * \n * \n * \n * console.log('Edit')}>\n * \n * Edit\n * \n * \n * \n * \n * Delete\n * \n * \n * \n * ```\n *\n * @example With labels and groups\n * ```tsx\n * \n * \n * \n * \n * \n * Actions\n * \n * Copy\n * Paste\n * \n * \n * Danger Zone\n * Delete\n * \n * \n * ```\n *\n * @example With keyboard shortcuts\n * ```tsx\n * \n * \n * \n * Copy\n * ⌘C\n * \n * \n * \n * Paste\n * ⌘V\n * \n * \n * ```\n *\n * @example With checkboxes\n * ```tsx\n * const [showStatusBar, setShowStatusBar] = useState(true)\n *\n * \n * \n * Status Bar\n * \n * \n * ```\n *\n * @accessibility\n * - **Keyboard Navigation:** Full keyboard support with Tab, Arrow keys, Enter to select, Escape to close\n * - **Focus Management:** Auto-focus on open, returns focus to trigger on close\n * - **Screen Readers:** Proper ARIA attributes (role=\"menu\", aria-haspopup, aria-expanded)\n * - **Item Variants:** Destructive items have appropriate visual styling for dangerous actions\n * - **Checkboxes/Radio:** Proper indicator icons and checked state announcements\n * - **Sub-menus:** Arrow icon indicator and keyboard navigation support\n * - **Touch Targets:** All items meet minimum 44x44px touch target (WCAG 2.5.5)\n * - **Color Contrast:** All text meets WCAG AA contrast ratio 4.5:1 minimum\n *\n * @see https://www.radix-ui.com/primitives/docs/components/dropdown-menu\n * @since v1.0.0\n */\n\n'use client';\n\nimport * as React from 'react';\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport {\n getDropdownContentStyles,\n dropdownContentClasses,\n getDropdownItemClasses,\n dropdownSeparatorClasses,\n dropdownLabelClasses,\n} from '@/lib/variants/dropdown-content-styles';\nimport '@/glass-theme.css';\n\n// ========================================\n// ROOT\n// ========================================\n\n// Note: DropdownMenuPrimitive.Root is a context provider and doesn't render DOM,\n// so data-slot is applied to Content instead. This matches shadcn/ui pattern.\nconst DropdownMenuGlassRoot = (\n props: React.ComponentPropsWithoutRef\n) => ;\nDropdownMenuGlassRoot.displayName = 'DropdownMenuGlass';\n\nconst DropdownMenuGlass = DropdownMenuGlassRoot;\n\n// ========================================\n// TRIGGER\n// ========================================\n\nconst DropdownMenuGlassTrigger = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef\n>((props, ref) => (\n \n));\nDropdownMenuGlassTrigger.displayName = 'DropdownMenuGlassTrigger';\n\n// ========================================\n// GROUP\n// ========================================\n\nconst DropdownMenuGlassGroup = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef\n>((props, ref) => (\n \n));\nDropdownMenuGlassGroup.displayName = 'DropdownMenuGlassGroup';\n\n// ========================================\n// PORTAL\n// ========================================\n\nconst DropdownMenuGlassPortal = DropdownMenuPrimitive.Portal;\n\n// ========================================\n// SUB\n// ========================================\n\n// Note: DropdownMenuPrimitive.Sub is a context provider and doesn't render DOM,\n// so data-slot is applied to SubContent instead. This matches shadcn/ui pattern.\nconst DropdownMenuGlassSub = (\n props: React.ComponentPropsWithoutRef\n) => ;\nDropdownMenuGlassSub.displayName = 'DropdownMenuGlassSub';\n\n// ========================================\n// RADIO GROUP\n// ========================================\n\nconst DropdownMenuGlassRadioGroup = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef\n>((props, ref) => (\n \n));\nDropdownMenuGlassRadioGroup.displayName = 'DropdownMenuGlassRadioGroup';\n\n// ========================================\n// SUB TRIGGER\n// ========================================\n\nconst DropdownMenuGlassSubTrigger = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef & {\n inset?: boolean;\n }\n>(({ className, inset, children, ...props }, ref) => (\n \n {children}\n \n \n));\nDropdownMenuGlassSubTrigger.displayName = 'DropdownMenuGlassSubTrigger';\n\n// ========================================\n// SUB CONTENT\n// ========================================\n\nconst DropdownMenuGlassSubContent = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nDropdownMenuGlassSubContent.displayName = 'DropdownMenuGlassSubContent';\n\n// ========================================\n// CONTENT\n// ========================================\n\nconst DropdownMenuGlassContent = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef\n>(({ className, sideOffset = 8, ...props }, ref) => (\n \n \n \n));\nDropdownMenuGlassContent.displayName = 'DropdownMenuGlassContent';\n\n// ========================================\n// ITEM\n// ========================================\n\n/**\n * Props for DropdownMenuGlassItem component.\n *\n * Individual menu item with support for icons, variants, and keyboard shortcuts.\n *\n * @example\n * ```tsx\n * const props: DropdownMenuGlassItemProps = {\n * variant: 'destructive',\n * onSelect: () => handleDelete(),\n * children: (\n * <>\n * \n * Delete\n * \n * ),\n * };\n * ```\n */\nexport interface DropdownMenuGlassItemProps extends React.ComponentPropsWithoutRef<\n typeof DropdownMenuPrimitive.Item\n> {\n /**\n * Adds left padding to align with items that have icons.\n *\n * @default false\n */\n inset?: boolean;\n\n /**\n * Visual variant of the menu item.\n * - `default` - Standard menu item styling\n * - `destructive` - Red styling for dangerous actions\n *\n * @default \"default\"\n */\n variant?: 'default' | 'destructive';\n}\n\nconst DropdownMenuGlassItem = React.forwardRef<\n React.ComponentRef,\n DropdownMenuGlassItemProps\n>(({ className, inset, variant = 'default', ...props }, ref) => (\n \n));\nDropdownMenuGlassItem.displayName = 'DropdownMenuGlassItem';\n\n// ========================================\n// CHECKBOX ITEM\n// ========================================\n\nconst DropdownMenuGlassCheckboxItem = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef\n>(({ className, children, checked, ...props }, ref) => (\n \n \n \n \n \n \n {children}\n \n));\nDropdownMenuGlassCheckboxItem.displayName = 'DropdownMenuGlassCheckboxItem';\n\n// ========================================\n// RADIO ITEM\n// ========================================\n\nconst DropdownMenuGlassRadioItem = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef\n>(({ className, children, ...props }, ref) => (\n \n \n \n \n \n \n {children}\n \n));\nDropdownMenuGlassRadioItem.displayName = 'DropdownMenuGlassRadioItem';\n\n// ========================================\n// LABEL\n// ========================================\n\nconst DropdownMenuGlassLabel = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n \n));\nDropdownMenuGlassLabel.displayName = 'DropdownMenuGlassLabel';\n\n// ========================================\n// SEPARATOR\n// ========================================\n\nconst DropdownMenuGlassSeparator = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nDropdownMenuGlassSeparator.displayName = 'DropdownMenuGlassSeparator';\n\n// ========================================\n// SHORTCUT\n// ========================================\n\nconst DropdownMenuGlassShortcut = ({\n className,\n ...props\n}: React.HTMLAttributes) => {\n return (\n \n );\n};\nDropdownMenuGlassShortcut.displayName = 'DropdownMenuGlassShortcut';\n\n// ========================================\n// EXPORTS\n// ========================================\n\nexport {\n DropdownMenuGlass,\n DropdownMenuGlassTrigger,\n DropdownMenuGlassContent,\n DropdownMenuGlassItem,\n DropdownMenuGlassCheckboxItem,\n DropdownMenuGlassRadioItem,\n DropdownMenuGlassLabel,\n DropdownMenuGlassSeparator,\n DropdownMenuGlassShortcut,\n DropdownMenuGlassGroup,\n DropdownMenuGlassPortal,\n DropdownMenuGlassSub,\n DropdownMenuGlassSubContent,\n DropdownMenuGlassSubTrigger,\n DropdownMenuGlassRadioGroup,\n};\n\n// ========================================\n// SHADCN/UI COMPATIBLE ALIASES\n// ========================================\n\n/**\n * shadcn/ui compatible aliases for DropdownMenuGlass components\n *\n * @example\n * ```tsx\n * import {\n * DropdownMenu,\n * DropdownMenuTrigger,\n * DropdownMenuContent,\n * DropdownMenuItem,\n * } from 'shadcn-glass-ui'\n *\n * \n * Open\n * \n * Profile\n * Settings\n * \n * \n * ```\n * @since v2.5.0\n */\nexport const DropdownMenu = DropdownMenuGlass;\nexport const DropdownMenuTrigger = DropdownMenuGlassTrigger;\nexport const DropdownMenuContent = DropdownMenuGlassContent;\nexport const DropdownMenuItem = DropdownMenuGlassItem;\nexport const DropdownMenuCheckboxItem = DropdownMenuGlassCheckboxItem;\nexport const DropdownMenuRadioItem = DropdownMenuGlassRadioItem;\nexport const DropdownMenuLabel = DropdownMenuGlassLabel;\nexport const DropdownMenuSeparator = DropdownMenuGlassSeparator;\nexport const DropdownMenuShortcut = DropdownMenuGlassShortcut;\nexport const DropdownMenuGroup = DropdownMenuGlassGroup;\nexport const DropdownMenuPortal = DropdownMenuGlassPortal;\nexport const DropdownMenuSub = DropdownMenuGlassSub;\nexport const DropdownMenuSubContent = DropdownMenuGlassSubContent;\nexport const DropdownMenuSubTrigger = DropdownMenuGlassSubTrigger;\nexport const DropdownMenuRadioGroup = DropdownMenuGlassRadioGroup;\n" } ], "categories": [ "ui" ], "cssVars": { "light": { "--glass-bg": "rgba(255, 255, 255, 0.1)", "--glass-border": "rgba(255, 255, 255, 0.2)", "--blur-sm": "8px", "--blur-md": "16px", "--blur-lg": "24px" }, "dark": { "--glass-bg": "rgba(255, 255, 255, 0.05)", "--glass-border": "rgba(255, 255, 255, 0.1)", "--blur-sm": "8px", "--blur-md": "16px", "--blur-lg": "24px" } } }