Team Switcher Sidebar
blocklayoutFull-featured app sidebar — collapsible="icon" rail with TeamSwitcher header, primary nav, projects section, secondary nav, and user dropdown footer with theme switching. Each section ships as a sibling file in the same folder so consumers can edit one piece at a time.
Installation
$pnpm dlx uipkge-ng@latest add sidebar-02$npx uipkge-ng@latest add sidebar-02$yarn dlx uipkge-ng@latest add sidebar-02$bunx uipkge-ng@latest add sidebar-02Manifest:
https://uipkge.dev/r/angular/sidebar-02.jsonInstalls to:src/app/components/blocks/sidebar-02/Variants
Loading interactive previews…
Loading interactive previews…
Schema
Type aliases exported from this item's source. Use these to shape the data you pass in.
SidebarSubIteminterface SidebarSubItem {
title: string
url: string
isActive?: boolean
}SidebarNavIteminterface SidebarNavItem {
title: string
url: string
icon: LucideIconData
isActive?: boolean
items?: SidebarSubItem[]
}SidebarProjectinterface SidebarProject {
name: string
url: string
icon: LucideIconData
}SidebarTeaminterface SidebarTeam {
name: string
plan: string
logo: LucideIconData | 'uipkge'
}SidebarUserinterface SidebarUser {
name: string
email: string
}npm dependencies
Files installed (8)
src/app/components/blocks/sidebar-02/sidebar-02.component.ts3.7 kB
import { Component, ChangeDetectionStrategy } from '@angular/core' import { UiSidebarComponent, UiSidebarContentComponent, UiSidebarFooterComponent, UiSidebarHeaderComponent, UiSidebarRailComponent, } from '@/ui/sidebar/sidebar.component' import { BookOpen, Bot, Frame, LifeBuoy, Map as MapIcon, PieChart, Send, Settings2, SquareTerminal, } from 'lucide-angular' import { NavMainComponent } from './nav-main.component' import { NavProjectsComponent } from './nav-projects.component' import { NavSecondaryComponent } from './nav-secondary.component' import { NavUserComponent } from './nav-user.component' import { TeamSwitcherComponent } from './team-switcher.component' import type { SidebarNavItem, SidebarProject, SidebarUser } from './sidebar-02.models' const data: { user: SidebarUser navMain: SidebarNavItem[] navSecondary: SidebarNavItem[] projects: SidebarProject[] } = { user: { name: 'shadcn', email: '[email protected]', }, navMain: [ { title: 'Playground', url: '#', icon: SquareTerminal, isActive: true, items: [ { title: 'History', url: '#' }, { title: 'Starred', url: '#' }, { title: 'Settings', url: '#' }, ], }, { title: 'Models', url: '#', icon: Bot, items: [ { title: 'Genesis', url: '#' }, { title: 'Explorer', url: '#' }, { title: 'Quantum', url: '#' }, ], }, { title: 'Documentation', url: '#', icon: BookOpen, items: [ { title: 'Introduction', url: '#' }, { title: 'Get Started', url: '#' }, { title: 'Tutorials', url: '#' }, { title: 'Changelog', url: '#' }, ], }, { title: 'Settings', url: '#', icon: Settings2, items: [ { title: 'General', url: '#' }, { title: 'Team', url: '#' }, { title: 'Billing', url: '#' }, { title: 'Limits', url: '#' }, ], }, ], navSecondary: [ { title: 'Support', url: '#', icon: LifeBuoy }, { title: 'Feedback', url: '#', icon: Send }, ], projects: [ { name: 'Design Engineering', url: '#', icon: Frame }, { name: 'Sales & Marketing', url: '#', icon: PieChart }, { name: 'Travel', url: '#', icon: MapIcon }, ], } /** * Sidebar02 -- the React block, 1:1: a `collapsible="icon"` Sidebar with TeamSwitcher * header, primary nav, projects, secondary links and a user dropdown footer. It reads * the surrounding <ui-sidebar-provider> (pair with <ui-sidebar-inset> + * <ui-sidebar-trigger>), so the trigger, the rail and Cmd/Ctrl+B all collapse it. * Edit `data` to change routes; each section is a sibling file. */ @Component({ changeDetection: ChangeDetectionStrategy.Eager, selector: 'ui-sidebar-02, [ui-sidebar-02]', standalone: true, // React renders <Sidebar> itself: keep this wrapper out of the provider's flex layout. host: { class: 'contents' }, imports: [ UiSidebarComponent, UiSidebarHeaderComponent, UiSidebarContentComponent, UiSidebarFooterComponent, UiSidebarRailComponent, TeamSwitcherComponent, NavMainComponent, NavProjectsComponent, NavSecondaryComponent, NavUserComponent, ], template: ` <ui-sidebar collapsible="icon"> <ui-sidebar-header> <team-switcher /> </ui-sidebar-header> <ui-sidebar-content> <nav-main [items]="data.navMain" /> <nav-projects [projects]="data.projects" /> <nav-secondary [items]="data.navSecondary" class="mt-auto" /> </ui-sidebar-content> <ui-sidebar-footer> <nav-user [user]="data.user" /> </ui-sidebar-footer> <button ui-sidebar-rail></button> </ui-sidebar> `, }) export class UiSidebar02Component { readonly data = data }src/app/components/blocks/sidebar-02/sidebar-02.models.ts0.6 kB
import type { LucideIconData } from 'lucide-angular' export interface SidebarSubItem { title: string url: string isActive?: boolean } export interface SidebarNavItem { title: string url: string icon: LucideIconData isActive?: boolean items?: SidebarSubItem[] } export interface SidebarProject { name: string url: string icon: LucideIconData } /** `logo: 'uipkge'` renders the 4-quadrant uipkge mark (inline SVG), like the React block. */ export interface SidebarTeam { name: string plan: string logo: LucideIconData | 'uipkge' } export interface SidebarUser { name: string email: string }src/app/components/blocks/sidebar-02/team-switcher.component.ts5.9 kB
// Edit teams + activeTeam below to match your tenant model. The dropdown // is the full team switcher pattern -- avatar tile, label, kbd shortcut, // and a "Add team" footer row. Wire the select handler to your tenant API. import { Component, signal, ChangeDetectionStrategy } from '@angular/core' import { AudioWaveform, Check, ChevronsUpDown, Command, LucideAngularModule, Plus } from 'lucide-angular' import { UiDropdownMenuComponent, UiDropdownMenuContentComponent, UiDropdownMenuItemComponent, UiDropdownMenuLabelComponent, UiDropdownMenuSeparatorComponent, UiDropdownMenuShortcutComponent, UiDropdownMenuTriggerComponent, } from '@/ui/dropdown-menu/dropdown-menu.component' import { UiSidebarMenuButtonComponent, UiSidebarMenuComponent, UiSidebarMenuItemComponent, injectSidebar, } from '@/ui/sidebar/sidebar.component' import type { SidebarTeam } from './sidebar-02.models' const teams: SidebarTeam[] = [ { name: 'uipkge', logo: 'uipkge', plan: 'UI registry' }, { name: 'uipkge HRMS', logo: AudioWaveform, plan: 'Vertical' }, { name: 'uipkge Hospital', logo: Command, plan: 'Vertical' }, ] @Component({ changeDetection: ChangeDetectionStrategy.Eager, selector: 'team-switcher', standalone: true, host: { class: 'contents' }, imports: [ LucideAngularModule, UiSidebarMenuComponent, UiSidebarMenuItemComponent, UiSidebarMenuButtonComponent, UiDropdownMenuComponent, UiDropdownMenuTriggerComponent, UiDropdownMenuContentComponent, UiDropdownMenuItemComponent, UiDropdownMenuLabelComponent, UiDropdownMenuSeparatorComponent, UiDropdownMenuShortcutComponent, ], 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" > <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" > @if (activeTeam().logo === 'uipkge') { <!-- 4-quadrant uipkge logo (inline, like the React UipkgeMark). --> <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> } @else { <lucide-icon [img]="$any(activeTeam().logo)" class="size-4 group-data-[collapsible=icon]:size-3.5" /> } </div> <div class="grid flex-1 text-left text-sm leading-tight group-data-[collapsible=icon]:hidden"> <span class="font-display truncate font-bold">{{ activeTeam().name }}</span> <span class="text-muted-foreground truncate text-xs">{{ activeTeam().plan }}</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="start" [sideOffset]="4" > <ui-dropdown-menu-label class="text-muted-foreground text-xs">Teams</ui-dropdown-menu-label> @for (team of teams; track team.name; let i = $index) { <ui-dropdown-menu-item class="gap-2 p-2" (select)="activeTeam.set(team)"> <div class="flex size-6 items-center justify-center rounded-sm border"> @if (team.logo === 'uipkge') { <!-- 4-quadrant uipkge logo (inline, like the React UipkgeMark). --> <svg viewBox="0 0 24 24" class="size-3.5 shrink-0" 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> } @else { <lucide-icon [img]="$any(team.logo)" class="size-3.5 shrink-0" /> } </div> {{ team.name }} @if (activeTeam() === team) { <lucide-icon [img]="Check" class="ml-auto size-4" /> } @else { <ui-dropdown-menu-shortcut>⌘{{ i + 1 }}</ui-dropdown-menu-shortcut> } </ui-dropdown-menu-item> } <ui-dropdown-menu-separator /> <ui-dropdown-menu-item class="gap-2 p-2"> <div class="bg-background flex size-6 items-center justify-center rounded-md border"> <lucide-icon [img]="Plus" class="size-4" /> </div> <div class="text-muted-foreground font-medium">Add team</div> </ui-dropdown-menu-item> </ui-dropdown-menu-content> </ui-dropdown-menu> </li> </ul> `, }) export class TeamSwitcherComponent { readonly sidebar = injectSidebar() readonly teams = teams readonly activeTeam = signal<SidebarTeam>(teams[0]!) protected readonly ChevronsUpDown = ChevronsUpDown protected readonly Check = Check protected readonly Plus = Plus }src/app/components/blocks/sidebar-02/nav-main.component.ts2.7 kB
import { Component, Input, ChangeDetectionStrategy } from '@angular/core' import { ChevronRight, LucideAngularModule } from 'lucide-angular' import { UiCollapsibleComponent, UiCollapsibleContentComponent, UiCollapsibleTriggerComponent, } from '@/ui/collapsible/collapsible.component' import { UiSidebarGroupComponent, UiSidebarGroupLabelComponent, UiSidebarMenuActionComponent, UiSidebarMenuButtonComponent, UiSidebarMenuComponent, UiSidebarMenuItemComponent, UiSidebarMenuSubButtonComponent, UiSidebarMenuSubComponent, UiSidebarMenuSubItemComponent, } from '@/ui/sidebar/sidebar.component' import type { SidebarNavItem } from './sidebar-02.models' @Component({ changeDetection: ChangeDetectionStrategy.Eager, selector: 'nav-main', standalone: true, host: { class: 'contents' }, imports: [ LucideAngularModule, UiCollapsibleComponent, UiCollapsibleTriggerComponent, UiCollapsibleContentComponent, UiSidebarGroupComponent, UiSidebarGroupLabelComponent, UiSidebarMenuComponent, UiSidebarMenuItemComponent, UiSidebarMenuButtonComponent, UiSidebarMenuActionComponent, UiSidebarMenuSubComponent, UiSidebarMenuSubItemComponent, UiSidebarMenuSubButtonComponent, ], template: ` <ui-sidebar-group> <ui-sidebar-group-label>Platform</ui-sidebar-group-label> <ul ui-sidebar-menu> @for (item of items; track item.title) { <li ui-sidebar-menu-item ui-collapsible [defaultOpen]="!!item.isActive"> <a ui-sidebar-menu-button [href]="item.url" [tooltip]="item.title" [isActive]="!!item.isActive"> <lucide-icon [img]="item.icon" class="size-4 shrink-0" /> <span>{{ item.title }}</span> </a> @if (item.items?.length) { <button type="button" ui-sidebar-menu-action ui-collapsible-trigger class="data-[state=open]:rotate-90"> <lucide-icon [img]="ChevronRight" class="size-4 shrink-0" /> <span class="sr-only">Toggle</span> </button> <ui-collapsible-content> <ul ui-sidebar-menu-sub> @for (subItem of item.items; track subItem.title) { <li ui-sidebar-menu-sub-item> <a ui-sidebar-menu-sub-button [href]="subItem.url" [isActive]="!!subItem.isActive"> <span>{{ subItem.title }}</span> </a> </li> } </ul> </ui-collapsible-content> } </li> } </ul> </ui-sidebar-group> `, }) export class NavMainComponent { @Input() items: SidebarNavItem[] = [] protected readonly ChevronRight = ChevronRight }src/app/components/blocks/sidebar-02/nav-projects.component.ts3.8 kB
import { Component, Input, ChangeDetectionStrategy } from '@angular/core' import { Folder, Forward, LucideAngularModule, MoreHorizontal, Trash2 } from 'lucide-angular' import { UiDropdownMenuComponent, UiDropdownMenuContentComponent, UiDropdownMenuItemComponent, UiDropdownMenuSeparatorComponent, UiDropdownMenuTriggerComponent, } from '@/ui/dropdown-menu/dropdown-menu.component' import { UiSidebarGroupComponent, UiSidebarGroupLabelComponent, UiSidebarMenuActionComponent, UiSidebarMenuButtonComponent, UiSidebarMenuComponent, UiSidebarMenuItemComponent, injectSidebar, } from '@/ui/sidebar/sidebar.component' import type { SidebarProject } from './sidebar-02.models' @Component({ changeDetection: ChangeDetectionStrategy.Eager, selector: 'nav-projects', standalone: true, host: { class: 'contents' }, imports: [ LucideAngularModule, UiDropdownMenuComponent, UiDropdownMenuTriggerComponent, UiDropdownMenuContentComponent, UiDropdownMenuItemComponent, UiDropdownMenuSeparatorComponent, UiSidebarGroupComponent, UiSidebarGroupLabelComponent, UiSidebarMenuComponent, UiSidebarMenuItemComponent, UiSidebarMenuButtonComponent, UiSidebarMenuActionComponent, ], template: ` <!-- Upstream shadcn-ui hides this entire group on icon-mode collapse with group-data-[collapsible=icon]:hidden. We keep it visible so the project icons stay reachable in the narrow column; the group label and the <span> children of each menu button already self-hide on collapse, leaving an icon-only column that lines up with NavMain. --> <ui-sidebar-group> <ui-sidebar-group-label>Projects</ui-sidebar-group-label> <ul ui-sidebar-menu> @for (item of projects; track item.name) { <li ui-sidebar-menu-item> <a ui-sidebar-menu-button [href]="item.url"> <lucide-icon [img]="item.icon" class="size-4 shrink-0" /> <span>{{ item.name }}</span> </a> <ui-dropdown-menu> <button type="button" ui-sidebar-menu-action ui-dropdown-menu-trigger showOnHover> <lucide-icon [img]="MoreHorizontal" class="size-4 shrink-0" /> <span class="sr-only">More</span> </button> <ui-dropdown-menu-content class="w-48 rounded-lg" [side]="sidebar.isMobile ? 'bottom' : 'right'" [align]="sidebar.isMobile ? 'end' : 'start'" > <ui-dropdown-menu-item> <lucide-icon [img]="Folder" class="text-muted-foreground" /> <span>View Project</span> </ui-dropdown-menu-item> <ui-dropdown-menu-item> <lucide-icon [img]="Forward" class="text-muted-foreground" /> <span>Share Project</span> </ui-dropdown-menu-item> <ui-dropdown-menu-separator /> <ui-dropdown-menu-item> <lucide-icon [img]="Trash2" class="text-muted-foreground" /> <span>Delete Project</span> </ui-dropdown-menu-item> </ui-dropdown-menu-content> </ui-dropdown-menu> </li> } <li ui-sidebar-menu-item> <button type="button" ui-sidebar-menu-button> <lucide-icon [img]="MoreHorizontal" class="size-4 shrink-0" /> <span>More</span> </button> </li> </ul> </ui-sidebar-group> `, }) export class NavProjectsComponent { readonly sidebar = injectSidebar() @Input() projects: SidebarProject[] = [] protected readonly MoreHorizontal = MoreHorizontal protected readonly Folder = Folder protected readonly Forward = Forward protected readonly Trash2 = Trash2 }src/app/components/blocks/sidebar-02/nav-secondary.component.ts1.5 kB
import { Component, Input, ChangeDetectionStrategy } from '@angular/core' import { LucideAngularModule } from 'lucide-angular' import { UiSidebarGroupComponent, UiSidebarGroupContentComponent, UiSidebarMenuButtonComponent, UiSidebarMenuComponent, UiSidebarMenuItemComponent, } from '@/ui/sidebar/sidebar.component' import type { SidebarNavItem } from './sidebar-02.models' @Component({ changeDetection: ChangeDetectionStrategy.Eager, selector: 'nav-secondary', standalone: true, host: { class: 'contents' }, imports: [ LucideAngularModule, UiSidebarGroupComponent, UiSidebarGroupContentComponent, UiSidebarMenuComponent, UiSidebarMenuItemComponent, UiSidebarMenuButtonComponent, ], template: ` <ui-sidebar-group [class]="className"> <ui-sidebar-group-content> <ul ui-sidebar-menu> @for (item of items; track item.title) { <li ui-sidebar-menu-item> <a ui-sidebar-menu-button size="sm" [href]="item.url" [isActive]="!!item.isActive"> <lucide-icon [img]="item.icon" class="size-4 shrink-0" /> <span>{{ item.title }}</span> </a> </li> } </ul> </ui-sidebar-group-content> </ui-sidebar-group> `, }) export class NavSecondaryComponent { @Input() items: SidebarNavItem[] = [] /** Forwarded to the SidebarGroup, like React's `{...props}` (e.g. class="mt-auto"). */ @Input('class') className?: string }src/app/components/blocks/sidebar-02/nav-user.component.ts6.6 kB
import { Component, Input, ChangeDetectionStrategy } from '@angular/core' import { BadgeCheck, Bell, ChevronsUpDown, CreditCard, LogOut, LucideAngularModule, Monitor, Moon, Palette, Sun, Zap, } 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' import type { SidebarUser } from './sidebar-02.models' export type SidebarTheme = Theme @Component({ changeDetection: ChangeDetectionStrategy.Eager, selector: '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">{{ 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 text-xs">{{ 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]="Zap" /> Upgrade to Pro </ui-dropdown-menu-item> </ui-dropdown-menu-group> <ui-dropdown-menu-separator /> <ui-dropdown-menu-group> <ui-dropdown-menu-item> <lucide-icon [img]="BadgeCheck" /> Account </ui-dropdown-menu-item> <ui-dropdown-menu-item> <lucide-icon [img]="CreditCard" /> Billing </ui-dropdown-menu-item> <ui-dropdown-menu-item> <lucide-icon [img]="Bell" /> Notifications </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" /> 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" /> Light </ui-dropdown-menu-radio-item> <ui-dropdown-menu-radio-item value="dark"> <lucide-icon [img]="Moon" /> Dark </ui-dropdown-menu-radio-item> <ui-dropdown-menu-radio-item value="system"> <lucide-icon [img]="Monitor" /> 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> <lucide-icon [img]="LogOut" /> Log out </ui-dropdown-menu-item> </ui-dropdown-menu-content> </ui-dropdown-menu> </li> </ul> `, }) export class NavUserComponent { readonly sidebar = injectSidebar() readonly theme = injectTheme() @Input() user: SidebarUser = { name: '', email: '' } get initials(): string { const parts = this.user.name.trim().split(/\s+/).slice(0, 2) return parts.map((p) => p[0]?.toUpperCase()).join('') || 'U' } protected readonly ChevronsUpDown = ChevronsUpDown protected readonly Zap = Zap protected readonly BadgeCheck = BadgeCheck protected readonly CreditCard = CreditCard protected readonly Bell = Bell 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-02/index.ts0.5 kB
export { UiSidebar02Component } from './sidebar-02.component' export { TeamSwitcherComponent } from './team-switcher.component' export { NavMainComponent } from './nav-main.component' export { NavProjectsComponent } from './nav-projects.component' export { NavSecondaryComponent } from './nav-secondary.component' export { NavUserComponent, type SidebarTheme } from './nav-user.component' export type { SidebarNavItem, SidebarSubItem, SidebarProject, SidebarTeam, SidebarUser } from './sidebar-02.models'
Raw manifest:https://uipkge.dev/r/angular/sidebar-02.json