Sidebar Component

August 16, 2025 ยท View on GitHub

The Sidebar component is a powerful, flexible navigation component built with Angular signals for optimal performance. It provides responsive behavior, keyboard navigation, multiple display modes, sticky header/footer, and extensive customization options.

Table of Contents

Features

  • ๐Ÿš€ Signal-based: Built with Angular signals for optimal performance
  • โŒจ๏ธ Full keyboard navigation: Arrow keys, Enter, Space, Home, End support
  • ๐Ÿ“ฑ Responsive design: Automatically adapts to different screen sizes with mobile overlay mode
  • ๐ŸŽฏ Target-based triggers: Control sidebars by ID without ViewChild references
  • ๐Ÿ”„ Multiple modes: Push (content shifts) and overlay (content covered) display modes
  • ๐Ÿ“ Flexible sizing: 5 different width sizes (sm, md, lg, xl, icon)
  • ๐ŸŽจ Icon mode: Compact icon-only mode with tooltips and dropdowns
  • ๐ŸŒณ Nested navigation: Multi-level navigation with expandable groups
  • ๐Ÿ“Œ Sticky layout: Header and footer stick to top/bottom with scrollable content
  • ๐ŸŽญ Flexible positioning: Left or right sidebar positioning with flexbox layout
  • โ™ฟ Accessibility: Full ARIA support and screen reader friendly
  • ๐Ÿ”ง Service integration: SidebarService for programmatic control across components

Basic Usage

Simple Sidebar Structure

The sidebar follows a specific hierarchy where users provide their own main content element:

import { Component } from '@angular/core';
import { 
  Sidebar, 
  SidebarContainer, 
  SidebarContent, 
  SidebarHeader, 
  SidebarFooter,
  SidebarNavGroup, 
  SidebarNavItem, 
  SidebarTrigger 
} from '@lib/sidebar';

@Component({
  selector: 'app-example',
  standalone: true,
  imports: [
    Sidebar,
    SidebarContainer,
    SidebarContent,
    SidebarHeader,
    SidebarFooter,
    SidebarNavGroup,
    SidebarNavItem,
    SidebarTrigger
  ],
  template: `
    <!-- Trigger button (optional - can be anywhere) -->
    <SidebarTrigger target="my-sidebar" [showLabel]="true" label="Toggle Sidebar" />
    
    <!-- Main sidebar container -->
    <SidebarContainer>
      <!-- Sidebar component -->
      <Sidebar 
        id="my-sidebar" 
        side="left" 
        mode="push" 
        size="md"
        [defaultExpanded]="true"
        ariaLabel="Main navigation"
      >
        <!-- Sticky header -->
        <SidebarHeader slot="sidebar-header">
          <div class="flex items-center gap-3">
            <div class="w-8 h-8 bg-blue-600 rounded-lg"></div>
            <h2 class="text-lg font-semibold">My App</h2>
          </div>
        </SidebarHeader>
        
        <!-- Scrollable content -->
        <SidebarContent slot="sidebar-content">
          <SidebarNavGroup title="Main Navigation">
            <SidebarNavItem 
              routerLink="/dashboard" 
              label="Dashboard" 
              icon="<svg>...</svg>" 
            />
            <SidebarNavItem 
              routerLink="/users" 
              label="Users" 
              icon="<svg>...</svg>"
              badge="12" 
            />
            <SidebarNavItem 
              [hasChildren]="true"
              label="Analytics"
              icon="<svg>...</svg>"
            >
              <SidebarNavItem 
                [isSubmenuItem]="true"
                routerLink="/analytics/reports" 
                label="Reports" 
              />
              <SidebarNavItem 
                [isSubmenuItem]="true"
                routerLink="/analytics/insights" 
                label="Insights" 
              />
            </SidebarNavItem>
          </SidebarNavGroup>
        </SidebarContent>
        
        <!-- Sticky footer -->
        <SidebarFooter slot="sidebar-footer">
          <div class="text-sm text-muted-foreground">
            v2.0.3 โ€ข ยฉ 2025 SuperUI
          </div>
        </SidebarFooter>
      </Sidebar>
      
      <!-- User's main content - use any HTML element -->
      <div class="flex-1 overflow-auto">
        <main class="p-6">
          <h1>Main Content Area</h1>
          <p>Your application content goes here...</p>
        </main>
      </div>
    </SidebarContainer>
  `
})
export class ExampleComponent {}

Installation

  1. Install the package (if using npm package):
npx ngsui-cli add sidebar
  1. Import the components in your module or standalone component:
import { 
  Sidebar, 
  SidebarContainer, 
  SidebarContent, 
  SidebarHeader, 
  SidebarFooter,
  SidebarNavGroup, 
  SidebarNavItem, 
  SidebarTrigger,
  SidebarService  // For programmatic control
} from '@lib/sidebar';
  1. Add required styles (usually automatically included with the component).

Component Architecture

The sidebar follows a hierarchical structure:

SidebarContainer (flexbox container)
โ”œโ”€โ”€ Sidebar (main sidebar component)
โ”‚   โ”œโ”€โ”€ SidebarHeader (sticky header)
โ”‚   โ”œโ”€โ”€ SidebarContent (scrollable content)
โ”‚   โ”‚   โ””โ”€โ”€ SidebarNavGroup
โ”‚   โ”‚       โ””โ”€โ”€ SidebarNavItem (can be nested)
โ”‚   โ””โ”€โ”€ SidebarFooter (sticky footer)
โ””โ”€โ”€ div/main/section (user's main content with flex-1 class)

Key Points:

  • SidebarContainer: Manages flexbox layout and positioning
  • Sidebar: Contains all navigation with sticky header/footer
  • User Content: Any HTML element with flex-1 class takes remaining space
  • No SidebarMainContent: Users write their own main content structure

API Reference

SidebarContainer

The root container component that manages flexbox layout and provides context to child components.

SidebarContainer Properties

PropertyTypeDefaultDescription
customClassstring''Additional CSS classes for the container
heightstring'h-screen'Height class for the container

SidebarContainer Usage

<SidebarContainer>
  <Sidebar>...</Sidebar>
  <div class="flex-1 overflow-auto">...</div>
</SidebarContainer>

The main sidebar component that contains navigation and controls display behavior.

PropertyTypeDefaultDescription
idstring''Unique identifier for the sidebar (used by triggers)
side'left' | 'right''left'Which side of the screen to display the sidebar
mode'push' | 'overlay''push'How the sidebar affects the main content
size'sm' | 'md' | 'lg' | 'xl''md'Width of the sidebar
defaultExpandedbooleantrueDefault expanded state on initialization
isExpandedboolean | undefinedundefinedExternal control of expanded state
allowCollapsebooleantrueWhether the sidebar can be collapsed
allowIconOnlybooleantrueWhether the sidebar can use icon-only mode
showBackdropInOverlaybooleantrueWhether to show backdrop in overlay mode
closeOnBackdropClickbooleantrueWhether to close sidebar when backdrop is clicked
closeOnEscapebooleantrueWhether to close sidebar when Escape is pressed
preventBodyScrollbooleantrueWhether to prevent body scroll in overlay mode
mobileBreakpointnumber768Pixel width for mobile breakpoint
mediumBreakpointnumber1024Pixel width for medium screen breakpoint
ariaLabelstring'Navigation sidebar'Accessibility label for the sidebar
customClassstring''Additional CSS classes for the sidebar
headerCustomClassstring''Additional CSS classes for the header area
contentCustomClassstring''Additional CSS classes for the content area
footerCustomClassstring''Additional CSS classes for the footer area
EventTypeDescription
onExpandedChangeEventEmitter<boolean>Emitted when expanded state changes
onStateChangeEventEmitter<SidebarState>Emitted when sidebar state changes
MethodDescription
expand()Expand the sidebar and exit icon mode
collapse()Collapse the sidebar
toggleExpanded()Toggle between expanded and collapsed states
setIconOnly()Set the sidebar to icon-only mode
toggleIconOnly()Toggle between icon-only and expanded modes
PropertyTypeDescription
isExpandedComputed()booleanCurrent expanded state (respects external control)
isIconOnly()booleanWhether sidebar is in icon-only mode
isMobile()booleanWhether current screen is mobile size
isMediumScreen()booleanWhether current screen is medium size
effectiveMode()'push' | 'overlay'Actual mode (forces overlay on mobile)
currentState()'collapsed' | 'expanded' | 'iconOnly'Current visual state
currentSize()'sm' | 'md' | 'lg' | 'xl' | 'icon'Current size (icon when in icon mode)

The sidebar uses Angular's content projection with slots:

  • sidebar-header: Content for the sticky header area
  • sidebar-content: Main scrollable content area
  • sidebar-footer: Content for the sticky footer area
SizeWidthDescription
sm256px (16rem)Compact sidebar for minimal interfaces
md320px (20rem)Standard width for most applications (default)
lg384px (24rem)Larger sidebar for content-heavy navigation
xl448px (28rem)Maximum width for complex navigation structures
icon64px (4rem)Icon-only mode for minimal space usage

SidebarHeader

Container for sidebar header content with sticky positioning.

SidebarHeader Properties

PropertyTypeDefaultDescription
customClassstring''Additional CSS classes

SidebarContent

Scrollable content area of the sidebar.

SidebarContent Properties

PropertyTypeDefaultDescription
customClassstring''Additional CSS classes
isIconOnlybooleanfalseWhether in icon-only mode (affects styling)

SidebarFooter

Container for sidebar footer content with sticky positioning.

SidebarFooter Properties

PropertyTypeDefaultDescription
customClassstring''Additional CSS classes

SidebarNavGroup

Groups related navigation items with an optional title.

SidebarNavGroup Properties

PropertyTypeDefaultDescription
titlestring''Optional group title
isIconOnlybooleanfalseWhether in icon-only mode (hides title)
customClassstring''Additional CSS classes
titleCustomClassstring''Additional CSS classes for the title

SidebarNavItem

Individual navigation item with support for icons, badges, and nesting.

SidebarNavItem Properties

PropertyTypeDefaultDescription
routerLinkstring | any[] | nullnullAngular router link
labelstring''Display text for the item
iconstring | Type<any> | TemplateRef<any> | LucideIconData''Universal icon support: SVG markup, Angular component, template, or Lucide icon data
badgestring''Badge text or number
isActivebooleanfalseWhether the item is currently active
hasChildrenbooleanfalseWhether this item has submenu items
isIconOnlybooleanfalseWhether in icon-only mode
isSubmenuItembooleanfalseWhether this is a submenu item
customClassstring''Additional CSS classes
badgeCustomClassstring''Additional CSS classes for the badge

SidebarNavItem Events

EventTypeDescription
onClickEventEmitter<Event>Emitted when item is clicked

SidebarNavItem Computed Properties

PropertyTypeDescription
isExpanded()booleanWhether submenu is expanded
isHovered()booleanWhether item is being hovered (for tooltips)
showLabel()booleanWhether to show the label text
showTooltip()booleanWhether to show tooltip in icon mode

SidebarNavItem Methods

MethodDescription
onItemClick(event: Event)Handle item click (toggles submenu if has children)
onKeyDown(event: KeyboardEvent)Handle keyboard navigation
onMouseEnter()Handle mouse enter for tooltip
onMouseLeave()Handle mouse leave for tooltip
getAriaLabel()Get accessible label for screen readers

SidebarTrigger

Button component to toggle sidebar visibility.

SidebarTrigger Properties

PropertyTypeDefaultDescription
targetstring''ID of the sidebar to control
labelstring''Button label text
showIconbooleantrueWhether to show the hamburger icon
showLabelbooleanfalseWhether to show text label
isExpandedbooleanfalseFallback expanded state if no target
variant'default' | 'outline' | 'ghost''outline'Button style variant
size'sm' | 'md' | 'lg''md'Button size
customClassstring''Additional CSS classes

SidebarTrigger Events

EventTypeDescription
onTriggerEventEmitter<void>Emitted when trigger is activated

SidebarTrigger Methods

MethodDescription
onTriggerClick()Handle trigger button click
getTargetExpandedState()Get expanded state from target sidebar
getAriaLabel()Get accessible label for the button

SidebarService

Injectable service for programmatic sidebar control.

SidebarService Methods

MethodParametersReturn TypeDescription
registerSidebar(id, sidebar)id: string, sidebar: SidebarvoidRegister a sidebar instance
unregisterSidebar(id)id: stringvoidUnregister a sidebar instance
getSidebar(id)id: stringSidebar | undefinedGet sidebar instance by ID
toggleSidebar(id)id: stringbooleanToggle sidebar by ID
getAllSidebars()-Sidebar[]Get all registered sidebar instances

SidebarService Usage

import { Component, inject } from '@angular/core';
import { SidebarService } from '@lib/sidebar';

@Component({
  template: `
    <button (click)="toggleSidebar()">Toggle Sidebar</button>
  `
})
export class MyComponent {
  private sidebarService = inject(SidebarService);
  
  toggleSidebar() {
    this.sidebarService.toggle('my-sidebar');
  }
}

Migration Note

SidebarMainContent has been removed in the current implementation for greater flexibility. Users should provide their own main content element with the flex-1 overflow-auto CSS classes.

Before (old implementation)

<SidebarContainer>
  <Sidebar>...</Sidebar>
  <SidebarMainContent>
    <!-- Your content here -->
  </SidebarMainContent>
</SidebarContainer>

After (current implementation)

<SidebarContainer>
  <Sidebar>...</Sidebar>
  <div class="flex-1 overflow-auto">
    <!-- Your content here -->
  </div>
</SidebarContainer>

Advanced Examples

Nested Navigation

<SidebarNavGroup title="Analytics">
  <SidebarNavItem 
    label="Reports" 
    icon="<svg>...</svg>" 
    [hasChildren]="true"
  >
    <!-- Level 2 -->
    <SidebarNavItem 
      routerLink="/reports/sales" 
      label="Sales Reports" 
      [isSubmenuItem]="true"
      [customClass]="isIconOnly ? '' : 'ml-4'"
    />
    <SidebarNavItem 
      label="User Reports" 
      [hasChildren]="true" 
      [isSubmenuItem]="true"
      [customClass]="isIconOnly ? '' : 'ml-4'"
    >
      <!-- Level 3 -->
      <SidebarNavItem 
        routerLink="/reports/users/active" 
        label="Active Users" 
        [isSubmenuItem]="true"
        [customClass]="isIconOnly ? '' : 'ml-8'"
      />
    </SidebarNavItem>
  </SidebarNavItem>
</SidebarNavGroup>

Responsive Sidebar

@Component({
  template: `
    <SidebarContainer>
      <Sidebar 
        id="responsive-sidebar"
        [side]="sidebarSide()"
        [mode]="sidebarMode()"
        [size]="sidebarSize()"
        [defaultExpanded]="!isMobile()"
      >
        <!-- Sidebar content -->
      </Sidebar>
      
      <div class="flex-1">
        <!-- Main content -->
      </div>
    </SidebarContainer>
  `
})
export class ResponsiveExample {
  // Responsive behavior
  readonly isMobile = computed(() => window.innerWidth <= 768);
  readonly sidebarMode = computed(() => this.isMobile() ? 'overlay' : 'push');
  readonly sidebarSide = computed(() => 'left');
  readonly sidebarSize = computed(() => this.isMobile() ? 'sm' : 'md');
}

Custom Styling

<Sidebar 
  id="custom-sidebar"
  [customClass]="'bg-gradient-to-b from-blue-900 to-purple-900 text-white'"
  [headerCustomClass]="'bg-blue-800 border-b border-blue-700'"
>
  <SidebarHeader slot="sidebar-header">
    <div class="text-white font-bold">Custom Sidebar</div>
  </SidebarHeader>
  
  <SidebarContent slot="sidebar-content">
    <SidebarNavGroup 
      title="Navigation" 
      [titleCustomClass]="'text-blue-200'"
    >
      <SidebarNavItem 
        label="Dashboard" 
        [customClass]="'text-white hover:bg-blue-800'"
        [badgeCustomClass]="'bg-yellow-500 text-yellow-900'"
        badge="3"
      />
    </SidebarNavGroup>
  </SidebarContent>
</Sidebar>

Icon Mode with Tooltips

@Component({
  template: `
    <Sidebar 
      id="icon-sidebar"
      #sidebar
      [defaultExpanded]="false"
    >
      <SidebarContent slot="sidebar-content" [isIconOnly]="sidebar.isIconOnly()">
        <SidebarNavGroup [isIconOnly]="sidebar.isIconOnly()">
          <SidebarNavItem 
            routerLink="/dashboard"
            label="Dashboard"
            icon="<svg>...</svg>"
            [isIconOnly]="sidebar.isIconOnly()"
          />
          <!-- In icon mode, tooltips automatically appear on hover -->
        </SidebarNavGroup>
      </SidebarContent>
    </Sidebar>
  `
})
export class IconModeExample {}

Multiple Sidebars

<SidebarContainer>
  <!-- Left sidebar -->
  <Sidebar 
    id="left-sidebar" 
    side="left" 
    mode="push"
    ariaLabel="Main navigation"
  >
    <!-- Navigation content -->
  </Sidebar>
  
  <!-- Main content -->
  <div class="flex-1">
    <main>Content</main>
  </div>
  
  <!-- Right sidebar -->
  <Sidebar 
    id="right-sidebar" 
    side="right" 
    mode="overlay"
    ariaLabel="Tools and settings"
  >
    <!-- Tools content -->
  </Sidebar>
</SidebarContainer>

<!-- Triggers -->
<SidebarTrigger target="left-sidebar" label="Menu" />
<SidebarTrigger target="right-sidebar" label="Tools" />

Keyboard Navigation

The sidebar provides comprehensive keyboard navigation support:

KeyAction
โ†‘ / โ†“Navigate between menu items
โ† / โ†’Collapse/expand submenus
Enter / SpaceActivate item or toggle submenu
HomeJump to first item
EndJump to last item
TabNavigate between sidebar groups
EscapeClose sidebar (when in overlay mode)

Focus Management

  • Focus is automatically managed when navigating with arrow keys
  • When a submenu is expanded, focus moves to the first submenu item
  • Focus is trapped within the sidebar when using overlay mode
  • Proper focus indicators are provided for keyboard users

Example: Programmatic Focus

@Component({
  template: `
    <Sidebar #sidebar id="my-sidebar">
      <SidebarContent slot="sidebar-content">
        <SidebarNavItem 
          #firstItem
          routerLink="/dashboard" 
          label="Dashboard" 
        />
      </SidebarContent>
    </Sidebar>
  `
})
export class FocusExample {
  @ViewChild('firstItem') firstItem!: SidebarNavItem;
  
  focusFirstItem() {
    // Focus first item programmatically
    this.firstItem.focus();
  }
}

Responsive Behavior

Automatic Responsive Mode

The sidebar automatically adapts to different screen sizes:

  • Desktop (>1024px): Push mode by default, full size
  • Tablet (768-1024px): Push mode, potentially smaller size
  • Mobile (<768px): Overlay mode, compact size

Manual Responsive Control

@Component({
  template: `
    <Sidebar 
      [mode]="responsiveMode()"
      [size]="responsiveSize()"
      [defaultExpanded]="!isMobileDevice()"
    >
      <!-- Content -->
    </Sidebar>
  `
})
export class ResponsiveControl {
  private readonly breakpoint = inject(BreakpointObserver);
  
  readonly isMobileDevice = computed(() => 
    this.breakpoint.isMatched('(max-width: 768px)')
  );
  
  readonly responsiveMode = computed(() => 
    this.isMobileDevice() ? 'overlay' : 'push'
  );
  
  readonly responsiveSize = computed(() => 
    this.isMobileDevice() ? 'sm' : 'md'
  );
}

Responsive Navigation Items

<!-- Show different content based on screen size -->
<SidebarNavItem 
  [label]="isMobile() ? 'Dash' : 'Dashboard'"
  [icon]="dashboardIcon"
  routerLink="/dashboard"
/>

<!-- Hide items on mobile -->
<SidebarNavItem 
  *ngIf="!isMobile()"
  label="Advanced Settings"
  routerLink="/settings/advanced"
/>

Accessibility

The sidebar component is built with accessibility in mind:

ARIA Support

  • Proper ARIA roles (navigation, menu, menuitem)
  • ARIA labels and descriptions
  • ARIA expanded state for submenus
  • ARIA current for active items

Screen Reader Support

  • Descriptive labels for all interactive elements
  • Status announcements for state changes
  • Proper heading hierarchy
  • Alternative text for icons

Example: Enhanced Accessibility

<Sidebar 
  id="accessible-sidebar"
  ariaLabel="Main navigation menu"
  role="navigation"
>
  <SidebarContent slot="sidebar-content">
    <SidebarNavGroup 
      title="Primary Navigation"
      role="group"
      [attr.aria-labelledby]="groupId"
    >
      <SidebarNavItem 
        routerLink="/dashboard"
        label="Dashboard"
        [attr.aria-current]="isCurrentPage('/dashboard') ? 'page' : null"
        [attr.aria-describedby]="'dashboard-desc'"
      />
      <div id="dashboard-desc" class="sr-only">
        Main dashboard with overview of all metrics
      </div>
    </SidebarNavGroup>
  </SidebarContent>
</Sidebar>

Best Practices

Performance

  1. Use OnPush Change Detection:
@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  // ...
})
  1. Lazy Load Navigation Data:
readonly navigationItems = computed(() => {
  return this.authService.user()?.role === 'admin' 
    ? this.adminNavItems() 
    : this.userNavItems();
});
  1. Optimize Icon Rendering:
// Pre-sanitize icons for better performance
readonly sanitizedIcon = computed(() => 
  this.sanitizer.bypassSecurityTrustHtml(this.icon())
);

UX Guidelines

  1. Consistent Navigation: Keep navigation structure consistent across your application
  2. Clear Labels: Use descriptive labels that clearly indicate the destination
  3. Visual Hierarchy: Use grouping and indentation to show relationships
  4. State Indicators: Show active states and loading indicators appropriately

Code Organization

  1. Separate Navigation Logic:
@Injectable()
export class NavigationService {
  getNavigationItems(userRole: string) {
    // Return navigation items based on user role
  }
}
  1. Use TypeScript Interfaces:
interface NavigationItem {
  label: string;
  route: string;
  icon: string;
  badge?: string;
  children?: NavigationItem[];
}
  1. Component Composition:
@Component({
  template: `
    <SidebarNavGroup title="Analytics">
      <app-analytics-nav-items />
    </SidebarNavGroup>
  `
})
export class AnalyticsNavComponent {}

Troubleshooting

Common Issues

Problem: Sidebar trigger button doesn't open/close the sidebar.

Solution: Ensure the trigger target matches the sidebar id:

<SidebarTrigger target="my-sidebar" />
<Sidebar id="my-sidebar"> <!-- Must match --> 

SidebarMainContent Not Found Error

Problem: Error about SidebarMainContent component not being found.

Solution: SidebarMainContent has been removed. Replace it with your own element:

<!-- OLD - Will cause errors -->
<SidebarContainer>
  <Sidebar>...</Sidebar>
  <SidebarMainContent>Content</SidebarMainContent>
</SidebarContainer>

<!-- NEW - Use regular HTML elements -->
<SidebarContainer>
  <Sidebar>...</Sidebar>
  <div class="flex-1 overflow-auto">
    <main class="p-6">Content</main>
  </div>
</SidebarContainer>

Main Content Not Taking Full Width

Problem: Content area doesn't expand to fill remaining space.

Solution: Ensure your main content element has flex-1 class:

<SidebarContainer>
  <Sidebar>...</Sidebar>
  <div class="flex-1 overflow-auto"> <!-- Required classes -->
    <!-- Your content -->
  </div>
</SidebarContainer>

Problem: Sidebar appears in wrong position or overlaps content.

Solution: Verify proper component structure and CSS classes:

<!-- Correct structure -->
<SidebarContainer> <!-- Manages flexbox layout -->
  <Sidebar side="left">...</Sidebar> <!-- Positioned first for left -->
  <div class="flex-1 overflow-auto">...</div> <!-- Takes remaining space -->
</SidebarContainer>

<!-- For right sidebar -->
<SidebarContainer>
  <div class="flex-1 overflow-auto">...</div> <!-- Content first -->
  <Sidebar side="right">...</Sidebar> <!-- Sidebar second for right -->
</SidebarContainer>

Icons Not Displaying

Problem: SVG icons don't appear in navigation items.

Solution: Ensure SVG strings are properly formatted:

readonly dashboardIcon = `
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
    <path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/>
  </svg>
`;

Header/Footer Not Sticky

Problem: Header and footer scroll with content instead of staying fixed.

Solution: Ensure proper slot usage and CSS structure:

<Sidebar>
  <SidebarHeader slot="sidebar-header">...</SidebarHeader>
  <SidebarContent slot="sidebar-content">...</SidebarContent>
  <SidebarFooter slot="sidebar-footer">...</SidebarFooter>
</Sidebar>

Keyboard Navigation Not Working

Problem: Arrow keys don't navigate between items.

Solution: Ensure items have proper tabindex and role attributes:

<SidebarNavItem 
  role="menuitem"
  tabindex="0"
  label="Dashboard"
/>

Problem: Nested items don't show when parent is clicked.

Solution: Set hasChildren to true and use proper nesting:

<SidebarNavItem 
  [hasChildren]="true"
  label="Analytics"
>
  <SidebarNavItem 
    [isSubmenuItem]="true"
    label="Reports"
  />
</SidebarNavItem>

Responsive Issues

Problem: Sidebar doesn't adapt to mobile screens.

Solution: Use responsive mode and size:

<Sidebar 
  [mode]="isMobile() ? 'overlay' : 'push'"
  [size]="isMobile() ? 'sm' : 'md'"
  [breakpoint]="'md'"
/>

Migration from Previous Versions

If upgrading from an older version:

  1. Remove SidebarMainContent imports:
// Remove this import
import { SidebarMainContent } from '@lib/sidebar';

// Keep these imports
import { 
  Sidebar, 
  SidebarContainer, 
  SidebarContent,
  // ... other components
} from '@lib/sidebar';
  1. Update template structure:
<!-- Replace SidebarMainContent with regular elements -->
<div class="flex-1 overflow-auto">
  <!-- Your content here -->
</div>
  1. Update CSS classes:
  • Replace customClass with className
  • Ensure flexbox layout with flex-1 on main content

Debugging Tips

  1. Check Console Errors: Look for any JavaScript errors that might prevent functionality
  2. Inspect Element: Use browser dev tools to verify proper HTML structure and CSS classes
  3. Test Keyboard Navigation: Use Tab and arrow keys to test navigation flow
  4. Verify ARIA Attributes: Check that accessibility attributes are properly set
  5. Check Component Structure: Ensure proper nesting of sidebar components
  6. Validate CSS Classes: Confirm flexbox classes are applied correctly

Performance Issues

If you experience performance issues:

  1. Minimize Re-renders: Use OnPush change detection
  2. Optimize Icons: Pre-process SVG icons instead of generating them dynamically
  3. Lazy Load: Load navigation items only when needed
  4. Use TrackBy: For dynamic navigation lists, use trackBy functions
  5. Signal Optimization: Use computed signals for derived state

Development Environment Issues

  • Hot Reload: Changes might require a full page refresh
  • Build Errors: Ensure all imports are correctly updated after migration
  • TypeScript Errors: Check component property names match current API

Contributing

If you find any issues or have suggestions for improvements, please:

  1. Check existing issues on GitHub
  2. Create a new issue with detailed description
  3. Consider submitting a pull request

License

This component is part of the Angular SuperUI library and follows the same license terms.