Icon Rail Sidebar
blocklayoutCollapsible icon-rail app sidebar with brand block, two grouped nav sections, and a user dropdown footer with theme switching. Pure template, no props — edit the files to change routes and wire your auth session.
Installation
$pnpm dlx uipkge-ng@latest add sidebar-01$npx uipkge-ng@latest add sidebar-01$yarn dlx uipkge-ng@latest add sidebar-01$bunx uipkge-ng@latest add sidebar-01Manifest:
https://uipkge.dev/r/angular/sidebar-01.jsonInstalls to:src/app/components/blocks/sidebar-01/Variants
Loading interactive previews…
Loading interactive previews…
npm dependencies
Files installed (3)
src/app/components/blocks/sidebar-01/sidebar-01.component.ts6.3 kB
// Edit this file to change brand, navigation, and the user dropdown. // Every menu item is spelled out below -- copy, remove, or rename rows directly. import { Component, ChangeDetectionStrategy } from '@angular/core' import { BarChart3, BookOpen, FileText, Files, History, LayoutDashboard, LucideAngularModule, Table as TableIcon, } from 'lucide-angular' import { UiSidebarComponent, UiSidebarContentComponent, UiSidebarFooterComponent, UiSidebarGroupComponent, UiSidebarGroupContentComponent, UiSidebarGroupLabelComponent, UiSidebarHeaderComponent, UiSidebarMenuButtonComponent, UiSidebarMenuComponent, UiSidebarMenuItemComponent, UiSidebarRailComponent, } from '@/ui/sidebar/sidebar.component' import { Sidebar01NavUserComponent } from './nav-user-01.component' /** * Sidebar01 -- the React block, 1:1: a `collapsible="icon"` Sidebar with a brand * row, Workspace + Resources groups and a user dropdown footer. It reads the * surrounding <ui-sidebar-provider>, so <ui-sidebar-trigger>, the rail and * Cmd/Ctrl+B collapse it to the icon rail (labels become tooltips). */ @Component({ changeDetection: ChangeDetectionStrategy.Eager, selector: 'ui-sidebar-01, [ui-sidebar-01]', standalone: true, // React renders <Sidebar> itself: keep this wrapper out of the provider's flex layout. host: { class: 'contents' }, imports: [ LucideAngularModule, UiSidebarComponent, UiSidebarHeaderComponent, UiSidebarContentComponent, UiSidebarFooterComponent, UiSidebarGroupComponent, UiSidebarGroupLabelComponent, UiSidebarGroupContentComponent, UiSidebarMenuComponent, UiSidebarMenuItemComponent, UiSidebarMenuButtonComponent, UiSidebarRailComponent, Sidebar01NavUserComponent, ], template: ` <ui-sidebar collapsible="icon"> <ui-sidebar-header> <ul ui-sidebar-menu> <li ui-sidebar-menu-item> <button type="button" ui-sidebar-menu-button 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-bold">uipkge</span> <span class="text-muted-foreground truncate text-xs">uipkge.dev</span> </div> </button> </li> </ul> </ui-sidebar-header> <ui-sidebar-content> <ui-sidebar-group> <ui-sidebar-group-label>Workspace</ui-sidebar-group-label> <ui-sidebar-group-content> <ul ui-sidebar-menu> <li ui-sidebar-menu-item> <!-- TODO: wrap in a routerLink and bind isActive to your route --> <button type="button" ui-sidebar-menu-button isActive tooltip="Dashboard"> <lucide-icon [img]="LayoutDashboard" class="size-4 shrink-0" /> <span>Dashboard</span> </button> </li> <li ui-sidebar-menu-item> <button type="button" ui-sidebar-menu-button tooltip="Data tables"> <lucide-icon [img]="TableIcon" class="size-4 shrink-0" /> <span>Data tables</span> </button> </li> <li ui-sidebar-menu-item> <button type="button" ui-sidebar-menu-button tooltip="Forms"> <lucide-icon [img]="FileText" class="size-4 shrink-0" /> <span>Forms</span> </button> </li> <li ui-sidebar-menu-item> <button type="button" ui-sidebar-menu-button tooltip="Charts"> <lucide-icon [img]="BarChart3" class="size-4 shrink-0" /> <span>Charts</span> </button> </li> <li ui-sidebar-menu-item> <button type="button" ui-sidebar-menu-button tooltip="Pages"> <lucide-icon [img]="Files" class="size-4 shrink-0" /> <span>Pages</span> </button> </li> </ul> </ui-sidebar-group-content> </ui-sidebar-group> <ui-sidebar-group> <ui-sidebar-group-label>Resources</ui-sidebar-group-label> <ui-sidebar-group-content> <ul ui-sidebar-menu> <li ui-sidebar-menu-item> <button type="button" ui-sidebar-menu-button tooltip="Docs"> <lucide-icon [img]="BookOpen" class="size-4 shrink-0" /> <span>Docs</span> </button> </li> <li ui-sidebar-menu-item> <button type="button" ui-sidebar-menu-button tooltip="Changelog"> <lucide-icon [img]="History" class="size-4 shrink-0" /> <span>Changelog</span> </button> </li> </ul> </ui-sidebar-group-content> </ui-sidebar-group> </ui-sidebar-content> <ui-sidebar-footer> <sidebar-01-nav-user /> </ui-sidebar-footer> <button ui-sidebar-rail></button> </ui-sidebar> `, }) export class UiSidebar01Component { protected readonly LayoutDashboard = LayoutDashboard protected readonly TableIcon = TableIcon protected readonly FileText = FileText protected readonly BarChart3 = BarChart3 protected readonly Files = Files protected readonly BookOpen = BookOpen protected readonly History = History }src/app/components/blocks/sidebar-01/nav-user-01.component.ts6.4 kB
// Edit this file to change the user dropdown content, avatar, and logout handler. // The user details are inlined below -- wire them to your auth session in place. import { Component, ChangeDetectionStrategy } from '@angular/core' import { BadgeCheck, ChevronsUpDown, LogOut, LucideAngularModule, Monitor, Moon, Palette, Settings, Sun, } from 'lucide-angular' import { injectTheme, type Theme } from '@/lib/use-theme' import { UiAvatarComponent, UiAvatarFallbackComponent } from '@/ui/avatar/avatar.component' import { UiDropdownMenuComponent, UiDropdownMenuContentComponent, UiDropdownMenuGroupComponent, UiDropdownMenuItemComponent, UiDropdownMenuLabelComponent, UiDropdownMenuRadioGroupComponent, UiDropdownMenuRadioItemComponent, UiDropdownMenuSeparatorComponent, UiDropdownMenuSubComponent, UiDropdownMenuSubContentComponent, UiDropdownMenuSubTriggerComponent, UiDropdownMenuTriggerComponent, } from '@/ui/dropdown-menu/dropdown-menu.component' import { UiSidebarMenuButtonComponent, UiSidebarMenuComponent, UiSidebarMenuItemComponent, injectSidebar, } from '@/ui/sidebar/sidebar.component' export type Sidebar01Theme = Theme // Replace these with your auth session. const user = { name: 'Test User', email: 'you@example.com', initials: 'TU', } function handleLogout(): void { // TODO: call your /api/auth/logout endpoint, then redirect. console.warn('NavUser: wire handleLogout() to your auth backend') } @Component({ changeDetection: ChangeDetectionStrategy.Eager, selector: 'sidebar-01-nav-user', standalone: true, host: { class: 'contents' }, imports: [ LucideAngularModule, UiAvatarComponent, UiAvatarFallbackComponent, UiDropdownMenuComponent, UiDropdownMenuTriggerComponent, UiDropdownMenuContentComponent, UiDropdownMenuGroupComponent, UiDropdownMenuItemComponent, UiDropdownMenuLabelComponent, UiDropdownMenuRadioGroupComponent, UiDropdownMenuRadioItemComponent, UiDropdownMenuSeparatorComponent, UiDropdownMenuSubComponent, UiDropdownMenuSubTriggerComponent, UiDropdownMenuSubContentComponent, UiSidebarMenuComponent, UiSidebarMenuItemComponent, UiSidebarMenuButtonComponent, ], template: ` <ul ui-sidebar-menu> <li ui-sidebar-menu-item> <ui-dropdown-menu> <button type="button" ui-sidebar-menu-button ui-dropdown-menu-trigger size="lg" class="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground group-data-[collapsible=icon]:!justify-center" > <ui-avatar class="h-8 w-8 shrink-0 rounded-lg group-data-[collapsible=icon]:size-6"> <ui-avatar-fallback class="rounded-lg text-xs">{{ user.initials }}</ui-avatar-fallback> </ui-avatar> <div class="grid flex-1 text-left text-sm leading-tight group-data-[collapsible=icon]:hidden"> <span class="truncate font-medium">{{ user.name }}</span> <span class="truncate text-xs">{{ user.email }}</span> </div> <lucide-icon [img]="ChevronsUpDown" class="ml-auto size-4 group-data-[collapsible=icon]:hidden" /> </button> <ui-dropdown-menu-content class="w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg" [side]="sidebar.isMobile ? 'bottom' : 'right'" align="end" [sideOffset]="4" > <ui-dropdown-menu-label class="p-0 font-normal"> <div class="flex items-center gap-2 px-1 py-1.5 text-left text-sm"> <ui-avatar class="h-8 w-8 rounded-lg"> <ui-avatar-fallback class="rounded-lg">{{ user.initials }}</ui-avatar-fallback> </ui-avatar> <div class="grid flex-1 text-left text-sm leading-tight"> <span class="truncate font-semibold">{{ user.name }}</span> <span class="truncate text-xs">{{ user.email }}</span> </div> </div> </ui-dropdown-menu-label> <ui-dropdown-menu-separator /> <ui-dropdown-menu-group> <ui-dropdown-menu-item><lucide-icon [img]="BadgeCheck" class="size-4" /> Profile</ui-dropdown-menu-item> <ui-dropdown-menu-item><lucide-icon [img]="Settings" class="size-4" /> Settings</ui-dropdown-menu-item> </ui-dropdown-menu-group> <ui-dropdown-menu-separator /> <ui-dropdown-menu-sub> <ui-dropdown-menu-sub-trigger> <lucide-icon [img]="Palette" class="size-4" /> Theme <span class="text-muted-foreground ml-auto text-xs capitalize">{{ theme.theme() }}</span> </ui-dropdown-menu-sub-trigger> <ui-dropdown-menu-sub-content class="min-w-36"> <ui-dropdown-menu-radio-group [value]="theme.theme()" (valueChange)="theme.setTheme($any($event))"> <ui-dropdown-menu-radio-item value="light" ><lucide-icon [img]="Sun" class="size-4" /> Light</ui-dropdown-menu-radio-item > <ui-dropdown-menu-radio-item value="dark" ><lucide-icon [img]="Moon" class="size-4" /> Dark</ui-dropdown-menu-radio-item > <ui-dropdown-menu-radio-item value="system" ><lucide-icon [img]="Monitor" class="size-4" /> System</ui-dropdown-menu-radio-item > </ui-dropdown-menu-radio-group> </ui-dropdown-menu-sub-content> </ui-dropdown-menu-sub> <ui-dropdown-menu-separator /> <ui-dropdown-menu-item (select)="logout()"> <lucide-icon [img]="LogOut" class="size-4" /> Log out </ui-dropdown-menu-item> </ui-dropdown-menu-content> </ui-dropdown-menu> </li> </ul> `, }) export class Sidebar01NavUserComponent { readonly sidebar = injectSidebar() readonly theme = injectTheme() readonly user = user logout(): void { handleLogout() } protected readonly ChevronsUpDown = ChevronsUpDown protected readonly BadgeCheck = BadgeCheck protected readonly Settings = Settings protected readonly Palette = Palette protected readonly Sun = Sun protected readonly Moon = Moon protected readonly Monitor = Monitor protected readonly LogOut = LogOut }src/app/components/blocks/sidebar-01/index.ts0.1 kB
export { UiSidebar01Component } from './sidebar-01.component' export { Sidebar01NavUserComponent, type Sidebar01Theme } from './nav-user-01.component'
Raw manifest:https://uipkge.dev/r/angular/sidebar-01.json