Sidebar 03
block sidebarDocs-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
$ pnpm dlx shadcn-vue@latest add https://uipkge.dev/r/vue/sidebar-03.json$ npx shadcn-vue@latest add https://uipkge.dev/r/vue/sidebar-03.json$ yarn dlx shadcn-vue@latest add https://uipkge.dev/r/vue/sidebar-03.json$ bunx 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
npm dependencies
Includes
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