{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "sidebar-menu", "title": "Sidebar Menu", "description": "Sidebar navigation menu with treeview support, section headers, icons, badges, and accordion behavior.", "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-badge.json", "https://raw.githubusercontent.com/dnachavez/adminlte-next/master/public/r/adminlte-label.json", "https://raw.githubusercontent.com/dnachavez/adminlte-next/master/public/r/use-treeview.json" ], "files": [ { "path": "registry/new-york/sidebar-menu/components/sidebar-menu.tsx", "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { useState, useCallback } from \"react\"\nimport { cn } from \"@/registry/new-york/adminlte-theme/lib/cn\"\n\n/* -------------------------------------------------------------------------- */\n/* SidebarMenuHeader */\n/* -------------------------------------------------------------------------- */\n\ninterface SidebarMenuHeaderProps extends React.LiHTMLAttributes {\n children?: React.ReactNode\n}\n\nconst SidebarMenuHeader = React.forwardRef(\n ({ className, children, ...props }, ref) => (\n \n {children}\n \n )\n)\nSidebarMenuHeader.displayName = \"SidebarMenuHeader\"\n\n/* -------------------------------------------------------------------------- */\n/* Chevron icon for treeview */\n/* -------------------------------------------------------------------------- */\n\nfunction TreeviewChevron({ isOpen }: { isOpen: boolean }) {\n return (\n \n \n \n )\n}\n\n/* -------------------------------------------------------------------------- */\n/* SidebarMenuItem */\n/* -------------------------------------------------------------------------- */\n\ninterface SidebarMenuItemProps extends React.LiHTMLAttributes {\n label?: string\n icon?: React.ReactNode\n href?: string\n active?: boolean\n badge?: React.ReactNode\n children?: React.ReactNode\n isOpen?: boolean\n onToggle?: () => void\n}\n\nconst SidebarMenuItem = React.forwardRef(\n (\n {\n className,\n label,\n icon,\n href,\n active = false,\n badge,\n children,\n isOpen: controlledIsOpen,\n onToggle: controlledOnToggle,\n ...props\n },\n ref\n ) => {\n const hasChildren = React.Children.count(children) > 0\n const [internalOpen, setInternalOpen] = useState(false)\n\n const isOpen = controlledIsOpen !== undefined ? controlledIsOpen : internalOpen\n const handleToggle = useCallback(() => {\n if (controlledOnToggle) {\n controlledOnToggle()\n } else {\n setInternalOpen((prev) => !prev)\n }\n }, [controlledOnToggle])\n\n const handleClick = useCallback(\n (e: React.MouseEvent) => {\n if (hasChildren) {\n e.preventDefault()\n handleToggle()\n }\n },\n [hasChildren, handleToggle]\n )\n\n return (\n \n \n {/* Icon */}\n {icon && (\n \n {icon}\n \n )}\n\n {/* Label */}\n {label && {label}}\n\n {/* Badge */}\n {badge && {badge}}\n\n {/* Treeview chevron */}\n {hasChildren && }\n \n\n {/* Submenu */}\n {hasChildren && (\n \n {children}\n \n )}\n \n )\n }\n)\nSidebarMenuItem.displayName = \"SidebarMenuItem\"\n\n/* -------------------------------------------------------------------------- */\n/* SidebarMenu */\n/* -------------------------------------------------------------------------- */\n\ninterface SidebarMenuProps extends React.HTMLAttributes {\n children?: React.ReactNode\n}\n\nconst SidebarMenu = React.forwardRef(\n ({ className, children, ...props }, ref) => (\n \n {children}\n \n )\n)\nSidebarMenu.displayName = \"SidebarMenu\"\n\nexport { SidebarMenu, SidebarMenuItem, SidebarMenuHeader }\nexport type { SidebarMenuProps, SidebarMenuItemProps, SidebarMenuHeaderProps }\n", "type": "registry:component" } ], "type": "registry:component" }