primeng 16.0.2 → 16.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/accordion/accordion.d.ts +35 -11
  2. package/api/translation.d.ts +23 -0
  3. package/api/treenode.d.ts +1 -1
  4. package/avatar/avatar.d.ts +11 -1
  5. package/breadcrumb/breadcrumb.d.ts +5 -1
  6. package/button/button.d.ts +3 -0
  7. package/chip/chip.d.ts +1 -0
  8. package/contextmenu/contextmenu.d.ts +157 -67
  9. package/dock/dock.d.ts +47 -2
  10. package/dom/domhandler.d.ts +1 -0
  11. package/esm2022/accordion/accordion.mjs +177 -43
  12. package/esm2022/api/primengconfig.mjs +75 -2
  13. package/esm2022/api/translation.mjs +1 -1
  14. package/esm2022/api/treenode.mjs +1 -1
  15. package/esm2022/autocomplete/autocomplete.mjs +3 -3
  16. package/esm2022/avatar/avatar.mjs +18 -4
  17. package/esm2022/blockui/blockui.mjs +19 -3
  18. package/esm2022/breadcrumb/breadcrumb.mjs +50 -33
  19. package/esm2022/button/button.mjs +4 -1
  20. package/esm2022/card/card.mjs +3 -3
  21. package/esm2022/chip/chip.mjs +18 -13
  22. package/esm2022/contextmenu/contextmenu.mjs +993 -547
  23. package/esm2022/divider/divider.mjs +3 -3
  24. package/esm2022/dock/dock.mjs +284 -86
  25. package/esm2022/dom/domhandler.mjs +19 -7
  26. package/esm2022/dynamicdialog/dynamicdialog-ref.mjs +4 -1
  27. package/esm2022/fieldset/fieldset.mjs +59 -32
  28. package/esm2022/image/image.mjs +11 -3
  29. package/esm2022/inplace/inplace.mjs +18 -11
  30. package/esm2022/megamenu/megamenu.mjs +997 -348
  31. package/esm2022/menu/menu.mjs +397 -166
  32. package/esm2022/menubar/menubar.mjs +895 -282
  33. package/esm2022/orderlist/orderlist.mjs +9 -15
  34. package/esm2022/panel/panel.mjs +44 -33
  35. package/esm2022/panelmenu/panelmenu.mjs +982 -344
  36. package/esm2022/progressbar/progressbar.mjs +19 -15
  37. package/esm2022/progressspinner/progressspinner.mjs +5 -5
  38. package/esm2022/ripple/ripple.mjs +3 -1
  39. package/esm2022/scrollpanel/scrollpanel.mjs +195 -23
  40. package/esm2022/scrolltop/scrolltop.mjs +11 -2
  41. package/esm2022/skeleton/skeleton.mjs +3 -3
  42. package/esm2022/slidemenu/slidemenu.mjs +1059 -372
  43. package/esm2022/splitbutton/splitbutton.mjs +2 -2
  44. package/esm2022/splitter/splitter.mjs +160 -29
  45. package/esm2022/steps/steps.mjs +112 -22
  46. package/esm2022/table/table.mjs +13 -7
  47. package/esm2022/tabmenu/tabmenu.mjs +191 -63
  48. package/esm2022/tabview/tabview.mjs +173 -39
  49. package/esm2022/terminal/terminal.mjs +3 -3
  50. package/esm2022/tieredmenu/tieredmenu.mjs +868 -392
  51. package/esm2022/toolbar/toolbar.mjs +17 -10
  52. package/esm2022/tooltip/tooltip.mjs +1 -1
  53. package/esm2022/tree/tree.mjs +3 -3
  54. package/esm2022/treetable/treetable.mjs +17 -17
  55. package/esm2022/utils/objectutils.mjs +31 -1
  56. package/esm2022/utils/uniquecomponentid.mjs +2 -3
  57. package/fesm2022/primeng-accordion.mjs +176 -42
  58. package/fesm2022/primeng-accordion.mjs.map +1 -1
  59. package/fesm2022/primeng-api.mjs +74 -1
  60. package/fesm2022/primeng-api.mjs.map +1 -1
  61. package/fesm2022/primeng-autocomplete.mjs +2 -2
  62. package/fesm2022/primeng-autocomplete.mjs.map +1 -1
  63. package/fesm2022/primeng-avatar.mjs +17 -3
  64. package/fesm2022/primeng-avatar.mjs.map +1 -1
  65. package/fesm2022/primeng-blockui.mjs +18 -2
  66. package/fesm2022/primeng-blockui.mjs.map +1 -1
  67. package/fesm2022/primeng-breadcrumb.mjs +49 -32
  68. package/fesm2022/primeng-breadcrumb.mjs.map +1 -1
  69. package/fesm2022/primeng-button.mjs +3 -0
  70. package/fesm2022/primeng-button.mjs.map +1 -1
  71. package/fesm2022/primeng-card.mjs +2 -2
  72. package/fesm2022/primeng-card.mjs.map +1 -1
  73. package/fesm2022/primeng-chip.mjs +17 -12
  74. package/fesm2022/primeng-chip.mjs.map +1 -1
  75. package/fesm2022/primeng-contextmenu.mjs +992 -546
  76. package/fesm2022/primeng-contextmenu.mjs.map +1 -1
  77. package/fesm2022/primeng-divider.mjs +2 -2
  78. package/fesm2022/primeng-divider.mjs.map +1 -1
  79. package/fesm2022/primeng-dock.mjs +283 -85
  80. package/fesm2022/primeng-dock.mjs.map +1 -1
  81. package/fesm2022/primeng-dom.mjs +18 -6
  82. package/fesm2022/primeng-dom.mjs.map +1 -1
  83. package/fesm2022/primeng-dynamicdialog.mjs +3 -0
  84. package/fesm2022/primeng-dynamicdialog.mjs.map +1 -1
  85. package/fesm2022/primeng-fieldset.mjs +57 -30
  86. package/fesm2022/primeng-fieldset.mjs.map +1 -1
  87. package/fesm2022/primeng-image.mjs +10 -2
  88. package/fesm2022/primeng-image.mjs.map +1 -1
  89. package/fesm2022/primeng-inplace.mjs +17 -10
  90. package/fesm2022/primeng-inplace.mjs.map +1 -1
  91. package/fesm2022/primeng-megamenu.mjs +996 -348
  92. package/fesm2022/primeng-megamenu.mjs.map +1 -1
  93. package/fesm2022/primeng-menu.mjs +396 -165
  94. package/fesm2022/primeng-menu.mjs.map +1 -1
  95. package/fesm2022/primeng-menubar.mjs +894 -281
  96. package/fesm2022/primeng-menubar.mjs.map +1 -1
  97. package/fesm2022/primeng-orderlist.mjs +8 -14
  98. package/fesm2022/primeng-orderlist.mjs.map +1 -1
  99. package/fesm2022/primeng-panel.mjs +44 -33
  100. package/fesm2022/primeng-panel.mjs.map +1 -1
  101. package/fesm2022/primeng-panelmenu.mjs +981 -344
  102. package/fesm2022/primeng-panelmenu.mjs.map +1 -1
  103. package/fesm2022/primeng-progressbar.mjs +18 -14
  104. package/fesm2022/primeng-progressbar.mjs.map +1 -1
  105. package/fesm2022/primeng-progressspinner.mjs +4 -4
  106. package/fesm2022/primeng-progressspinner.mjs.map +1 -1
  107. package/fesm2022/primeng-ripple.mjs +2 -0
  108. package/fesm2022/primeng-ripple.mjs.map +1 -1
  109. package/fesm2022/primeng-scrollpanel.mjs +194 -22
  110. package/fesm2022/primeng-scrollpanel.mjs.map +1 -1
  111. package/fesm2022/primeng-scrolltop.mjs +10 -1
  112. package/fesm2022/primeng-scrolltop.mjs.map +1 -1
  113. package/fesm2022/primeng-skeleton.mjs +2 -2
  114. package/fesm2022/primeng-skeleton.mjs.map +1 -1
  115. package/fesm2022/primeng-slidemenu.mjs +1058 -371
  116. package/fesm2022/primeng-slidemenu.mjs.map +1 -1
  117. package/fesm2022/primeng-splitbutton.mjs +1 -1
  118. package/fesm2022/primeng-splitbutton.mjs.map +1 -1
  119. package/fesm2022/primeng-splitter.mjs +160 -29
  120. package/fesm2022/primeng-splitter.mjs.map +1 -1
  121. package/fesm2022/primeng-steps.mjs +111 -21
  122. package/fesm2022/primeng-steps.mjs.map +1 -1
  123. package/fesm2022/primeng-table.mjs +12 -6
  124. package/fesm2022/primeng-table.mjs.map +1 -1
  125. package/fesm2022/primeng-tabmenu.mjs +190 -62
  126. package/fesm2022/primeng-tabmenu.mjs.map +1 -1
  127. package/fesm2022/primeng-tabview.mjs +172 -38
  128. package/fesm2022/primeng-tabview.mjs.map +1 -1
  129. package/fesm2022/primeng-terminal.mjs +2 -2
  130. package/fesm2022/primeng-terminal.mjs.map +1 -1
  131. package/fesm2022/primeng-tieredmenu.mjs +867 -391
  132. package/fesm2022/primeng-tieredmenu.mjs.map +1 -1
  133. package/fesm2022/primeng-toolbar.mjs +16 -9
  134. package/fesm2022/primeng-toolbar.mjs.map +1 -1
  135. package/fesm2022/primeng-tooltip.mjs.map +1 -1
  136. package/fesm2022/primeng-tree.mjs +2 -2
  137. package/fesm2022/primeng-tree.mjs.map +1 -1
  138. package/fesm2022/primeng-treetable.mjs +16 -16
  139. package/fesm2022/primeng-treetable.mjs.map +1 -1
  140. package/fesm2022/primeng-utils.mjs +31 -2
  141. package/fesm2022/primeng-utils.mjs.map +1 -1
  142. package/fieldset/fieldset.d.ts +6 -5
  143. package/image/image.d.ts +1 -0
  144. package/inplace/inplace.d.ts +6 -1
  145. package/megamenu/megamenu.d.ts +137 -15
  146. package/menu/menu.d.ts +64 -7
  147. package/menubar/menubar.d.ts +116 -22
  148. package/orderlist/orderlist.d.ts +2 -1
  149. package/package.json +124 -124
  150. package/panel/panel.d.ts +6 -5
  151. package/panelmenu/panelmenu.d.ts +134 -22
  152. package/resources/components/autocomplete/autocomplete.css +9 -8
  153. package/resources/components/breadcrumb/breadcrumb.css +9 -3
  154. package/resources/components/common/common.css +1 -1
  155. package/resources/components/contextmenu/contextmenu.css +1 -7
  156. package/resources/components/dock/dock.css +1 -1
  157. package/resources/components/megamenu/megamenu.css +9 -10
  158. package/resources/components/panelmenu/panelmenu.css +4 -2
  159. package/resources/components/slidemenu/slidemenu.css +40 -41
  160. package/resources/primeng.css +1 -1
  161. package/resources/primeng.min.css +1 -1
  162. package/resources/themes/arya-blue/theme.css +342 -390
  163. package/resources/themes/arya-green/theme.css +342 -390
  164. package/resources/themes/arya-orange/theme.css +342 -390
  165. package/resources/themes/arya-purple/theme.css +342 -390
  166. package/resources/themes/bootstrap4-dark-blue/theme.css +357 -416
  167. package/resources/themes/bootstrap4-dark-purple/theme.css +357 -416
  168. package/resources/themes/bootstrap4-light-blue/theme.css +369 -428
  169. package/resources/themes/bootstrap4-light-purple/theme.css +369 -428
  170. package/resources/themes/fluent-light/theme.css +352 -400
  171. package/resources/themes/lara-dark-blue/theme.css +344 -392
  172. package/resources/themes/lara-dark-indigo/theme.css +344 -392
  173. package/resources/themes/lara-dark-purple/theme.css +344 -392
  174. package/resources/themes/lara-dark-teal/theme.css +344 -392
  175. package/resources/themes/lara-light-blue/theme.css +370 -418
  176. package/resources/themes/lara-light-indigo/theme.css +370 -418
  177. package/resources/themes/lara-light-purple/theme.css +370 -418
  178. package/resources/themes/lara-light-teal/theme.css +370 -418
  179. package/resources/themes/luna-amber/theme.css +360 -408
  180. package/resources/themes/luna-blue/theme.css +360 -408
  181. package/resources/themes/luna-green/theme.css +360 -408
  182. package/resources/themes/luna-pink/theme.css +360 -408
  183. package/resources/themes/md-dark-deeppurple/theme.css +373 -403
  184. package/resources/themes/md-dark-indigo/theme.css +373 -403
  185. package/resources/themes/md-light-deeppurple/theme.css +373 -403
  186. package/resources/themes/md-light-indigo/theme.css +373 -403
  187. package/resources/themes/mdc-dark-deeppurple/theme.css +373 -403
  188. package/resources/themes/mdc-dark-indigo/theme.css +373 -403
  189. package/resources/themes/mdc-light-deeppurple/theme.css +373 -403
  190. package/resources/themes/mdc-light-indigo/theme.css +373 -403
  191. package/resources/themes/mira/theme.css +347 -395
  192. package/resources/themes/nano/theme.css +348 -396
  193. package/resources/themes/nova/theme.css +336 -384
  194. package/resources/themes/nova-accent/theme.css +336 -384
  195. package/resources/themes/nova-alt/theme.css +336 -384
  196. package/resources/themes/rhea/theme.css +336 -384
  197. package/resources/themes/saga-blue/theme.css +348 -396
  198. package/resources/themes/saga-green/theme.css +348 -396
  199. package/resources/themes/saga-orange/theme.css +348 -396
  200. package/resources/themes/saga-purple/theme.css +348 -396
  201. package/resources/themes/soho-dark/theme.css +362 -410
  202. package/resources/themes/soho-light/theme.css +370 -418
  203. package/resources/themes/tailwind-light/theme.css +361 -409
  204. package/resources/themes/vela-blue/theme.css +348 -396
  205. package/resources/themes/vela-green/theme.css +348 -396
  206. package/resources/themes/vela-orange/theme.css +348 -396
  207. package/resources/themes/vela-purple/theme.css +348 -396
  208. package/resources/themes/viva-dark/theme.css +342 -390
  209. package/resources/themes/viva-light/theme.css +348 -396
  210. package/scrollpanel/scrollpanel.d.ts +22 -4
  211. package/scrolltop/scrolltop.d.ts +6 -1
  212. package/slidemenu/slidemenu.d.ts +192 -88
  213. package/splitter/splitter.d.ts +18 -5
  214. package/steps/steps.d.ts +20 -3
  215. package/table/table.d.ts +3 -1
  216. package/tabmenu/tabmenu.d.ts +24 -1
  217. package/tabview/tabview.d.ts +26 -3
  218. package/tieredmenu/tieredmenu.d.ts +134 -50
  219. package/toolbar/toolbar.d.ts +6 -1
  220. package/tooltip/tooltip.d.ts +1 -1
  221. package/utils/objectutils.d.ts +4 -0
  222. package/utils/uniquecomponentid.d.ts +1 -1
@@ -1,10 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
- import { PLATFORM_ID, Pipe, Inject, forwardRef, Component, ViewEncapsulation, Input, EventEmitter, ChangeDetectionStrategy, Output, NgModule } from '@angular/core';
2
+ import { PLATFORM_ID, Pipe, Inject, EventEmitter, forwardRef, Component, ViewEncapsulation, Input, Output, computed, signal, ChangeDetectionStrategy, ViewChild, NgModule } from '@angular/core';
3
3
  import { trigger, transition, style, animate } from '@angular/animations';
4
4
  import * as i2 from '@angular/common';
5
5
  import { isPlatformBrowser, DOCUMENT, CommonModule } from '@angular/common';
6
6
  import { DomHandler, ConnectedOverlayScrollHandler } from 'primeng/dom';
7
- import { ZIndexUtils } from 'primeng/utils';
7
+ import { UniqueComponentId, ZIndexUtils } from 'primeng/utils';
8
8
  import * as i3 from '@angular/router';
9
9
  import { RouterModule } from '@angular/router';
10
10
  import * as i4 from 'primeng/ripple';
@@ -41,103 +41,67 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImpor
41
41
  }] }, { type: i1.DomSanitizer }]; } });
42
42
  class MenuItemContent {
43
43
  item;
44
+ id;
45
+ onMenuItemClick = new EventEmitter();
44
46
  menu;
45
47
  constructor(menu) {
46
48
  this.menu = menu;
47
49
  }
48
- onItemKeyDown(event) {
49
- let listItem = event.currentTarget.parentElement;
50
- switch (event.code) {
51
- case 'ArrowDown':
52
- var nextItem = this.findNextItem(listItem);
53
- if (nextItem) {
54
- nextItem.children[0].focus();
55
- }
56
- event.preventDefault();
57
- break;
58
- case 'ArrowUp':
59
- var prevItem = this.findPrevItem(listItem);
60
- if (prevItem) {
61
- prevItem.children[0].focus();
62
- }
63
- event.preventDefault();
64
- break;
65
- case 'Space':
66
- case 'Enter':
67
- if (listItem && !DomHandler.hasClass(listItem, 'p-disabled')) {
68
- listItem.children[0].click();
69
- }
70
- event.preventDefault();
71
- break;
72
- default:
73
- break;
74
- }
75
- }
76
- findNextItem(item) {
77
- let nextItem = item.nextElementSibling;
78
- if (nextItem)
79
- return DomHandler.hasClass(nextItem, 'p-disabled') || !DomHandler.hasClass(nextItem, 'p-menuitem') ? this.findNextItem(nextItem) : nextItem;
80
- else
81
- return null;
82
- }
83
- findPrevItem(item) {
84
- let prevItem = item.previousElementSibling;
85
- if (prevItem)
86
- return DomHandler.hasClass(prevItem, 'p-disabled') || !DomHandler.hasClass(prevItem, 'p-menuitem') ? this.findPrevItem(prevItem) : prevItem;
87
- else
88
- return null;
50
+ onItemClick(event, item) {
51
+ this.onMenuItemClick.emit({ originalEvent: event, item: { ...item, id: this.id } });
89
52
  }
90
53
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: MenuItemContent, deps: [{ token: forwardRef(() => Menu) }], target: i0.ɵɵFactoryTarget.Component });
91
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.2", type: MenuItemContent, selector: "[pMenuItemContent]", inputs: { item: ["pMenuItemContent", "item"] }, host: { classAttribute: "p-element" }, ngImport: i0, template: `
92
- <a
93
- *ngIf="!item?.routerLink"
94
- (keydown)="onItemKeyDown($event)"
95
- [attr.href]="item.url || null"
96
- class="p-menuitem-link"
97
- [attr.tabindex]="item.disabled ? null : '0'"
98
- [attr.data-automationid]="item.automationId"
99
- [target]="item.target"
100
- [attr.title]="item.title"
101
- [attr.id]="item.id"
102
- [ngClass]="{ 'p-disabled': item.disabled }"
103
- (click)="menu.itemClick($event, item)"
104
- role="menuitem"
105
- >
106
- <ng-container *ngTemplateOutlet="itemContent"></ng-container>
107
- </a>
108
- <a
109
- *ngIf="item?.routerLink"
110
- (keydown)="onItemKeyDown($event)"
111
- [routerLink]="item.routerLink"
112
- [attr.data-automationid]="item.automationId"
113
- [queryParams]="item.queryParams"
114
- routerLinkActive="p-menuitem-link-active"
115
- [routerLinkActiveOptions]="item.routerLinkActiveOptions || { exact: false }"
116
- class="p-menuitem-link"
117
- [target]="item.target"
118
- [attr.id]="item.id"
119
- [attr.tabindex]="item.disabled ? null : '0'"
120
- [attr.title]="item.title"
121
- [ngClass]="{ 'p-disabled': item.disabled }"
122
- (click)="menu.itemClick($event, item)"
123
- role="menuitem"
124
- pRipple
125
- [fragment]="item.fragment"
126
- [queryParamsHandling]="item.queryParamsHandling"
127
- [preserveFragment]="item.preserveFragment"
128
- [skipLocationChange]="item.skipLocationChange"
129
- [replaceUrl]="item.replaceUrl"
130
- [state]="item.state"
131
- >
132
- <ng-container *ngTemplateOutlet="itemContent"></ng-container>
133
- </a>
54
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.2", type: MenuItemContent, selector: "[pMenuItemContent]", inputs: { item: ["pMenuItemContent", "item"], id: "id" }, outputs: { onMenuItemClick: "onMenuItemClick" }, host: { classAttribute: "p-element" }, ngImport: i0, template: `
55
+ <div [attr.data-pc-section]="'content'" class="p-menuitem-content">
56
+ <a
57
+ *ngIf="!item?.routerLink"
58
+ [attr.title]="item.title"
59
+ [attr.href]="item.url || null"
60
+ [attr.data-automationid]="item.automationId"
61
+ [attr.tabindex]="-1"
62
+ [attr.data-pc-section]="'action'"
63
+ [attr.aria-hidden]="true"
64
+ class="p-menuitem-link"
65
+ [target]="item.target"
66
+ [ngClass]="{ 'p-disabled': item.disabled }"
67
+ (click)="onItemClick($event, item)"
68
+ pRipple
69
+ >
70
+ <ng-container *ngTemplateOutlet="itemContent"></ng-container>
71
+ </a>
72
+ <a
73
+ *ngIf="item?.routerLink"
74
+ [routerLink]="item.routerLink"
75
+ [attr.data-automationid]="item.automationId"
76
+ [attr.tabindex]="-1"
77
+ [attr.data-pc-section]="'action'"
78
+ [attr.aria-hidden]="true"
79
+ [attr.title]="item.title"
80
+ [queryParams]="item.queryParams"
81
+ routerLinkActive="p-menuitem-link-active"
82
+ [routerLinkActiveOptions]="item.routerLinkActiveOptions || { exact: false }"
83
+ class="p-menuitem-link"
84
+ [target]="item.target"
85
+ [ngClass]="{ 'p-disabled': item.disabled }"
86
+ (click)="onItemClick($event, item)"
87
+ [fragment]="item.fragment"
88
+ [queryParamsHandling]="item.queryParamsHandling"
89
+ [preserveFragment]="item.preserveFragment"
90
+ [skipLocationChange]="item.skipLocationChange"
91
+ [replaceUrl]="item.replaceUrl"
92
+ [state]="item.state"
93
+ pRipple
94
+ >
95
+ <ng-container *ngTemplateOutlet="itemContent"></ng-container>
96
+ </a>
134
97
 
135
- <ng-template #itemContent>
136
- <span class="p-menuitem-icon" *ngIf="item.icon" [ngClass]="item.icon" [class]="item.iconClass" [ngStyle]="item.iconStyle"></span>
137
- <span class="p-menuitem-text" *ngIf="item.escape !== false; else htmlLabel">{{ item.label }}</span>
138
- <ng-template #htmlLabel><span class="p-menuitem-text" [innerHTML]="item.label | safeHtml"></span></ng-template>
139
- <span class="p-menuitem-badge" *ngIf="item.badge" [ngClass]="item.badgeStyleClass">{{ item.badge }}</span>
140
- </ng-template>
98
+ <ng-template #itemContent>
99
+ <span class="p-menuitem-icon" *ngIf="item.icon" [ngClass]="item.icon" [class]="item.iconClass" [ngStyle]="item.iconStyle"></span>
100
+ <span class="p-menuitem-text" *ngIf="item.escape !== false; else htmlLabel">{{ item.label }}</span>
101
+ <ng-template #htmlLabel><span class="p-menuitem-text" [innerHTML]="item.label | safeHtml"></span></ng-template>
102
+ <span class="p-menuitem-badge" *ngIf="item.badge" [ngClass]="item.badgeStyleClass">{{ item.badge }}</span>
103
+ </ng-template>
104
+ </div>
141
105
  `, isInline: true, dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i3.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i3.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "directive", type: i4.Ripple, selector: "[pRipple]" }, { kind: "pipe", type: SafeHtmlPipe, name: "safeHtml" }], encapsulation: i0.ViewEncapsulation.None });
142
106
  }
143
107
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: MenuItemContent, decorators: [{
@@ -145,55 +109,56 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImpor
145
109
  args: [{
146
110
  selector: '[pMenuItemContent]',
147
111
  template: `
148
- <a
149
- *ngIf="!item?.routerLink"
150
- (keydown)="onItemKeyDown($event)"
151
- [attr.href]="item.url || null"
152
- class="p-menuitem-link"
153
- [attr.tabindex]="item.disabled ? null : '0'"
154
- [attr.data-automationid]="item.automationId"
155
- [target]="item.target"
156
- [attr.title]="item.title"
157
- [attr.id]="item.id"
158
- [ngClass]="{ 'p-disabled': item.disabled }"
159
- (click)="menu.itemClick($event, item)"
160
- role="menuitem"
161
- >
162
- <ng-container *ngTemplateOutlet="itemContent"></ng-container>
163
- </a>
164
- <a
165
- *ngIf="item?.routerLink"
166
- (keydown)="onItemKeyDown($event)"
167
- [routerLink]="item.routerLink"
168
- [attr.data-automationid]="item.automationId"
169
- [queryParams]="item.queryParams"
170
- routerLinkActive="p-menuitem-link-active"
171
- [routerLinkActiveOptions]="item.routerLinkActiveOptions || { exact: false }"
172
- class="p-menuitem-link"
173
- [target]="item.target"
174
- [attr.id]="item.id"
175
- [attr.tabindex]="item.disabled ? null : '0'"
176
- [attr.title]="item.title"
177
- [ngClass]="{ 'p-disabled': item.disabled }"
178
- (click)="menu.itemClick($event, item)"
179
- role="menuitem"
180
- pRipple
181
- [fragment]="item.fragment"
182
- [queryParamsHandling]="item.queryParamsHandling"
183
- [preserveFragment]="item.preserveFragment"
184
- [skipLocationChange]="item.skipLocationChange"
185
- [replaceUrl]="item.replaceUrl"
186
- [state]="item.state"
187
- >
188
- <ng-container *ngTemplateOutlet="itemContent"></ng-container>
189
- </a>
112
+ <div [attr.data-pc-section]="'content'" class="p-menuitem-content">
113
+ <a
114
+ *ngIf="!item?.routerLink"
115
+ [attr.title]="item.title"
116
+ [attr.href]="item.url || null"
117
+ [attr.data-automationid]="item.automationId"
118
+ [attr.tabindex]="-1"
119
+ [attr.data-pc-section]="'action'"
120
+ [attr.aria-hidden]="true"
121
+ class="p-menuitem-link"
122
+ [target]="item.target"
123
+ [ngClass]="{ 'p-disabled': item.disabled }"
124
+ (click)="onItemClick($event, item)"
125
+ pRipple
126
+ >
127
+ <ng-container *ngTemplateOutlet="itemContent"></ng-container>
128
+ </a>
129
+ <a
130
+ *ngIf="item?.routerLink"
131
+ [routerLink]="item.routerLink"
132
+ [attr.data-automationid]="item.automationId"
133
+ [attr.tabindex]="-1"
134
+ [attr.data-pc-section]="'action'"
135
+ [attr.aria-hidden]="true"
136
+ [attr.title]="item.title"
137
+ [queryParams]="item.queryParams"
138
+ routerLinkActive="p-menuitem-link-active"
139
+ [routerLinkActiveOptions]="item.routerLinkActiveOptions || { exact: false }"
140
+ class="p-menuitem-link"
141
+ [target]="item.target"
142
+ [ngClass]="{ 'p-disabled': item.disabled }"
143
+ (click)="onItemClick($event, item)"
144
+ [fragment]="item.fragment"
145
+ [queryParamsHandling]="item.queryParamsHandling"
146
+ [preserveFragment]="item.preserveFragment"
147
+ [skipLocationChange]="item.skipLocationChange"
148
+ [replaceUrl]="item.replaceUrl"
149
+ [state]="item.state"
150
+ pRipple
151
+ >
152
+ <ng-container *ngTemplateOutlet="itemContent"></ng-container>
153
+ </a>
190
154
 
191
- <ng-template #itemContent>
192
- <span class="p-menuitem-icon" *ngIf="item.icon" [ngClass]="item.icon" [class]="item.iconClass" [ngStyle]="item.iconStyle"></span>
193
- <span class="p-menuitem-text" *ngIf="item.escape !== false; else htmlLabel">{{ item.label }}</span>
194
- <ng-template #htmlLabel><span class="p-menuitem-text" [innerHTML]="item.label | safeHtml"></span></ng-template>
195
- <span class="p-menuitem-badge" *ngIf="item.badge" [ngClass]="item.badgeStyleClass">{{ item.badge }}</span>
196
- </ng-template>
155
+ <ng-template #itemContent>
156
+ <span class="p-menuitem-icon" *ngIf="item.icon" [ngClass]="item.icon" [class]="item.iconClass" [ngStyle]="item.iconStyle"></span>
157
+ <span class="p-menuitem-text" *ngIf="item.escape !== false; else htmlLabel">{{ item.label }}</span>
158
+ <ng-template #htmlLabel><span class="p-menuitem-text" [innerHTML]="item.label | safeHtml"></span></ng-template>
159
+ <span class="p-menuitem-badge" *ngIf="item.badge" [ngClass]="item.badgeStyleClass">{{ item.badge }}</span>
160
+ </ng-template>
161
+ </div>
197
162
  `,
198
163
  encapsulation: ViewEncapsulation.None,
199
164
  host: {
@@ -206,6 +171,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImpor
206
171
  }] }]; }, propDecorators: { item: [{
207
172
  type: Input,
208
173
  args: ['pMenuItemContent']
174
+ }], id: [{
175
+ type: Input,
176
+ args: ['id']
177
+ }], onMenuItemClick: [{
178
+ type: Output
209
179
  }] } });
210
180
  /**
211
181
  * Menu is a navigation / command component that supports dynamic and static positioning.
@@ -264,6 +234,26 @@ class Menu {
264
234
  * @group Props
265
235
  */
266
236
  hideTransitionOptions = '.1s linear';
237
+ /**
238
+ * Defines a string value that labels an interactive element.
239
+ * @group Props
240
+ */
241
+ ariaLabel;
242
+ /**
243
+ * Identifier of the underlying input element.
244
+ * @group Props
245
+ */
246
+ ariaLabelledBy;
247
+ /**
248
+ * Current id state as a string.
249
+ * @group Props
250
+ */
251
+ id;
252
+ /**
253
+ * Index of the element in tabbing order.
254
+ * @group Props
255
+ */
256
+ tabindex = 0;
267
257
  /**
268
258
  * Callback to invoke when overlay menu is shown.
269
259
  * @group Emits
@@ -274,6 +264,20 @@ class Menu {
274
264
  * @group Emits
275
265
  */
276
266
  onHide = new EventEmitter();
267
+ /**
268
+ * Callback to invoke when the list loses focus.
269
+ * @param {Event} event - blur event.
270
+ * @group Emits
271
+ */
272
+ onBlur = new EventEmitter();
273
+ /**
274
+ * Callback to invoke when the list receives focus.
275
+ * @param {Event} event - focus event.
276
+ * @group Emits
277
+ */
278
+ onFocus = new EventEmitter();
279
+ listViewChild;
280
+ containerViewChild;
277
281
  container;
278
282
  scrollHandler;
279
283
  documentClickListener;
@@ -281,6 +285,13 @@ class Menu {
281
285
  preventDocumentDefault;
282
286
  target;
283
287
  visible;
288
+ focusedOptionId = computed(() => {
289
+ return this.focusedOptionIndex() !== -1 ? this.focusedOptionIndex() : null;
290
+ });
291
+ focusedOptionIndex = signal(-1);
292
+ selectedOptionIndex = signal(-1);
293
+ focused = false;
294
+ overlayVisible = false;
284
295
  relativeAlign;
285
296
  constructor(document, platformId, el, renderer, cd, config, overlayService) {
286
297
  this.document = document;
@@ -290,6 +301,7 @@ class Menu {
290
301
  this.cd = cd;
291
302
  this.config = config;
292
303
  this.overlayService = overlayService;
304
+ this.id = this.id || UniqueComponentId();
293
305
  }
294
306
  /**
295
307
  * Toggles the visibility of the popup menu.
@@ -313,8 +325,14 @@ class Menu {
313
325
  this.relativeAlign = event.relativeAlign;
314
326
  this.visible = true;
315
327
  this.preventDocumentDefault = true;
328
+ this.overlayVisible = true;
316
329
  this.cd.markForCheck();
317
330
  }
331
+ ngOnInit() {
332
+ if (!this.popup) {
333
+ this.bindDocumentClickListener();
334
+ }
335
+ }
318
336
  onOverlayAnimationStart(event) {
319
337
  switch (event.toState) {
320
338
  case 'visible':
@@ -327,6 +345,8 @@ class Menu {
327
345
  this.bindDocumentClickListener();
328
346
  this.bindDocumentResizeListener();
329
347
  this.bindScrollListener();
348
+ DomHandler.focus(this.listViewChild.nativeElement);
349
+ this.changeFocusedOptionIndex(0);
330
350
  }
331
351
  break;
332
352
  case 'void':
@@ -382,23 +402,144 @@ class Menu {
382
402
  this.hide();
383
403
  }
384
404
  }
385
- itemClick(event, item) {
386
- if (item.disabled) {
405
+ menuitemId(id, index, childIndex) {
406
+ return `${id}_${index}${typeof childIndex !== 'undefined' ? '_' + childIndex : ''}`;
407
+ }
408
+ isItemFocused(id) {
409
+ return this.focusedOptionId() === id;
410
+ }
411
+ label(label) {
412
+ return typeof label === 'function' ? label() : label;
413
+ }
414
+ disabled(disabled) {
415
+ return typeof disabled === 'function' ? disabled() : typeof disabled === 'undefined' ? false : disabled;
416
+ }
417
+ activedescendant() {
418
+ return this.focused ? this.focusedOptionId() : undefined;
419
+ }
420
+ onListFocus(event) {
421
+ this.focused = true;
422
+ if (!this.popup) {
423
+ if (this.selectedOptionIndex() !== -1) {
424
+ this.changeFocusedOptionIndex(this.selectedOptionIndex());
425
+ this.selectedOptionIndex.set(-1);
426
+ }
427
+ else {
428
+ this.changeFocusedOptionIndex(0);
429
+ }
430
+ }
431
+ this.onFocus.emit(event);
432
+ }
433
+ onListBlur(event) {
434
+ this.focused = false;
435
+ this.changeFocusedOptionIndex(-1);
436
+ this.selectedOptionIndex.set(null);
437
+ this.focusedOptionIndex.set(null);
438
+ this.onBlur.emit(event);
439
+ }
440
+ onListKeyDown(event) {
441
+ switch (event.code) {
442
+ case 'ArrowDown':
443
+ this.onArrowDownKey(event);
444
+ break;
445
+ case 'ArrowUp':
446
+ this.onArrowUpKey(event);
447
+ break;
448
+ case 'Home':
449
+ this.onHomeKey(event);
450
+ break;
451
+ case 'End':
452
+ this.onEndKey(event);
453
+ break;
454
+ case 'Enter':
455
+ this.onEnterKey(event);
456
+ break;
457
+ case 'Space':
458
+ this.onSpaceKey(event);
459
+ break;
460
+ case 'Escape':
461
+ if (this.popup) {
462
+ DomHandler.focus(this.target);
463
+ this.hide();
464
+ }
465
+ case 'Tab':
466
+ this.overlayVisible && this.hide();
467
+ break;
468
+ default:
469
+ break;
470
+ }
471
+ }
472
+ onArrowDownKey(event) {
473
+ const optionIndex = this.findNextOptionIndex(this.focusedOptionIndex());
474
+ this.changeFocusedOptionIndex(optionIndex);
475
+ event.preventDefault();
476
+ }
477
+ onArrowUpKey(event) {
478
+ if (event.altKey && this.popup) {
479
+ DomHandler.focus(this.target);
480
+ this.hide();
387
481
  event.preventDefault();
482
+ }
483
+ else {
484
+ const optionIndex = this.findPrevOptionIndex(this.focusedOptionIndex());
485
+ this.changeFocusedOptionIndex(optionIndex);
486
+ event.preventDefault();
487
+ }
488
+ }
489
+ onHomeKey(event) {
490
+ this.changeFocusedOptionIndex(0);
491
+ event.preventDefault();
492
+ }
493
+ onEndKey(event) {
494
+ this.changeFocusedOptionIndex(DomHandler.find(this.containerViewChild.nativeElement, 'li[data-pc-section="menuitem"][data-p-disabled="false"]').length - 1);
495
+ event.preventDefault();
496
+ }
497
+ onEnterKey(event) {
498
+ const element = DomHandler.findSingle(this.containerViewChild.nativeElement, `li[id="${`${this.focusedOptionIndex()}`}"]`);
499
+ const anchorElement = element && DomHandler.findSingle(element, 'a[data-pc-section="action"]');
500
+ this.popup && DomHandler.focus(this.target);
501
+ anchorElement ? anchorElement.click() : element && element.click();
502
+ event.preventDefault();
503
+ }
504
+ onSpaceKey(event) {
505
+ this.onEnterKey(event);
506
+ }
507
+ findNextOptionIndex(index) {
508
+ const links = DomHandler.find(this.containerViewChild.nativeElement, 'li[data-pc-section="menuitem"][data-p-disabled="false"]');
509
+ const matchedOptionIndex = [...links].findIndex((link) => link.id === index);
510
+ return matchedOptionIndex > -1 ? matchedOptionIndex + 1 : 0;
511
+ }
512
+ findPrevOptionIndex(index) {
513
+ const links = DomHandler.find(this.containerViewChild.nativeElement, 'li[data-pc-section="menuitem"][data-p-disabled="false"]');
514
+ const matchedOptionIndex = [...links].findIndex((link) => link.id === index);
515
+ return matchedOptionIndex > -1 ? matchedOptionIndex - 1 : 0;
516
+ }
517
+ changeFocusedOptionIndex(index) {
518
+ const links = DomHandler.find(this.containerViewChild.nativeElement, 'li[data-pc-section="menuitem"][data-p-disabled="false"]');
519
+ let order = index >= links.length ? links.length - 1 : index < 0 ? 0 : index;
520
+ order > -1 && this.focusedOptionIndex.set(links[order].getAttribute('id'));
521
+ }
522
+ itemClick(event) {
523
+ const { originalEvent, item } = event;
524
+ if (item.disabled) {
525
+ originalEvent.preventDefault();
388
526
  return;
389
527
  }
390
528
  if (!item.url && !item.routerLink) {
391
- event.preventDefault();
529
+ originalEvent.preventDefault();
392
530
  }
393
531
  if (item.command) {
394
532
  item.command({
395
- originalEvent: event,
533
+ originalEvent: originalEvent,
396
534
  item: item
397
535
  });
398
536
  }
399
537
  if (this.popup) {
400
538
  this.hide();
401
539
  }
540
+ if (!this.popup && this.focusedOptionIndex() !== item.id) {
541
+ this.focusedOptionIndex.set(item.id);
542
+ }
402
543
  }
403
544
  onOverlayClick(event) {
404
545
  if (this.popup) {
@@ -412,11 +553,16 @@ class Menu {
412
553
  bindDocumentClickListener() {
413
554
  if (!this.documentClickListener && isPlatformBrowser(this.platformId)) {
414
555
  const documentTarget = this.el ? this.el.nativeElement.ownerDocument : 'document';
415
- this.documentClickListener = this.renderer.listen(documentTarget, 'click', () => {
416
- if (!this.preventDocumentDefault) {
556
+ this.documentClickListener = this.renderer.listen(documentTarget, 'click', (event) => {
557
+ const isOutsideContainer = this.containerViewChild.nativeElement && !this.containerViewChild.nativeElement.contains(event.target);
558
+ const isOutsideTarget = !(this.target && (this.target === event.target || this.target.contains(event.target)));
559
+ if (!this.popup && isOutsideContainer && isOutsideTarget) {
560
+ this.onListBlur(event);
561
+ }
562
+ if (this.preventDocumentDefault && this.overlayVisible && isOutsideContainer && isOutsideTarget) {
417
563
  this.hide();
564
+ this.preventDocumentDefault = false;
418
565
  }
419
- this.preventDocumentDefault = false;
420
566
  });
421
567
  }
422
568
  }
@@ -474,6 +620,9 @@ class Menu {
474
620
  this.restoreOverlayAppend();
475
621
  this.onOverlayHide();
476
622
  }
623
+ if (!this.popup) {
624
+ this.unbindDocumentClickListener();
625
+ }
477
626
  }
478
627
  hasSubMenu() {
479
628
  if (this.model) {
@@ -486,7 +635,7 @@ class Menu {
486
635
  return false;
487
636
  }
488
637
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: Menu, deps: [{ token: DOCUMENT }, { token: PLATFORM_ID }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i5.PrimeNGConfig }, { token: i5.OverlayService }], target: i0.ɵɵFactoryTarget.Component });
489
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.2", type: Menu, selector: "p-menu", inputs: { model: "model", popup: "popup", style: "style", styleClass: "styleClass", appendTo: "appendTo", autoZIndex: "autoZIndex", baseZIndex: "baseZIndex", showTransitionOptions: "showTransitionOptions", hideTransitionOptions: "hideTransitionOptions" }, outputs: { onShow: "onShow", onHide: "onHide" }, host: { classAttribute: "p-element" }, ngImport: i0, template: `
638
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.2", type: Menu, selector: "p-menu", inputs: { model: "model", popup: "popup", style: "style", styleClass: "styleClass", appendTo: "appendTo", autoZIndex: "autoZIndex", baseZIndex: "baseZIndex", showTransitionOptions: "showTransitionOptions", hideTransitionOptions: "hideTransitionOptions", ariaLabel: "ariaLabel", ariaLabelledBy: "ariaLabelledBy", id: "id", tabindex: "tabindex" }, outputs: { onShow: "onShow", onHide: "onHide", onBlur: "onBlur", onFocus: "onFocus" }, host: { classAttribute: "p-element" }, viewQueries: [{ propertyName: "listViewChild", first: true, predicate: ["list"], descendants: true }, { propertyName: "containerViewChild", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: `
490
639
  <div
491
640
  #container
492
641
  [ngClass]="{ 'p-menu p-component': true, 'p-menu-overlay': popup }"
@@ -498,9 +647,24 @@ class Menu {
498
647
  [@.disabled]="popup !== true"
499
648
  (@overlayAnimation.start)="onOverlayAnimationStart($event)"
500
649
  (@overlayAnimation.done)="onOverlayAnimationEnd($event)"
650
+ [attr.data-pc-name]="'menu'"
651
+ [id]="id"
501
652
  >
502
- <ul class="p-menu-list p-reset" role="menu">
503
- <ng-template ngFor let-submenu [ngForOf]="model" *ngIf="hasSubMenu()">
653
+ <ul
654
+ #list
655
+ class="p-menu-list p-reset"
656
+ role="menu"
657
+ [id]="id + '_list'"
658
+ [tabindex]="tabindex"
659
+ [attr.data-pc-section]="'menu'"
660
+ [attr.aria-activedescendant]="activedescendant()"
661
+ [attr.aria-label]="ariaLabel"
662
+ [attr.aria-labelledBy]="ariaLabelledBy"
663
+ (focus)="onListFocus($event)"
664
+ (blur)="onListBlur($event)"
665
+ (keydown)="onListKeyDown($event)"
666
+ >
667
+ <ng-template ngFor let-submenu let-i="index" [ngForOf]="model" *ngIf="hasSubMenu()">
504
668
  <li class="p-menu-separator" *ngIf="submenu.separator" [ngClass]="{ 'p-hidden': submenu.visible === false }" role="separator"></li>
505
669
  <li
506
670
  class="p-submenu-header"
@@ -510,42 +674,59 @@ class Menu {
510
674
  pTooltip
511
675
  [tooltipOptions]="submenu.tooltipOptions"
512
676
  role="none"
677
+ [attr.id]="menuitemId(id, i)"
513
678
  >
514
679
  <span *ngIf="submenu.escape !== false; else htmlSubmenuLabel">{{ submenu.label }}</span>
515
680
  <ng-template #htmlSubmenuLabel><span [innerHTML]="submenu.label | safeHtml"></span></ng-template>
516
681
  </li>
517
- <ng-template ngFor let-item [ngForOf]="submenu.items">
682
+ <ng-template ngFor let-item let-j="index" [ngForOf]="submenu.items">
518
683
  <li class="p-menu-separator" *ngIf="item.separator" [ngClass]="{ 'p-hidden': item.visible === false || submenu.visible === false }" role="separator"></li>
519
684
  <li
520
685
  class="p-menuitem"
521
686
  *ngIf="!item.separator"
522
687
  [pMenuItemContent]="item"
523
- [ngClass]="{ 'p-hidden': item.visible === false || submenu.visible === false }"
688
+ [ngClass]="{ 'p-hidden': item.visible === false || submenu.visible === false, 'p-focus': focusedOptionId() && menuitemId(id, i, j) === focusedOptionId(), 'p-disabled': disabled(item.disabled) }"
524
689
  [ngStyle]="item.style"
525
690
  [class]="item.styleClass"
691
+ (onMenuItemClick)="itemClick($event)"
526
692
  pTooltip
527
693
  [tooltipOptions]="item.tooltipOptions"
528
- role="none"
694
+ role="menuitem"
695
+ [attr.data-pc-section]="'menuitem'"
696
+ [attr.aria-label]="label(item.label)"
697
+ [attr.data-p-focused]="isItemFocused(menuitemId(id, i, j))"
698
+ [attr.data-p-disabled]="disabled(item.disabled)"
699
+ [attr.aria-disabled]="disabled(item.disabled)"
700
+ [attr.id]="menuitemId(id, i, j)"
701
+ [id]="menuitemId(id, i, j)"
529
702
  ></li>
530
703
  </ng-template>
531
704
  </ng-template>
532
- <ng-template ngFor let-item [ngForOf]="model" *ngIf="!hasSubMenu()">
705
+ <ng-template ngFor let-item let-i="index" [ngForOf]="model" *ngIf="!hasSubMenu()">
533
706
  <li class="p-menu-separator" *ngIf="item.separator" [ngClass]="{ 'p-hidden': item.visible === false }" role="separator"></li>
534
707
  <li
535
708
  class="p-menuitem"
536
709
  *ngIf="!item.separator"
537
710
  [pMenuItemContent]="item"
538
- [ngClass]="{ 'p-hidden': item.visible === false }"
711
+ [ngClass]="{ 'p-hidden': item.visible === false, 'p-focus': focusedOptionId() && menuitemId(id, i) === focusedOptionId(), 'p-disabled': disabled(item.disabled) }"
539
712
  [ngStyle]="item.style"
540
713
  [class]="item.styleClass"
714
+ (onMenuItemClick)="itemClick($event)"
541
715
  pTooltip
542
716
  [tooltipOptions]="item.tooltipOptions"
543
- role="none"
717
+ role="menuitem"
718
+ [attr.data-pc-section]="'menuitem'"
719
+ [attr.aria-label]="label(item.label)"
720
+ [attr.data-p-focused]="isItemFocused(menuitemId(id, i))"
721
+ [attr.data-p-disabled]="disabled(item.disabled)"
722
+ [attr.aria-disabled]="disabled(item.disabled)"
723
+ [attr.id]="menuitemId(id, i)"
724
+ [id]="menuitemId(id, i)"
544
725
  ></li>
545
726
  </ng-template>
546
727
  </ul>
547
728
  </div>
548
- `, isInline: true, styles: [".p-menu-overlay{position:absolute;top:0;left:0}.p-menu ul{margin:0;padding:0;list-style:none}.p-menu .p-submenu-header{align-items:center}.p-menu .p-menuitem-link{cursor:pointer;display:flex;align-items:center;text-decoration:none;overflow:hidden;position:relative}.p-menu .p-menuitem-text{line-height:1}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: MenuItemContent, selector: "[pMenuItemContent]", inputs: ["pMenuItemContent"] }, { kind: "pipe", type: SafeHtmlPipe, name: "safeHtml" }], animations: [trigger('overlayAnimation', [transition(':enter', [style({ opacity: 0, transform: 'scaleY(0.8)' }), animate('{{showTransitionParams}}')]), transition(':leave', [animate('{{hideTransitionParams}}', style({ opacity: 0 }))])])], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
729
+ `, isInline: true, styles: [".p-menu-overlay{position:absolute;top:0;left:0}.p-menu ul{margin:0;padding:0;list-style:none}.p-menu .p-submenu-header{align-items:center}.p-menu .p-menuitem-link{cursor:pointer;display:flex;align-items:center;text-decoration:none;overflow:hidden;position:relative}.p-menu .p-menuitem-text{line-height:1}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: MenuItemContent, selector: "[pMenuItemContent]", inputs: ["pMenuItemContent", "id"], outputs: ["onMenuItemClick"] }, { kind: "pipe", type: SafeHtmlPipe, name: "safeHtml" }], animations: [trigger('overlayAnimation', [transition(':enter', [style({ opacity: 0, transform: 'scaleY(0.8)' }), animate('{{showTransitionParams}}')]), transition(':leave', [animate('{{hideTransitionParams}}', style({ opacity: 0 }))])])], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
549
730
  }
550
731
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: Menu, decorators: [{
551
732
  type: Component,
@@ -561,9 +742,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImpor
561
742
  [@.disabled]="popup !== true"
562
743
  (@overlayAnimation.start)="onOverlayAnimationStart($event)"
563
744
  (@overlayAnimation.done)="onOverlayAnimationEnd($event)"
745
+ [attr.data-pc-name]="'menu'"
746
+ [id]="id"
564
747
  >
565
- <ul class="p-menu-list p-reset" role="menu">
566
- <ng-template ngFor let-submenu [ngForOf]="model" *ngIf="hasSubMenu()">
748
+ <ul
749
+ #list
750
+ class="p-menu-list p-reset"
751
+ role="menu"
752
+ [id]="id + '_list'"
753
+ [tabindex]="tabindex"
754
+ [attr.data-pc-section]="'menu'"
755
+ [attr.aria-activedescendant]="activedescendant()"
756
+ [attr.aria-label]="ariaLabel"
757
+ [attr.aria-labelledBy]="ariaLabelledBy"
758
+ (focus)="onListFocus($event)"
759
+ (blur)="onListBlur($event)"
760
+ (keydown)="onListKeyDown($event)"
761
+ >
762
+ <ng-template ngFor let-submenu let-i="index" [ngForOf]="model" *ngIf="hasSubMenu()">
567
763
  <li class="p-menu-separator" *ngIf="submenu.separator" [ngClass]="{ 'p-hidden': submenu.visible === false }" role="separator"></li>
568
764
  <li
569
765
  class="p-submenu-header"
@@ -573,37 +769,54 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImpor
573
769
  pTooltip
574
770
  [tooltipOptions]="submenu.tooltipOptions"
575
771
  role="none"
772
+ [attr.id]="menuitemId(id, i)"
576
773
  >
577
774
  <span *ngIf="submenu.escape !== false; else htmlSubmenuLabel">{{ submenu.label }}</span>
578
775
  <ng-template #htmlSubmenuLabel><span [innerHTML]="submenu.label | safeHtml"></span></ng-template>
579
776
  </li>
580
- <ng-template ngFor let-item [ngForOf]="submenu.items">
777
+ <ng-template ngFor let-item let-j="index" [ngForOf]="submenu.items">
581
778
  <li class="p-menu-separator" *ngIf="item.separator" [ngClass]="{ 'p-hidden': item.visible === false || submenu.visible === false }" role="separator"></li>
582
779
  <li
583
780
  class="p-menuitem"
584
781
  *ngIf="!item.separator"
585
782
  [pMenuItemContent]="item"
586
- [ngClass]="{ 'p-hidden': item.visible === false || submenu.visible === false }"
783
+ [ngClass]="{ 'p-hidden': item.visible === false || submenu.visible === false, 'p-focus': focusedOptionId() && menuitemId(id, i, j) === focusedOptionId(), 'p-disabled': disabled(item.disabled) }"
587
784
  [ngStyle]="item.style"
588
785
  [class]="item.styleClass"
786
+ (onMenuItemClick)="itemClick($event)"
589
787
  pTooltip
590
788
  [tooltipOptions]="item.tooltipOptions"
591
- role="none"
789
+ role="menuitem"
790
+ [attr.data-pc-section]="'menuitem'"
791
+ [attr.aria-label]="label(item.label)"
792
+ [attr.data-p-focused]="isItemFocused(menuitemId(id, i, j))"
793
+ [attr.data-p-disabled]="disabled(item.disabled)"
794
+ [attr.aria-disabled]="disabled(item.disabled)"
795
+ [attr.id]="menuitemId(id, i, j)"
796
+ [id]="menuitemId(id, i, j)"
592
797
  ></li>
593
798
  </ng-template>
594
799
  </ng-template>
595
- <ng-template ngFor let-item [ngForOf]="model" *ngIf="!hasSubMenu()">
800
+ <ng-template ngFor let-item let-i="index" [ngForOf]="model" *ngIf="!hasSubMenu()">
596
801
  <li class="p-menu-separator" *ngIf="item.separator" [ngClass]="{ 'p-hidden': item.visible === false }" role="separator"></li>
597
802
  <li
598
803
  class="p-menuitem"
599
804
  *ngIf="!item.separator"
600
805
  [pMenuItemContent]="item"
601
- [ngClass]="{ 'p-hidden': item.visible === false }"
806
+ [ngClass]="{ 'p-hidden': item.visible === false, 'p-focus': focusedOptionId() && menuitemId(id, i) === focusedOptionId(), 'p-disabled': disabled(item.disabled) }"
602
807
  [ngStyle]="item.style"
603
808
  [class]="item.styleClass"
809
+ (onMenuItemClick)="itemClick($event)"
604
810
  pTooltip
605
811
  [tooltipOptions]="item.tooltipOptions"
606
- role="none"
812
+ role="menuitem"
813
+ [attr.data-pc-section]="'menuitem'"
814
+ [attr.aria-label]="label(item.label)"
815
+ [attr.data-p-focused]="isItemFocused(menuitemId(id, i))"
816
+ [attr.data-p-disabled]="disabled(item.disabled)"
817
+ [attr.aria-disabled]="disabled(item.disabled)"
818
+ [attr.id]="menuitemId(id, i)"
819
+ [id]="menuitemId(id, i)"
607
820
  ></li>
608
821
  </ng-template>
609
822
  </ul>
@@ -635,10 +848,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImpor
635
848
  type: Input
636
849
  }], hideTransitionOptions: [{
637
850
  type: Input
851
+ }], ariaLabel: [{
852
+ type: Input
853
+ }], ariaLabelledBy: [{
854
+ type: Input
855
+ }], id: [{
856
+ type: Input
857
+ }], tabindex: [{
858
+ type: Input
638
859
  }], onShow: [{
639
860
  type: Output
640
861
  }], onHide: [{
641
862
  type: Output
863
+ }], onBlur: [{
864
+ type: Output
865
+ }], onFocus: [{
866
+ type: Output
867
+ }], listViewChild: [{
868
+ type: ViewChild,
869
+ args: ['list']
870
+ }], containerViewChild: [{
871
+ type: ViewChild,
872
+ args: ['container']
642
873
  }] } });
643
874
  class MenuModule {
644
875
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: MenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });