{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "sidebar-glass",
"type": "registry:ui",
"title": "Sidebar Glass",
"description": "SidebarGlass Core Components",
"dependencies": [
"@radix-ui/react-slot",
"lucide-react"
],
"registryDependencies": [
"cn"
],
"files": [
{
"path": "components/glass/ui/sidebar-glass.tsx",
"type": "registry:component",
"content": "/**\n * SidebarGlass Core Components\n *\n * Layout components for building sidebars with glassmorphism effects.\n * **100% API compatible with shadcn/ui Sidebar.**\n *\n * ## Features\n * - shadcn/ui Sidebar API compatibility\n * - Theme-aware glassmorphism styling (glass/light/aurora)\n * - Compound component API (13+ sub-components)\n * - Three collapsible modes: offcanvas, icon, none\n * - Three variants: sidebar (default), floating, inset\n * - Left/right side positioning\n * - Mobile drawer (automatic ModalGlass integration)\n * - Keyboard shortcut (Cmd/Ctrl + B to toggle)\n * - Cookie persistence for open/closed state\n * - Nested submenu support\n * - Loading skeletons\n * - Badge notifications\n *\n * ## CSS Variables\n * - `--sidebar-width` - Desktop width (default: `16rem`)\n * - `--sidebar-width-mobile` - Mobile drawer width (default: `18rem`)\n * - `--sidebar-width-icon` - Icon mode width (default: `3rem`)\n * - `--sidebar-bg` - Background color\n * - `--sidebar-border` - Border color\n * - `--sidebar-primary` - Primary accent color\n * - `--sidebar-primary-foreground` - Primary text color\n * - `--sidebar-accent` - Hover background\n * - `--sidebar-accent-foreground` - Hover text color\n * - `--sidebar-ring` - Focus ring color\n * - `--sidebar-glow` - Box shadow with glow effect\n * - `--sidebar-backdrop-blur` - Backdrop blur amount\n * - `--sidebar-foreground` - Text color\n *\n * @since v1.0.0\n * @module sidebar-glass\n */\n\nimport {\n forwardRef,\n type ReactNode,\n type CSSProperties,\n type ComponentPropsWithoutRef,\n} from 'react';\nimport { PanelLeft } from 'lucide-react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cn } from '@/lib/utils';\nimport {\n useSidebar,\n type SidebarSide,\n type SidebarVariant,\n type SidebarCollapsible,\n} from './sidebar-context';\nimport { ModalGlass } from '@/components/glass/ui/modal-glass';\nimport '@/glass-theme.css';\n\n// ========================================\n// SIDEBAR ROOT\n// ========================================\n\nexport interface SidebarRootProps extends ComponentPropsWithoutRef<'aside'> {\n children: ReactNode;\n /** Override side from provider */\n side?: SidebarSide;\n /** Override variant from provider */\n variant?: SidebarVariant;\n /** Override collapsible from provider */\n collapsible?: SidebarCollapsible;\n}\n\n/**\n * SidebarGlass.Root - Main sidebar container\n *\n * @example\n * ```tsx\n * \n * \n * ...\n * \n * \n * ```\n */\nexport const SidebarRoot = forwardRef(\n (\n {\n children,\n side: sideProp,\n variant: variantProp,\n collapsible: collapsibleProp,\n className,\n ...props\n },\n ref\n ) => {\n const context = useSidebar();\n const side = sideProp ?? context.side;\n const variant = variantProp ?? context.variant;\n const collapsible = collapsibleProp ?? context.collapsible;\n const { state, open, openMobile, isMobile, setOpenMobile } = context;\n\n // Mobile: render as Sheet/Drawer\n if (isMobile) {\n return (\n \n \n \n \n );\n }\n\n // Desktop: collapsible sidebar\n const isCollapsed = !open && collapsible !== 'none';\n const width =\n isCollapsed && collapsible === 'icon' ? 'var(--sidebar-width-icon)' : 'var(--sidebar-width)';\n\n return (\n \n );\n }\n);\n\nSidebarRoot.displayName = 'SidebarGlass.Root';\n\n// ========================================\n// SIDEBAR HEADER\n// ========================================\n\nexport interface SidebarHeaderProps extends ComponentPropsWithoutRef<'div'> {\n children: ReactNode;\n}\n\n/**\n * SidebarGlass.Header - Sticky header section\n */\nexport const SidebarHeader = forwardRef(\n ({ children, className, ...props }, ref) => {\n return (\n \n {children}\n
\n );\n }\n);\n\nSidebarHeader.displayName = 'SidebarGlass.Header';\n\n// ========================================\n// SIDEBAR CONTENT\n// ========================================\n\nexport interface SidebarContentProps extends ComponentPropsWithoutRef<'div'> {\n children: ReactNode;\n}\n\n/**\n * SidebarGlass.Content - Scrollable content area\n */\nexport const SidebarContent = forwardRef(\n ({ children, className, ...props }, ref) => {\n return (\n \n {children}\n
\n );\n }\n);\n\nSidebarContent.displayName = 'SidebarGlass.Content';\n\n// ========================================\n// SIDEBAR FOOTER\n// ========================================\n\nexport interface SidebarFooterProps extends ComponentPropsWithoutRef<'div'> {\n children: ReactNode;\n}\n\n/**\n * SidebarGlass.Footer - Sticky footer section\n */\nexport const SidebarFooter = forwardRef(\n ({ children, className, ...props }, ref) => {\n return (\n \n {children}\n
\n );\n }\n);\n\nSidebarFooter.displayName = 'SidebarGlass.Footer';\n\n// ========================================\n// SIDEBAR RAIL\n// ========================================\n\nexport type SidebarRailProps = ComponentPropsWithoutRef<'button'>;\n\n/**\n * SidebarGlass.Rail - Interactive rail for toggling sidebar\n *\n * Shows on hover and allows click to toggle collapsed/expanded state.\n */\nexport const SidebarRail = forwardRef(\n ({ className, ...props }, ref) => {\n const { toggleSidebar, side } = useSidebar();\n\n return (\n \n );\n }\n);\n\nSidebarRail.displayName = 'SidebarGlass.Rail';\n\n// ========================================\n// SIDEBAR INSET\n// ========================================\n\nexport interface SidebarInsetProps extends ComponentPropsWithoutRef<'main'> {\n children: ReactNode;\n}\n\n/**\n * SidebarGlass.Inset - Main content area next to sidebar\n *\n * Use this for the main content that sits beside the sidebar.\n */\nexport const SidebarInset = forwardRef(\n ({ children, className, ...props }, ref) => {\n return (\n \n {children}\n \n );\n }\n);\n\nSidebarInset.displayName = 'SidebarGlass.Inset';\n\n// ========================================\n// SIDEBAR TRIGGER\n// ========================================\n\nexport interface SidebarTriggerProps extends ComponentPropsWithoutRef<'button'> {\n /** Render as child element */\n asChild?: boolean;\n}\n\n/**\n * SidebarGlass.Trigger - Toggle button for sidebar\n *\n * @example\n * ```tsx\n * // Default button\n * \n *\n * // Custom trigger\n * \n * \n * \n * \n * \n * ```\n */\nexport const SidebarTrigger = forwardRef(\n ({ asChild = false, className, children, ...props }, ref) => {\n const { toggleSidebar } = useSidebar();\n\n const Comp = asChild ? Slot : 'button';\n\n return (\n \n {children ?? }\n {!children && Toggle Sidebar}\n \n );\n }\n);\n\nSidebarTrigger.displayName = 'SidebarGlass.Trigger';\n\n// ========================================\n// SIDEBAR SEPARATOR\n// ========================================\n\nexport type SidebarSeparatorProps = ComponentPropsWithoutRef<'hr'>;\n\n/**\n * SidebarGlass.Separator - Visual divider\n */\nexport const SidebarSeparator = forwardRef(\n ({ className, ...props }, ref) => {\n return (\n
\n );\n }\n);\n\nSidebarSeparator.displayName = 'SidebarGlass.Separator';\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"
}
}
}