1const e=`import * as React from "react" 2import { Slot } from "@radix-ui/react-slot" 3import { cva } from "class-variance-authority"; 4import { PanelLeft } from "lucide-react" 5 6import { useIsMobile } from "@/hooks/use-mobile" 7import { cn } from "@/lib/utils" 8import { Button } from "@/components/ui/button" 9import { Input } from "@/components/ui/input" 10import { Separator } from "@/components/ui/separator" 11import { Sheet, SheetContent } from "@/components/ui/sheet" 12import { Skeleton } from "@/components/ui/skeleton" 13import { 14 Tooltip, 15 TooltipContent, 16 TooltipProvider, 17 TooltipTrigger, 18} from "@/components/ui/tooltip" 19 20const SIDEBAR_COOKIE_NAME = "sidebar_state" 21const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7 22const SIDEBAR_WIDTH = "16rem" 23const SIDEBAR_WIDTH_MOBILE = "18rem" 24const SIDEBAR_WIDTH_ICON = "3rem" 25const SIDEBAR_KEYBOARD_SHORTCUT = "b" 26 27const SidebarContext = React.createContext(null) 28 29function useSidebar() { 30 const context = React.useContext(SidebarContext) 31 if (!context) { 32 throw new Error("useSidebar must be used within a SidebarProvider.") 33 } 34 35 return context 36} 37 38const SidebarProvider = React.forwardRef(( 39 { 40 defaultOpen = true, 41 open: openProp, 42 onOpenChange: setOpenProp, 43 className, 44 style, 45 children, 46 ...props 47 }, 48 ref 49) => { 50 const isMobile = useIsMobile() 51 const [openMobile, setOpenMobile] = React.useState(false) 52 53 // This is the internal state of the sidebar. 54 // We use openProp and setOpenProp for control from outside the component. 55 const [_open, _setOpen] = React.useState(defaultOpen) 56 const open = openProp ?? _open 57 const setOpen = React.useCallback((value) => { 58 const openState = typeof value === "function" ? value(open) : value 59 if (setOpenProp) { 60 setOpenProp(openState) 61 } else { 62 _setOpen(openState) 63 } 64 65 // This sets the cookie to keep the sidebar state. 66 document.cookie = \`\${SIDEBAR_COOKIE_NAME}=\${openState}; path=/; max-age=\${SIDEBAR_COOKIE_MAX_AGE}\` 67 }, [setOpenProp, open]) 68 69 // Helper to toggle the sidebar. 70 const toggleSidebar = React.useCallback(() => { 71 return isMobile 72 ? setOpenMobile((open) => !open) 73 : setOpen((open) => !open); 74 }, [isMobile, setOpen, setOpenMobile]) 75 76 // Adds a keyboard shortcut to toggle the sidebar. 77 React.useEffect(() => { 78 const handleKeyDown = (event) => { 79 if ( 80 event.key === SIDEBAR_KEYBOARD_SHORTCUT && 81 (event.metaKey || event.ctrlKey) 82 ) { 83 event.preventDefault() 84 toggleSidebar() 85 } 86 } 87 88 window.addEventListener("keydown", handleKeyDown) 89 return () => window.removeEventListener("keydown", handleKeyDown); 90 }, [toggleSidebar]) 91 92 // We add a state so that we can do data-state="expanded" or "collapsed". 93 // This makes it easier to style the sidebar with Tailwind classes. 94 const state = open ? "expanded" : "collapsed" 95 96 const contextValue = React.useMemo(() => ({ 97 state, 98 open, 99 setOpen, 100 isMobile, 101 openMobile, 102 setOpenMobile, 103 toggleSidebar, 104 }), [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]) 105 106 return ( 107 (<SidebarContext.Provider value={contextValue}> 108 <TooltipProvider delayDuration={0}> 109 <div 110 style={ 111 { 112 "--sidebar-width": SIDEBAR_WIDTH, 113 "--sidebar-width-icon": SIDEBAR_WIDTH_ICON, 114 ...style 115 } 116 } 117 className={cn( 118 "group/sidebar-wrapper flex min-h-svh w-full has-[[data-variant=inset]]:bg-sidebar", 119 className 120 )} 121 ref={ref} 122 {...props}> 123 {children} 124 </div> 125 </TooltipProvider> 126 </SidebarContext.Provider>) 127 ); 128}) 129SidebarProvider.displayName = "SidebarProvider" 130 131const Sidebar = React.forwardRef(( 132 { 133 side = "left", 134 variant = "sidebar", 135 collapsible = "offcanvas", 136 className, 137 children, 138 ...props 139 }, 140 ref 141) => { 142 const { isMobile, state, openMobile, setOpenMobile } = useSidebar() 143 144 if (collapsible === "none") { 145 return ( 146 (<div 147 className={cn( 148 "flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground", 149 className 150 )} 151 ref={ref} 152 {...props}> 153 {children} 154 </div>) 155 ); 156 } 157 158 if (isMobile) { 159 return ( 160 (<Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}> 161 <SheetContent 162 data-sidebar="sidebar" 163 data-mobile="true" 164 className="w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden" 165 style={ 166 { 167 "--sidebar-width": SIDEBAR_WIDTH_MOBILE 168 } 169 } 170 side={side}> 171 <div className="flex h-full w-full flex-col">{children}</div> 172 </SheetContent> 173 </Sheet>) 174 ); 175 } 176 177 return ( 178 (<div 179 ref={ref} 180 className="group peer hidden text-sidebar-foreground md:block" 181 data-state={state} 182 data-collapsible={state === "collapsed" ? collapsible : ""} 183 data-variant={variant} 184 data-side={side}> 185 {/* This is what handles the sidebar gap on desktop */} 186 <div 187 className={cn( 188 "relative h-svh w-[--sidebar-width] bg-transparent transition-[width] duration-200 ease-linear", 189 "group-data-[collapsible=offcanvas]:w-0", 190 "group-data-[side=right]:rotate-180", 191 variant === "floating" || variant === "inset" 192 ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]" 193 : "group-data-[collapsible=icon]:w-[--sidebar-width-icon]" 194 )} /> 195 <div 196 className={cn( 197 "fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] duration-200 ease-linear md:flex", 198 side === "left" 199 ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]" 200 : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]", 201 // Adjust the padding for floating and inset variants. 202 variant === "floating" || variant === "inset" 203 ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]" 204 : "group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l", 205 className 206 )} 207 {...props}> 208 <div 209 data-sidebar="sidebar" 210 className="flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow"> 211 {children} 212 </div> 213 </div> 214 </div>) 215 ); 216}) 217Sidebar.displayName = "Sidebar" 218 219const SidebarTrigger = React.forwardRef(({ className, onClick, asChild
219= false, ...props }, ref) => { 220 const { toggleSidebar } = useSidebar() 221 222 return ( 223 (<Button 224 ref={ref} 225 data-sidebar="trigger" 226 variant="ghost" 227 size="icon" 228 className={cn("h-7 w-7", className)} 229 onClick={(event) => { 230 onClick?.(event) 231 toggleSidebar() 232 }} 233 asChild={asChild} 234 {...props}> 235 {asChild ? ( 236 <PanelLeft /> 237 ) : ( 238 <> 239 <PanelLeft /> 240 <span className="sr-only">Toggle Sidebar</span> 241 </> 242 )} 243 </Button>) 244 ); 245}) 246SidebarTrigger.displayName = "SidebarTrigger" 247 248const SidebarRail = React.forwardRef(({ className, ...props }, ref) => { 249 const { toggleSidebar } = useSidebar() 250 251 return ( 252 (<button 253 ref={ref} 254 data-sidebar="rail" 255 aria-label="Toggle Sidebar" 256 tabIndex={-1} 257 onClick={toggleSidebar} 258 title="Toggle Sidebar" 259 className={cn( 260 "absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex", 261 "[[data-side=left]_&]:cursor-w-resize [[data-side=right]_&]:cursor-e-resize", 262 "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize", 263 "group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-sidebar", 264 "[[data-side=left][data-collapsible=offcanvas]_&]:-right-2", 265 "[[data-side=right][data-collapsible=offcanvas]_&]:-left-2", 266 className 267 )} 268 {...props} />) 269 ); 270}) 271SidebarRail.displayName = "SidebarRail" 272 273const SidebarInset = React.forwardRef(({ className, ...props }, ref) => { 274 return ( 275 (<main 276 ref={ref} 277 className={cn( 278 "relative flex min-h-svh flex-1 flex-col bg-background", 279 "peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow", 280 className 281 )} 282 {...props} />) 283 ); 284}) 285SidebarInset.displayName = "SidebarInset" 286 287const SidebarInput = React.forwardRef(({ className, ...props }, ref) => { 288 return ( 289 (<Input 290 ref={ref} 291 data-sidebar="input" 292 className={cn( 293 "h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring", 294 className 295 )} 296 {...props} />) 297 ); 298}) 299SidebarInput.displayName = "SidebarInput" 300 301const SidebarHeader = React.forwardRef(({ className, ...props }, ref) => { 302 return ( 303 (<div 304 ref={ref} 305 data-sidebar="header" 306 className={cn("flex flex-col gap-2 p-2", className)} 307 {...props} />) 308 ); 309}) 310SidebarHeader.displayName = "SidebarHeader" 311 312const SidebarFooter = React.forwardRef(({ className, ...props }, ref) => { 313 return ( 314 (<div 315 ref={ref} 316 data-sidebar="footer" 317 className={cn("flex flex-col gap-2 p-2", className)} 318 {...props} />) 319 ); 320}) 321SidebarFooter.displayName = "SidebarFooter" 322 323const SidebarSeparator = React.forwardRef(({ className, ...props }, ref) => { 324 return ( 325 (<Separator 326 ref={ref} 327 data-sidebar="separator" 328 className={cn("mx-2 w-auto bg-sidebar-border", className)} 329 {...props} />) 330 ); 331}) 332SidebarSeparator.displayName = "SidebarSeparator" 333 334const SidebarContent = React.forwardRef(({ className, ...props }, ref) => { 335 return ( 336 (<div 337 ref={ref} 338 data-sidebar="content" 339 className={cn( 340 "flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden", 341 className 342 )} 343 {...props} />) 344 ); 345}) 346SidebarContent.displayName = "SidebarContent" 347 348const SidebarGroup = React.forwardRef(({ className, ...props }, ref) => { 349 return ( 350 (<div 351 ref={ref} 352 data-sidebar="group" 353 className={cn("relative flex w-full min-w-0 flex-col p-2", className)} 354 {...props} />) 355 ); 356}) 357SidebarGroup.displayName = "SidebarGroup" 358 359const SidebarGroupLabel = React.forwardRef(({ className, asChild
359= false, ...props }, ref) => { 360 const Comp = asChild ? Slot : "div" 361 362 return ( 363 (<Comp 364 ref={ref} 365 data-sidebar="group-label" 366 className={cn( 367 "flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0", 368 "group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0", 369 className 370 )} 371 {...props} />) 372 ); 373}) 374SidebarGroupLabel.displayName = "SidebarGroupLabel" 375 376const SidebarGroupAction = React.forwardRef(({ className, asChild = false, ...props }, ref) => { 377 const Comp = asChild ? Slot : "button" 378 379 return ( 380 (<Comp 381 ref={ref} 382 data-sidebar="group-action" 383 className={cn( 384 "absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0", 385 // Increases the hit area of the button on mobile. 386 "after:absolute after:-inset-2 after:md:hidden", 387 "group-data-[collapsible=icon]:hidden", 388 className 389 )} 390 {...props} />) 391 ); 392}) 393SidebarGroupAction.displayName = "SidebarGroupAction" 394 395const SidebarGroupContent = React.forwardRef(({ className, ...props }, ref) => ( 396 <div 397 ref={ref} 398 data-sidebar="group-content" 399 className={cn("w-full text-sm", className)} 400 {...props} /> 401)) 402SidebarGroupContent.displayName = "SidebarGroupContent" 403 404const SidebarMenu = React.forwardRef(({ className, ...props }, ref) => ( 405 <ul 406 ref={ref} 407 data-sidebar="menu" 408 className={cn("flex w-full min-w-0 flex-col gap-1", className)} 409 {...props} /> 410)) 411SidebarMenu.displayName = "SidebarMenu" 412 413const SidebarMenuItem = React.forwardRef(({ className, ...props }, ref) => ( 414 <li 415 ref={ref} 416 data-sidebar="menu-item" 417 className={cn("group/menu-item relative", className)} 418 {...props} /> 419)) 420SidebarMenuItem.displayName = "SidebarMenuItem" 421 422const sidebarMenuButtonVariants = cva( 423 "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", 424 { 425 variants: { 426 variant: { 427 default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground", 428 outline: 429 "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))]", 430 }, 431 size: { 432 default: "h-8 text-sm", 433 sm: "h-7 text-xs", 434 lg: "h-12 text-sm group-data-[collapsible=icon]:!p-0", 435 }, 436 }, 437 defaultVariants: { 438 variant: "default", 439 size: "default", 440 }, 441 } 442) 443 444const SidebarMenuButton = React.forwardRef(( 445 { 446 asChild = false, 447 isActive = false, 448 variant = "default", 449 size = "default", 450 tooltip, 451 className, 452 ...props 453 }, 454 ref 455) => { 456 const Comp = asChild ? Slot : "button" 457 const { isMobile, state } = useSidebar() 458 459 const button = ( 460 <Comp 461 ref={ref} 462 data-sidebar="menu-button" 463 data-size={size} 464 data-active={isActive} 465 className={cn(sidebarMenuButtonVariants({ variant, size }), className)} 466 {...props} /> 467 ) 468 469 if (!tooltip) { 470 return button 471 } 472 473 if (typeof tooltip === "string") { 474 tooltip = { 475 children: tooltip, 476 } 477 } 478 479 return ( 480 (<Tooltip> 481 <TooltipTrigger asChild>{button}</TooltipTrigger> 482 <TooltipContent 483 side="right" 484 align="center" 485 hidden={state !== "collapsed" || isMobile} 486 {...tooltip} /> 487 </Tooltip>) 488 ); 489}) 490SidebarMenuButton.displayName = "SidebarMenuButton" 491 492const SidebarMenuAction = React.forwardRef(({ className, asChild
492= false, showOnHover = false, ...props }, ref) => { 493 const Comp = asChild ? Slot : "button" 494 495 return ( 496 (<Comp 497 ref={ref} 498 data-sidebar="menu-action" 499 className={cn( 500 "absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0", 501 // Increases the hit area of the button on mobile. 502 "after:absolute after:-inset-2 after:md:hidden", 503 "peer-data-[size=sm]/menu-button:top-1", 504 "peer-data-[size=default]/menu-button:top-1.5", 505 "peer-data-[size=lg]/menu-button:top-2.5", 506 "group-data-[collapsible=icon]:hidden", 507 showOnHover && 508 "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0", 509 className 510 )} 511 {...props} />) 512 ); 513}) 514SidebarMenuAction.displayName = "SidebarMenuAction" 515 516const SidebarMenuBadge = React.forwardRef(({ className, ...props }, ref) => ( 517 <div 518 ref={ref} 519 data-sidebar="menu-badge" 520 className={cn( 521 "pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-sidebar-foreground", 522 "peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground", 523 "peer-data-[size=sm]/menu-button:top-1", 524 "peer-data-[size=default]/menu-button:top-1.5", 525 "peer-data-[size=lg]/menu-button:top-2.5", 526 "group-data-[collapsible=icon]:hidden", 527 className 528 )} 529 {...props} /> 530)) 531SidebarMenuBadge.displayName = "SidebarMenuBadge" 532 533const SidebarMenuSkeleton = React.forwardRef(({ className, showIcon = false, ...props }, ref) => { 534 // Random width between 50 to 90%. 535 const width = React.useMemo(() => { 536 return \`\${Math.floor(Math.random() * 40) + 50}%\`; 537 }, []) 538 539 return ( 540 (<div 541 ref={ref} 542 data-sidebar="menu-skeleton" 543 className={cn("flex h-8 items-center gap-2 rounded-md px-2", className)} 544 {...props}> 545 {showIcon && ( 546 <Skeleton className="size-4 rounded-md" data-sidebar="menu-skeleton-icon" /> 547 )} 548 <Skeleton 549 className="h-4 max-w-[--skeleton-width] flex-1" 550 data-sidebar="menu-skeleton-text" 551 style={ 552 { 553 "--skeleton-width": width 554 } 555 } /> 556 </div>) 557 ); 558}) 559SidebarMenuSkeleton.displayName = "SidebarMenuSkeleton" 560 561const SidebarMenuSub = React.forwardRef(({ className, ...props }, ref) => ( 562 <ul 563 ref={ref} 564 data-sidebar="menu-sub" 565 className={cn( 566 "mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5", 567 "group-data-[collapsible=icon]:hidden", 568 className 569 )} 570 {...props} /> 571)) 572SidebarMenuSub.displayName = "SidebarMenuSub" 573 574const SidebarMenuSubItem = React.forwardRef(({ ...props }, ref) => <li ref={ref} {...props} />) 575SidebarMenuSubItem.displayName = "SidebarMenuSubItem" 576 577const SidebarMenuSubButton = React.forwardRef( 578 ({ asChild = false, size = "md", isActive, className, ...props }, ref) => { 579 const Comp = asChild ? Slot : "a" 580 581 return ( 582 (<Comp 583 ref={ref} 584 data-sidebar="menu-sub-button" 585 data-size={size} 586 data-active={isActive} 587 className={cn( 588 "flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-none ring-sidebar-ring 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 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground", 589 "data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground", 590 size === "sm" && "text-xs", 591 size === "md" && "text-sm", 592 "group-data-[collapsible=icon]:hidden", 593 className 594 )} 595 {...props} />) 596 ); 597 } 598) 599SidebarMenuSubButton.displayName = "SidebarMenuSubButton" 600 601export { 602 Sidebar, 603 SidebarContent, 604 SidebarFooter, 605 SidebarGroup, 606 SidebarGroupAction, 607 SidebarGroupContent, 608 SidebarGroupLabel, 609 SidebarHeader, 610 SidebarInput, 611 SidebarInset, 612 SidebarMenu, 613 SidebarMenuAction, 614 SidebarMenuBadge, 615 SidebarMenuButton, 616 SidebarMenuItem, 617 SidebarMenuSkeleton, 618 SidebarMenuSub, 619 SidebarMenuSubButton, 620 SidebarMenuSubItem, 621 SidebarProvider, 622 SidebarRail, 623 SidebarSeparator, 624 SidebarTrigger, 625 useSidebar, 626} 627`;export{e as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.