UIPackage

Sidebar 03

block sidebar
Edit on GitHub

Docs-style sidebar with a version switcher at the top, a search input below, and collapsible navigation groups. All sample data inlined so consumers edit routes in place.

Also available for Vue ->

Installation

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

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

Examples

Files (3)

  • components/blocks/sidebar-03/Sidebar03.tsx 3.8 kB
    'use client'
    
    import { ChevronRight } from 'lucide-react'
    import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'
    import {
      Sidebar,
      SidebarContent,
      SidebarGroup,
      SidebarGroupContent,
      SidebarGroupLabel,
      SidebarHeader,
      SidebarMenu,
      SidebarMenuButton,
      SidebarMenuItem,
      SidebarRail,
    } from '@/components/ui/sidebar'
    import { SearchForm } from './SearchForm'
    import { VersionSwitcher } from './VersionSwitcher'
    
    // This is sample data.
    const data = {
      versions: ['1.0.1', '1.1.0-alpha', '2.0.0-beta1'],
      navMain: [
        {
          title: 'Getting Started',
          url: '#',
          items: [
            { title: 'Installation', url: '#' },
            { title: 'Project Structure', url: '#' },
          ],
        },
        {
          title: 'Building Your Application',
          url: '#',
          items: [
            { title: 'Routing', url: '#' },
            { title: 'Data Fetching', url: '#', isActive: true },
            { title: 'Rendering', url: '#' },
            { title: 'Caching', url: '#' },
            { title: 'Styling', url: '#' },
            { title: 'Optimizing', url: '#' },
            { title: 'Configuring', url: '#' },
            { title: 'Testing', url: '#' },
            { title: 'Authentication', url: '#' },
            { title: 'Deploying', url: '#' },
            { title: 'Upgrading', url: '#' },
            { title: 'Examples', url: '#' },
          ],
        },
        {
          title: 'API Reference',
          url: '#',
          items: [
            { title: 'Components', url: '#' },
            { title: 'File Conventions', url: '#' },
            { title: 'Functions', url: '#' },
            { title: 'next.config.js Options', url: '#' },
            { title: 'CLI', url: '#' },
            { title: 'Edge Runtime', url: '#' },
          ],
        },
        {
          title: 'Architecture',
          url: '#',
          items: [
            { title: 'Accessibility', url: '#' },
            { title: 'Fast Refresh', url: '#' },
            { title: 'Next.js Compiler', url: '#' },
            { title: 'Supported Browsers', url: '#' },
            { title: 'Turbopack', url: '#' },
          ],
        },
        {
          title: 'Community',
          url: '#',
          items: [{ title: 'Contribution Guide', url: '#' }],
        },
      ],
    }
    
    type NavItem = (typeof data.navMain)[number]
    type NavChild = NavItem['items'][number] & { isActive?: boolean }
    
    export function Sidebar03() {
      return (
        <Sidebar>
          <SidebarHeader>
            <VersionSwitcher versions={data.versions} defaultVersion={data.versions[0]!} />
            <SearchForm />
          </SidebarHeader>
          <SidebarContent className="gap-0">
            {data.navMain.map((item) => (
              <Collapsible key={item.title} title={item.title} defaultOpen className="group/collapsible">
                <SidebarGroup>
                  <SidebarGroupLabel
                    asChild
                    className="group/label text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground text-sm"
                  >
                    <CollapsibleTrigger>
                      {item.title}
                      <ChevronRight className="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-90" />
                    </CollapsibleTrigger>
                  </SidebarGroupLabel>
                  <CollapsibleContent>
                    <SidebarGroupContent>
                      <SidebarMenu>
                        {(item.items as NavChild[]).map((childItem) => (
                          <SidebarMenuItem key={childItem.title}>
                            <SidebarMenuButton asChild isActive={childItem.isActive}>
                              <a href={item.url}>{childItem.title}</a>
                            </SidebarMenuButton>
                          </SidebarMenuItem>
                        ))}
                      </SidebarMenu>
                    </SidebarGroupContent>
                  </CollapsibleContent>
                </SidebarGroup>
              </Collapsible>
            ))}
          </SidebarContent>
          <SidebarRail />
        </Sidebar>
      )
    }
  • components/blocks/sidebar-03/SearchForm.tsx 0.7 kB
    'use client'
    
    import { Search } from 'lucide-react'
    import { Label } from '@/components/ui/label'
    import { SidebarGroup, SidebarGroupContent, SidebarInput } from '@/components/ui/sidebar'
    
    export function SearchForm() {
      return (
        <form>
          <SidebarGroup className="py-0">
            <SidebarGroupContent>
              <Label htmlFor="search" className="sr-only">
                Search
              </Label>
              <SidebarInput
                id="search"
                type="text"
                placeholder="Search the docs..."
                allowClear
                prefix={<Search className="text-muted-foreground size-3.5" />}
              />
            </SidebarGroupContent>
          </SidebarGroup>
        </form>
      )
    }
  • components/blocks/sidebar-03/VersionSwitcher.tsx 2.2 kB
    'use client'
    
    import * as React from 'react'
    import { Check, ChevronsUpDown } from 'lucide-react'
    import {
      DropdownMenu,
      DropdownMenuContent,
      DropdownMenuItem,
      DropdownMenuTrigger,
    } from '@/components/ui/dropdown-menu'
    import { SidebarMenu, SidebarMenuButton, SidebarMenuItem } from '@/components/ui/sidebar'
    
    export interface VersionSwitcherProps {
      versions: string[]
      defaultVersion: string
    }
    
    export function VersionSwitcher({ versions, defaultVersion }: VersionSwitcherProps) {
      const [selectedVersion, setSelectedVersion] = React.useState(defaultVersion)
    
      return (
        <SidebarMenu>
          <SidebarMenuItem>
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <SidebarMenuButton
                  size="lg"
                  className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
                >
                  <div className="bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg">
                    <svg viewBox="0 0 24 24" className="size-4" 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="flex flex-col gap-0.5 leading-none">
                    <span className="font-medium">uipkge</span>
                    <span className="">v{selectedVersion}</span>
                  </div>
                  <ChevronsUpDown className="ml-auto" />
                </SidebarMenuButton>
              </DropdownMenuTrigger>
              <DropdownMenuContent className="w-(--radix-dropdown-menu-trigger-width)" align="start">
                {versions.map((version) => (
                  <DropdownMenuItem key={version} onSelect={() => setSelectedVersion(version)}>
                    v{version}
                    {selectedVersion === version ? <Check className="ml-auto" /> : null}
                  </DropdownMenuItem>
                ))}
              </DropdownMenuContent>
            </DropdownMenu>
          </SidebarMenuItem>
        </SidebarMenu>
      )
    }

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