{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "sidebar-03",
  "type": "registry:block",
  "title": "Sidebar Dashboard Floating",
  "description": "A sidebar dashboard floating block.",
  "author": "ephraim duncan <https://ephraimduncan.com>",
  "registryDependencies": [
    "avatar",
    "button",
    "collapsible",
    "dropdown-menu",
    "sidebar"
  ],
  "dependencies": [
    "framer-motion",
    "lucide-react"
  ],
  "files": [
    {
      "path": "content/components/sidebar/sidebar-03/logo.tsx",
      "type": "registry:component",
      "target": "components/sidebar-03/logo.tsx",
      "content": "import type { SVGProps } from 'react';\n\nexport const Logo = (props: SVGProps<SVGSVGElement>) => (\n  <svg\n    fill=\"currentColor\"\n    height=\"48\"\n    viewBox=\"0 0 40 48\"\n    width=\"40\"\n    {...props}\n  >\n    <title>Logo</title>\n    <clipPath id=\"a\">\n      <path d=\"m0 0h40v48h-40z\" />\n    </clipPath>\n    <g clipPath=\"url(#a)\">\n      <path d=\"m25.0887 5.05386-3.933-1.05386-3.3145 12.3696-2.9923-11.16736-3.9331 1.05386 3.233 12.0655-8.05262-8.0526-2.87919 2.8792 8.83271 8.8328-10.99975-2.9474-1.05385625 3.933 12.01860625 3.2204c-.1376-.5935-.2104-1.2119-.2104-1.8473 0-4.4976 3.646-8.1436 8.1437-8.1436 4.4976 0 8.1436 3.646 8.1436 8.1436 0 .6313-.0719 1.2459-.2078 1.8359l10.9227 2.9267 1.0538-3.933-12.0664-3.2332 11.0005-2.9476-1.0539-3.933-12.0659 3.233 8.0526-8.0526-2.8792-2.87916-8.7102 8.71026z\" />\n      <path d=\"m27.8723 26.2214c-.3372 1.4256-1.0491 2.7063-2.0259 3.7324l7.913 7.9131 2.8792-2.8792z\" />\n      <path d=\"m25.7665 30.0366c-.9886 1.0097-2.2379 1.7632-3.6389 2.1515l2.8794 10.746 3.933-1.0539z\" />\n      <path d=\"m21.9807 32.2274c-.65.1671-1.3313.2559-2.0334.2559-.7522 0-1.4806-.102-2.1721-.2929l-2.882 10.7558 3.933 1.0538z\" />\n      <path d=\"m17.6361 32.1507c-1.3796-.4076-2.6067-1.1707-3.5751-2.1833l-7.9325 7.9325 2.87919 2.8792z\" />\n      <path d=\"m13.9956 29.8973c-.9518-1.019-1.6451-2.2826-1.9751-3.6862l-10.95836 2.9363 1.05385 3.933z\" />\n    </g>\n  </svg>\n);\n"
    },
    {
      "path": "content/components/sidebar/sidebar-03/app-sidebar.tsx",
      "type": "registry:component",
      "target": "components/sidebar-03/app-sidebar.tsx",
      "content": "'use client';\n\nimport { motion } from 'framer-motion';\nimport {\n  Activity,\n  DollarSign,\n  Home,\n  Infinity,\n  LinkIcon,\n  Package2,\n  Percent,\n  PieChart,\n  Settings,\n  ShoppingBag,\n  Sparkles,\n  Store,\n  TrendingUp,\n  Users,\n} from 'lucide-react';\nimport {\n  Sidebar,\n  SidebarContent,\n  SidebarFooter,\n  SidebarHeader,\n  SidebarTrigger,\n  useSidebar,\n} from '@/components/ui/sidebar';\nimport { cn } from '@/lib/utils';\nimport { Logo } from '@/components/sidebar-03/logo';\nimport type { Route } from '@/components/sidebar-03/nav-main';\nimport DashboardNavigation from '@/components/sidebar-03/nav-main';\nimport { NotificationsPopover } from '@/components/sidebar-03/nav-notifications';\nimport { TeamSwitcher } from '@/components/sidebar-03/team-switcher';\n\nconst sampleNotifications = [\n  {\n    id: '1',\n    avatar: '/avatars/01.png',\n    fallback: 'OM',\n    text: 'New order received.',\n    time: '10m ago',\n  },\n  {\n    id: '2',\n    avatar: '/avatars/02.png',\n    fallback: 'JL',\n    text: 'Server upgrade completed.',\n    time: '1h ago',\n  },\n  {\n    id: '3',\n    avatar: '/avatars/03.png',\n    fallback: 'HH',\n    text: 'New user signed up.',\n    time: '2h ago',\n  },\n];\n\nconst dashboardRoutes: Route[] = [\n  {\n    id: 'home',\n    title: 'Home',\n    icon: <Home className=\"size-4\" />,\n    link: '#',\n  },\n  {\n    id: 'products',\n    title: 'Products',\n    icon: <Package2 className=\"size-4\" />,\n    link: '#',\n    subs: [\n      {\n        title: 'Catalogue',\n        link: '#',\n        icon: <Package2 className=\"size-4\" />,\n      },\n      {\n        title: 'Checkout Links',\n        link: '#',\n        icon: <LinkIcon className=\"size-4\" />,\n      },\n      {\n        title: 'Discounts',\n        link: '#',\n        icon: <Percent className=\"size-4\" />,\n      },\n    ],\n  },\n  {\n    id: 'usage-billing',\n    title: 'Usage Billing',\n    icon: <PieChart className=\"size-4\" />,\n    link: '#',\n    subs: [\n      {\n        title: 'Meters',\n        link: '#',\n        icon: <PieChart className=\"size-4\" />,\n      },\n      {\n        title: 'Events',\n        link: '#',\n        icon: <Activity className=\"size-4\" />,\n      },\n    ],\n  },\n  {\n    id: 'benefits',\n    title: 'Benefits',\n    icon: <Sparkles className=\"size-4\" />,\n    link: '#',\n  },\n  {\n    id: 'customers',\n    title: 'Customers',\n    icon: <Users className=\"size-4\" />,\n    link: '#',\n  },\n  {\n    id: 'sales',\n    title: 'Sales',\n    icon: <ShoppingBag className=\"size-4\" />,\n    link: '#',\n    subs: [\n      {\n        title: 'Orders',\n        link: '#',\n        icon: <ShoppingBag className=\"size-4\" />,\n      },\n      {\n        title: 'Subscriptions',\n        link: '#',\n        icon: <Infinity className=\"size-4\" />,\n      },\n    ],\n  },\n  {\n    id: 'storefront',\n    title: 'Storefront',\n    icon: <Store className=\"size-4\" />,\n    link: '#',\n  },\n  {\n    id: 'analytics',\n    title: 'Analytics',\n    icon: <TrendingUp className=\"size-4\" />,\n    link: '#',\n  },\n  {\n    id: 'finance',\n    title: 'Finance',\n    icon: <DollarSign className=\"size-4\" />,\n    link: '#',\n    subs: [\n      { title: 'Incoming', link: '#' },\n      { title: 'Outgoing', link: '#' },\n      { title: 'Payout Account', link: '#' },\n    ],\n  },\n  {\n    id: 'settings',\n    title: 'Settings',\n    icon: <Settings className=\"size-4\" />,\n    link: '#',\n    subs: [\n      { title: 'General', link: '#' },\n      { title: 'Webhooks', link: '#' },\n      { title: 'Custom Fields', link: '#' },\n    ],\n  },\n];\n\nconst teams = [\n  { id: '1', name: 'Alpha Inc.', logo: Logo, plan: 'Free' },\n  { id: '2', name: 'Beta Corp.', logo: Logo, plan: 'Free' },\n  { id: '3', name: 'Gamma Tech', logo: Logo, plan: 'Free' },\n];\n\nexport function DashboardSidebar() {\n  const { state } = useSidebar();\n  const isCollapsed = state === 'collapsed';\n\n  return (\n    <Sidebar collapsible=\"icon\" variant=\"floating\">\n      <SidebarHeader\n        className={cn(\n          'flex md:pt-3.5',\n          isCollapsed\n            ? 'flex-row items-center justify-between gap-y-4 md:flex-col md:items-start md:justify-start'\n            : 'flex-row items-center justify-between'\n        )}\n      >\n        <a className=\"flex items-center gap-2\" href=\"#\">\n          <Logo className=\"h-8 w-8\" />\n          {!isCollapsed && (\n            <span className=\"font-semibold text-black dark:text-white\">\n              Acme\n            </span>\n          )}\n        </a>\n\n        <motion.div\n          animate={{ opacity: 1 }}\n          className={cn(\n            'flex items-center gap-2',\n            isCollapsed ? 'flex-row md:flex-col-reverse' : 'flex-row'\n          )}\n          initial={{ opacity: 0 }}\n          key={isCollapsed ? 'header-collapsed' : 'header-expanded'}\n          transition={{ duration: 0.8 }}\n        >\n          <NotificationsPopover notifications={sampleNotifications} />\n          <SidebarTrigger />\n        </motion.div>\n      </SidebarHeader>\n      <SidebarContent className=\"gap-4 px-2 py-4\">\n        <DashboardNavigation routes={dashboardRoutes} />\n      </SidebarContent>\n      <SidebarFooter className=\"px-2\">\n        <TeamSwitcher teams={teams} />\n      </SidebarFooter>\n    </Sidebar>\n  );\n}\n"
    },
    {
      "path": "content/components/sidebar/sidebar-03/team-switcher.tsx",
      "type": "registry:component",
      "target": "components/sidebar-03/team-switcher.tsx",
      "content": "'use client';\n\nimport { ChevronsUpDown, Plus } from 'lucide-react';\nimport * as React from 'react';\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\nimport {\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  useSidebar,\n} from '@/components/ui/sidebar';\n\ntype Team = {\n  name: string;\n  logo: React.ElementType;\n  plan: string;\n};\n\nexport function TeamSwitcher({ teams }: { teams: Team[] }) {\n  const { isMobile } = useSidebar();\n  const [activeTeam, setActiveTeam] = React.useState(teams[0]);\n\n  if (!activeTeam) return null;\n\n  const Logo = activeTeam.logo;\n\n  return (\n    <SidebarMenu>\n      <SidebarMenuItem>\n        <DropdownMenu>\n          <DropdownMenuTrigger\n            render={\n              <SidebarMenuButton\n                className=\"data-popup-open:bg-sidebar-accent data-popup-open:text-sidebar-accent-foreground\"\n                size=\"lg\"\n              />\n            }\n          >\n            <div className=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-background text-foreground\">\n              <Logo className=\"size-4\" />\n            </div>\n            <div className=\"grid flex-1 text-left text-sm leading-tight\">\n              <span className=\"truncate font-semibold\">{activeTeam.name}</span>\n              <span className=\"truncate text-xs\">{activeTeam.plan}</span>\n            </div>\n            <ChevronsUpDown className=\"ml-auto\" />\n          </DropdownMenuTrigger>\n          <DropdownMenuContent\n            align=\"start\"\n            className=\"mb-4 w-(--anchor-width) min-w-56 rounded-lg\"\n            side={isMobile ? 'bottom' : 'right'}\n            sideOffset={4}\n          >\n            <DropdownMenuLabel className=\"text-muted-foreground text-xs\">\n              Teams\n            </DropdownMenuLabel>\n            {teams.map((team, index) => (\n              <DropdownMenuItem\n                className=\"gap-2 p-2\"\n                key={team.name}\n                onClick={() => setActiveTeam(team)}\n              >\n                <div className=\"flex size-6 items-center justify-center rounded-sm border\">\n                  <team.logo className=\"size-4 shrink-0\" />\n                </div>\n                {team.name}\n                <DropdownMenuShortcut>⌘{index + 1}</DropdownMenuShortcut>\n              </DropdownMenuItem>\n            ))}\n            <DropdownMenuSeparator />\n            <DropdownMenuItem className=\"gap-2 p-2\">\n              <div className=\"flex size-6 items-center justify-center rounded-md border bg-background\">\n                <Plus className=\"size-4\" />\n              </div>\n              <div className=\"font-medium text-muted-foreground\">Add team</div>\n            </DropdownMenuItem>\n          </DropdownMenuContent>\n        </DropdownMenu>\n      </SidebarMenuItem>\n    </SidebarMenu>\n  );\n}\n"
    },
    {
      "path": "content/components/sidebar/sidebar-03/nav-notifications.tsx",
      "type": "registry:component",
      "target": "components/sidebar-03/nav-notifications.tsx",
      "content": "'use client';\n\nimport { BellIcon } from 'lucide-react';\nimport { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';\nimport { Button } from '@/components/ui/button';\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\n\ntype Notification = {\n  id: string;\n  avatar: string;\n  fallback: string;\n  text: string;\n  time: string;\n};\n\nexport function NotificationsPopover({\n  notifications,\n}: {\n  notifications: Notification[];\n}) {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger\n        render={\n          <Button\n            aria-label=\"Open notifications\"\n            className=\"rounded-full\"\n            size=\"icon\"\n            variant=\"ghost\"\n          />\n        }\n      >\n        <BellIcon className=\"size-5\" />\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"my-6 w-80\" side=\"right\">\n        <DropdownMenuLabel>Notifications</DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        {notifications.map(({ id, avatar, fallback, text, time }) => (\n          <DropdownMenuItem className=\"flex items-start gap-3\" key={id}>\n            <Avatar className=\"size-8\">\n              <AvatarImage alt=\"Avatar\" src={avatar} />\n              <AvatarFallback>{fallback}</AvatarFallback>\n            </Avatar>\n            <div className=\"flex flex-col\">\n              <span className=\"font-medium text-sm\">{text}</span>\n              <span className=\"text-muted-foreground text-xs\">{time}</span>\n            </div>\n          </DropdownMenuItem>\n        ))}\n        <DropdownMenuSeparator />\n        <DropdownMenuItem className=\"justify-center text-muted-foreground text-sm hover:text-primary\">\n          View all notifications\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  );\n}\n"
    },
    {
      "path": "content/components/sidebar/sidebar-03/index.tsx",
      "type": "registry:component",
      "target": "components/sidebar-03/index.tsx",
      "content": "import { SidebarInset, SidebarProvider } from '@/components/ui/sidebar';\nimport { DashboardSidebar } from '@/components/sidebar-03/app-sidebar';\n\nexport default function Sidebar03() {\n  return (\n    <SidebarProvider>\n      <div className=\"relative flex h-dvh w-full\">\n        <DashboardSidebar />\n        <SidebarInset className=\"flex flex-col\" />\n      </div>\n    </SidebarProvider>\n  );\n}\n"
    },
    {
      "path": "content/components/sidebar/sidebar-03/nav-main.tsx",
      "type": "registry:component",
      "target": "components/sidebar-03/nav-main.tsx",
      "content": "'use client';\n\nimport { ChevronDown, ChevronUp } from 'lucide-react';\nimport Link from 'next/link';\nimport type React from 'react';\nimport { useState } from 'react';\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from '@/components/ui/collapsible';\nimport {\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  SidebarMenuSub,\n  SidebarMenuSubButton,\n  SidebarMenuItem as SidebarMenuSubItem,\n  useSidebar,\n} from '@/components/ui/sidebar';\nimport { cn } from '@/lib/utils';\n\nexport type Route = {\n  id: string;\n  title: string;\n  icon?: React.ReactNode;\n  link: string;\n  subs?: {\n    title: string;\n    link: string;\n    icon?: React.ReactNode;\n  }[];\n};\n\nexport default function DashboardNavigation({ routes }: { routes: Route[] }) {\n  const { state } = useSidebar();\n  const isCollapsed = state === 'collapsed';\n  const [openCollapsible, setOpenCollapsible] = useState<string | null>(null);\n\n  return (\n    <SidebarMenu>\n      {routes.map((route) => {\n        const isOpen = !isCollapsed && openCollapsible === route.id;\n        const hasSubRoutes = !!route.subs?.length;\n\n        return (\n          <SidebarMenuItem key={route.id}>\n            {hasSubRoutes ? (\n              <Collapsible\n                className=\"w-full\"\n                onOpenChange={(open) =>\n                  setOpenCollapsible(open ? route.id : null)\n                }\n                open={isOpen}\n              >\n                <CollapsibleTrigger\n                  render={\n                    <SidebarMenuButton\n                      className={cn(\n                        'flex w-full items-center rounded-lg px-2 transition-colors',\n                        isOpen\n                          ? 'bg-sidebar-muted text-foreground'\n                          : 'text-muted-foreground hover:bg-sidebar-muted hover:text-foreground',\n                        isCollapsed && 'justify-center'\n                      )}\n                    />\n                  }\n                >\n                  {route.icon}\n                  {!isCollapsed && (\n                    <span className=\"ml-2 flex-1 font-medium text-sm\">\n                      {route.title}\n                    </span>\n                  )}\n                  {!isCollapsed && hasSubRoutes && (\n                    <span className=\"ml-auto\">\n                      {isOpen ? (\n                        <ChevronUp className=\"size-4\" />\n                      ) : (\n                        <ChevronDown className=\"size-4\" />\n                      )}\n                    </span>\n                  )}\n                </CollapsibleTrigger>\n\n                {!isCollapsed && (\n                  <CollapsibleContent>\n                    <SidebarMenuSub className=\"my-1 ml-3.5 \">\n                      {route.subs?.map((subRoute) => (\n                        <SidebarMenuSubItem\n                          className=\"h-auto\"\n                          key={`${route.id}-${subRoute.title}`}\n                        >\n                          <SidebarMenuSubButton\n                            render={\n                              <Link\n                                className=\"flex items-center rounded-md px-4 py-1.5 font-medium text-muted-foreground text-sm hover:bg-sidebar-muted hover:text-foreground\"\n                                href={subRoute.link}\n                                prefetch={true}\n                              />\n                            }\n                          >\n                            {subRoute.title}\n                          </SidebarMenuSubButton>\n                        </SidebarMenuSubItem>\n                      ))}\n                    </SidebarMenuSub>\n                  </CollapsibleContent>\n                )}\n              </Collapsible>\n            ) : (\n              <SidebarMenuButton\n                render={\n                  <Link\n                    className={cn(\n                      'flex items-center rounded-lg px-2 text-muted-foreground transition-colors hover:bg-sidebar-muted hover:text-foreground',\n                      isCollapsed && 'justify-center'\n                    )}\n                    href={route.link}\n                    prefetch={true}\n                  />\n                }\n                tooltip={route.title}\n              >\n                {route.icon}\n                {!isCollapsed && (\n                  <span className=\"ml-2 font-medium text-sm\">\n                    {route.title}\n                  </span>\n                )}\n              </SidebarMenuButton>\n            )}\n          </SidebarMenuItem>\n        );\n      })}\n    </SidebarMenu>\n  );\n}\n"
    }
  ],
  "categories": [
    "sidebar"
  ]
}