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 React ->

Installation

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

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

Examples

Files (3)

  • app/components/blocks/sidebar-03/Sidebar03.vue 4.3 kB
    <script setup lang="ts">
    import { ChevronRight } from 'lucide-vue-next'
    import SearchForm from './SearchForm.vue'
    import VersionSwitcher from './VersionSwitcher.vue'
    import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'
    import {
      Sidebar,
      SidebarContent,
      SidebarGroup,
      SidebarGroupContent,
      SidebarGroupLabel,
      SidebarHeader,
      SidebarMenu,
      SidebarMenuButton,
      SidebarMenuItem,
      SidebarRail,
    } from '@/components/ui/sidebar'
    
    // 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: '#',
            },
          ],
        },
      ],
    }
    </script>
    
    <template>
      <Sidebar>
        <SidebarHeader>
          <VersionSwitcher :versions="data.versions" :default-version="data.versions[0]!" />
          <SearchForm />
        </SidebarHeader>
        <SidebarContent class="gap-0">
          <Collapsible
            v-for="item in data.navMain"
            :key="item.title"
            :title="item.title"
            default-open
            class="group/collapsible"
          >
            <SidebarGroup>
              <SidebarGroupLabel
                as-child
                class="group/label text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground text-sm"
              >
                <CollapsibleTrigger>
                  {{ item.title }}
                  <ChevronRight class="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-90" />
                </CollapsibleTrigger>
              </SidebarGroupLabel>
              <CollapsibleContent>
                <SidebarGroupContent>
                  <SidebarMenu>
                    <SidebarMenuItem v-for="childItem in item.items" :key="childItem.title">
                      <SidebarMenuButton as-child :is-active="childItem.isActive">
                        <a :href="item.url">{{ childItem.title }}</a>
                      </SidebarMenuButton>
                    </SidebarMenuItem>
                  </SidebarMenu>
                </SidebarGroupContent>
              </CollapsibleContent>
            </SidebarGroup>
          </Collapsible>
        </SidebarContent>
        <SidebarRail />
      </Sidebar>
    </template>
  • app/components/blocks/sidebar-03/SearchForm.vue 0.6 kB
    <script setup lang="ts">
    import { Search } from 'lucide-vue-next'
    import { Label } from '@/components/ui/label'
    import { SidebarGroup, SidebarGroupContent, SidebarInput } from '@/components/ui/sidebar'
    </script>
    
    <template>
      <form>
        <SidebarGroup class="py-0">
          <SidebarGroupContent>
            <Label for="search" class="sr-only">Search</Label>
            <SidebarInput id="search" type="text" placeholder="Search the docs..." :allow-clear="true">
              <template #prefix>
                <Search class="text-muted-foreground size-3.5" />
              </template>
            </SidebarInput>
          </SidebarGroupContent>
        </SidebarGroup>
      </form>
    </template>
  • app/components/blocks/sidebar-03/VersionSwitcher.vue 2 kB
    <script setup lang="ts">
    import { Check, ChevronsUpDown } from 'lucide-vue-next'
    
    import { ref } from 'vue'
    import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'
    import { SidebarMenu, SidebarMenuButton, SidebarMenuItem } from '@/components/ui/sidebar'
    
    const props = defineProps<{
      versions: string[]
      defaultVersion: string
    }>()
    
    const selectedVersion = ref(props.defaultVersion)
    </script>
    
    <template>
      <SidebarMenu>
        <SidebarMenuItem>
          <DropdownMenu>
            <DropdownMenuTrigger as-child>
              <SidebarMenuButton
                size="lg"
                class="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
              >
                <div
                  class="bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg"
                >
                  <svg viewBox="0 0 24 24" class="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 class="flex flex-col gap-0.5 leading-none">
                  <span class="font-medium">uipkge</span>
                  <span class="">v{{ selectedVersion }}</span>
                </div>
                <ChevronsUpDown class="ml-auto" />
              </SidebarMenuButton>
            </DropdownMenuTrigger>
            <DropdownMenuContent class="w-(--reka-dropdown-menu-trigger-width)" align="start">
              <DropdownMenuItem v-for="version in versions" :key="version" @select="selectedVersion = version">
                v{{ version }}
                <Check v-if="selectedVersion === version" class="ml-auto" />
              </DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        </SidebarMenuItem>
      </SidebarMenu>
    </template>

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