"use client"
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { type VariantProps, cva } from "class-variance-authority"
import { ChevronRight, PanelLeft } from "lucide-react"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { Separator } from "@/components/ui/separator"
import { Sheet, SheetContent } from "@/components/ui/sheet"
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
import { useSidebar } from "@/components/sidebar-provider"
const Sidebar = React.forwardRef<
HTMLDivElement,
React.ComponentProps<"div"> & {
side?: "left" | "right"
variant?: "sidebar" | "floating" | "inset"
collapsible?: "offcanvas" | "icon" | "none"
}
>(({ side = "left", variant = "sidebar", collapsible = "offcanvas", className, children, ...props }, ref) => {
const { isMobile, state, openMobile, setOpenMobile, toggleSidebar } = useSidebar()
if (collapsible === "none") {
return (
{children}
)
}
if (isMobile) {
return (
{children}
)
}
return (
{/* This is what handles the sidebar gap on desktop */}
{children}
{/* Expand indicator and clickable area when sidebar is collapsed */}
{state === "collapsed" && (
<>
{/* Wider clickable area along the entire edge */}
{/* Visual indicator */}
>
)}
)
})
Sidebar.displayName = "Sidebar"
const SidebarTrigger = React.forwardRef, React.ComponentProps>(
({ className, onClick, ...props }, ref) => {
const { toggleSidebar, state } = useSidebar()
return (
{
onClick?.(event)
toggleSidebar()
}}
{...props}
>
Toggle Sidebar
)
},
)
SidebarTrigger.displayName = "SidebarTrigger"
const SidebarHeader = React.forwardRef>(({ className, ...props }, ref) => {
return
})
SidebarHeader.displayName = "SidebarHeader"
const SidebarFooter = React.forwardRef>(({ className, ...props }, ref) => {
return
})
SidebarFooter.displayName = "SidebarFooter"
const SidebarSeparator = React.forwardRef, React.ComponentProps>(
({ className, ...props }, ref) => {
return (
)
},
)
SidebarSeparator.displayName = "SidebarSeparator"
const SidebarContent = React.forwardRef>(({ className, ...props }, ref) => {
return (
)
})
SidebarContent.displayName = "SidebarContent"
const SidebarGroup = React.forwardRef>(({ className, ...props }, ref) => {
return (
)
})
SidebarGroup.displayName = "SidebarGroup"
const SidebarGroupLabel = React.forwardRef & { asChild?: boolean }>(
({ className, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "div"
return (
svg]:size-4 [&>svg]:shrink-0",
"group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",
className,
)}
{...props}
/>
)
},
)
SidebarGroupLabel.displayName = "SidebarGroupLabel"
const SidebarGroupContent = React.forwardRef>(
({ className, ...props }, ref) => (
),
)
SidebarGroupContent.displayName = "SidebarGroupContent"
const SidebarMenu = React.forwardRef>(({ className, ...props }, ref) => (
))
SidebarMenu.displayName = "SidebarMenu"
const SidebarMenuItem = React.forwardRef>(({ className, ...props }, ref) => (
))
SidebarMenuItem.displayName = "SidebarMenuItem"
const sidebarMenuButtonVariants = cva(
"peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
{
variants: {
variant: {
default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
outline:
"bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]",
},
size: {
default: "h-8 text-sm",
sm: "h-7 text-xs",
lg: "h-12 text-sm group-data-[collapsible=icon]:!p-0",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
},
)
const SidebarMenuButton = React.forwardRef<
HTMLButtonElement,
React.ComponentProps<"button"> & {
asChild?: boolean
isActive?: boolean
tooltip?: string | React.ComponentProps
} & VariantProps
>(({ asChild = false, isActive = false, variant = "default", size = "default", tooltip, className, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
const { isMobile, state } = useSidebar()
const button = (
)
if (!tooltip) {
return button
}
if (typeof tooltip === "string") {
tooltip = {
children: tooltip,
}
}
return (
{button}
)
})
SidebarMenuButton.displayName = "SidebarMenuButton"
const SidebarInset = React.forwardRef>(({ className, ...props }, ref) => {
return (
)
})
SidebarInset.displayName = "SidebarInset"
export {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarHeader,
SidebarInset,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarSeparator,
SidebarTrigger,
}