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.
- Features
- Basic Usage
- Installation
- Component Architecture
- API Reference
- Advanced Examples
- Keyboard Navigation
- Responsive Behavior
- Customization
- Accessibility
- Best Practices
- Troubleshooting
- 🚀 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
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 {}- Install the package (if using npm package):
npx ngsui-cli add sidebar- 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';- Add required styles (usually automatically included with the component).
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)
- SidebarContainer: Manages flexbox layout and positioning
- Sidebar: Contains all navigation with sticky header/footer
- User Content: Any HTML element with
flex-1class takes remaining space - No SidebarMainContent: Users write their own main content structure
The root container component that manages flexbox layout and provides context to child components.
| Property | Type | Default | Description |
|---|---|---|---|
customClass |
string |
'' |
Additional CSS classes for the container |
height |
string |
'h-screen' |
Height class for the container |
<SidebarContainer>
<Sidebar>...</Sidebar>
<div class="flex-1 overflow-auto">...</div>
</SidebarContainer>The main sidebar component that contains navigation and controls display behavior.
| Property | Type | Default | Description |
|---|---|---|---|
id |
string |
'' |
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 |
defaultExpanded |
boolean |
true |
Default expanded state on initialization |
isExpanded |
boolean | undefined |
undefined |
External control of expanded state |
allowCollapse |
boolean |
true |
Whether the sidebar can be collapsed |
allowIconOnly |
boolean |
true |
Whether the sidebar can use icon-only mode |
showBackdropInOverlay |
boolean |
true |
Whether to show backdrop in overlay mode |
closeOnBackdropClick |
boolean |
true |
Whether to close sidebar when backdrop is clicked |
closeOnEscape |
boolean |
true |
Whether to close sidebar when Escape is pressed |
preventBodyScroll |
boolean |
true |
Whether to prevent body scroll in overlay mode |
mobileBreakpoint |
number |
768 |
Pixel width for mobile breakpoint |
mediumBreakpoint |
number |
1024 |
Pixel width for medium screen breakpoint |
ariaLabel |
string |
'Navigation sidebar' |
Accessibility label for the sidebar |
customClass |
string |
'' |
Additional CSS classes for the sidebar |
headerCustomClass |
string |
'' |
Additional CSS classes for the header area |
contentCustomClass |
string |
'' |
Additional CSS classes for the content area |
footerCustomClass |
string |
'' |
Additional CSS classes for the footer area |
| Event | Type | Description |
|---|---|---|
onExpandedChange |
EventEmitter<boolean> |
Emitted when expanded state changes |
onStateChange |
EventEmitter<SidebarState> |
Emitted when sidebar state changes |
| Method | Description |
|---|---|
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 |
| Property | Type | Description |
|---|---|---|
isExpandedComputed() |
boolean |
Current expanded state (respects external control) |
isIconOnly() |
boolean |
Whether sidebar is in icon-only mode |
isMobile() |
boolean |
Whether current screen is mobile size |
isMediumScreen() |
boolean |
Whether 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 areasidebar-content: Main scrollable content areasidebar-footer: Content for the sticky footer area
| Size | Width | Description |
|---|---|---|
sm |
256px (16rem) | Compact sidebar for minimal interfaces |
md |
320px (20rem) | Standard width for most applications (default) |
lg |
384px (24rem) | Larger sidebar for content-heavy navigation |
xl |
448px (28rem) | Maximum width for complex navigation structures |
icon |
64px (4rem) | Icon-only mode for minimal space usage |
Container for sidebar header content with sticky positioning.
| Property | Type | Default | Description |
|---|---|---|---|
customClass |
string |
'' |
Additional CSS classes |
Scrollable content area of the sidebar.
| Property | Type | Default | Description |
|---|---|---|---|
customClass |
string |
'' |
Additional CSS classes |
isIconOnly |
boolean |
false |
Whether in icon-only mode (affects styling) |
Container for sidebar footer content with sticky positioning.
| Property | Type | Default | Description |
|---|---|---|---|
customClass |
string |
'' |
Additional CSS classes |
Groups related navigation items with an optional title.
| Property | Type | Default | Description |
|---|---|---|---|
title |
string |
'' |
Optional group title |
isIconOnly |
boolean |
false |
Whether in icon-only mode (hides title) |
customClass |
string |
'' |
Additional CSS classes |
titleCustomClass |
string |
'' |
Additional CSS classes for the title |
Individual navigation item with support for icons, badges, and nesting.
| Property | Type | Default | Description |
|---|---|---|---|
routerLink |
string | any[] | null |
null |
Angular router link |
label |
string |
'' |
Display text for the item |
icon |
string | Type<any> | TemplateRef<any> | LucideIconData |
'' |
Universal icon support: SVG markup, Angular component, template, or Lucide icon data |
badge |
string |
'' |
Badge text or number |
isActive |
boolean |
false |
Whether the item is currently active |
hasChildren |
boolean |
false |
Whether this item has submenu items |
isIconOnly |
boolean |
false |
Whether in icon-only mode |
isSubmenuItem |
boolean |
false |
Whether this is a submenu item |
customClass |
string |
'' |
Additional CSS classes |
badgeCustomClass |
string |
'' |
Additional CSS classes for the badge |
| Event | Type | Description |
|---|---|---|
onClick |
EventEmitter<Event> |
Emitted when item is clicked |
| Property | Type | Description |
|---|---|---|
isExpanded() |
boolean |
Whether submenu is expanded |
isHovered() |
boolean |
Whether item is being hovered (for tooltips) |
showLabel() |
boolean |
Whether to show the label text |
showTooltip() |
boolean |
Whether to show tooltip in icon mode |
| Method | Description |
|---|---|
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 |
Button component to toggle sidebar visibility.
| Property | Type | Default | Description |
|---|---|---|---|
target |
string |
'' |
ID of the sidebar to control |
label |
string |
'' |
Button label text |
showIcon |
boolean |
true |
Whether to show the hamburger icon |
showLabel |
boolean |
false |
Whether to show text label |
isExpanded |
boolean |
false |
Fallback expanded state if no target |
variant |
'default' | 'outline' | 'ghost' |
'outline' |
Button style variant |
size |
'sm' | 'md' | 'lg' |
'md' |
Button size |
customClass |
string |
'' |
Additional CSS classes |
| Event | Type | Description |
|---|---|---|
onTrigger |
EventEmitter<void> |
Emitted when trigger is activated |
| Method | Description |
|---|---|
onTriggerClick() |
Handle trigger button click |
getTargetExpandedState() |
Get expanded state from target sidebar |
getAriaLabel() |
Get accessible label for the button |
Injectable service for programmatic sidebar control.
| Method | Parameters | Return Type | Description |
|---|---|---|---|
registerSidebar(id, sidebar) |
id: string, sidebar: Sidebar |
void |
Register a sidebar instance |
unregisterSidebar(id) |
id: string |
void |
Unregister a sidebar instance |
getSidebar(id) |
id: string |
Sidebar | undefined |
Get sidebar instance by ID |
toggleSidebar(id) |
id: string |
boolean |
Toggle sidebar by ID |
getAllSidebars() |
- | Sidebar[] |
Get all registered sidebar instances |
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');
}
}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.
<SidebarContainer>
<Sidebar>...</Sidebar>
<SidebarMainContent>
<!-- Your content here -->
</SidebarMainContent>
</SidebarContainer><SidebarContainer>
<Sidebar>...</Sidebar>
<div class="flex-1 overflow-auto">
<!-- Your content here -->
</div>
</SidebarContainer><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>@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');
}<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>@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 {}<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" />The sidebar provides comprehensive keyboard navigation support:
| Key | Action |
|---|---|
↑ / ↓ |
Navigate between menu items |
← / → |
Collapse/expand submenus |
Enter / Space |
Activate item or toggle submenu |
Home |
Jump to first item |
End |
Jump to last item |
Tab |
Navigate between sidebar groups |
Escape |
Close sidebar (when in overlay mode) |
- 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
@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();
}
}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
@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'
);
}<!-- 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"
/>The sidebar component is built with accessibility in mind:
- Proper ARIA roles (
navigation,menu,menuitem) - ARIA labels and descriptions
- ARIA expanded state for submenus
- ARIA current for active items
- Descriptive labels for all interactive elements
- Status announcements for state changes
- Proper heading hierarchy
- Alternative text for icons
<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>- Use OnPush Change Detection:
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
// ...
})- Lazy Load Navigation Data:
readonly navigationItems = computed(() => {
return this.authService.user()?.role === 'admin'
? this.adminNavItems()
: this.userNavItems();
});- Optimize Icon Rendering:
// Pre-sanitize icons for better performance
readonly sanitizedIcon = computed(() =>
this.sanitizer.bypassSecurityTrustHtml(this.icon())
);- Consistent Navigation: Keep navigation structure consistent across your application
- Clear Labels: Use descriptive labels that clearly indicate the destination
- Visual Hierarchy: Use grouping and indentation to show relationships
- State Indicators: Show active states and loading indicators appropriately
- Separate Navigation Logic:
@Injectable()
export class NavigationService {
getNavigationItems(userRole: string) {
// Return navigation items based on user role
}
}- Use TypeScript Interfaces:
interface NavigationItem {
label: string;
route: string;
icon: string;
badge?: string;
children?: NavigationItem[];
}- Component Composition:
@Component({
template: `
<SidebarNavGroup title="Analytics">
<app-analytics-nav-items />
</SidebarNavGroup>
`
})
export class AnalyticsNavComponent {}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 --> 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>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>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>
`;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>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>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'"
/>If upgrading from an older version:
- Remove SidebarMainContent imports:
// Remove this import
import { SidebarMainContent } from '@lib/sidebar';
// Keep these imports
import {
Sidebar,
SidebarContainer,
SidebarContent,
// ... other components
} from '@lib/sidebar';- Update template structure:
<!-- Replace SidebarMainContent with regular elements -->
<div class="flex-1 overflow-auto">
<!-- Your content here -->
</div>- Update CSS classes:
- Replace
customClasswithclassName - Ensure flexbox layout with
flex-1on main content
- Check Console Errors: Look for any JavaScript errors that might prevent functionality
- Inspect Element: Use browser dev tools to verify proper HTML structure and CSS classes
- Test Keyboard Navigation: Use Tab and arrow keys to test navigation flow
- Verify ARIA Attributes: Check that accessibility attributes are properly set
- Check Component Structure: Ensure proper nesting of sidebar components
- Validate CSS Classes: Confirm flexbox classes are applied correctly
If you experience performance issues:
- Minimize Re-renders: Use
OnPushchange detection - Optimize Icons: Pre-process SVG icons instead of generating them dynamically
- Lazy Load: Load navigation items only when needed
- Use TrackBy: For dynamic navigation lists, use trackBy functions
- Signal Optimization: Use computed signals for derived state
- 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
If you find any issues or have suggestions for improvements, please:
- Check existing issues on GitHub
- Create a new issue with detailed description
- Consider submitting a pull request
This component is part of the Angular SuperUI library and follows the same license terms.