0
# Navigation
1
2
PrimeNG provides 12 comprehensive navigation components for building menus, breadcrumbs, tabs, and step indicators to guide users through your application.
3
4
## Menu Components
5
6
### MenuBar
7
8
Horizontal navigation menu with multi-level support.
9
10
```typescript { .api }
11
// Import
12
import { MenuBar } from 'primeng/menubar';
13
// Module: MenubarModule
14
15
// Component Interface
16
interface MenuBarProps {
17
model?: MenuItem[];
18
style?: any;
19
styleClass?: string;
20
autoZIndex?: boolean;
21
baseZIndex?: number;
22
autoDisplay?: boolean;
23
autoHide?: boolean;
24
autoHideDelay?: number;
25
}
26
27
// Usage
28
@Component({
29
template: `
30
<p-menubar [model]="items">
31
<ng-template pTemplate="start">
32
<img src="assets/showcase/images/logo.svg" height="40" class="mr-2">
33
</ng-template>
34
<ng-template pTemplate="end">
35
<input type="text" pInputText placeholder="Search" class="w-full sm:w-auto">
36
</ng-template>
37
</p-menubar>
38
`
39
})
40
export class MenuBarComponent implements OnInit {
41
items: MenuItem[] = [];
42
43
ngOnInit() {
44
this.items = [
45
{
46
label: 'File',
47
icon: 'pi pi-fw pi-file',
48
items: [
49
{
50
label: 'New',
51
icon: 'pi pi-fw pi-plus',
52
items: [
53
{ label: 'Project' },
54
{ label: 'Other' }
55
]
56
},
57
{ label: 'Open' },
58
{ separator: true },
59
{ label: 'Quit' }
60
]
61
},
62
{
63
label: 'Edit',
64
icon: 'pi pi-fw pi-pencil',
65
items: [
66
{ label: 'Delete', icon: 'pi pi-fw pi-trash' },
67
{ label: 'Refresh', icon: 'pi pi-fw pi-refresh' }
68
]
69
},
70
{
71
label: 'Help',
72
icon: 'pi pi-fw pi-question',
73
items: [
74
{
75
label: 'Contents'
76
},
77
{
78
label: 'Search',
79
icon: 'pi pi-fw pi-search',
80
items: [
81
{
82
label: 'Text',
83
items: [
84
{ label: 'Workspace' }
85
]
86
},
87
{ label: 'File' }
88
]
89
}
90
]
91
}
92
];
93
}
94
}
95
```
96
97
### Menu
98
99
Vertical popup menu component.
100
101
```typescript { .api }
102
// Import
103
import { Menu } from 'primeng/menu';
104
// Module: MenuModule
105
106
// Component Interface
107
interface MenuProps {
108
model?: MenuItem[];
109
popup?: boolean;
110
style?: any;
111
styleClass?: string;
112
appendTo?: any;
113
autoZIndex?: boolean;
114
baseZIndex?: number;
115
showTransitionOptions?: string;
116
hideTransitionOptions?: string;
117
ariaLabel?: string;
118
ariaLabelledBy?: string;
119
}
120
121
// Usage
122
@Component({
123
template: `
124
<p-toast></p-toast>
125
126
<p-menu #menu [model]="items" [popup]="true"></p-menu>
127
<button type="button" pButton icon="pi pi-bars" label="Show" (click)="menu.toggle($event)"></button>
128
129
<!-- Inline Menu -->
130
<p-menu [model]="items"></p-menu>
131
`
132
})
133
export class MenuComponent implements OnInit {
134
items: MenuItem[] = [];
135
136
ngOnInit() {
137
this.items = [
138
{ label: 'New', icon: 'pi pi-plus', command: () => this.messageService.add({severity:'success', summary:'Success', detail:'File Created'}) },
139
{ label: 'Open', icon: 'pi pi-download', url: 'http://primetek.com.tr' },
140
{ separator: true },
141
{ label: 'Export', icon: 'pi pi-external-link', routerLink: ['/fileupload'] }
142
];
143
}
144
}
145
```
146
147
### MegaMenu
148
149
Multi-column dropdown menu for complex navigation.
150
151
```typescript { .api }
152
// Import
153
import { MegaMenu } from 'primeng/megamenu';
154
// Module: MegaMenuModule
155
156
// Component Interface
157
interface MegaMenuProps {
158
model?: MegaMenuItem[];
159
orientation?: 'horizontal' | 'vertical';
160
style?: any;
161
styleClass?: string;
162
autoZIndex?: boolean;
163
baseZIndex?: number;
164
}
165
166
interface MegaMenuItem extends MenuItem {
167
columns?: MegaMenuColumn[];
168
}
169
170
interface MegaMenuColumn {
171
header?: string;
172
items?: MenuItem[];
173
}
174
175
// Usage
176
@Component({
177
template: `
178
<p-megamenu [model]="items"></p-megamenu>
179
`
180
})
181
export class MegaMenuComponent implements OnInit {
182
items: MegaMenuItem[] = [];
183
184
ngOnInit() {
185
this.items = [
186
{
187
label: 'TV',
188
icon: 'pi pi-fw pi-eye',
189
items: [
190
{
191
label: 'Submenu 1',
192
items: [
193
{ label: 'Submenu 1.1' },
194
{ label: 'Submenu 1.2' }
195
]
196
},
197
{
198
label: 'Submenu 2',
199
items: [
200
{ label: 'Submenu 2.1' },
201
{ label: 'Submenu 2.2' }
202
]
203
}
204
]
205
},
206
{
207
label: 'Sports',
208
items: [
209
{
210
label: 'Basketball',
211
items: [
212
{ label: 'NBA' },
213
{ label: 'Euroleague' }
214
]
215
},
216
{
217
label: 'Football',
218
items: [
219
{ label: 'Premier League' },
220
{ label: 'La Liga' }
221
]
222
}
223
]
224
}
225
];
226
}
227
}
228
```
229
230
### TieredMenu
231
232
Nested popup menu with unlimited levels.
233
234
```typescript { .api }
235
// Import
236
import { TieredMenu } from 'primeng/tieredmenu';
237
// Module: TieredMenuModule
238
239
// Component Interface
240
interface TieredMenuProps {
241
model?: MenuItem[];
242
popup?: boolean;
243
style?: any;
244
styleClass?: string;
245
appendTo?: any;
246
autoZIndex?: boolean;
247
baseZIndex?: number;
248
showTransitionOptions?: string;
249
hideTransitionOptions?: string;
250
ariaLabel?: string;
251
ariaLabelledBy?: string;
252
}
253
254
// Usage
255
@Component({
256
template: `
257
<p-tieredmenu #menu [model]="items" [popup]="true"></p-tieredmenu>
258
<button type="button" pButton icon="pi pi-bars" label="Show" (click)="menu.toggle($event)"></button>
259
`
260
})
261
export class TieredMenuComponent implements OnInit {
262
items: MenuItem[] = [];
263
264
ngOnInit() {
265
this.items = [
266
{
267
label: 'Customers',
268
icon: 'pi pi-fw pi-table',
269
items: [
270
{
271
label: 'New',
272
icon: 'pi pi-fw pi-user-plus',
273
items: [
274
{
275
label: 'Customer',
276
icon: 'pi pi-fw pi-plus'
277
},
278
{
279
label: 'Duplicate',
280
icon: 'pi pi-fw pi-copy'
281
}
282
]
283
},
284
{
285
label: 'Edit',
286
icon: 'pi pi-fw pi-user-edit'
287
}
288
]
289
}
290
];
291
}
292
}
293
```
294
295
### ContextMenu
296
297
Right-click context menu.
298
299
```typescript { .api }
300
// Import
301
import { ContextMenu } from 'primeng/contextmenu';
302
// Module: ContextMenuModule
303
304
// Component Interface
305
interface ContextMenuProps {
306
model?: MenuItem[];
307
global?: boolean;
308
target?: any;
309
style?: any;
310
styleClass?: string;
311
appendTo?: any;
312
autoZIndex?: boolean;
313
baseZIndex?: number;
314
showTransitionOptions?: string;
315
hideTransitionOptions?: string;
316
ariaLabel?: string;
317
ariaLabelledBy?: string;
318
}
319
320
// Usage
321
@Component({
322
template: `
323
<p-contextmenu #cm [model]="items"></p-contextmenu>
324
325
<!-- Global Context Menu -->
326
<p-contextmenu [global]="true" [model]="items"></p-contextmenu>
327
328
<!-- Target-specific Context Menu -->
329
<img #img src="assets/showcase/images/demo/nature/nature3.jpg" alt="Logo" (contextmenu)="cm.show($event)" style="width: 300px">
330
`
331
})
332
export class ContextMenuComponent implements OnInit {
333
items: MenuItem[] = [];
334
335
ngOnInit() {
336
this.items = [
337
{ label: 'View', icon: 'pi pi-fw pi-search' },
338
{ label: 'Delete', icon: 'pi pi-fw pi-times' }
339
];
340
}
341
}
342
```
343
344
### PanelMenu
345
346
Collapsible menu with accordion-style panels.
347
348
```typescript { .api }
349
// Import
350
import { PanelMenu } from 'primeng/panelmenu';
351
// Module: PanelMenuModule
352
353
// Component Interface
354
interface PanelMenuProps {
355
model?: MenuItem[];
356
style?: any;
357
styleClass?: string;
358
multiple?: boolean;
359
transitionOptions?: string;
360
id?: string;
361
}
362
363
// Usage
364
@Component({
365
template: `
366
<p-panelmenu [model]="items" [multiple]="true" styleClass="w-full md:w-20rem"></p-panelmenu>
367
`
368
})
369
export class PanelMenuComponent implements OnInit {
370
items: MenuItem[] = [];
371
372
ngOnInit() {
373
this.items = [
374
{
375
label: 'Mail',
376
icon: 'pi pi-fw pi-envelope',
377
items: [
378
{ label: 'Compose', icon: 'pi pi-fw pi-plus' },
379
{ label: 'Inbox', icon: 'pi pi-fw pi-inbox' },
380
{ label: 'Sent', icon: 'pi pi-fw pi-send' },
381
{ label: 'Trash', icon: 'pi pi-fw pi-trash' }
382
]
383
},
384
{
385
label: 'Reports',
386
icon: 'pi pi-fw pi-chart-bar',
387
items: [
388
{ label: 'Sales', icon: 'pi pi-fw pi-chart-line' },
389
{ label: 'Products', icon: 'pi pi-fw pi-list' }
390
]
391
}
392
];
393
}
394
}
395
```
396
397
### Dock
398
399
macOS-style dock menu with magnification effects.
400
401
```typescript { .api }
402
// Import
403
import { Dock } from 'primeng/dock';
404
// Module: DockModule
405
406
// Component Interface
407
interface DockProps {
408
model?: MenuItem[];
409
position?: 'bottom' | 'top' | 'left' | 'right';
410
style?: any;
411
styleClass?: string;
412
tooltipOptions?: any;
413
}
414
415
// Usage
416
@Component({
417
template: `
418
<p-dock [model]="dockItems" position="bottom">
419
<ng-template pTemplate="item" let-item>
420
<img [src]="item.icon" [alt]="item.label" width="100%">
421
</ng-template>
422
</p-dock>
423
`
424
})
425
export class DockComponent implements OnInit {
426
dockItems: MenuItem[] = [];
427
428
ngOnInit() {
429
this.dockItems = [
430
{
431
label: 'Finder',
432
tooltipOptions: { tooltipLabel: 'Finder', tooltipPosition: 'top', positionLeft: 0, positionTop: -80 },
433
icon: 'assets/showcase/images/dock/finder.svg',
434
command: () => { this.displayFinder = true; }
435
},
436
{
437
label: 'Terminal',
438
tooltipOptions: { tooltipLabel: 'Terminal', tooltipPosition: 'top', positionLeft: 0, positionTop: -80 },
439
icon: 'assets/showcase/images/dock/terminal.svg',
440
command: () => { this.displayTerminal = true; }
441
}
442
];
443
}
444
}
445
```
446
447
## Breadcrumb and Steps
448
449
### Breadcrumb
450
451
Navigation breadcrumb trail.
452
453
```typescript { .api }
454
// Import
455
import { Breadcrumb } from 'primeng/breadcrumb';
456
// Module: BreadcrumbModule
457
458
// Component Interface
459
interface BreadcrumbProps {
460
model?: MenuItem[];
461
style?: any;
462
styleClass?: string;
463
home?: MenuItem;
464
}
465
466
// Usage
467
@Component({
468
template: `
469
<p-breadcrumb [model]="items" [home]="home"></p-breadcrumb>
470
`
471
})
472
export class BreadcrumbComponent implements OnInit {
473
items: MenuItem[] = [];
474
home: MenuItem = {};
475
476
ngOnInit() {
477
this.home = { icon: 'pi pi-home', routerLink: '/' };
478
479
this.items = [
480
{ label: 'Computer' },
481
{ label: 'Notebook' },
482
{ label: 'Accessories' },
483
{ label: 'Backpacks' },
484
{ label: 'Item' }
485
];
486
}
487
}
488
```
489
490
### Steps
491
492
Step indicator for multi-step processes.
493
494
```typescript { .api }
495
// Import
496
import { Steps } from 'primeng/steps';
497
// Module: StepsModule
498
499
// Component Interface
500
interface StepsProps {
501
model?: MenuItem[];
502
activeIndex?: number;
503
readonly?: boolean;
504
style?: any;
505
styleClass?: string;
506
}
507
508
// Usage
509
@Component({
510
template: `
511
<div class="card">
512
<p-steps [model]="items" [activeIndex]="activeIndex" [readonly]="true"></p-steps>
513
</div>
514
515
<router-outlet></router-outlet>
516
517
<div class="flex pt-4 justify-content-between">
518
<p-button label="Back" (onClick)="prevPage()" icon="pi pi-angle-left" [disabled]="activeIndex === 0"></p-button>
519
<p-button label="Next" (onClick)="nextPage()" icon="pi pi-angle-right" iconPos="right" [disabled]="activeIndex === items.length - 1"></p-button>
520
</div>
521
`
522
})
523
export class StepsComponent implements OnInit {
524
items: MenuItem[] = [];
525
activeIndex: number = 0;
526
527
ngOnInit() {
528
this.items = [
529
{ label: 'Personal Info', routerLink: 'personal' },
530
{ label: 'Seat Selection', routerLink: 'seat' },
531
{ label: 'Payment', routerLink: 'payment' },
532
{ label: 'Confirmation', routerLink: 'confirmation' }
533
];
534
}
535
536
nextPage() {
537
this.activeIndex++;
538
}
539
540
prevPage() {
541
this.activeIndex--;
542
}
543
}
544
```
545
546
### Stepper
547
548
Multi-step workflow component with content panels.
549
550
```typescript { .api }
551
// Import
552
import { Stepper, StepperPanel } from 'primeng/stepper';
553
// Module: StepperModule
554
555
// Component Interface
556
interface StepperProps {
557
activeStep?: number;
558
orientation?: 'horizontal' | 'vertical';
559
linear?: boolean;
560
value?: any;
561
}
562
563
interface StepperPanelProps {
564
header?: string;
565
disabled?: boolean;
566
}
567
568
// Usage
569
@Component({
570
template: `
571
<p-stepper [(activeStep)]="active" styleClass="basis-50rem">
572
<p-stepperPanel header="Personal Info">
573
<ng-template pTemplate="content" let-nextCallback="nextCallback" let-index="index">
574
<div class="flex flex-column h-12rem">
575
<div class="border-2 border-dashed surface-border border-round surface-ground flex-auto flex justify-content-center align-items-center font-medium">Personal Information Content</div>
576
</div>
577
<div class="flex pt-4 justify-content-end">
578
<p-button label="Next" icon="pi pi-arrow-right" iconPos="right" (onClick)="nextCallback.emit()"></p-button>
579
</div>
580
</ng-template>
581
</p-stepperPanel>
582
<p-stepperPanel header="Seat Selection">
583
<ng-template pTemplate="content" let-prevCallback="prevCallback" let-nextCallback="nextCallback" let-index="index">
584
<div class="flex flex-column h-12rem">
585
<div class="border-2 border-dashed surface-border border-round surface-ground flex-auto flex justify-content-center align-items-center font-medium">Seat Selection Content</div>
586
</div>
587
<div class="flex pt-4 justify-content-between">
588
<p-button label="Back" severity="secondary" icon="pi pi-arrow-left" (onClick)="prevCallback.emit()"></p-button>
589
<p-button label="Next" icon="pi pi-arrow-right" iconPos="right" (onClick)="nextCallback.emit()"></p-button>
590
</div>
591
</ng-template>
592
</p-stepperPanel>
593
<p-stepperPanel header="Payment">
594
<ng-template pTemplate="content" let-prevCallback="prevCallback" let-nextCallback="nextCallback" let-index="index">
595
<div class="flex flex-column h-12rem">
596
<div class="border-2 border-dashed surface-border border-round surface-ground flex-auto flex justify-content-center align-items-center font-medium">Payment Information Content</div>
597
</div>
598
<div class="flex pt-4 justify-content-between">
599
<p-button label="Back" severity="secondary" icon="pi pi-arrow-left" (onClick)="prevCallback.emit()"></p-button>
600
<p-button label="Complete" icon="pi pi-arrow-right" iconPos="right" (onClick)="nextCallback.emit()"></p-button>
601
</div>
602
</ng-template>
603
</p-stepperPanel>
604
</p-stepper>
605
`
606
})
607
export class StepperComponent {
608
active: number = 0;
609
}
610
```
611
612
## Tab Navigation
613
614
### Tabs
615
616
Tab navigation with content panels.
617
618
```typescript { .api }
619
// Import
620
import { Tabs, TabPanel } from 'primeng/tabs';
621
// Module: TabsModule
622
623
// Component Interface
624
interface TabsProps {
625
activeIndex?: number;
626
lazy?: boolean;
627
scrollable?: boolean;
628
showNavigators?: boolean;
629
buttonPrevIcon?: string;
630
buttonNextIcon?: string;
631
prevButtonAriaLabel?: string;
632
nextButtonAriaLabel?: string;
633
}
634
635
interface TabPanelProps {
636
header?: string;
637
headerTemplate?: TemplateRef<any>;
638
disabled?: boolean;
639
closable?: boolean;
640
selected?: boolean;
641
leftIcon?: string;
642
rightIcon?: string;
643
cache?: boolean;
644
tooltip?: string;
645
tooltipPosition?: string;
646
tooltipPositionStyle?: string;
647
tooltipStyleClass?: string;
648
}
649
650
// Events
651
interface TabChangeEvent {
652
originalEvent: Event;
653
index: number;
654
}
655
656
interface TabCloseEvent {
657
originalEvent: Event;
658
index: number;
659
close: Function;
660
}
661
662
// Usage
663
@Component({
664
template: `
665
<p-tabs [(activeIndex)]="activeIndex" (onChange)="onTabChange($event)">
666
<p-tabpanel header="Header I" leftIcon="pi pi-calendar">
667
<p>
668
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
669
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
670
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
671
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
672
</p>
673
</p-tabpanel>
674
<p-tabpanel header="Header II" rightIcon="pi pi-user">
675
<p>
676
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam,
677
eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo
678
enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui
679
ratione voluptatem sequi nesciunt. Consectetur, adipisci velit, sed quia non numquam eius modi.
680
</p>
681
</p-tabpanel>
682
<p-tabpanel header="Header III" leftIcon="pi pi-search">
683
<p>
684
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti
685
quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in
686
culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita
687
distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus.
688
</p>
689
</p-tabpanel>
690
<p-tabpanel header="Header IV" [disabled]="true">
691
<p>
692
Disabled tab content.
693
</p>
694
</p-tabpanel>
695
</p-tabs>
696
`
697
})
698
export class TabsComponent {
699
activeIndex: number = 0;
700
701
onTabChange(event: TabChangeEvent) {
702
console.log('Tab changed:', event.index);
703
}
704
}
705
```
706
707
## Pagination
708
709
### Paginator
710
711
Data pagination controls.
712
713
```typescript { .api }
714
// Import
715
import { Paginator } from 'primeng/paginator';
716
// Module: PaginatorModule
717
718
// Component Interface
719
interface PaginatorProps {
720
totalRecords?: number;
721
rows?: number;
722
first?: number;
723
pageLinkSize?: number;
724
rowsPerPageOptions?: number[];
725
style?: any;
726
styleClass?: string;
727
alwaysShow?: boolean;
728
templateLeft?: TemplateRef<any>;
729
templateRight?: TemplateRef<any>;
730
dropdownAppendTo?: any;
731
dropdownScrollHeight?: string;
732
currentPageReportTemplate?: string;
733
showCurrentPageReport?: boolean;
734
showFirstLastIcon?: boolean;
735
totalRecordsText?: string;
736
showPageLinks?: boolean;
737
showJumpToPageDropdown?: boolean;
738
showJumpToPageInput?: boolean;
739
jumpToPageInputTooltip?: string;
740
showRowsPerPageDropdown?: boolean;
741
rowsPerPageDropdownTooltip?: string;
742
}
743
744
// Events
745
interface PageEvent {
746
first: number;
747
rows: number;
748
page: number;
749
pageCount: number;
750
}
751
752
// Usage
753
@Component({
754
template: `
755
<p-paginator
756
[first]="first"
757
[rows]="rows"
758
[totalRecords]="totalRecords"
759
[rowsPerPageOptions]="[10, 20, 30]"
760
[showCurrentPageReport]="true"
761
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
762
[showJumpToPageDropdown]="true"
763
[showPageLinks]="true"
764
(onPageChange)="onPageChange($event)">
765
</p-paginator>
766
`
767
})
768
export class PaginatorComponent {
769
first: number = 0;
770
rows: number = 10;
771
totalRecords: number = 120;
772
773
onPageChange(event: PageEvent) {
774
this.first = event.first;
775
this.rows = event.rows;
776
}
777
}
778
```
779
780
## MenuItem Interface
781
782
All navigation components use the standardized MenuItem interface:
783
784
```typescript { .api }
785
interface MenuItem {
786
label?: string; // Display text
787
icon?: string; // Icon CSS class
788
command?: (event?: any) => void; // Click handler
789
url?: string; // External URL
790
routerLink?: any; // Angular router link
791
queryParams?: { [key: string]: any }; // Router query params
792
fragment?: string; // Router fragment
793
queryParamsHandling?: string; // Router query params handling
794
preserveFragment?: boolean; // Preserve URL fragment
795
skipLocationChange?: boolean; // Skip location change
796
replaceUrl?: boolean; // Replace URL
797
state?: { [key: string]: any }; // Router state
798
items?: MenuItem[]; // Submenu items
799
expanded?: boolean; // Expanded state
800
disabled?: boolean; // Disabled state
801
visible?: boolean; // Visibility state
802
target?: string; // Link target
803
separator?: boolean; // Separator item
804
badge?: string; // Badge text
805
badgeStyleClass?: string; // Badge CSS class
806
style?: any; // Inline styles
807
styleClass?: string; // CSS class
808
title?: string; // Tooltip text
809
id?: string; // Element ID
810
automationId?: any; // Automation ID
811
tabindex?: string; // Tab index
812
ariaLabel?: string; // ARIA label
813
columns?: MegaMenuColumn[]; // MegaMenu columns
814
}
815
```
816
817
## Router Integration
818
819
PrimeNG navigation components integrate seamlessly with Angular Router:
820
821
```typescript
822
// Component
823
export class NavigationComponent implements OnInit {
824
items: MenuItem[] = [];
825
826
ngOnInit() {
827
this.items = [
828
{
829
label: 'Home',
830
icon: 'pi pi-home',
831
routerLink: ['/'],
832
queryParams: { tab: 'overview' }
833
},
834
{
835
label: 'Products',
836
icon: 'pi pi-box',
837
items: [
838
{
839
label: 'All Products',
840
routerLink: ['/products'],
841
queryParams: { category: 'all' }
842
},
843
{
844
label: 'Featured',
845
routerLink: ['/products'],
846
queryParams: { category: 'featured' }
847
}
848
]
849
},
850
{
851
label: 'External',
852
icon: 'pi pi-external-link',
853
url: 'https://www.primefaces.org/',
854
target: '_blank'
855
}
856
];
857
}
858
}
859
```
860
861
## Accessibility Features
862
863
All navigation components include comprehensive accessibility support:
864
865
- **ARIA attributes** - Proper roles, labels, and states
866
- **Keyboard navigation** - Arrow keys, Tab, Enter, Escape
867
- **Focus management** - Proper focus indication and trapping
868
- **Screen reader support** - Descriptive labels and announcements
869
- **High contrast themes** - Support for accessibility themes