{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "sidebar",
  "type": "registry:ui",
  "title": "Sidebar",
  "registryDependencies": [
    "https://neobrutalism.dev/r/nbutton.json",
    "https://neobrutalism.dev/r/nsheet.json",
    "https://neobrutalism.dev/r/ntooltip.json",
    "https://neobrutalism.dev/r/ninput.json",
    "https://neobrutalism.dev/r/nskeleton.json"
  ],
  "files": [
    {
      "path": "src/components/ui/sidebar.tsx",
      "content": "\"use client\"\r\n\r\nimport { useIsMobile } from \"@/hooks/use-mobile\"\r\nimport { Slot } from \"@radix-ui/react-slot\"\r\nimport { cva, VariantProps } from \"class-variance-authority\"\r\nimport { PanelLeftIcon } from \"lucide-react\"\r\n\r\nimport * as React from \"react\"\r\n\r\nimport { Button } from \"@/components/ui/button\"\r\nimport { Input } from \"@/components/ui/input\"\r\nimport {\r\n  Sheet,\r\n  SheetContent,\r\n  SheetDescription,\r\n  SheetHeader,\r\n  SheetTitle,\r\n} from \"@/components/ui/sheet\"\r\nimport { Skeleton } from \"@/components/ui/skeleton\"\r\nimport {\r\n  Tooltip,\r\n  TooltipContent,\r\n  TooltipProvider,\r\n  TooltipTrigger,\r\n} from \"@/components/ui/tooltip\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nconst SIDEBAR_COOKIE_NAME = \"sidebar_state\"\r\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\r\nconst SIDEBAR_WIDTH = \"16rem\"\r\nconst SIDEBAR_WIDTH_MOBILE = \"18rem\"\r\nconst SIDEBAR_WIDTH_ICON = \"3rem\"\r\nconst SIDEBAR_KEYBOARD_SHORTCUT = \"b\"\r\n\r\ntype SidebarContextProps = {\r\n  state: \"expanded\" | \"collapsed\"\r\n  open: boolean\r\n  setOpen: (open: boolean) => void\r\n  openMobile: boolean\r\n  setOpenMobile: (open: boolean) => void\r\n  isMobile: boolean\r\n  toggleSidebar: () => void\r\n}\r\n\r\nconst SidebarContext = React.createContext<SidebarContextProps | null>(null)\r\n\r\nfunction useSidebar() {\r\n  const context = React.useContext(SidebarContext)\r\n  if (!context) {\r\n    throw new Error(\"useSidebar must be used within a SidebarProvider.\")\r\n  }\r\n\r\n  return context\r\n}\r\n\r\nfunction SidebarProvider({\r\n  defaultOpen = true,\r\n  open: openProp,\r\n  onOpenChange: setOpenProp,\r\n  className,\r\n  style,\r\n  children,\r\n  ...props\r\n}: React.ComponentProps<\"div\"> & {\r\n  defaultOpen?: boolean\r\n  open?: boolean\r\n  onOpenChange?: (open: boolean) => void\r\n}) {\r\n  const isMobile = useIsMobile()\r\n  const [openMobile, setOpenMobile] = React.useState(false)\r\n\r\n  // This is the internal state of the sidebar.\r\n  // We use openProp and setOpenProp for control from outside the component.\r\n  const [_open, _setOpen] = React.useState(defaultOpen)\r\n  const open = openProp ?? _open\r\n  const setOpen = React.useCallback(\r\n    (value: boolean | ((value: boolean) => boolean)) => {\r\n      const openState = typeof value === \"function\" ? value(open) : value\r\n      if (setOpenProp) {\r\n        setOpenProp(openState)\r\n      } else {\r\n        _setOpen(openState)\r\n      }\r\n\r\n      // This sets the cookie to keep the sidebar state.\r\n      document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\r\n    },\r\n    [setOpenProp, open],\r\n  )\r\n\r\n  // Helper to toggle the sidebar.\r\n  const toggleSidebar = React.useCallback(() => {\r\n    return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)\r\n  }, [isMobile, setOpen, setOpenMobile])\r\n\r\n  // Adds a keyboard shortcut to toggle the sidebar.\r\n  React.useEffect(() => {\r\n    const handleKeyDown = (event: KeyboardEvent) => {\r\n      if (\r\n        event.key === SIDEBAR_KEYBOARD_SHORTCUT &&\r\n        (event.metaKey || event.ctrlKey)\r\n      ) {\r\n        event.preventDefault()\r\n        toggleSidebar()\r\n      }\r\n    }\r\n\r\n    window.addEventListener(\"keydown\", handleKeyDown)\r\n    return () => window.removeEventListener(\"keydown\", handleKeyDown)\r\n  }, [toggleSidebar])\r\n\r\n  // We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\r\n  // This makes it easier to style the sidebar with Tailwind classes.\r\n  const state = open ? \"expanded\" : \"collapsed\"\r\n\r\n  const contextValue = React.useMemo<SidebarContextProps>(\r\n    () => ({\r\n      state,\r\n      open,\r\n      setOpen,\r\n      isMobile,\r\n      openMobile,\r\n      setOpenMobile,\r\n      toggleSidebar,\r\n    }),\r\n    [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar],\r\n  )\r\n\r\n  return (\r\n    <SidebarContext.Provider value={contextValue}>\r\n      <TooltipProvider delayDuration={0}>\r\n        <div\r\n          data-slot=\"sidebar-wrapper\"\r\n          style={\r\n            {\r\n              \"--sidebar-width\": SIDEBAR_WIDTH,\r\n              \"--sidebar-width-icon\": SIDEBAR_WIDTH_ICON,\r\n              ...style,\r\n            } as React.CSSProperties\r\n          }\r\n          className={cn(\r\n            \"group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full\",\r\n            className,\r\n          )}\r\n          {...props}\r\n        >\r\n          {children}\r\n        </div>\r\n      </TooltipProvider>\r\n    </SidebarContext.Provider>\r\n  )\r\n}\r\n\r\nfunction Sidebar({\r\n  side = \"left\",\r\n  variant = \"sidebar\",\r\n  collapsible = \"offcanvas\",\r\n  className,\r\n  children,\r\n  ...props\r\n}: React.ComponentProps<\"div\"> & {\r\n  side?: \"left\" | \"right\"\r\n  variant?: \"sidebar\" | \"floating\" | \"inset\"\r\n  collapsible?: \"offcanvas\" | \"icon\" | \"none\"\r\n}) {\r\n  const { isMobile, state, openMobile, setOpenMobile } = useSidebar()\r\n\r\n  if (collapsible === \"none\") {\r\n    return (\r\n      <div\r\n        data-slot=\"sidebar\"\r\n        className={cn(\r\n          \"bg-secondary-background text-foreground flex h-full w-(--sidebar-width) flex-col\",\r\n          className,\r\n        )}\r\n        {...props}\r\n      >\r\n        {children}\r\n      </div>\r\n    )\r\n  }\r\n\r\n  if (isMobile) {\r\n    return (\r\n      <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\r\n        <SheetContent\r\n          data-sidebar=\"sidebar\"\r\n          data-slot=\"sidebar\"\r\n          data-mobile=\"true\"\r\n          className=\"bg-secondary-background text-foreground w-(--sidebar-width) p-0 [&>button]:hidden\"\r\n          style={\r\n            {\r\n              \"--sidebar-width\": SIDEBAR_WIDTH_MOBILE,\r\n            } as React.CSSProperties\r\n          }\r\n          side={side}\r\n        >\r\n          <SheetHeader className=\"sr-only\">\r\n            <SheetTitle>Sidebar</SheetTitle>\r\n            <SheetDescription>Displays the mobile sidebar.</SheetDescription>\r\n          </SheetHeader>\r\n          <div className=\"flex h-full w-full flex-col\">{children}</div>\r\n        </SheetContent>\r\n      </Sheet>\r\n    )\r\n  }\r\n\r\n  return (\r\n    <div\r\n      className=\"group peer hidden md:block\"\r\n      data-state={state}\r\n      data-collapsible={state === \"collapsed\" ? collapsible : \"\"}\r\n      data-variant={variant}\r\n      data-side={side}\r\n      data-slot=\"sidebar\"\r\n    >\r\n      {/* This is what handles the sidebar gap on desktop */}\r\n      <div\r\n        data-slot=\"sidebar-gap\"\r\n        className={cn(\r\n          \"relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear\",\r\n          \"group-data-[collapsible=offcanvas]:w-0\",\r\n          \"group-data-[side=right]:rotate-180\",\r\n          variant === \"floating\" || variant === \"inset\"\r\n            ? \"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]\"\r\n            : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon)\",\r\n        )}\r\n      />\r\n      <div\r\n        data-slot=\"sidebar-container\"\r\n        className={cn(\r\n          \"fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex\",\r\n          side === \"left\"\r\n            ? \"left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]\"\r\n            : \"right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]\",\r\n          // Adjust the padding for floating and inset variants.\r\n          variant === \"floating\" || variant === \"inset\"\r\n            ? \"p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]\"\r\n            : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r-2 border-r-border group-data-[side=right]:border-l-2 border-l-border\",\r\n          className,\r\n        )}\r\n        {...props}\r\n      >\r\n        <div\r\n          data-sidebar=\"sidebar\"\r\n          data-slot=\"sidebar-inner\"\r\n          className=\"bg-secondary-background flex h-full w-full flex-col\"\r\n        >\r\n          {children}\r\n        </div>\r\n      </div>\r\n    </div>\r\n  )\r\n}\r\n\r\nfunction SidebarTrigger({\r\n  className,\r\n  onClick,\r\n  ...props\r\n}: React.ComponentProps<typeof Button>) {\r\n  const { toggleSidebar } = useSidebar()\r\n\r\n  return (\r\n    <Button\r\n      data-sidebar=\"trigger\"\r\n      data-slot=\"sidebar-trigger\"\r\n      variant=\"noShadow\"\r\n      size=\"icon\"\r\n      className={cn(\"size-7\", className)}\r\n      onClick={(event) => {\r\n        onClick?.(event)\r\n        toggleSidebar()\r\n      }}\r\n      {...props}\r\n    >\r\n      <PanelLeftIcon />\r\n      <span className=\"sr-only\">Toggle Sidebar</span>\r\n    </Button>\r\n  )\r\n}\r\n\r\nfunction SidebarRail({ className, ...props }: React.ComponentProps<\"button\">) {\r\n  const { toggleSidebar } = useSidebar()\r\n\r\n  return (\r\n    <button\r\n      data-sidebar=\"rail\"\r\n      data-slot=\"sidebar-rail\"\r\n      aria-label=\"Toggle Sidebar\"\r\n      tabIndex={-1}\r\n      onClick={toggleSidebar}\r\n      title=\"Toggle Sidebar\"\r\n      className={cn(\r\n        \"absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex\",\r\n        \"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize\",\r\n        \"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize\",\r\n        \"hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full\",\r\n        \"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2\",\r\n        \"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nfunction SidebarInset({ className, ...props }: React.ComponentProps<\"main\">) {\r\n  return (\r\n    <main\r\n      data-slot=\"sidebar-inset\"\r\n      className={cn(\r\n        \"bg-secondary-background relative flex w-full flex-1 flex-col\",\r\n        \"md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-base md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nfunction SidebarInput({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof Input>) {\r\n  return (\r\n    <Input\r\n      data-slot=\"sidebar-input\"\r\n      data-sidebar=\"input\"\r\n      className={cn(\r\n        \"bg-secondary-background h-8 w-full shadow-none\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nfunction SidebarHeader({ className, ...props }: React.ComponentProps<\"div\">) {\r\n  return (\r\n    <div\r\n      data-slot=\"sidebar-header\"\r\n      data-sidebar=\"header\"\r\n      className={cn(\r\n        \"flex flex-col gap-2 p-2 border-b-2 border-b-border\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nfunction SidebarFooter({ className, ...props }: React.ComponentProps<\"div\">) {\r\n  return (\r\n    <div\r\n      data-slot=\"sidebar-footer\"\r\n      data-sidebar=\"footer\"\r\n      className={cn(\r\n        \"flex flex-col gap-2 p-2 border-t-2 border-t-border\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nfunction SidebarContent({ className, ...props }: React.ComponentProps<\"div\">) {\r\n  return (\r\n    <div\r\n      data-slot=\"sidebar-content\"\r\n      data-sidebar=\"content\"\r\n      className={cn(\r\n        \"flex min-h-0 flex-1 flex-col overflow-auto group-data-[collapsible=icon]:overflow-hidden\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nfunction SidebarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\r\n  return (\r\n    <div\r\n      data-slot=\"sidebar-group\"\r\n      data-sidebar=\"group\"\r\n      className={cn(\r\n        \"relative flex w-full min-w-0 flex-col p-2 border-b-2 border-b-border last:border-b-0\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nfunction SidebarGroupLabel({\r\n  className,\r\n  asChild = false,\r\n  ...props\r\n}: React.ComponentProps<\"div\"> & { asChild?: boolean }) {\r\n  const Comp = asChild ? Slot : \"div\"\r\n\r\n  return (\r\n    <Comp\r\n      data-slot=\"sidebar-group-label\"\r\n      data-sidebar=\"group-label\"\r\n      className={cn(\r\n        \"text-foreground ring-ring flex h-8 shrink-0 items-center rounded-base px-2 text-sm font-heading outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\r\n        \"group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nfunction SidebarGroupAction({\r\n  className,\r\n  asChild = false,\r\n  ...props\r\n}: React.ComponentProps<\"button\"> & { asChild?: boolean }) {\r\n  const Comp = asChild ? Slot : \"button\"\r\n\r\n  return (\r\n    <Comp\r\n      data-slot=\"sidebar-group-action\"\r\n      data-sidebar=\"group-action\"\r\n      className={cn(\r\n        \"absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-base p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\r\n        // Increases the hit area of the button on mobile.\r\n        \"after:absolute after:-inset-2 md:after:hidden\",\r\n        \"group-data-[collapsible=icon]:hidden\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nfunction SidebarGroupContent({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<\"div\">) {\r\n  return (\r\n    <div\r\n      data-slot=\"sidebar-group-content\"\r\n      data-sidebar=\"group-content\"\r\n      className={cn(\"w-full text-sm\", className)}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nfunction SidebarMenu({ className, ...props }: React.ComponentProps<\"ul\">) {\r\n  return (\r\n    <ul\r\n      data-slot=\"sidebar-menu\"\r\n      data-sidebar=\"menu\"\r\n      className={cn(\"flex w-full min-w-0 flex-col gap-1\", className)}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nfunction SidebarMenuItem({ className, ...props }: React.ComponentProps<\"li\">) {\r\n  return (\r\n    <li\r\n      data-slot=\"sidebar-menu-item\"\r\n      data-sidebar=\"menu-item\"\r\n      className={cn(\"group/menu-item relative font-base\", className)}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nconst sidebarMenuButtonVariants = cva(\r\n  \"peer/menu-button flex w-full items-center gap-2 overflow-hidden outline-2 outline-transparent rounded-base p-2 text-left text-sm ring-ring transition-[width,height,padding] hover:bg-main hover:text-main-foreground hover:outline-border focus-visible:outline-border focus-visible:text-main-foreground focus-visible:bg-main 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 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0\",\r\n  {\r\n    variants: {\r\n      size: {\r\n        default: \"h-8 text-sm\",\r\n        sm: \"h-7 text-xs\",\r\n        lg: \"h-12 text-sm group-data-[collapsible=icon]:p-0!\",\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      size: \"default\",\r\n    },\r\n  },\r\n)\r\n\r\nfunction SidebarMenuButton({\r\n  asChild = false,\r\n  isActive = false,\r\n  size = \"default\",\r\n  tooltip,\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<\"button\"> & {\r\n  asChild?: boolean\r\n  isActive?: boolean\r\n  tooltip?: string | React.ComponentProps<typeof TooltipContent>\r\n} & VariantProps<typeof sidebarMenuButtonVariants>) {\r\n  const Comp = asChild ? Slot : \"button\"\r\n  const { isMobile, state } = useSidebar()\r\n\r\n  const button = (\r\n    <Comp\r\n      data-slot=\"sidebar-menu-button\"\r\n      data-sidebar=\"menu-button\"\r\n      data-size={size}\r\n      data-active={isActive}\r\n      className={cn(sidebarMenuButtonVariants({ size }), className)}\r\n      {...props}\r\n    />\r\n  )\r\n\r\n  if (!tooltip) {\r\n    return button\r\n  }\r\n\r\n  if (typeof tooltip === \"string\") {\r\n    tooltip = {\r\n      children: tooltip,\r\n    }\r\n  }\r\n\r\n  return (\r\n    <Tooltip>\r\n      <TooltipTrigger asChild>{button}</TooltipTrigger>\r\n      <TooltipContent\r\n        side=\"right\"\r\n        align=\"center\"\r\n        hidden={state !== \"collapsed\" || isMobile}\r\n        {...tooltip}\r\n      />\r\n    </Tooltip>\r\n  )\r\n}\r\n\r\nfunction SidebarMenuAction({\r\n  className,\r\n  asChild = false,\r\n  showOnHover = false,\r\n  ...props\r\n}: React.ComponentProps<\"button\"> & {\r\n  asChild?: boolean\r\n  showOnHover?: boolean\r\n}) {\r\n  const Comp = asChild ? Slot : \"button\"\r\n\r\n  return (\r\n    <Comp\r\n      data-slot=\"sidebar-menu-action\"\r\n      data-sidebar=\"menu-action\"\r\n      className={cn(\r\n        \"[&_svg]:text-foreground hover:[&_svg]:text-main-foreground text-main-foreground hover:bg-main hover:outline-border outline-transparent outline-2 absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-base p-0 transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\r\n        // Increases the hit area of the button on mobile.\r\n        \"after:absolute after:-inset-2 md:after:hidden\",\r\n        \"peer-data-[size=sm]/menu-button:top-1\",\r\n        \"peer-data-[size=default]/menu-button:top-1.5\",\r\n        \"peer-data-[size=lg]/menu-button:top-2.5\",\r\n        \"group-data-[collapsible=icon]:hidden\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nfunction SidebarMenuBadge({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<\"div\">) {\r\n  return (\r\n    <div\r\n      data-slot=\"sidebar-menu-badge\"\r\n      data-sidebar=\"menu-badge\"\r\n      className={cn(\r\n        \"text-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-base px-1 text-xs font-base tabular-nums select-none\",\r\n        \"peer-hover/menu-button:text-main-foreground\",\r\n        \"peer-data-[size=sm]/menu-button:top-1\",\r\n        \"peer-data-[size=default]/menu-button:top-1.5\",\r\n        \"peer-data-[size=lg]/menu-button:top-2.5\",\r\n        \"group-data-[collapsible=icon]:hidden\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nfunction SidebarMenuSkeleton({\r\n  className,\r\n  showIcon = false,\r\n  ...props\r\n}: React.ComponentProps<\"div\"> & {\r\n  showIcon?: boolean\r\n}) {\r\n  // Random width between 50 to 90%.\r\n  const width = React.useMemo(() => {\r\n    return `${Math.floor(Math.random() * 40) + 50}%`\r\n  }, [])\r\n\r\n  return (\r\n    <div\r\n      data-slot=\"sidebar-menu-skeleton\"\r\n      data-sidebar=\"menu-skeleton\"\r\n      className={cn(\"flex h-8 items-center gap-2 rounded-base px-2\", className)}\r\n      {...props}\r\n    >\r\n      {showIcon && (\r\n        <Skeleton\r\n          className=\"size-4 rounded-base\"\r\n          data-sidebar=\"menu-skeleton-icon\"\r\n        />\r\n      )}\r\n      <Skeleton\r\n        className=\"h-4 max-w-(--skeleton-width) flex-1\"\r\n        data-sidebar=\"menu-skeleton-text\"\r\n        style={\r\n          {\r\n            \"--skeleton-width\": width,\r\n          } as React.CSSProperties\r\n        }\r\n      />\r\n    </div>\r\n  )\r\n}\r\n\r\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<\"ul\">) {\r\n  return (\r\n    <ul\r\n      data-slot=\"sidebar-menu-sub\"\r\n      data-sidebar=\"menu-sub\"\r\n      className={cn(\r\n        \"border-l-foreground/50 mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l-2 px-2.5 py-0.5\",\r\n        \"group-data-[collapsible=icon]:hidden\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nfunction SidebarMenuSubItem({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<\"li\">) {\r\n  return (\r\n    <li\r\n      data-slot=\"sidebar-menu-sub-item\"\r\n      data-sidebar=\"menu-sub-item\"\r\n      className={cn(\"group/menu-sub-item relative\", className)}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nfunction SidebarMenuSubButton({\r\n  asChild = false,\r\n  size = \"md\",\r\n  isActive = false,\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<\"a\"> & {\r\n  asChild?: boolean\r\n  size?: \"sm\" | \"md\"\r\n  isActive?: boolean\r\n}) {\r\n  const Comp = asChild ? Slot : \"a\"\r\n\r\n  return (\r\n    <Comp\r\n      data-slot=\"sidebar-menu-sub-button\"\r\n      data-sidebar=\"menu-sub-button\"\r\n      data-size={size}\r\n      data-active={isActive}\r\n      className={cn(\r\n        \"text-foreground hover:bg-main hover:outline-border hover:text-main-foreground  active:bg-main outline-transparent outline-2 [&>svg]:text-main-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-base px-2 focus-visible:ring-2 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\",\r\n        \"data-[active=true]:bg-main data-[active=true]:outline-border\",\r\n        size === \"sm\" && \"text-xs\",\r\n        size === \"md\" && \"text-sm\",\r\n        \"group-data-[collapsible=icon]:hidden\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  )\r\n}\r\n\r\nexport {\r\n  Sidebar,\r\n  SidebarContent,\r\n  SidebarFooter,\r\n  SidebarGroup,\r\n  SidebarGroupAction,\r\n  SidebarGroupContent,\r\n  SidebarGroupLabel,\r\n  SidebarHeader,\r\n  SidebarInput,\r\n  SidebarInset,\r\n  SidebarMenu,\r\n  SidebarMenuAction,\r\n  SidebarMenuBadge,\r\n  SidebarMenuButton,\r\n  SidebarMenuItem,\r\n  SidebarMenuSkeleton,\r\n  SidebarMenuSub,\r\n  SidebarMenuSubButton,\r\n  SidebarMenuSubItem,\r\n  SidebarProvider,\r\n  SidebarRail,\r\n  SidebarTrigger,\r\n  useSidebar,\r\n}\r\n",
      "type": "registry:ui"
    },
    {
      "path": "src/hooks/use-mobile.ts",
      "content": "import * as React from \"react\"\r\n\r\nconst MOBILE_BREAKPOINT = 768\r\n\r\nexport function useIsMobile() {\r\n  const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)\r\n\r\n  React.useEffect(() => {\r\n    const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)\r\n    const onChange = () => {\r\n      setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)\r\n    }\r\n    mql.addEventListener(\"change\", onChange)\r\n    setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)\r\n    return () => mql.removeEventListener(\"change\", onChange)\r\n  }, [])\r\n\r\n  return !!isMobile\r\n}\r\n",
      "type": "registry:hook"
    }
  ]
}