Menu

Change language

GitHub repo

Toolbar Action Sidebar

blocklayout

App 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

$npx shadcn-svelte@latest add https://uipkge.dev/r/svelte/sidebar-07.json
Manifest:https://uipkge.dev/r/svelte/sidebar-07.jsonInstalls to:src/lib/components/blocks/sidebar-07/

Variants

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>&#8984;</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

Raw manifest:https://uipkge.dev/r/svelte/sidebar-07.json