{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "user-menu-dropdown", "title": "User Menu Dropdown", "description": "Navbar dropdown for user account with header banner, avatar, menu items, and sign out button.", "registryDependencies": [ "https://raw.githubusercontent.com/dnachavez/adminlte-next/master/public/r/adminlte-theme.json", "https://raw.githubusercontent.com/dnachavez/adminlte-next/master/public/r/adminlte-dropdown.json", "https://raw.githubusercontent.com/dnachavez/adminlte-next/master/public/r/adminlte-button.json" ], "files": [ { "path": "registry/new-york/user-menu-dropdown/components/user-menu-dropdown.tsx", "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"@/registry/new-york/adminlte-theme/lib/cn\"\n\ninterface UserMenuItem {\n icon: React.ReactNode\n text: string\n href?: string\n badge?: React.ReactNode\n}\n\ninterface UserMenuDropdownProps extends React.HTMLAttributes {\n avatarUrl: string\n name: string\n memberSince: string\n headerBg?: string\n menuItems?: UserMenuItem[]\n onSignOut?: () => void\n onProfile?: () => void\n}\n\nconst UserMenuDropdown = React.forwardRef(\n (\n {\n className,\n avatarUrl,\n name,\n memberSince,\n headerBg,\n menuItems = [],\n onSignOut,\n onProfile,\n ...props\n },\n ref\n ) => {\n const [isOpen, setIsOpen] = React.useState(false)\n const containerRef = React.useRef(null)\n\n React.useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(e.target as Node)\n ) {\n setIsOpen(false)\n }\n }\n if (isOpen) {\n document.addEventListener(\"mousedown\", handleClickOutside)\n }\n return () =>\n document.removeEventListener(\"mousedown\", handleClickOutside)\n }, [isOpen])\n\n return (\n {\n ;(\n containerRef as React.MutableRefObject\n ).current = node\n if (typeof ref === \"function\") ref(node)\n else if (ref) ref.current = node\n }}\n className={cn(\"relative inline-block\", className)}\n {...props}\n >\n setIsOpen(!isOpen)}\n className=\"flex items-center gap-[8px] h-[50px] px-[15px] bg-transparent border-none text-[var(--adminlte-skin-navbar-color)] cursor-pointer hover:bg-black/10\"\n >\n \n \n \n\n {isOpen && (\n
    \n {/* Header */}\n \n \n

    {name}

    \n

    \n Member since {memberSince}\n

    \n \n\n {/* Menu items in 2-column grid */}\n {menuItems.length > 0 && (\n
  • \n
    \n {menuItems.map((item, index) => (\n \n {item.icon}\n {item.text}\n {item.badge && (\n \n {item.badge}\n \n )}\n \n ))}\n
    \n
  • \n )}\n\n {/* Footer */}\n
  • \n {\n setIsOpen(false)\n onProfile?.()\n }}\n className=\"px-[15px] py-[5px] text-[12px] bg-[#3c8dbc] text-white border border-[#367fa9] rounded-[3px] cursor-pointer hover:bg-[#367fa9]\"\n >\n Profile\n \n {\n setIsOpen(false)\n onSignOut?.()\n }}\n className=\"px-[15px] py-[5px] text-[12px] bg-[#dd4b39] text-white border border-[#d73925] rounded-[3px] cursor-pointer hover:bg-[#d73925]\"\n >\n Sign out\n \n
  • \n
\n )}\n \n )\n }\n)\nUserMenuDropdown.displayName = \"UserMenuDropdown\"\n\nexport { UserMenuDropdown }\nexport type { UserMenuDropdownProps, UserMenuItem }\n", "type": "registry:component" } ], "type": "registry:component" }