UIPackage

Sidebar 01

block sidebar
Edit on GitHub

Collapsible icon-rail app sidebar with brand block, two grouped nav sections, and a user dropdown footer. Pure markup, no props -- edit Sidebar01.tsx to change routes and NavUser.tsx to wire your auth session. Pair with SidebarProvider + SidebarInset for the full admin shell.

Also available for Vue ->

Installation

$ npx shadcn@latest add https://react.uipkge.dev/r/react/sidebar-01.json

Or with the named registry: npx shadcn@latest add @uipkge-react/sidebar-01

Examples

Files (2)

  • components/blocks/sidebar-01/Sidebar01.tsx 4.3 kB
    'use client'
    
    // Edit this file to change brand, navigation, and the user dropdown.
    // Every menu item is spelled out below -- copy, remove, or rename rows directly.
    
    import { BarChart3, BookOpen, FileText, Files, History, LayoutDashboard, Table as TableIcon } from 'lucide-react'
    import {
      Sidebar,
      SidebarContent,
      SidebarFooter,
      SidebarGroup,
      SidebarGroupContent,
      SidebarGroupLabel,
      SidebarHeader,
      SidebarMenu,
      SidebarMenuButton,
      SidebarMenuItem,
      SidebarRail,
    } from '@/components/ui/sidebar'
    import { NavUser } from './NavUser'
    
    export function Sidebar01() {
      return (
        <Sidebar collapsible="icon">
          <SidebarHeader>
            <SidebarMenu>
              <SidebarMenuItem>
                <SidebarMenuButton size="lg" tooltip="uipkge" className="group-data-[collapsible=icon]:!justify-center">
                  <div className="bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 shrink-0 items-center justify-center rounded-lg group-data-[collapsible=icon]:size-6">
                    <svg
                      viewBox="0 0 24 24"
                      className="size-4 group-data-[collapsible=icon]:size-3.5"
                      fill="currentColor"
                      aria-hidden="true"
                    >
                      <rect x="2" y="2" width="9" height="9" rx="1.5" />
                      <rect x="13" y="2" width="9" height="9" rx="1.5" opacity="0.55" />
                      <rect x="2" y="13" width="9" height="9" rx="1.5" opacity="0.55" />
                      <rect x="13" y="13" width="9" height="9" rx="1.5" />
                    </svg>
                  </div>
                  <div className="grid flex-1 text-left text-sm leading-tight group-data-[collapsible=icon]:hidden">
                    <span className="font-display truncate font-bold">uipkge</span>
                    <span className="text-muted-foreground truncate text-xs">uipkge.dev</span>
                  </div>
                </SidebarMenuButton>
              </SidebarMenuItem>
            </SidebarMenu>
          </SidebarHeader>
    
          <SidebarContent>
            <SidebarGroup>
              <SidebarGroupLabel>Workspace</SidebarGroupLabel>
              <SidebarGroupContent>
                <SidebarMenu>
                  <SidebarMenuItem>
                    {/* TODO: wrap in a <Link> and bind isActive to your route */}
                    <SidebarMenuButton isActive tooltip="Dashboard">
                      <LayoutDashboard className="size-4" />
                      <span>Dashboard</span>
                    </SidebarMenuButton>
                  </SidebarMenuItem>
                  <SidebarMenuItem>
                    <SidebarMenuButton tooltip="Data tables">
                      <TableIcon className="size-4" />
                      <span>Data tables</span>
                    </SidebarMenuButton>
                  </SidebarMenuItem>
                  <SidebarMenuItem>
                    <SidebarMenuButton tooltip="Forms">
                      <FileText className="size-4" />
                      <span>Forms</span>
                    </SidebarMenuButton>
                  </SidebarMenuItem>
                  <SidebarMenuItem>
                    <SidebarMenuButton tooltip="Charts">
                      <BarChart3 className="size-4" />
                      <span>Charts</span>
                    </SidebarMenuButton>
                  </SidebarMenuItem>
                  <SidebarMenuItem>
                    <SidebarMenuButton tooltip="Pages">
                      <Files className="size-4" />
                      <span>Pages</span>
                    </SidebarMenuButton>
                  </SidebarMenuItem>
                </SidebarMenu>
              </SidebarGroupContent>
            </SidebarGroup>
    
            <SidebarGroup>
              <SidebarGroupLabel>Resources</SidebarGroupLabel>
              <SidebarGroupContent>
                <SidebarMenu>
                  <SidebarMenuItem>
                    <SidebarMenuButton tooltip="Docs">
                      <BookOpen className="size-4" />
                      <span>Docs</span>
                    </SidebarMenuButton>
                  </SidebarMenuItem>
                  <SidebarMenuItem>
                    <SidebarMenuButton tooltip="Changelog">
                      <History className="size-4" />
                      <span>Changelog</span>
                    </SidebarMenuButton>
                  </SidebarMenuItem>
                </SidebarMenu>
              </SidebarGroupContent>
            </SidebarGroup>
          </SidebarContent>
    
          <SidebarFooter>
            <NavUser />
          </SidebarFooter>
    
          <SidebarRail />
        </Sidebar>
      )
    }
  • components/blocks/sidebar-01/NavUser.tsx 4.7 kB
    'use client'
    
    // Edit this file to change the user dropdown content, avatar, and logout handler.
    // The user details are inlined below -- wire them to your auth session in place.
    
    import { BadgeCheck, ChevronsUpDown, LogOut, Monitor, Moon, Palette, Settings, Sun } from 'lucide-react'
    import { useTheme } from '@/lib/use-theme'
    import { Avatar, AvatarFallback } from '@/components/ui/avatar'
    import {
      DropdownMenu,
      DropdownMenuContent,
      DropdownMenuGroup,
      DropdownMenuItem,
      DropdownMenuLabel,
      DropdownMenuRadioGroup,
      DropdownMenuRadioItem,
      DropdownMenuSeparator,
      DropdownMenuSub,
      DropdownMenuSubContent,
      DropdownMenuSubTrigger,
      DropdownMenuTrigger,
    } from '@/components/ui/dropdown-menu'
    import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, useSidebar } from '@/components/ui/sidebar'
    
    // Replace these with your auth session.
    const user = {
      name: 'Test User',
      email: '[email protected]',
      initials: 'TU',
    }
    
    function handleLogout() {
      // TODO: call your /api/auth/logout endpoint, then redirect.
      console.warn('NavUser: wire handleLogout() to your auth backend')
    }
    
    export function NavUser() {
      const { isMobile } = useSidebar()
      const { theme, setTheme } = useTheme()
    
      return (
        <SidebarMenu>
          <SidebarMenuItem>
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <SidebarMenuButton
                  size="lg"
                  className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground group-data-[collapsible=icon]:!justify-center"
                >
                  <Avatar className="h-8 w-8 shrink-0 rounded-lg group-data-[collapsible=icon]:size-6">
                    <AvatarFallback className="rounded-lg text-xs group-data-[collapsible=icon]:text-[10px]">
                      {user.initials}
                    </AvatarFallback>
                  </Avatar>
                  <div className="grid flex-1 text-left text-sm leading-tight group-data-[collapsible=icon]:hidden">
                    <span className="truncate font-medium">{user.name}</span>
                    <span className="truncate text-xs">{user.email}</span>
                  </div>
                  <ChevronsUpDown className="ml-auto size-4 group-data-[collapsible=icon]:hidden" />
                </SidebarMenuButton>
              </DropdownMenuTrigger>
              <DropdownMenuContent
                className="w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg"
                side={isMobile ? 'bottom' : 'right'}
                align="end"
                sideOffset={4}
              >
                <DropdownMenuLabel className="p-0 font-normal">
                  <div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
                    <Avatar className="h-8 w-8 rounded-lg">
                      <AvatarFallback className="rounded-lg">{user.initials}</AvatarFallback>
                    </Avatar>
                    <div className="grid flex-1 text-left text-sm leading-tight">
                      <span className="truncate font-semibold">{user.name}</span>
                      <span className="truncate text-xs">{user.email}</span>
                    </div>
                  </div>
                </DropdownMenuLabel>
                <DropdownMenuSeparator />
                <DropdownMenuGroup>
                  <DropdownMenuItem>
                    <BadgeCheck className="size-4" /> Profile
                  </DropdownMenuItem>
                  <DropdownMenuItem>
                    <Settings className="size-4" /> Settings
                  </DropdownMenuItem>
                </DropdownMenuGroup>
                <DropdownMenuSeparator />
                <DropdownMenuSub>
                  <DropdownMenuSubTrigger>
                    <Palette className="size-4" />
                    Theme
                    <span className="text-muted-foreground ml-auto text-xs capitalize">{theme}</span>
                  </DropdownMenuSubTrigger>
                  <DropdownMenuSubContent className="min-w-36">
                    <DropdownMenuRadioGroup value={theme} onValueChange={(v) => setTheme(v)}>
                      <DropdownMenuRadioItem value="light">
                        <Sun className="size-4" /> Light
                      </DropdownMenuRadioItem>
                      <DropdownMenuRadioItem value="dark">
                        <Moon className="size-4" /> Dark
                      </DropdownMenuRadioItem>
                      <DropdownMenuRadioItem value="system">
                        <Monitor className="size-4" /> System
                      </DropdownMenuRadioItem>
                    </DropdownMenuRadioGroup>
                  </DropdownMenuSubContent>
                </DropdownMenuSub>
                <DropdownMenuSeparator />
                <DropdownMenuItem onClick={handleLogout}>
                  <LogOut className="size-4" />
                  Log out
                </DropdownMenuItem>
              </DropdownMenuContent>
            </DropdownMenu>
          </SidebarMenuItem>
        </SidebarMenu>
      )
    }

Raw manifest: https://react.uipkge.dev/r/react/sidebar-01.json