Toolbar Action Sidebar
blocklayoutApp sidebar with a bottom action bar -- workspace pill, ⌘K search, grouped nav with section labels (Dashboard / Management / Content), badge counts, user pill above an icon toolbar (Settings, Help, Notifications, Command, theme toggle, collapse). Built on sidebar-01.
Installation
$pnpm dlx shadcn-svelte@latest add https://uipkge.dev/r/svelte/sidebar-07.json$npx shadcn-svelte@latest add https://uipkge.dev/r/svelte/sidebar-07.json$yarn dlx shadcn-svelte@latest add https://uipkge.dev/r/svelte/sidebar-07.json$bunx shadcn-svelte@latest add https://uipkge.dev/r/svelte/sidebar-07.jsonManifest:
https://uipkge.dev/r/svelte/sidebar-07.jsonInstalls to:src/lib/components/blocks/sidebar-07/Variants
Loading interactive previews…
Loading interactive previews…
npm dependencies
Files installed (2)
src/lib/components/blocks/sidebar-07/Sidebar07.svelte9.9 kB
<script lang="ts"> // App sidebar with a bottom action bar. Workspace pill + search at the top, // three grouped nav sections, user pill above an icon toolbar (Settings, // Help, Notifications, Command palette, theme toggle, collapse) anchored at // the very bottom. Every row is spelled out inline so you can edit in place. import { onMount } from 'svelte' import { Bell, ChartBar, ChevronsUpDown, Command, CreditCard, FileText, HelpCircle, LineChart, Mail, Moon, Package, Plus, Search, Settings as SettingsIcon, ShoppingCart, Sun, Users, } from '@lucide/svelte' import { Avatar, AvatarFallback } from '$lib/components/ui/avatar' import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarMenu, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarRail, SidebarSeparator, SidebarTrigger, useSidebar, } from '$lib/components/ui/sidebar' const sidebar = useSidebar() // `mounted` stays false during SSR + the client's first synchronous // render, so isDark is also false on both sides -- no hydration // mismatch on the Sun/Moon icon. Once hydration settles `onMount` // flips the flag and the derived re-runs against the real // matchMedia signal. let mounted = $state(false) let dark = $state(false) onMount(() => { mounted = true dark = document.documentElement.classList.contains('dark') || window.matchMedia('(prefers-color-scheme: dark)').matches }) const isDark = $derived(mounted && dark) function toggleTheme() { dark = !dark document.documentElement.classList.toggle('dark', dark) } </script> <Sidebar data-slot="sidebar-07" collapsible="icon"> <SidebarHeader> <SidebarMenu> <SidebarMenuItem> <SidebarMenuButton size="lg" tooltip="uipkge" class="group-data-[collapsible=icon]:!justify-center"> <div class="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" class="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 class="grid flex-1 text-left text-sm leading-tight group-data-[collapsible=icon]:hidden"> <span class="font-display truncate font-semibold">uipkge</span> <span class="text-muted-foreground truncate text-xs">uipkge.dev</span> </div> </SidebarMenuButton> </SidebarMenuItem> </SidebarMenu> <div class="px-1 pt-1 group-data-[collapsible=icon]:hidden"> <div class="relative"> <Search class="text-muted-foreground pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2" aria-hidden="true" /> <SidebarInput type="text" placeholder="Search..." class="pr-9 pl-8" /> <kbd class="bg-muted text-muted-foreground pointer-events-none absolute top-1/2 right-2 inline-flex h-5 -translate-y-1/2 items-center gap-0.5 rounded border px-1 font-mono text-xs font-medium select-none" > <span>⌘</span>K </kbd> </div> </div> </SidebarHeader> <SidebarContent> <SidebarGroup> <SidebarGroupLabel>Dashboard</SidebarGroupLabel> <SidebarGroupContent> <SidebarMenu> <SidebarMenuItem> <!-- Active row gets a subtle success-tinted gradient to mark it without competing with the rest of the nav. --> <SidebarMenuButton isActive tooltip="Analytics" class="data-[active=true]:!bg-success/20 data-[active=true]:!text-foreground" > <ChartBar class="size-4" /> <span>Analytics</span> </SidebarMenuButton> </SidebarMenuItem> <SidebarMenuItem> <SidebarMenuButton tooltip="Performance"> <LineChart class="size-4" /> <span>Performance</span> </SidebarMenuButton> </SidebarMenuItem> </SidebarMenu> </SidebarGroupContent> </SidebarGroup> <SidebarGroup> <SidebarGroupLabel>Management</SidebarGroupLabel> <SidebarGroupContent> <SidebarMenu> <SidebarMenuItem> <SidebarMenuButton tooltip="Products"> <Package class="size-4" /> <span>Products</span> </SidebarMenuButton> </SidebarMenuItem> <SidebarMenuItem> <SidebarMenuButton tooltip="Orders"> <ShoppingCart class="size-4" /> <span>Orders</span> </SidebarMenuButton> </SidebarMenuItem> <SidebarMenuItem> <SidebarMenuButton tooltip="Subscribers"> <Users class="size-4" /> <span>Subscribers</span> </SidebarMenuButton> </SidebarMenuItem> <SidebarMenuItem> <SidebarMenuButton tooltip="Transactions"> <CreditCard class="size-4" /> <span>Transactions</span> </SidebarMenuButton> </SidebarMenuItem> </SidebarMenu> </SidebarGroupContent> </SidebarGroup> <SidebarGroup> <SidebarGroupLabel>Content</SidebarGroupLabel> <SidebarGroupAction aria-label="Add content"> <Plus class="size-4" /> </SidebarGroupAction> <SidebarGroupContent> <SidebarMenu> <SidebarMenuItem> <SidebarMenuButton tooltip="Posts"> <FileText class="size-4" /> <span>Posts</span> </SidebarMenuButton> <SidebarMenuBadge class="bg-destructive text-white">10</SidebarMenuBadge> </SidebarMenuItem> <SidebarMenuItem> <SidebarMenuButton tooltip="Pages"> <Mail class="size-4" /> <span>Pages</span> </SidebarMenuButton> </SidebarMenuItem> </SidebarMenu> </SidebarGroupContent> </SidebarGroup> </SidebarContent> <SidebarFooter> <SidebarMenu> <SidebarMenuItem> <SidebarMenuButton size="lg" class="group-data-[collapsible=icon]:!justify-center"> <Avatar class="size-8 rounded-lg group-data-[collapsible=icon]:size-6"> <AvatarFallback class="bg-sidebar-accent text-sidebar-accent-foreground rounded-lg text-xs" >SW</AvatarFallback > </Avatar> <div class="grid flex-1 text-left text-sm leading-tight group-data-[collapsible=icon]:hidden"> <span class="truncate font-medium">Sarah Wilson</span> <span class="text-muted-foreground truncate text-xs">Admin Account</span> </div> <ChevronsUpDown class="ml-auto size-4 group-data-[collapsible=icon]:hidden" /> </SidebarMenuButton> </SidebarMenuItem> </SidebarMenu> {#if sidebar.state === 'expanded'} <SidebarSeparator class="my-1" /> <!-- Action toolbar -- evenly spaced quick icons. Last button is the SidebarTrigger collapse toggle. Replace others with <a> / <button onclick="..."> as needed. --> <div class="flex items-center justify-between px-1 pb-1"> <button type="button" aria-label="Settings" class="text-muted-foreground hover:bg-sidebar-accent hover:text-foreground flex aspect-square size-8 items-center justify-center rounded-md transition-colors" > <SettingsIcon class="size-4" /> </button> <button type="button" aria-label="Help" class="text-muted-foreground hover:bg-sidebar-accent hover:text-foreground flex aspect-square size-8 items-center justify-center rounded-md transition-colors" > <HelpCircle class="size-4" /> </button> <button type="button" aria-label="Notifications" class="text-muted-foreground hover:bg-sidebar-accent hover:text-foreground flex aspect-square size-8 items-center justify-center rounded-md transition-colors" > <Bell class="size-4" /> </button> <button type="button" aria-label="Command palette" class="text-muted-foreground hover:bg-sidebar-accent hover:text-foreground flex aspect-square size-8 items-center justify-center rounded-md transition-colors" > <Command class="size-4" /> </button> <button type="button" aria-label={isDark ? 'Switch to light theme' : 'Switch to dark theme'} class="text-muted-foreground hover:bg-sidebar-accent hover:text-foreground flex aspect-square size-8 items-center justify-center rounded-md transition-colors" onclick={toggleTheme} > {#if isDark} <Sun class="size-4" /> {:else} <Moon class="size-4" /> {/if} </button> <SidebarTrigger class="text-muted-foreground hover:bg-sidebar-accent hover:text-foreground size-8 rounded-md" /> </div> <!-- Collapsed-state: surface the trigger on its own so the rail always has an expand affordance. --> {:else} <div class="flex items-center justify-center pb-1"> <SidebarTrigger class="text-muted-foreground hover:bg-sidebar-accent hover:text-foreground size-8 rounded-md" /> </div> {/if} </SidebarFooter> <SidebarRail /> </Sidebar>src/routes/sidebar-07-demo/+page.svelte1.1 kB
<script lang="ts"> // Demo page wired by `npx shadcn-svelte@latest add https://uipkge.dev/r/svelte/sidebar-07.json`. // Visit /sidebar-07-demo after install to see the block without // editing your own pages. Free to edit or delete me. import Sidebar07 from '$lib/components/blocks/sidebar-07/Sidebar07.svelte' import { SidebarInset, SidebarProvider, SidebarTrigger } from '$lib/components/ui/sidebar' </script> <SidebarProvider> <Sidebar07 /> <SidebarInset> <header class="border-border flex h-14 shrink-0 items-center gap-3 border-b px-4"> <SidebarTrigger class="size-7" /> <h1 class="text-sm font-semibold">sidebar-07 demo</h1> </header> <div class="flex-1 p-6"> <div class="grid auto-rows-min gap-4 md:grid-cols-3"> <div class="bg-muted/50 aspect-video rounded-xl"></div> <div class="bg-muted/50 aspect-video rounded-xl"></div> <div class="bg-muted/50 aspect-video rounded-xl"></div> </div> <div class="bg-muted/50 mt-4 min-h-[60vh] rounded-xl"></div> </div> </SidebarInset> </SidebarProvider>
Raw manifest:https://uipkge.dev/r/svelte/sidebar-07.json