Sidebar Component
The MonaSidebar is a flexible, accessible sidebar navigation component for Angular applications. It supports multiple menu item types, collapsible sections, and various visual variants.
Architecture Diagram
SidebarConfig Interface
The main configuration object for the sidebar.
interface SidebarConfig {
header?: SidebarMenuItem[];
content: SidebarMenuItem[];
footer?: SidebarMenuItem[];
}
SidebarMenuItem Interface
interface SidebarMenuItem {
id: string; /** Unique identifier for the menu item */
type: 'button' | 'submenu' | 'group'; /** Type of menu item: 'button', 'submenu', or 'group' */
label: string; /** Display label for the menu item */
icon?: string; /** Optional icon name */
route?: string; /** Optional router link for navigation */
action?: () => void; /** Optional callback function for custom actions */
items?: SidebarMenuItem[]; /** Submenu items (for 'submenu' and 'group' types) */
expanded?: boolean; /** Initial expanded state */
variant?: SidebarButtonType; /** Visual variant for button items */
subMenuVariant?: SidebarSubmenuType; /** Visual variant for submenu display */
}
The SidebarButtonType and SidebarSubmenuType variants are subject to design refinements. Visual styling, spacing, and behavior may change in future releases.
Button Types
type SidebarButtonType =
| 'simple' // Basic text button
| 'collapsible' // Button with expand/collapse
| 'dropdown' // Dropdown menu style
| 'tree' // Tree structure style
| 'badge' // Button with badge
| 'big_icon' // Large icon style
| 'checkbox'; // Checkbox style
Submenu Types
type SidebarSubmenuType =
| 'border' // Submenu with border
| 'default' // Default submenu style
| 'indent'; // Indented submenu
Sidebar Trigger Button
The mona-sidebar-trigger-button is a standalone component that provides a convenient way to toggle the sidebar open/closed state. It acts as the primary control for managing sidebar visibility.
Basic Usage
<mona-header>
<mona-sidebar-trigger-button></mona-sidebar-trigger-button>
Header
</mona-header>
<div>
<mona-sidebar [config]="config"></mona-sidebar>
<router-outlet></router-outlet>
</div>
State Management
The sidebar uses two main services for state management:
MonaSidebarService
export class MonaSidebarService {
isOpen: WritableSignal; /** Signals whether the sidebar is open/pinned */
isHovered: WritableSignal; /** Signals whether the user is hovering over the sidebar */
ignoreHover: WritableSignal; /** Controls whether hover effects are ignored */
}
SidebarFocusService
Manages keyboard navigation and focus management for accessibility.
Features:
- Builds and maintains a list of focusable elements
- Handles arrow key navigation
- Supports Enter/Space for activation
- Automatically manages focus when sidebar opens/closes
Keyboard Navigation
The Sidebar component includes full keyboard navigation support:
| Key | Action |
|---|---|
| Tab | Move focus to next focusable element |
| Shift + Tab | Move focus to previous focusable element |
| Enter / Space | Activate button or toggle submenu |
| Arrow Up | Move focus up in the menu |
| Arrow Down | Move focus down in the menu |
| Escape | Close the sidebar (if open) |
Responsive Behavior
Component Lifecycle
Examples
const config: {
header: [
{
id: 'd3fc4ee9-1e8c-43a1-8c85-269842eaa991',
type: 'group',
label: 'Anesthesia',
items: [
{
type: 'button',
label: 'Assessments',
icon: 'file',
route: '/1',
id: '8d8e07b0-9878-4a38-9f4e-e716297cdc7e',
},
{
type: 'button',
label: 'Documentation',
icon: 'file',
route: '/2',
id: '2e281363-6319-4429-9b39-c68ff1179738',
},
],
},
],
content: [
{
id: '66a0fb0d-0d88-40a0-86a8-44129f683d8d',
type: 'group',
label: 'Departments',
items: [
{
id: '00a2de1a-143f-416e-909d-fea6c80ca673',
type: 'submenu',
label: 'Department 1',
icon: 'hospital',
variant: 'tree',
subMenuVariant: 'border',
items: [
{
id: '1504cb22-7dfd-4f88-a28b-baa9a884b944',
type: 'submenu',
label: 'Ward 1',
icon: 'folder',
variant: 'tree',
subMenuVariant: 'border',
items: [
{
id: '028a02db-d60b-4486-865c-3e953360d66c',
type: 'button',
label: 'Bed 1 ',
icon: 'bed',
route: '/1',
},
{
id: 'cc09a25e-f7a6-4425-a070-b52eead2e2dc',
type: 'button',
label: 'Bed 2',
icon: 'bed',
route: '/2',
},
],
},
{
id: 'f8d1b1a7-6e9f-4c5b-9d2a-442a86b9c1d0',
type: 'submenu',
label: 'Ward 2',
icon: 'folder',
variant: 'tree',
subMenuVariant: 'border',
items: [
{
id: 'e2f0a5d4-7b8c-4a3f-91e2-b7c6d0e3a5f2',
type: 'button',
label: 'Bed 1 ',
icon: 'bed',
route: '/1',
},
{
id: 'd0c3b2f1-6a7e-4d5c-8b9a-112c3e0d4f56',
type: 'button',
label: 'Bed 2',
icon: 'bed',
route: '/2',
},
{
id: 'c1a2d3b4-5e6f-4789-a0b1-23c4d5e6f7a8',
type: 'button',
label: 'Bed 3 ',
icon: 'bed',
route: '/1',
},
{
id: 'a9b8c7d6-e5f4-3210-9876-543210fedcba',
type: 'button',
label: 'Bed 4',
icon: 'bed',
route: '/2',
},
],
},
],
},
{
id: 'b0a9c8d7-e6f5-4321-0987-654321fedcba',
type: 'submenu',
label: 'Department 2',
icon: 'hospital',
variant: 'tree',
subMenuVariant: 'border',
items: [
{
id: '45f6e7d8-9c0a-4b1c-2d3e-5f6g7h8i9j0k',
type: 'submenu',
label: 'Operation Rooms',
icon: 'folder',
variant: 'tree',
subMenuVariant: 'border',
items: [
{
id: '11223344-5566-7788-9900-aabbccddeeff',
type: 'button',
label: 'OR 1 ',
icon: 'bed',
route: '/1',
},
],
},
{
id: 'fedcba98-7654-3210-fedc-ba9876543210',
type: 'submenu',
label: 'Pacu',
icon: 'folder',
variant: 'tree',
subMenuVariant: 'border',
items: [
{
id: '0f1e2d3c-4b5a-6789-9876-543210fedcba',
type: 'button',
label: 'Bed 1 ',
icon: 'bed',
route: '/1',
},
],
},
],
},
],
},
],
footer: [
{
id: '1a2b3c4d-5e6f-7890-1234-567890abcdef',
type: 'button',
label: 'Profil',
icon: 'user',
route: '/user',
},
{
id: 'a1b2c3d4-e5f6-7890-1234-567890fedcba',
type: 'button',
label: 'Einstellungen',
icon: 'gear',
route: '/settings',
},
{
id: '01020304-0506-0708-090a-0b0c0d0e0f10',
type: 'button',
label: 'Ausloggen',
icon: 'arrow-left-from-bracket',
},
],
},
}