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
@@ -2,180 +2,266 @@ import { trigger, transition, style, animate } from '@angular/animations';
2
2
  import * as i1 from '@angular/common';
3
3
  import { DOCUMENT, isPlatformBrowser, CommonModule } from '@angular/common';
4
4
  import * as i0 from '@angular/core';
5
- import { forwardRef, PLATFORM_ID, Component, ViewEncapsulation, Inject, Input, ViewChild, EventEmitter, ChangeDetectionStrategy, Output, ContentChildren, NgModule } from '@angular/core';
5
+ import { EventEmitter, Component, ViewEncapsulation, Inject, Input, Output, ViewChild, signal, effect, PLATFORM_ID, ChangeDetectionStrategy, ContentChildren, NgModule } from '@angular/core';
6
6
  import * as i2 from '@angular/router';
7
7
  import { RouterModule } from '@angular/router';
8
- import * as i4 from 'primeng/api';
8
+ import * as i5 from 'primeng/api';
9
9
  import { PrimeTemplate, SharedModule } from 'primeng/api';
10
- import { DomHandler, ConnectedOverlayScrollHandler } from 'primeng/dom';
10
+ import { DomHandler } from 'primeng/dom';
11
11
  import { AngleRightIcon } from 'primeng/icons/angleright';
12
- import { CaretLeftIcon } from 'primeng/icons/caretleft';
13
- import { CaretRightIcon } from 'primeng/icons/caretright';
14
- import * as i3 from 'primeng/tooltip';
12
+ import * as i3 from 'primeng/ripple';
13
+ import { RippleModule } from 'primeng/ripple';
14
+ import * as i4 from 'primeng/tooltip';
15
15
  import { TooltipModule } from 'primeng/tooltip';
16
- import { ZIndexUtils } from 'primeng/utils';
16
+ import { ObjectUtils, UniqueComponentId, ZIndexUtils } from 'primeng/utils';
17
+ import { CaretLeftIcon } from 'primeng/icons/caretleft';
17
18
 
18
19
  class SlideMenuSub {
19
20
  document;
20
- platformId;
21
+ el;
21
22
  renderer;
22
- item;
23
- root;
24
- backLabel = 'Back';
23
+ cd;
24
+ slideMenu;
25
+ items;
25
26
  menuWidth;
26
- effectDuration;
27
+ root = false;
27
28
  easing = 'ease-out';
28
- index;
29
+ effectDuration;
30
+ autoDisplay;
31
+ autoZIndex = true;
32
+ baseZIndex = 0;
33
+ popup;
34
+ menuId;
35
+ ariaLabel;
36
+ ariaLabelledBy;
37
+ level = 0;
38
+ focusedItemId;
39
+ activeItemPath;
40
+ tabindex = 0;
41
+ itemClick = new EventEmitter();
42
+ itemMouseEnter = new EventEmitter();
43
+ menuFocus = new EventEmitter();
44
+ menuBlur = new EventEmitter();
45
+ menuKeydown = new EventEmitter();
29
46
  sublistViewChild;
30
- slideMenu;
31
- transitionEndListener;
32
- constructor(slideMenu, document, platformId, renderer) {
47
+ get isActive() {
48
+ return -this.slideMenu.left == this.level * this.menuWidth;
49
+ }
50
+ constructor(document, el, renderer, cd, slideMenu) {
33
51
  this.document = document;
34
- this.platformId = platformId;
52
+ this.el = el;
35
53
  this.renderer = renderer;
54
+ this.cd = cd;
36
55
  this.slideMenu = slideMenu;
37
56
  }
38
- activeItem;
39
- itemClick(event, item, listitem) {
40
- if (item.disabled) {
41
- event.preventDefault();
42
- return;
43
- }
44
- if (!item.url && !item.routerLink) {
45
- event.preventDefault();
46
- }
47
- if (item.command) {
48
- item.command({
49
- originalEvent: event,
50
- item: item
51
- });
52
- }
53
- if (item.items && !this.slideMenu.animating) {
54
- this.slideMenu.left -= this.slideMenu.menuWidth;
55
- this.activeItem = listitem;
56
- this.slideMenu.animating = true;
57
- setTimeout(() => (this.slideMenu.animating = false), this.effectDuration);
58
- }
59
- if (!item.items && this.slideMenu.popup) {
60
- this.slideMenu.hide();
61
- }
57
+ getItemProp(processedItem, name, params = null) {
58
+ return processedItem && processedItem.item ? ObjectUtils.getItemValue(processedItem.item[name], params) : undefined;
62
59
  }
63
- focusNextList(listitem) {
64
- if (!this.slideMenu.animating) {
65
- let focusableElements = DomHandler.getFocusableElements(listitem);
66
- if (focusableElements && focusableElements.length > 0) {
67
- focusableElements[0].focus();
68
- }
69
- this.unbindTransitionEndListener();
70
- }
60
+ getItemId(processedItem) {
61
+ return `${this.menuId}_${processedItem.key}`;
71
62
  }
72
- onItemKeyDown(event) {
73
- let listItem = event.target.parentElement;
74
- switch (event.code) {
75
- case 'Space':
76
- case 'Enter':
77
- if (listItem && !DomHandler.hasClass(listItem, 'p-disabled')) {
78
- listItem.children[0].click();
79
- this.transitionEndListener = this.renderer.listen(this.sublistViewChild?.nativeElement, 'transitionend', this.focusNextList.bind(this, listItem));
80
- }
81
- event.preventDefault();
82
- break;
83
- default:
84
- break;
85
- }
63
+ getItemKey(processedItem) {
64
+ return this.getItemId(processedItem);
86
65
  }
87
- unbindTransitionEndListener() {
88
- if (this.transitionEndListener && this.sublistViewChild) {
89
- this.transitionEndListener();
90
- this.transitionEndListener = null;
66
+ getItemClass(processedItem) {
67
+ return {
68
+ ...this.getItemProp(processedItem, 'class'),
69
+ 'p-menuitem': true,
70
+ 'p-menuitem-active': this.isItemActive(processedItem),
71
+ 'p-focus': this.isItemFocused(processedItem),
72
+ 'p-disabled': this.isItemDisabled(processedItem)
73
+ };
74
+ }
75
+ getItemLabel(processedItem) {
76
+ return this.getItemProp(processedItem, 'label');
77
+ }
78
+ getSeparatorItemClass(processedItem) {
79
+ return {
80
+ ...this.getItemProp(processedItem, 'class'),
81
+ 'p-menuitem-separator': true
82
+ };
83
+ }
84
+ getAriaSetSize() {
85
+ return this.items.filter((processedItem) => this.isItemVisible(processedItem) && !this.getItemProp(processedItem, 'separator')).length;
86
+ }
87
+ getAriaPosInset(index) {
88
+ return index - this.items.slice(0, index).filter((processedItem) => this.isItemVisible(processedItem) && this.getItemProp(processedItem, 'separator')).length + 1;
89
+ }
90
+ isItemVisible(processedItem) {
91
+ return this.getItemProp(processedItem, 'visible') !== false;
92
+ }
93
+ isItemActive(processedItem) {
94
+ if (this.activeItemPath) {
95
+ return this.activeItemPath.some((path) => path.key === processedItem.key);
91
96
  }
92
97
  }
93
- ngOnDestroy() {
94
- this.activeItem = null;
95
- this.unbindTransitionEndListener();
98
+ isItemDisabled(processedItem) {
99
+ return this.getItemProp(processedItem, 'disabled');
96
100
  }
97
- get isActive() {
98
- return -this.slideMenu.left == this.index * this.menuWidth;
101
+ isItemFocused(processedItem) {
102
+ return this.focusedItemId === this.getItemId(processedItem);
99
103
  }
100
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: SlideMenuSub, deps: [{ token: forwardRef(() => SlideMenu) }, { token: DOCUMENT }, { token: PLATFORM_ID }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
101
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.2", type: SlideMenuSub, selector: "p-slideMenuSub", inputs: { item: "item", root: "root", backLabel: "backLabel", menuWidth: "menuWidth", effectDuration: "effectDuration", easing: "easing", index: "index" }, host: { classAttribute: "p-element" }, viewQueries: [{ propertyName: "sublistViewChild", first: true, predicate: ["sublist"], descendants: true }], ngImport: i0, template: `
104
+ isItemGroup(processedItem) {
105
+ return ObjectUtils.isNotEmpty(processedItem.items);
106
+ }
107
+ onItemClick(event, processedItem) {
108
+ this.getItemProp(processedItem, 'command', { originalEvent: event, item: processedItem.item });
109
+ this.itemClick.emit({ originalEvent: event, processedItem, isFocus: true });
110
+ event.preventDefault();
111
+ }
112
+ onMenuKeyDown(event) {
113
+ this.menuKeydown.emit(event);
114
+ }
115
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: SlideMenuSub, deps: [{ token: DOCUMENT }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: SlideMenu }], target: i0.ɵɵFactoryTarget.Component });
116
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.2", type: SlideMenuSub, selector: "p-slideMenuSub", inputs: { items: "items", menuWidth: "menuWidth", root: "root", easing: "easing", effectDuration: "effectDuration", autoDisplay: "autoDisplay", autoZIndex: "autoZIndex", baseZIndex: "baseZIndex", popup: "popup", menuId: "menuId", ariaLabel: "ariaLabel", ariaLabelledBy: "ariaLabelledBy", level: "level", focusedItemId: "focusedItemId", activeItemPath: "activeItemPath", tabindex: "tabindex" }, outputs: { itemClick: "itemClick", itemMouseEnter: "itemMouseEnter", menuFocus: "menuFocus", menuBlur: "menuBlur", menuKeydown: "menuKeydown" }, host: { classAttribute: "p-element" }, viewQueries: [{ propertyName: "sublistViewChild", first: true, predicate: ["sublist"], descendants: true, static: true }], ngImport: i0, template: `
102
117
  <ul
103
118
  #sublist
104
- [ngClass]="{ 'p-slidemenu-rootlist': root, 'p-submenu-list': !root, 'p-active-submenu': isActive }"
119
+ role="menu"
120
+ [ngClass]="{ 'p-submenu-list': !root, 'p-slidemenu-root-list': root, 'p-active-submenu': isActive }"
121
+ [id]="menuId + '_list'"
105
122
  [style.width.px]="menuWidth"
106
123
  [style.left.px]="root ? slideMenu.left : slideMenu.menuWidth"
107
124
  [style.transitionProperty]="root ? 'left' : 'none'"
108
125
  [style.transitionDuration]="effectDuration + 'ms'"
109
126
  [style.transitionTimingFunction]="easing"
127
+ [tabindex]="tabindex"
128
+ [attr.aria-label]="ariaLabel"
129
+ [attr.aria-labelledBy]="ariaLabelledBy"
130
+ [attr.aria-aria-activedescendant]="focusedItemId"
131
+ [attr.aria-orientation]="'vertical'"
132
+ [attr.data-pc-section]="'menu'"
133
+ (keydown)="menuKeydown.emit($event)"
134
+ (focusin)="menuFocus.emit($event)"
135
+ [attr.data-pc-state]="isActive ? 'active' : 'inactive'"
110
136
  >
111
- <ng-template ngFor let-child [ngForOf]="root ? item : item?.items">
112
- <li *ngIf="child.separator" class="p-menu-separator" [ngClass]="{ 'p-hidden': child.visible === false }"></li>
137
+ <ng-template ngFor let-processedItem [ngForOf]="items" let-index="index">
138
+ <li
139
+ *ngIf="isItemVisible(processedItem) && getItemProp(processedItem, 'separator')"
140
+ [id]="getItemId(processedItem)"
141
+ [style]="getItemProp(processedItem, 'style')"
142
+ [ngClass]="getSeparatorItemClass(processedItem)"
143
+ role="separator"
144
+ [attr.data-pc-section]="'separator'"
145
+ ></li>
113
146
  <li
114
- *ngIf="!child.separator"
115
- #listitem
116
- [ngClass]="{ 'p-menuitem': true, 'p-menuitem-active': listitem == activeItem, 'p-hidden': child.visible === false }"
147
+ #listItem
148
+ *ngIf="isItemVisible(processedItem) && !getItemProp(processedItem, 'separator')"
149
+ role="menuitem"
150
+ [id]="getItemId(processedItem)"
151
+ [attr.data-pc-section]="'menuitem'"
152
+ [attr.data-p-highlight]="isItemActive(processedItem)"
153
+ [attr.data-p-focused]="isItemFocused(processedItem)"
154
+ [attr.data-p-disabled]="isItemDisabled(processedItem)"
155
+ [attr.aria-label]="getItemLabel(processedItem)"
156
+ [attr.aria-disabled]="isItemDisabled(processedItem) || undefined"
157
+ [attr.aria-haspopup]="isItemGroup(processedItem) && !getItemProp(processedItem, 'to') ? 'menu' : undefined"
158
+ [attr.aria-expanded]="isItemGroup(processedItem) ? isItemActive(processedItem) : undefined"
159
+ [attr.aria-level]="level + 1"
160
+ [attr.aria-setsize]="getAriaSetSize()"
161
+ [attr.aria-posinset]="getAriaPosInset(index)"
162
+ [ngStyle]="getItemProp(processedItem, 'style')"
163
+ [ngClass]="getItemClass(processedItem)"
164
+ [class]="getItemProp(processedItem, 'styleClass')"
117
165
  pTooltip
118
- [tooltipOptions]="child.tooltipOptions"
119
- [class]="child.styleClass"
120
- [ngStyle]="child.style"
166
+ [tooltipOptions]="getItemProp(processedItem, 'tooltipOptions')"
121
167
  >
122
- <a
123
- *ngIf="!child.routerLink"
124
- (keydown)="onItemKeyDown($event)"
125
- [attr.href]="child.url"
126
- class="p-menuitem-link"
127
- [target]="child.target"
128
- [attr.title]="child.title"
129
- [attr.id]="child.id"
130
- [ngClass]="{ 'p-disabled': child.disabled }"
131
- [attr.tabindex]="child.disabled || !isActive ? null : '0'"
132
- (click)="itemClick($event, child, listitem)"
133
- >
134
- <span class="p-menuitem-icon" *ngIf="child.icon" [ngClass]="child.icon" [ngStyle]="child.iconStyle"></span>
135
- <span class="p-menuitem-text" *ngIf="child.escape !== false; else htmlRouteLabel">{{ child.label }}</span>
136
- <ng-template #htmlRouteLabel><span class="p-menuitem-text" [innerHTML]="child.label"></span></ng-template>
137
- <span class="p-menuitem-badge" *ngIf="child.badge" [ngClass]="child.badgeStyleClass">{{ child.badge }}</span>
138
- <ng-container *ngIf="child.items">
139
- <AngleRightIcon *ngIf="!slideMenu.submenuIconTemplate" [styleClass]="'p-submenu-icon'" />
140
- <ng-template *ngTemplateOutlet="slideMenu.submenuIconTemplate"></ng-template>
141
- </ng-container>
142
- </a>
143
- <a
144
- *ngIf="child.routerLink"
145
- (keydown)="onItemKeyDown($event)"
146
- [routerLink]="child.routerLink"
147
- [queryParams]="child.queryParams"
148
- [routerLinkActive]="'p-menuitem-link-active'"
149
- [routerLinkActiveOptions]="child.routerLinkActiveOptions || { exact: false }"
150
- [href]="child.url"
151
- class="p-menuitem-link"
152
- [target]="child.target"
153
- [attr.title]="child.title"
154
- [attr.id]="child.id"
155
- [attr.tabindex]="child.disabled || !isActive ? null : '0'"
156
- [ngClass]="{ 'p-disabled': child.disabled }"
157
- (click)="itemClick($event, child, listitem)"
158
- [fragment]="child.fragment"
159
- [queryParamsHandling]="child.queryParamsHandling"
160
- [preserveFragment]="child.preserveFragment"
161
- [skipLocationChange]="child.skipLocationChange"
162
- [replaceUrl]="child.replaceUrl"
163
- [state]="child.state"
164
- >
165
- <span class="p-menuitem-icon" *ngIf="child.icon" [ngClass]="child.icon" [ngStyle]="child.iconStyle"></span>
166
- <span class="p-menuitem-text" *ngIf="child.escape !== false; else htmlRouteLabel">{{ child.label }}</span>
167
- <ng-template #htmlRouteLabel><span class="p-menuitem-text" [innerHTML]="child.label"></span></ng-template>
168
- <span class="p-menuitem-badge" *ngIf="child.badge" [ngClass]="child.badgeStyleClass">{{ child.badge }}</span>
169
- <ng-container *ngIf="child.items">
170
- <CaretRightIcon *ngIf="!slideMenu.submenuIconTemplate" [styleClass]="'p-submenu-icon'" />
171
- <ng-template *ngTemplateOutlet="slideMenu.submenuIconTemplate"></ng-template>
172
- </ng-container>
173
- </a>
174
- <p-slideMenuSub class="p-submenu" [item]="child" [index]="index + 1" [menuWidth]="menuWidth" *ngIf="child.items"></p-slideMenuSub>
168
+ <div [attr.data-pc-section]="'content'" class="p-menuitem-content" (click)="onItemClick($event, processedItem)" (mouseenter)="itemMouseEnter.emit({ originalEvent: $event, processedItem })">
169
+ <a
170
+ *ngIf="!getItemProp(processedItem, 'routerLink')"
171
+ [attr.href]="getItemProp(processedItem, 'url')"
172
+ [attr.aria-hidden]="true"
173
+ [attr.data-automationid]="getItemProp(processedItem, 'automationId')"
174
+ [attr.data-pc-section]="'action'"
175
+ [target]="getItemProp(processedItem, 'target')"
176
+ [ngClass]="{ 'p-menuitem-link': true, 'p-disabled': getItemProp(processedItem, 'disabled') }"
177
+ [attr.tabindex]="-1"
178
+ pRipple
179
+ >
180
+ <span
181
+ *ngIf="getItemProp(processedItem, 'icon')"
182
+ class="p-menuitem-icon"
183
+ [ngClass]="getItemProp(processedItem, 'icon')"
184
+ [ngStyle]="getItemProp(processedItem, 'iconStyle')"
185
+ [attr.data-pc-section]="'icon'"
186
+ [attr.aria-hidden]="true"
187
+ [attr.tabindex]="-1"
188
+ >
189
+ </span>
190
+ <span *ngIf="getItemProp(processedItem, 'escape'); else htmlLabel" class="p-menuitem-text" [attr.data-pc-section]="'label'">
191
+ {{ getItemLabel(processedItem) }}
192
+ </span>
193
+ <ng-template #htmlLabel>
194
+ <span class="p-menuitem-text" [innerHTML]="getItemLabel(processedItem)" [attr.data-pc-section]="'label'"></span>
195
+ </ng-template>
196
+ <span class="p-menuitem-badge" *ngIf="getItemProp(processedItem, 'badge')" [ngClass]="getItemProp(processedItem, 'badgeStyleClass')">{{ child.badge }}</span>
197
+
198
+ <ng-container *ngIf="isItemGroup(processedItem)">
199
+ <AngleRightIcon *ngIf="!slideMenu.submenuIconTemplate" [styleClass]="'p-submenu-icon'" [attr.data-pc-section]="'submenuicon'" [attr.aria-hidden]="true" />
200
+ <ng-template *ngTemplateOutlet="slideMenu.submenuIconTemplate" [attr.data-pc-section]="'submenuicon'" [attr.aria-hidden]="true"></ng-template>
201
+ </ng-container>
202
+ </a>
203
+ <a
204
+ *ngIf="getItemProp(processedItem, 'routerLink')"
205
+ [routerLink]="getItemProp(processedItem, 'routerLink')"
206
+ [attr.data-automationid]="getItemProp(processedItem, 'automationId')"
207
+ [attr.tabindex]="-1"
208
+ [attr.aria-hidden]="true"
209
+ [attr.data-pc-section]="'action'"
210
+ [queryParams]="getItemProp(processedItem, 'queryParams')"
211
+ [routerLinkActive]="'p-menuitem-link-active'"
212
+ [routerLinkActiveOptions]="getItemProp(processedItem, 'routerLinkActiveOptions') || { exact: false }"
213
+ [target]="getItemProp(processedItem, 'target')"
214
+ [ngClass]="{ 'p-menuitem-link': true, 'p-disabled': getItemProp(processedItem, 'disabled') }"
215
+ [fragment]="getItemProp(processedItem, 'fragment')"
216
+ [queryParamsHandling]="getItemProp(processedItem, 'queryParamsHandling')"
217
+ [preserveFragment]="getItemProp(processedItem, 'preserveFragment')"
218
+ [skipLocationChange]="getItemProp(processedItem, 'skipLocationChange')"
219
+ [replaceUrl]="getItemProp(processedItem, 'replaceUrl')"
220
+ [state]="getItemProp(processedItem, 'state')"
221
+ pRipple
222
+ >
223
+ <span
224
+ *ngIf="getItemProp(processedItem, 'icon')"
225
+ class="p-menuitem-icon"
226
+ [ngClass]="getItemProp(processedItem, 'icon')"
227
+ [ngStyle]="getItemProp(processedItem, 'iconStyle')"
228
+ [attr.data-pc-section]="'icon'"
229
+ [attr.aria-hidden]="true"
230
+ [attr.tabindex]="-1"
231
+ >
232
+ </span>
233
+ <span *ngIf="getItemProp(processedItem, 'escape'); else htmlLabel" class="p-menuitem-text" [attr.data-pc-section]="'label'">
234
+ {{ getItemLabel(processedItem) }}
235
+ </span>
236
+ <ng-template #htmlLabel>
237
+ <span class="p-menuitem-text" [innerHTML]="getItemLabel(processedItem)" [attr.data-pc-section]="'label'"></span>
238
+ </ng-template>
239
+ <span class="p-menuitem-badge" *ngIf="getItemProp(processedItem, 'badge')" [ngClass]="getItemProp(processedItem, 'badgeStyleClass')">{{ child.badge }}</span>
240
+
241
+ <ng-container *ngIf="isItemGroup(processedItem)">
242
+ <AngleRightIcon *ngIf="!slideMenu.submenuIconTemplate" [styleClass]="'p-submenu-icon'" [attr.data-pc-section]="'submenuicon'" [attr.aria-hidden]="true" />
243
+ <ng-template *ngTemplateOutlet="slideMenu.submenuIconTemplate" [attr.data-pc-section]="'submenuicon'" [attr.aria-hidden]="true"></ng-template>
244
+ </ng-container>
245
+ </a>
246
+ </div>
247
+
248
+ <p-slideMenuSub
249
+ *ngIf="isItemVisible(processedItem) && isItemGroup(processedItem)"
250
+ class="p-submenu"
251
+ [items]="processedItem.items"
252
+ [autoDisplay]="autoDisplay"
253
+ [menuId]="menuId"
254
+ [activeItemPath]="activeItemPath"
255
+ [focusedItemId]="focusedItemId"
256
+ [level]="level + 1"
257
+ [menuWidth]="menuWidth"
258
+ (itemClick)="itemClick.emit($event)"
259
+ (itemMouseEnter)="itemMouseEnter.emit($event)"
260
+ ></p-slideMenuSub>
175
261
  </li>
176
262
  </ng-template>
177
263
  </ul>
178
- `, isInline: true, dependencies: [{ kind: "directive", type: i0.forwardRef(function () { return i1.NgClass; }), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i0.forwardRef(function () { return i1.NgForOf; }), selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i0.forwardRef(function () { return i1.NgIf; }), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i0.forwardRef(function () { return i1.NgTemplateOutlet; }), selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i0.forwardRef(function () { return i1.NgStyle; }), selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i0.forwardRef(function () { return i2.RouterLink; }), selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i0.forwardRef(function () { return i2.RouterLinkActive; }), selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "directive", type: i0.forwardRef(function () { return i3.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: i0.forwardRef(function () { return CaretRightIcon; }), selector: "CaretRightIcon" }, { kind: "component", type: i0.forwardRef(function () { return AngleRightIcon; }), selector: "AngleRightIcon" }, { kind: "component", type: i0.forwardRef(function () { return SlideMenuSub; }), selector: "p-slideMenuSub", inputs: ["item", "root", "backLabel", "menuWidth", "effectDuration", "easing", "index"] }], encapsulation: i0.ViewEncapsulation.None });
264
+ `, isInline: true, dependencies: [{ kind: "directive", type: i0.forwardRef(function () { return i1.NgClass; }), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i0.forwardRef(function () { return i1.NgForOf; }), selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i0.forwardRef(function () { return i1.NgIf; }), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i0.forwardRef(function () { return i1.NgTemplateOutlet; }), selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i0.forwardRef(function () { return i1.NgStyle; }), selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i0.forwardRef(function () { return i2.RouterLink; }), selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i0.forwardRef(function () { return i2.RouterLinkActive; }), selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "directive", type: i0.forwardRef(function () { return i3.Ripple; }), selector: "[pRipple]" }, { kind: "directive", type: i0.forwardRef(function () { return i4.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: i0.forwardRef(function () { return AngleRightIcon; }), selector: "AngleRightIcon" }, { kind: "component", type: i0.forwardRef(function () { return SlideMenuSub; }), selector: "p-slideMenuSub", inputs: ["items", "menuWidth", "root", "easing", "effectDuration", "autoDisplay", "autoZIndex", "baseZIndex", "popup", "menuId", "ariaLabel", "ariaLabelledBy", "level", "focusedItemId", "activeItemPath", "tabindex"], outputs: ["itemClick", "itemMouseEnter", "menuFocus", "menuBlur", "menuKeydown"] }], encapsulation: i0.ViewEncapsulation.None });
179
265
  }
180
266
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: SlideMenuSub, decorators: [{
181
267
  type: Component,
@@ -184,77 +270,148 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImpor
184
270
  template: `
185
271
  <ul
186
272
  #sublist
187
- [ngClass]="{ 'p-slidemenu-rootlist': root, 'p-submenu-list': !root, 'p-active-submenu': isActive }"
273
+ role="menu"
274
+ [ngClass]="{ 'p-submenu-list': !root, 'p-slidemenu-root-list': root, 'p-active-submenu': isActive }"
275
+ [id]="menuId + '_list'"
188
276
  [style.width.px]="menuWidth"
189
277
  [style.left.px]="root ? slideMenu.left : slideMenu.menuWidth"
190
278
  [style.transitionProperty]="root ? 'left' : 'none'"
191
279
  [style.transitionDuration]="effectDuration + 'ms'"
192
280
  [style.transitionTimingFunction]="easing"
281
+ [tabindex]="tabindex"
282
+ [attr.aria-label]="ariaLabel"
283
+ [attr.aria-labelledBy]="ariaLabelledBy"
284
+ [attr.aria-aria-activedescendant]="focusedItemId"
285
+ [attr.aria-orientation]="'vertical'"
286
+ [attr.data-pc-section]="'menu'"
287
+ (keydown)="menuKeydown.emit($event)"
288
+ (focusin)="menuFocus.emit($event)"
289
+ [attr.data-pc-state]="isActive ? 'active' : 'inactive'"
193
290
  >
194
- <ng-template ngFor let-child [ngForOf]="root ? item : item?.items">
195
- <li *ngIf="child.separator" class="p-menu-separator" [ngClass]="{ 'p-hidden': child.visible === false }"></li>
291
+ <ng-template ngFor let-processedItem [ngForOf]="items" let-index="index">
196
292
  <li
197
- *ngIf="!child.separator"
198
- #listitem
199
- [ngClass]="{ 'p-menuitem': true, 'p-menuitem-active': listitem == activeItem, 'p-hidden': child.visible === false }"
293
+ *ngIf="isItemVisible(processedItem) && getItemProp(processedItem, 'separator')"
294
+ [id]="getItemId(processedItem)"
295
+ [style]="getItemProp(processedItem, 'style')"
296
+ [ngClass]="getSeparatorItemClass(processedItem)"
297
+ role="separator"
298
+ [attr.data-pc-section]="'separator'"
299
+ ></li>
300
+ <li
301
+ #listItem
302
+ *ngIf="isItemVisible(processedItem) && !getItemProp(processedItem, 'separator')"
303
+ role="menuitem"
304
+ [id]="getItemId(processedItem)"
305
+ [attr.data-pc-section]="'menuitem'"
306
+ [attr.data-p-highlight]="isItemActive(processedItem)"
307
+ [attr.data-p-focused]="isItemFocused(processedItem)"
308
+ [attr.data-p-disabled]="isItemDisabled(processedItem)"
309
+ [attr.aria-label]="getItemLabel(processedItem)"
310
+ [attr.aria-disabled]="isItemDisabled(processedItem) || undefined"
311
+ [attr.aria-haspopup]="isItemGroup(processedItem) && !getItemProp(processedItem, 'to') ? 'menu' : undefined"
312
+ [attr.aria-expanded]="isItemGroup(processedItem) ? isItemActive(processedItem) : undefined"
313
+ [attr.aria-level]="level + 1"
314
+ [attr.aria-setsize]="getAriaSetSize()"
315
+ [attr.aria-posinset]="getAriaPosInset(index)"
316
+ [ngStyle]="getItemProp(processedItem, 'style')"
317
+ [ngClass]="getItemClass(processedItem)"
318
+ [class]="getItemProp(processedItem, 'styleClass')"
200
319
  pTooltip
201
- [tooltipOptions]="child.tooltipOptions"
202
- [class]="child.styleClass"
203
- [ngStyle]="child.style"
320
+ [tooltipOptions]="getItemProp(processedItem, 'tooltipOptions')"
204
321
  >
205
- <a
206
- *ngIf="!child.routerLink"
207
- (keydown)="onItemKeyDown($event)"
208
- [attr.href]="child.url"
209
- class="p-menuitem-link"
210
- [target]="child.target"
211
- [attr.title]="child.title"
212
- [attr.id]="child.id"
213
- [ngClass]="{ 'p-disabled': child.disabled }"
214
- [attr.tabindex]="child.disabled || !isActive ? null : '0'"
215
- (click)="itemClick($event, child, listitem)"
216
- >
217
- <span class="p-menuitem-icon" *ngIf="child.icon" [ngClass]="child.icon" [ngStyle]="child.iconStyle"></span>
218
- <span class="p-menuitem-text" *ngIf="child.escape !== false; else htmlRouteLabel">{{ child.label }}</span>
219
- <ng-template #htmlRouteLabel><span class="p-menuitem-text" [innerHTML]="child.label"></span></ng-template>
220
- <span class="p-menuitem-badge" *ngIf="child.badge" [ngClass]="child.badgeStyleClass">{{ child.badge }}</span>
221
- <ng-container *ngIf="child.items">
222
- <AngleRightIcon *ngIf="!slideMenu.submenuIconTemplate" [styleClass]="'p-submenu-icon'" />
223
- <ng-template *ngTemplateOutlet="slideMenu.submenuIconTemplate"></ng-template>
224
- </ng-container>
225
- </a>
226
- <a
227
- *ngIf="child.routerLink"
228
- (keydown)="onItemKeyDown($event)"
229
- [routerLink]="child.routerLink"
230
- [queryParams]="child.queryParams"
231
- [routerLinkActive]="'p-menuitem-link-active'"
232
- [routerLinkActiveOptions]="child.routerLinkActiveOptions || { exact: false }"
233
- [href]="child.url"
234
- class="p-menuitem-link"
235
- [target]="child.target"
236
- [attr.title]="child.title"
237
- [attr.id]="child.id"
238
- [attr.tabindex]="child.disabled || !isActive ? null : '0'"
239
- [ngClass]="{ 'p-disabled': child.disabled }"
240
- (click)="itemClick($event, child, listitem)"
241
- [fragment]="child.fragment"
242
- [queryParamsHandling]="child.queryParamsHandling"
243
- [preserveFragment]="child.preserveFragment"
244
- [skipLocationChange]="child.skipLocationChange"
245
- [replaceUrl]="child.replaceUrl"
246
- [state]="child.state"
247
- >
248
- <span class="p-menuitem-icon" *ngIf="child.icon" [ngClass]="child.icon" [ngStyle]="child.iconStyle"></span>
249
- <span class="p-menuitem-text" *ngIf="child.escape !== false; else htmlRouteLabel">{{ child.label }}</span>
250
- <ng-template #htmlRouteLabel><span class="p-menuitem-text" [innerHTML]="child.label"></span></ng-template>
251
- <span class="p-menuitem-badge" *ngIf="child.badge" [ngClass]="child.badgeStyleClass">{{ child.badge }}</span>
252
- <ng-container *ngIf="child.items">
253
- <CaretRightIcon *ngIf="!slideMenu.submenuIconTemplate" [styleClass]="'p-submenu-icon'" />
254
- <ng-template *ngTemplateOutlet="slideMenu.submenuIconTemplate"></ng-template>
255
- </ng-container>
256
- </a>
257
- <p-slideMenuSub class="p-submenu" [item]="child" [index]="index + 1" [menuWidth]="menuWidth" *ngIf="child.items"></p-slideMenuSub>
322
+ <div [attr.data-pc-section]="'content'" class="p-menuitem-content" (click)="onItemClick($event, processedItem)" (mouseenter)="itemMouseEnter.emit({ originalEvent: $event, processedItem })">
323
+ <a
324
+ *ngIf="!getItemProp(processedItem, 'routerLink')"
325
+ [attr.href]="getItemProp(processedItem, 'url')"
326
+ [attr.aria-hidden]="true"
327
+ [attr.data-automationid]="getItemProp(processedItem, 'automationId')"
328
+ [attr.data-pc-section]="'action'"
329
+ [target]="getItemProp(processedItem, 'target')"
330
+ [ngClass]="{ 'p-menuitem-link': true, 'p-disabled': getItemProp(processedItem, 'disabled') }"
331
+ [attr.tabindex]="-1"
332
+ pRipple
333
+ >
334
+ <span
335
+ *ngIf="getItemProp(processedItem, 'icon')"
336
+ class="p-menuitem-icon"
337
+ [ngClass]="getItemProp(processedItem, 'icon')"
338
+ [ngStyle]="getItemProp(processedItem, 'iconStyle')"
339
+ [attr.data-pc-section]="'icon'"
340
+ [attr.aria-hidden]="true"
341
+ [attr.tabindex]="-1"
342
+ >
343
+ </span>
344
+ <span *ngIf="getItemProp(processedItem, 'escape'); else htmlLabel" class="p-menuitem-text" [attr.data-pc-section]="'label'">
345
+ {{ getItemLabel(processedItem) }}
346
+ </span>
347
+ <ng-template #htmlLabel>
348
+ <span class="p-menuitem-text" [innerHTML]="getItemLabel(processedItem)" [attr.data-pc-section]="'label'"></span>
349
+ </ng-template>
350
+ <span class="p-menuitem-badge" *ngIf="getItemProp(processedItem, 'badge')" [ngClass]="getItemProp(processedItem, 'badgeStyleClass')">{{ child.badge }}</span>
351
+
352
+ <ng-container *ngIf="isItemGroup(processedItem)">
353
+ <AngleRightIcon *ngIf="!slideMenu.submenuIconTemplate" [styleClass]="'p-submenu-icon'" [attr.data-pc-section]="'submenuicon'" [attr.aria-hidden]="true" />
354
+ <ng-template *ngTemplateOutlet="slideMenu.submenuIconTemplate" [attr.data-pc-section]="'submenuicon'" [attr.aria-hidden]="true"></ng-template>
355
+ </ng-container>
356
+ </a>
357
+ <a
358
+ *ngIf="getItemProp(processedItem, 'routerLink')"
359
+ [routerLink]="getItemProp(processedItem, 'routerLink')"
360
+ [attr.data-automationid]="getItemProp(processedItem, 'automationId')"
361
+ [attr.tabindex]="-1"
362
+ [attr.aria-hidden]="true"
363
+ [attr.data-pc-section]="'action'"
364
+ [queryParams]="getItemProp(processedItem, 'queryParams')"
365
+ [routerLinkActive]="'p-menuitem-link-active'"
366
+ [routerLinkActiveOptions]="getItemProp(processedItem, 'routerLinkActiveOptions') || { exact: false }"
367
+ [target]="getItemProp(processedItem, 'target')"
368
+ [ngClass]="{ 'p-menuitem-link': true, 'p-disabled': getItemProp(processedItem, 'disabled') }"
369
+ [fragment]="getItemProp(processedItem, 'fragment')"
370
+ [queryParamsHandling]="getItemProp(processedItem, 'queryParamsHandling')"
371
+ [preserveFragment]="getItemProp(processedItem, 'preserveFragment')"
372
+ [skipLocationChange]="getItemProp(processedItem, 'skipLocationChange')"
373
+ [replaceUrl]="getItemProp(processedItem, 'replaceUrl')"
374
+ [state]="getItemProp(processedItem, 'state')"
375
+ pRipple
376
+ >
377
+ <span
378
+ *ngIf="getItemProp(processedItem, 'icon')"
379
+ class="p-menuitem-icon"
380
+ [ngClass]="getItemProp(processedItem, 'icon')"
381
+ [ngStyle]="getItemProp(processedItem, 'iconStyle')"
382
+ [attr.data-pc-section]="'icon'"
383
+ [attr.aria-hidden]="true"
384
+ [attr.tabindex]="-1"
385
+ >
386
+ </span>
387
+ <span *ngIf="getItemProp(processedItem, 'escape'); else htmlLabel" class="p-menuitem-text" [attr.data-pc-section]="'label'">
388
+ {{ getItemLabel(processedItem) }}
389
+ </span>
390
+ <ng-template #htmlLabel>
391
+ <span class="p-menuitem-text" [innerHTML]="getItemLabel(processedItem)" [attr.data-pc-section]="'label'"></span>
392
+ </ng-template>
393
+ <span class="p-menuitem-badge" *ngIf="getItemProp(processedItem, 'badge')" [ngClass]="getItemProp(processedItem, 'badgeStyleClass')">{{ child.badge }}</span>
394
+
395
+ <ng-container *ngIf="isItemGroup(processedItem)">
396
+ <AngleRightIcon *ngIf="!slideMenu.submenuIconTemplate" [styleClass]="'p-submenu-icon'" [attr.data-pc-section]="'submenuicon'" [attr.aria-hidden]="true" />
397
+ <ng-template *ngTemplateOutlet="slideMenu.submenuIconTemplate" [attr.data-pc-section]="'submenuicon'" [attr.aria-hidden]="true"></ng-template>
398
+ </ng-container>
399
+ </a>
400
+ </div>
401
+
402
+ <p-slideMenuSub
403
+ *ngIf="isItemVisible(processedItem) && isItemGroup(processedItem)"
404
+ class="p-submenu"
405
+ [items]="processedItem.items"
406
+ [autoDisplay]="autoDisplay"
407
+ [menuId]="menuId"
408
+ [activeItemPath]="activeItemPath"
409
+ [focusedItemId]="focusedItemId"
410
+ [level]="level + 1"
411
+ [menuWidth]="menuWidth"
412
+ (itemClick)="itemClick.emit($event)"
413
+ (itemMouseEnter)="itemMouseEnter.emit($event)"
414
+ ></p-slideMenuSub>
258
415
  </li>
259
416
  </ng-template>
260
417
  </ul>
@@ -264,32 +421,54 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImpor
264
421
  class: 'p-element'
265
422
  }
266
423
  }]
267
- }], ctorParameters: function () { return [{ type: SlideMenu, decorators: [{
268
- type: Inject,
269
- args: [forwardRef(() => SlideMenu)]
270
- }] }, { type: Document, decorators: [{
424
+ }], ctorParameters: function () { return [{ type: Document, decorators: [{
271
425
  type: Inject,
272
426
  args: [DOCUMENT]
273
- }] }, { type: undefined, decorators: [{
274
- type: Inject,
275
- args: [PLATFORM_ID]
276
- }] }, { type: i0.Renderer2 }]; }, propDecorators: { item: [{
427
+ }] }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: SlideMenu }]; }, propDecorators: { items: [{
277
428
  type: Input
278
- }], root: [{
429
+ }], menuWidth: [{
279
430
  type: Input
280
- }], backLabel: [{
431
+ }], root: [{
281
432
  type: Input
282
- }], menuWidth: [{
433
+ }], easing: [{
283
434
  type: Input
284
435
  }], effectDuration: [{
285
436
  type: Input
286
- }], easing: [{
437
+ }], autoDisplay: [{
438
+ type: Input
439
+ }], autoZIndex: [{
440
+ type: Input
441
+ }], baseZIndex: [{
442
+ type: Input
443
+ }], popup: [{
444
+ type: Input
445
+ }], menuId: [{
446
+ type: Input
447
+ }], ariaLabel: [{
448
+ type: Input
449
+ }], ariaLabelledBy: [{
287
450
  type: Input
288
- }], index: [{
451
+ }], level: [{
289
452
  type: Input
453
+ }], focusedItemId: [{
454
+ type: Input
455
+ }], activeItemPath: [{
456
+ type: Input
457
+ }], tabindex: [{
458
+ type: Input
459
+ }], itemClick: [{
460
+ type: Output
461
+ }], itemMouseEnter: [{
462
+ type: Output
463
+ }], menuFocus: [{
464
+ type: Output
465
+ }], menuBlur: [{
466
+ type: Output
467
+ }], menuKeydown: [{
468
+ type: Output
290
469
  }], sublistViewChild: [{
291
470
  type: ViewChild,
292
- args: ['sublist']
471
+ args: ['sublist', { static: true }]
293
472
  }] } });
294
473
  /**
295
474
  * SlideMenu displays submenus with slide animation.
@@ -304,52 +483,62 @@ class SlideMenu {
304
483
  config;
305
484
  overlayService;
306
485
  /**
307
- * An array of menuitems.
486
+ * Width of the submenus.
308
487
  * @group Props
309
488
  */
310
- model;
489
+ menuWidth = 190;
311
490
  /**
312
- * Defines if menu would displayed as a popup.
491
+ * Height of the scrollable area, a scrollbar appears if a menu height is longer than this value.
313
492
  * @group Props
314
493
  */
315
- popup;
494
+ viewportHeight = 180;
316
495
  /**
317
- * Inline style of the element.
496
+ * Duration of the sliding animation in milliseconds.
318
497
  * @group Props
319
498
  */
320
- style;
499
+ effectDuration = 250;
321
500
  /**
322
- * Class of the element.
501
+ * Easing animation to use for sliding.
323
502
  * @group Props
324
503
  */
325
- styleClass;
504
+ easing = 'ease-out';
326
505
  /**
327
- * Width of the submenus.
506
+ * Label of element to navigate back.
328
507
  * @group Props
329
508
  */
330
- menuWidth = 190;
509
+ backLabel = 'Back';
331
510
  /**
332
- * Height of the scrollable area, a scrollbar appears if a menu height is longer than this value.
511
+ * When present, it specifies that the component should be disabled.
333
512
  * @group Props
334
513
  */
335
- viewportHeight = 180;
514
+ disabled = false;
336
515
  /**
337
- * Duration of the sliding animation in milliseconds.
516
+ * Index of the element in tabbing order.
338
517
  * @group Props
339
518
  */
340
- effectDuration = 250;
519
+ tabindex = 0;
341
520
  /**
342
- * Easing animation to use for sliding.
521
+ * An array of menuitems.
343
522
  * @group Props
344
523
  */
345
- easing = 'ease-out';
524
+ model;
346
525
  /**
347
- * Label of element to navigate back.
526
+ * Defines if menu would displayed as a popup.
348
527
  * @group Props
349
528
  */
350
- backLabel = 'Back';
529
+ popup;
351
530
  /**
352
- * Target element to attach the overlay, valid values are "body" or a local ng-template variable of another element (note: use binding with brackets for template variables, e.g. [appendTo]="mydiv" for a div element having #mydiv as variable name).
531
+ * Inline style of the component.
532
+ * @group Props
533
+ */
534
+ style;
535
+ /**
536
+ * Style class of the component.
537
+ * @group Props
538
+ */
539
+ styleClass;
540
+ /**
541
+ * Target element to attach the overlay, valid values are "body" or a local ng-template variable of another element.
353
542
  * @group Props
354
543
  */
355
544
  appendTo;
@@ -363,6 +552,12 @@ class SlideMenu {
363
552
  * @group Props
364
553
  */
365
554
  baseZIndex = 0;
555
+ /**
556
+ * Whether to show a root submenu on mouse over.
557
+ * @defaultValue true
558
+ * @group Props
559
+ */
560
+ autoDisplay = true;
366
561
  /**
367
562
  * Transition options of the show animation.
368
563
  * @group Props
@@ -373,6 +568,21 @@ class SlideMenu {
373
568
  * @group Props
374
569
  */
375
570
  hideTransitionOptions = '.1s linear';
571
+ /**
572
+ * Current id state as a string.
573
+ * @group Props
574
+ */
575
+ id;
576
+ /**
577
+ * Defines a string value that labels an interactive element.
578
+ * @group Props
579
+ */
580
+ ariaLabel;
581
+ /**
582
+ * Identifier of the underlying input element.
583
+ * @group Props
584
+ */
585
+ ariaLabelledBy;
376
586
  /**
377
587
  * Callback to invoke when overlay menu is shown.
378
588
  * @group Emits
@@ -384,21 +594,48 @@ class SlideMenu {
384
594
  */
385
595
  onHide = new EventEmitter();
386
596
  templates;
597
+ rootmenu;
387
598
  containerViewChild;
388
- backwardViewChild;
599
+ set backward(element) {
600
+ this.backwardViewChild = element;
601
+ }
389
602
  slideMenuContentViewChild;
390
- documentClickListener;
391
- documentResizeListener;
392
- preventDocumentDefault;
393
- scrollHandler;
603
+ submenuIconTemplate;
604
+ backIconTemplate;
605
+ outsideClickListener;
606
+ resizeListener;
607
+ transitionEndListener;
608
+ transitionStartListener;
609
+ backwardViewChild;
610
+ transition = false;
394
611
  left = 0;
395
612
  animating = false;
396
613
  target;
397
614
  visible;
398
- viewportUpdated;
615
+ relativeAlign;
399
616
  window;
400
- submenuIconTemplate;
401
- backIconTemplate;
617
+ focused = false;
618
+ activeItemPath = signal([]);
619
+ focusedItemInfo = signal({ index: -1, level: 0, parentKey: '' });
620
+ searchValue = '';
621
+ searchTimeout;
622
+ _processedItems;
623
+ container;
624
+ itemClick = false;
625
+ get visibleItems() {
626
+ const processedItem = this.activeItemPath().find((p) => p.key === this.focusedItemInfo().parentKey);
627
+ return processedItem ? processedItem.items : this.processedItems;
628
+ }
629
+ get processedItems() {
630
+ if (!this._processedItems || !this._processedItems.length) {
631
+ this._processedItems = this.createProcessedItems(this.model || []);
632
+ }
633
+ return this._processedItems;
634
+ }
635
+ get focusedItemId() {
636
+ const focusedItemInfo = this.focusedItemInfo();
637
+ return focusedItemInfo.index !== -1 ? `${this.id}${ObjectUtils.isNotEmpty(focusedItemInfo.parentKey) ? '_' + focusedItemInfo.parentKey : ''}_${focusedItemInfo.index}` : null;
638
+ }
402
639
  constructor(document, platformId, el, renderer, cd, config, overlayService) {
403
640
  this.document = document;
404
641
  this.platformId = platformId;
@@ -408,15 +645,26 @@ class SlideMenu {
408
645
  this.config = config;
409
646
  this.overlayService = overlayService;
410
647
  this.window = this.document.defaultView;
648
+ effect(() => {
649
+ const path = this.activeItemPath();
650
+ if (this.popup) {
651
+ if (ObjectUtils.isNotEmpty(path)) {
652
+ this.bindOutsideClickListener();
653
+ this.bindResizeListener();
654
+ }
655
+ else {
656
+ this.unbindOutsideClickListener();
657
+ this.unbindResizeListener();
658
+ }
659
+ }
660
+ });
411
661
  }
412
- ngAfterViewChecked() {
413
- if (!this.viewportUpdated && !this.popup && this.containerViewChild) {
414
- this.updateViewPort();
415
- this.viewportUpdated = true;
416
- }
662
+ documentFocusListener;
663
+ ngOnInit() {
664
+ this.id = this.id || UniqueComponentId();
417
665
  }
418
666
  ngAfterContentInit() {
419
- this.templates?.forEach((item) => {
667
+ this.templates.forEach((item) => {
420
668
  switch (item.getType()) {
421
669
  case 'backicon':
422
670
  this.backIconTemplate = item.template;
@@ -427,40 +675,56 @@ class SlideMenu {
427
675
  }
428
676
  });
429
677
  }
430
- set container(element) {
431
- this.containerViewChild = element;
678
+ createProcessedItems(items, level = 0, parent = {}, parentKey = '') {
679
+ const processedItems = [];
680
+ items &&
681
+ items.forEach((item, index) => {
682
+ const key = (parentKey !== '' ? parentKey + '_' : '') + index;
683
+ const newItem = {
684
+ item,
685
+ index,
686
+ level,
687
+ key,
688
+ parent,
689
+ parentKey
690
+ };
691
+ newItem['items'] = this.createProcessedItems(item.items, level + 1, newItem, key);
692
+ processedItems.push(newItem);
693
+ });
694
+ return processedItems;
432
695
  }
433
- set backward(element) {
434
- this.backwardViewChild = element;
696
+ getItemProp(item, name) {
697
+ return item ? ObjectUtils.getItemValue(item[name]) : undefined;
435
698
  }
436
- set slideMenuContent(element) {
437
- this.slideMenuContentViewChild = element;
699
+ getProccessedItemLabel(processedItem) {
700
+ return processedItem ? this.getItemLabel(processedItem.item) : undefined;
438
701
  }
439
- updateViewPort() {
440
- this.renderer.setStyle(this.slideMenuContentViewChild?.nativeElement, 'height', this.viewportHeight - DomHandler.getHiddenElementOuterHeight(this.backwardViewChild?.nativeElement) + 'px');
702
+ getItemLabel(item) {
703
+ return this.getItemProp(item, 'label');
441
704
  }
442
- /**
443
- * Toggles the visibility of the popup menu.
444
- * @param {Event} event - Browser event.
445
- * @group Method
446
- */
447
- toggle(event) {
448
- if (this.visible)
449
- this.hide();
450
- else
451
- this.show(event);
452
- this.preventDocumentDefault = true;
705
+ isProcessedItemGroup(processedItem) {
706
+ return processedItem && ObjectUtils.isNotEmpty(processedItem.items);
453
707
  }
454
- /**
455
- * Displays the popup menu.
456
- * @param {Event} event - Browser event.
457
- * @group Method
458
- */
459
- show(event) {
460
- this.target = event.currentTarget;
461
- this.visible = true;
462
- this.preventDocumentDefault = true;
463
- this.cd.markForCheck();
708
+ isSelected(processedItem) {
709
+ return this.activeItemPath().some((p) => p.key === processedItem.key);
710
+ }
711
+ isValidSelectedItem(processedItem) {
712
+ return this.isValidItem(processedItem) && this.isSelected(processedItem);
713
+ }
714
+ isValidItem(processedItem) {
715
+ return !!processedItem && !this.isItemDisabled(processedItem.item) && !this.isItemSeparator(processedItem.item);
716
+ }
717
+ isItemDisabled(item) {
718
+ return this.getItemProp(item, 'disabled');
719
+ }
720
+ isItemSeparator(item) {
721
+ return this.getItemProp(item, 'separator');
722
+ }
723
+ isItemMatched(processedItem) {
724
+ return this.isValidItem(processedItem) && this.getProccessedItemLabel(processedItem).toLocaleLowerCase().startsWith(this.searchValue.toLocaleLowerCase());
725
+ }
726
+ isProccessedItemGroup(processedItem) {
727
+ return processedItem && ObjectUtils.isNotEmpty(processedItem.items);
464
728
  }
465
729
  onOverlayClick(event) {
466
730
  if (this.popup) {
@@ -469,20 +733,303 @@ class SlideMenu {
469
733
  target: this.el.nativeElement
470
734
  });
471
735
  }
472
- this.preventDocumentDefault = true;
736
+ }
737
+ goBack(event) {
738
+ this.animate('left');
739
+ event.stopPropagation();
740
+ event.preventDefault();
741
+ }
742
+ onItemClick(event) {
743
+ if (this.transition) {
744
+ return;
745
+ }
746
+ else {
747
+ if (!this.itemClick) {
748
+ this.itemClick = true;
749
+ this.onMenuFocus();
750
+ }
751
+ const { originalEvent, processedItem } = event;
752
+ const grouped = this.isProcessedItemGroup(processedItem);
753
+ if (grouped) {
754
+ this.focusedItemInfo.mutate((value) => {
755
+ value.index = -1;
756
+ value.level = value.level + 1;
757
+ value.parentKey = processedItem.key;
758
+ });
759
+ this.animate('right');
760
+ }
761
+ else {
762
+ this.onItemChange(event);
763
+ this.popup && this.hide();
764
+ }
765
+ }
766
+ }
767
+ onItemMouseEnter(event) {
768
+ this.onItemChange(event);
769
+ }
770
+ onKeyDown(event) {
771
+ if (!this.transition) {
772
+ const metaKey = event.metaKey || event.ctrlKey;
773
+ switch (event.code) {
774
+ case 'ArrowDown':
775
+ this.onArrowDownKey(event);
776
+ break;
777
+ case 'ArrowUp':
778
+ this.onArrowUpKey(event);
779
+ break;
780
+ case 'ArrowLeft':
781
+ this.onArrowLeftKey(event);
782
+ break;
783
+ case 'ArrowRight':
784
+ this.onArrowRightKey(event);
785
+ break;
786
+ case 'Home':
787
+ this.onHomeKey(event);
788
+ break;
789
+ case 'End':
790
+ this.onEndKey(event);
791
+ break;
792
+ case 'Space':
793
+ this.onSpaceKey(event);
794
+ break;
795
+ case 'Enter':
796
+ this.onEnterKey(event);
797
+ break;
798
+ case 'Escape':
799
+ this.onEscapeKey(event);
800
+ break;
801
+ case 'Tab':
802
+ this.onTabKey(event);
803
+ break;
804
+ case 'PageDown':
805
+ case 'PageUp':
806
+ case 'Backspace':
807
+ case 'ShiftLeft':
808
+ case 'ShiftRight':
809
+ //NOOP
810
+ break;
811
+ default:
812
+ if (!metaKey && ObjectUtils.isPrintableCharacter(event.key)) {
813
+ this.searchItems(event, event.key);
814
+ }
815
+ break;
816
+ }
817
+ }
818
+ }
819
+ onNavigationKeyDown(event) {
820
+ switch (event.code) {
821
+ case 'Enter':
822
+ case 'Space':
823
+ this.onArrowLeftKey(event);
824
+ this.focusedItemInfo.mutate((value) => (value.index = -1));
825
+ break;
826
+ default:
827
+ break;
828
+ }
829
+ }
830
+ animate(to) {
831
+ switch (to) {
832
+ case 'right':
833
+ this.left -= this.menuWidth;
834
+ break;
835
+ case 'left':
836
+ this.left += this.menuWidth;
837
+ break;
838
+ default:
839
+ break;
840
+ }
841
+ this.animating = true;
842
+ setTimeout(() => (this.animating = false), this.effectDuration);
843
+ }
844
+ onArrowDownKey(event) {
845
+ const itemIndex = this.focusedItemInfo().index !== -1 ? this.findNextItemIndex(this.focusedItemInfo().index) : this.findFirstFocusedItemIndex();
846
+ this.changeFocusedItemIndex(event, itemIndex);
847
+ event.preventDefault();
848
+ }
849
+ onArrowRightKey(event) {
850
+ const focusedItemInfo = this.focusedItemInfo();
851
+ if (focusedItemInfo.index === -1) {
852
+ focusedItemInfo.index = 0;
853
+ }
854
+ const processedItem = this.visibleItems[this.focusedItemInfo().index];
855
+ const grouped = this.isProccessedItemGroup(processedItem);
856
+ if (grouped) {
857
+ let { index, level, key } = processedItem;
858
+ this.onItemChange({ originalEvent: event, processedItem });
859
+ this.focusedItemInfo.set({ index: 0, level: processedItem.level, parentKey: processedItem.key });
860
+ this.searchValue = '';
861
+ this.animate('right');
862
+ }
863
+ event.preventDefault();
864
+ }
865
+ onArrowUpKey(event) {
866
+ if (event.altKey) {
867
+ if (this.focusedItemInfo().index !== -1) {
868
+ const processedItem = this.visibleItems[this.focusedItemInfo().index];
869
+ const grouped = this.isProccessedItemGroup(processedItem);
870
+ !grouped && this.onItemChange({ originalEvent: event, processedItem });
871
+ }
872
+ this.popup && this.hide(event, true);
873
+ event.preventDefault();
874
+ }
875
+ else {
876
+ const itemIndex = this.focusedItemInfo().index !== -1 ? this.findPrevItemIndex(this.focusedItemInfo().index) : this.findLastFocusedItemIndex();
877
+ this.changeFocusedItemIndex(event, itemIndex);
878
+ event.preventDefault();
879
+ }
880
+ }
881
+ onArrowLeftKey(event) {
882
+ const focusedItemInfo = this.focusedItemInfo();
883
+ if (focusedItemInfo.index === -1) {
884
+ focusedItemInfo.index = 0;
885
+ }
886
+ const processedItem = this.visibleItems[focusedItemInfo.index];
887
+ const parentItem = this.activeItemPath().find((p) => p.key === processedItem.parentKey);
888
+ const root = ObjectUtils.isEmpty(processedItem.parent);
889
+ if (!root) {
890
+ let { level, index, parentKey } = parentItem;
891
+ this.focusedItemInfo.set({ index, level, parentKey });
892
+ this.searchValue = '';
893
+ }
894
+ const activeItemPath = this.activeItemPath().filter((p) => p.parentKey !== focusedItemInfo.parentKey);
895
+ this.activeItemPath.set(activeItemPath);
896
+ parentItem && this.animate('left');
897
+ event.preventDefault();
898
+ }
899
+ onHomeKey(event) {
900
+ this.changeFocusedItemIndex(event, this.findFirstItemIndex());
901
+ event.preventDefault();
902
+ }
903
+ onEndKey(event) {
904
+ this.changeFocusedItemIndex(event, this.findLastItemIndex());
905
+ event.preventDefault();
906
+ }
907
+ onSpaceKey(event) {
908
+ this.onEnterKey(event);
909
+ }
910
+ onEscapeKey(event) {
911
+ if (this.popup) {
912
+ this.hide(event, true);
913
+ this.focusedItemInfo().index = this.findFirstFocusedItemIndex();
914
+ event.preventDefault();
915
+ }
916
+ }
917
+ onTabKey(event) {
918
+ if (this.backwardViewChild.nativeElement.style.display !== 'none') {
919
+ this.backwardViewChild.nativeElement.focus();
920
+ }
921
+ if (this.popup && !this.containerViewChild.nativeElement.contains(event.target)) {
922
+ this.hide();
923
+ }
924
+ event.preventDefault();
925
+ }
926
+ onEnterKey(event) {
927
+ if (this.focusedItemInfo().index !== -1) {
928
+ const processedItem = this.visibleItems[this.focusedItemInfo().index];
929
+ const grouped = this.isProccessedItemGroup(processedItem);
930
+ if (grouped) {
931
+ this.onArrowRightKey(event);
932
+ }
933
+ else {
934
+ const element = DomHandler.findSingle(this.rootmenu.el.nativeElement, `li[id="${`${this.focusedItemId}`}"]`);
935
+ const anchorElement = element && DomHandler.findSingle(element, 'a[data-pc-section="action"]');
936
+ anchorElement ? anchorElement.click() : element && element.click();
937
+ this.focusedItemInfo.mutate((value) => (value.index = processedItem.index));
938
+ }
939
+ }
940
+ event.preventDefault();
941
+ }
942
+ onItemChange(event) {
943
+ const { processedItem, isFocus } = event;
944
+ if (ObjectUtils.isEmpty(processedItem))
945
+ return;
946
+ const { index, key, level, parentKey, items } = processedItem;
947
+ const grouped = ObjectUtils.isNotEmpty(items);
948
+ const activeItemPath = this.activeItemPath().filter((p) => p.parentKey !== parentKey && p.parentKey !== key);
949
+ grouped && activeItemPath.push(processedItem);
950
+ this.focusedItemInfo.set({ index, level, parentKey });
951
+ this.activeItemPath.set(activeItemPath);
952
+ isFocus && DomHandler.focus(this.rootmenu.sublistViewChild.nativeElement);
953
+ }
954
+ onMenuFocus() {
955
+ this.focused = true;
956
+ this.bindOutsideClickListener();
957
+ this.bindTransitionListeners();
958
+ if (!this.left && this.focusedItemInfo().level > 0) {
959
+ this.focusedItemInfo.set({ index: 0, level: 0, parentKey: '' });
960
+ }
961
+ if (this.focusedItemInfo().index === -1 && this.left < 0) {
962
+ this.focusedItemInfo.mutate((value) => (value.index = 0));
963
+ }
964
+ if (this.focusedItemInfo().index === -1 && !this.left) {
965
+ this.focusedItemInfo.set({ index: 0, level: 0, parentKey: '' });
966
+ }
967
+ }
968
+ onMenuBlur() {
969
+ this.focused = false;
970
+ this.popup && this.focusedItemInfo.set({ index: -1, level: 0, parentKey: '' });
971
+ if (!this.popup) {
972
+ this.focusedItemInfo.mutate((value) => {
973
+ value.index = -1;
974
+ });
975
+ }
976
+ this.searchValue = '';
977
+ !this.popup && this.unbindOutsideClickListener();
978
+ }
979
+ activeLevel = signal(0);
980
+ bindTransitionListeners() {
981
+ if (!this.transitionStartListener) {
982
+ this.transitionStartListener = this.renderer.listen(this.rootmenu.sublistViewChild.nativeElement, 'transitionstart', (event) => {
983
+ this.transition = true;
984
+ event.preventDefault();
985
+ });
986
+ }
987
+ if (!this.transitionEndListener) {
988
+ this.transitionEndListener = this.renderer.listen(this.rootmenu.sublistViewChild.nativeElement, 'transitionend', (event) => {
989
+ const activeMenu = DomHandler.findSingle(this.rootmenu.el.nativeElement, `ul[data-pc-state="active"]`);
990
+ const activeLevel = DomHandler.getAttribute(activeMenu.firstElementChild, 'aria-level') - 1;
991
+ this.activeLevel.set(activeLevel);
992
+ if (!this.left) {
993
+ this.rootmenu.sublistViewChild.nativeElement.focus();
994
+ }
995
+ else {
996
+ const activeLevel = DomHandler.getAttribute(activeMenu.firstElementChild, 'aria-level') - 1;
997
+ this.activeLevel.set(activeLevel);
998
+ if (this.focusedItemInfo().level > this.activeLevel()) {
999
+ let newActiveItemPath = this.activeItemPath().slice(0, this.activeItemPath().length - 1);
1000
+ let lastActiveParent = newActiveItemPath[newActiveItemPath.length - 1];
1001
+ this.focusedItemInfo.set({ index: -1, level: this.activeLevel(), parentKey: lastActiveParent.key });
1002
+ this.activeItemPath.set(newActiveItemPath);
1003
+ }
1004
+ }
1005
+ this.transition = false;
1006
+ event.preventDefault();
1007
+ });
1008
+ }
1009
+ }
1010
+ unbindTransitionListeners() {
1011
+ if (this.transitionEndListener) {
1012
+ this.transitionEndListener();
1013
+ this.transitionEndListener = null;
1014
+ }
1015
+ if (this.transitionStartListener) {
1016
+ this.transitionStartListener();
1017
+ this.transitionStartListener = null;
1018
+ }
473
1019
  }
474
1020
  onOverlayAnimationStart(event) {
475
1021
  switch (event.toState) {
476
1022
  case 'visible':
477
1023
  if (this.popup) {
478
- this.updateViewPort();
1024
+ this.container = event.element;
479
1025
  this.moveOnTop();
480
1026
  this.onShow.emit({});
481
1027
  this.appendOverlay();
482
- DomHandler.absolutePosition(this.containerViewChild?.nativeElement, this.target);
483
- this.bindDocumentClickListener();
484
- this.bindDocumentResizeListener();
485
- this.bindScrollListener();
1028
+ this.alignOverlay();
1029
+ this.bindOutsideClickListener();
1030
+ this.bindResizeListener();
1031
+ DomHandler.focus(this.rootmenu.sublistViewChild.nativeElement);
1032
+ this.scrollInView();
486
1033
  }
487
1034
  break;
488
1035
  case 'void':
@@ -491,6 +1038,12 @@ class SlideMenu {
491
1038
  break;
492
1039
  }
493
1040
  }
1041
+ alignOverlay() {
1042
+ if (this.relativeAlign)
1043
+ DomHandler.relativePosition(this.container, this.target);
1044
+ else
1045
+ DomHandler.absolutePosition(this.container, this.target);
1046
+ }
494
1047
  onOverlayAnimationEnd(event) {
495
1048
  switch (event.toState) {
496
1049
  case 'void':
@@ -501,123 +1054,197 @@ class SlideMenu {
501
1054
  appendOverlay() {
502
1055
  if (this.appendTo) {
503
1056
  if (this.appendTo === 'body')
504
- this.renderer.appendChild(this.document.body, this.containerViewChild?.nativeElement);
1057
+ this.renderer.appendChild(this.document.body, this.containerViewChild.nativeElement);
505
1058
  else
506
- DomHandler.appendChild(this.containerViewChild?.nativeElement, this.appendTo);
1059
+ DomHandler.appendChild(this.container, this.appendTo);
507
1060
  }
508
1061
  }
509
1062
  restoreOverlayAppend() {
510
- if (this.container && this.appendTo) {
511
- this.renderer.appendChild(this.el.nativeElement, this.containerViewChild?.nativeElement);
1063
+ if (this.containerViewChild && this.appendTo) {
1064
+ this.renderer.appendChild(this.el.nativeElement, this.container);
512
1065
  }
513
1066
  }
514
1067
  moveOnTop() {
515
1068
  if (this.autoZIndex) {
516
- ZIndexUtils.set('menu', this.containerViewChild?.nativeElement, this.baseZIndex + this.config.zIndex.menu);
1069
+ ZIndexUtils.set('menu', this.container, this.baseZIndex + this.config.zIndex.menu);
517
1070
  }
518
1071
  }
519
1072
  /**
520
1073
  * Hides the popup menu.
521
1074
  * @group Method
522
1075
  */
523
- hide() {
524
- this.visible = false;
1076
+ hide(event, isFocus) {
1077
+ if (this.popup) {
1078
+ this.onHide.emit({});
1079
+ this.visible = false;
1080
+ }
1081
+ isFocus && DomHandler.focus(this.target || this.rootmenu.sublistViewChild.nativeElement);
1082
+ }
1083
+ /**
1084
+ * Toggles the visibility of the popup menu.
1085
+ * @param {Event} event - Browser event.
1086
+ * @group Method
1087
+ */
1088
+ toggle(event) {
1089
+ this.visible ? this.hide(event, true) : this.show(event);
1090
+ }
1091
+ /**
1092
+ * Displays the popup menu.
1093
+ * @param {Event} even - Browser event.
1094
+ * @group Method
1095
+ */
1096
+ show(event, isFocus) {
1097
+ if (this.popup) {
1098
+ this.visible = true;
1099
+ this.target = event.currentTarget;
1100
+ }
1101
+ this.focusedItemInfo.set({ index: this.findFirstFocusedItemIndex(), level: 0, parentKey: '' });
1102
+ if (!this.popup) {
1103
+ isFocus && DomHandler.focus(this.rootmenu.sublistViewChild.nativeElement);
1104
+ }
525
1105
  this.cd.markForCheck();
526
1106
  }
527
- onWindowResize() {
528
- if (this.visible && !DomHandler.isTouchDevice()) {
529
- this.hide();
1107
+ searchItems(event, char) {
1108
+ this.searchValue = (this.searchValue || '') + char;
1109
+ let itemIndex = -1;
1110
+ let matched = false;
1111
+ if (this.focusedItemInfo().index !== -1) {
1112
+ itemIndex = this.visibleItems.slice(this.focusedItemInfo().index).findIndex((processedItem) => this.isItemMatched(processedItem));
1113
+ itemIndex = itemIndex === -1 ? this.visibleItems.slice(0, this.focusedItemInfo().index).findIndex((processedItem) => this.isItemMatched(processedItem)) : itemIndex + this.focusedItemInfo().index;
1114
+ }
1115
+ else {
1116
+ itemIndex = this.visibleItems.findIndex((processedItem) => this.isItemMatched(processedItem));
1117
+ }
1118
+ if (itemIndex !== -1) {
1119
+ matched = true;
1120
+ }
1121
+ if (itemIndex === -1 && this.focusedItemInfo().index === -1) {
1122
+ itemIndex = this.findFirstFocusedItemIndex();
1123
+ }
1124
+ if (itemIndex !== -1) {
1125
+ this.changeFocusedItemIndex(event, itemIndex);
1126
+ }
1127
+ if (this.searchTimeout) {
1128
+ clearTimeout(this.searchTimeout);
530
1129
  }
1130
+ this.searchTimeout = setTimeout(() => {
1131
+ this.searchValue = '';
1132
+ this.searchTimeout = null;
1133
+ }, 500);
1134
+ return matched;
531
1135
  }
532
- goBack() {
533
- this.left += this.menuWidth;
1136
+ findLastFocusedItemIndex() {
1137
+ const selectedIndex = this.findSelectedItemIndex();
1138
+ return selectedIndex < 0 ? this.findLastItemIndex() : selectedIndex;
534
1139
  }
535
- onBackwardKeydown(event) {
536
- this.goBack();
537
- if (!this.left) {
538
- setTimeout(() => {
539
- let focusableElements = DomHandler.getFocusableElements(this.el.nativeElement);
540
- if (focusableElements && focusableElements.length > 0) {
541
- focusableElements[0].focus();
542
- }
543
- }, 1);
544
- }
545
- event.preventDefault();
1140
+ findLastItemIndex() {
1141
+ return ObjectUtils.findLastIndex(this.visibleItems, (processedItem) => this.isValidItem(processedItem));
546
1142
  }
547
- bindDocumentClickListener() {
548
- if (isPlatformBrowser(this.platformId)) {
549
- if (!this.documentClickListener) {
550
- const documentTarget = this.el ? this.el.nativeElement.ownerDocument : this.document;
551
- this.documentClickListener = this.renderer.listen(documentTarget, 'click', () => {
552
- if (!this.preventDocumentDefault) {
553
- this.hide();
554
- this.cd.detectChanges();
555
- }
556
- this.preventDocumentDefault = false;
557
- });
558
- }
1143
+ findPrevItemIndex(index) {
1144
+ const matchedItemIndex = index > 0 ? ObjectUtils.findLastIndex(this.visibleItems.slice(0, index), (processedItem) => this.isValidItem(processedItem)) : -1;
1145
+ return matchedItemIndex > -1 ? matchedItemIndex : index;
1146
+ }
1147
+ findNextItemIndex(index) {
1148
+ const matchedItemIndex = index < this.visibleItems.length - 1 ? this.visibleItems.slice(index + 1).findIndex((processedItem) => this.isValidItem(processedItem)) : -1;
1149
+ return matchedItemIndex > -1 ? matchedItemIndex + index + 1 : index;
1150
+ }
1151
+ findFirstFocusedItemIndex() {
1152
+ const selectedIndex = this.findSelectedItemIndex();
1153
+ return selectedIndex < 0 ? this.findFirstItemIndex() : selectedIndex;
1154
+ }
1155
+ findFirstItemIndex() {
1156
+ return this.visibleItems.findIndex((processedItem) => this.isValidItem(processedItem));
1157
+ }
1158
+ findSelectedItemIndex() {
1159
+ return this.visibleItems.findIndex((processedItem) => this.isValidSelectedItem(processedItem));
1160
+ }
1161
+ changeFocusedItemIndex(event, index) {
1162
+ if (this.focusedItemInfo().index !== index) {
1163
+ this.focusedItemInfo.mutate((value) => {
1164
+ value.index = index;
1165
+ });
1166
+ this.scrollInView();
559
1167
  }
560
1168
  }
561
- unbindDocumentClickListener() {
562
- if (this.documentClickListener) {
563
- this.documentClickListener();
564
- this.documentClickListener = null;
1169
+ scrollInView(index = -1) {
1170
+ const id = index !== -1 ? `${this.id}_${index}` : this.focusedItemId;
1171
+ const element = DomHandler.findSingle(this.rootmenu.el.nativeElement, `li[id="${id}"]`);
1172
+ if (element) {
1173
+ element.scrollIntoView && element.scrollIntoView({ block: 'nearest', inline: 'start' });
565
1174
  }
566
1175
  }
567
- bindDocumentResizeListener() {
1176
+ bindResizeListener() {
568
1177
  if (isPlatformBrowser(this.platformId)) {
569
- if (!this.documentResizeListener) {
570
- this.documentResizeListener = this.renderer.listen(this.window, 'resize', this.onWindowResize.bind(this));
1178
+ if (!this.resizeListener) {
1179
+ this.resizeListener = this.renderer.listen(this.document.defaultView, 'resize', (event) => {
1180
+ if (!DomHandler.isTouchDevice()) {
1181
+ this.hide(event, true);
1182
+ }
1183
+ });
571
1184
  }
572
1185
  }
573
1186
  }
574
- unbindDocumentResizeListener() {
575
- if (this.documentResizeListener) {
576
- this.documentResizeListener();
577
- this.documentResizeListener = null;
578
- }
579
- }
580
- bindScrollListener() {
1187
+ bindOutsideClickListener() {
581
1188
  if (isPlatformBrowser(this.platformId)) {
582
- if (!this.scrollHandler) {
583
- this.scrollHandler = new ConnectedOverlayScrollHandler(this.target, () => {
584
- if (this.visible) {
585
- this.hide();
1189
+ if (!this.outsideClickListener) {
1190
+ this.outsideClickListener = this.renderer.listen(this.document, 'click', (event) => {
1191
+ const isOutsideContainer = this.containerViewChild && !this.containerViewChild.nativeElement.contains(event.target);
1192
+ const isOutsideTarget = this.popup ? !(this.target && (this.target === event.target || this.target.contains(event.target))) : true;
1193
+ if (this.popup) {
1194
+ if (isOutsideContainer && isOutsideTarget) {
1195
+ this.onMenuBlur();
1196
+ this.hide();
1197
+ }
1198
+ }
1199
+ else {
1200
+ if (isOutsideContainer && isOutsideTarget && this.focused) {
1201
+ this.onMenuBlur();
1202
+ }
586
1203
  }
587
1204
  });
588
1205
  }
589
- this.scrollHandler.bindScrollListener();
590
1206
  }
591
1207
  }
592
- unbindScrollListener() {
593
- if (this.scrollHandler) {
594
- this.scrollHandler.unbindScrollListener();
1208
+ unbindOutsideClickListener() {
1209
+ if (this.outsideClickListener) {
1210
+ this.outsideClickListener();
1211
+ this.outsideClickListener = null;
1212
+ }
1213
+ }
1214
+ unbindResizeListener() {
1215
+ if (this.resizeListener) {
1216
+ this.resizeListener();
1217
+ this.resizeListener = null;
595
1218
  }
596
1219
  }
597
1220
  onOverlayHide() {
598
- this.unbindDocumentClickListener();
599
- this.unbindDocumentResizeListener();
600
- this.unbindScrollListener();
601
- this.preventDocumentDefault = false;
1221
+ this.unbindOutsideClickListener();
1222
+ this.unbindResizeListener();
602
1223
  this.left = 0;
603
1224
  if (!this.cd.destroyed) {
604
1225
  this.target = null;
605
1226
  }
1227
+ if (this.container) {
1228
+ this.container = null;
1229
+ }
606
1230
  }
607
1231
  ngOnDestroy() {
608
1232
  if (this.popup) {
609
- if (this.scrollHandler) {
610
- this.scrollHandler.destroy();
611
- this.scrollHandler = null;
1233
+ if (this.container && this.autoZIndex) {
1234
+ ZIndexUtils.clear(this.container);
612
1235
  }
613
1236
  this.restoreOverlayAppend();
614
1237
  this.onOverlayHide();
615
1238
  }
1239
+ this.unbindTransitionListeners();
616
1240
  }
617
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: SlideMenu, deps: [{ token: DOCUMENT }, { token: PLATFORM_ID }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i4.PrimeNGConfig }, { token: i4.OverlayService }], target: i0.ɵɵFactoryTarget.Component });
618
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.2", type: SlideMenu, selector: "p-slideMenu", inputs: { model: "model", popup: "popup", style: "style", styleClass: "styleClass", menuWidth: "menuWidth", viewportHeight: "viewportHeight", effectDuration: "effectDuration", easing: "easing", backLabel: "backLabel", appendTo: "appendTo", autoZIndex: "autoZIndex", baseZIndex: "baseZIndex", showTransitionOptions: "showTransitionOptions", hideTransitionOptions: "hideTransitionOptions" }, outputs: { onShow: "onShow", onHide: "onHide" }, host: { classAttribute: "p-element" }, queries: [{ propertyName: "templates", predicate: PrimeTemplate }], viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }, { propertyName: "backward", first: true, predicate: ["backward"], descendants: true }, { propertyName: "slideMenuContent", first: true, predicate: ["slideMenuContent"], descendants: true }], ngImport: i0, template: `
1241
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: SlideMenu, 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 });
1242
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.2", type: SlideMenu, selector: "p-slideMenu", inputs: { menuWidth: "menuWidth", viewportHeight: "viewportHeight", effectDuration: "effectDuration", easing: "easing", backLabel: "backLabel", disabled: "disabled", tabindex: "tabindex", model: "model", popup: "popup", style: "style", styleClass: "styleClass", appendTo: "appendTo", autoZIndex: "autoZIndex", baseZIndex: "baseZIndex", autoDisplay: "autoDisplay", showTransitionOptions: "showTransitionOptions", hideTransitionOptions: "hideTransitionOptions", id: "id", ariaLabel: "ariaLabel", ariaLabelledBy: "ariaLabelledBy" }, outputs: { onShow: "onShow", onHide: "onHide" }, host: { classAttribute: "p-element" }, queries: [{ propertyName: "templates", predicate: PrimeTemplate }], viewQueries: [{ propertyName: "rootmenu", first: true, predicate: ["rootmenu"], descendants: true }, { propertyName: "containerViewChild", first: true, predicate: ["container"], descendants: true }, { propertyName: "backward", first: true, predicate: ["backward"], descendants: true }, { propertyName: "slideMenuContentViewChild", first: true, predicate: ["slideMenuContent"], descendants: true }], ngImport: i0, template: `
619
1243
  <div
620
1244
  #container
1245
+ [attr.data-pc-section]="'root'"
1246
+ [attr.data-pc-name]="'slidemenu'"
1247
+ [id]="id"
621
1248
  [ngClass]="{ 'p-slidemenu p-component': true, 'p-slidemenu-overlay': popup }"
622
1249
  [class]="styleClass"
623
1250
  [ngStyle]="style"
@@ -629,23 +1256,47 @@ class SlideMenu {
629
1256
  *ngIf="!popup || visible"
630
1257
  >
631
1258
  <div class="p-slidemenu-wrapper" [style.height]="left ? viewportHeight + 'px' : 'auto'" [style.width]="menuWidth + 'px'">
632
- <div #slideMenuContent class="p-slidemenu-content">
633
- <p-slideMenuSub [item]="model" root="root" [index]="0" [menuWidth]="menuWidth" [effectDuration]="effectDuration" [easing]="easing"></p-slideMenuSub>
1259
+ <div #slideMenuContent class="p-slidemenu-content" (focus)="logFocus($event, slideMenuContent)">
1260
+ <p-slideMenuSub
1261
+ #rootmenu
1262
+ [root]="true"
1263
+ [items]="processedItems"
1264
+ [menuId]="id"
1265
+ [tabindex]="!disabled ? tabindex : -1"
1266
+ [ariaLabel]="ariaLabel"
1267
+ [ariaLabelledBy]="ariaLabelledBy"
1268
+ [baseZIndex]="baseZIndex"
1269
+ [autoZIndex]="autoZIndex"
1270
+ [autoDisplay]="autoDisplay"
1271
+ [menuWidth]="menuWidth"
1272
+ [popup]="popup"
1273
+ [effectDuration]="effectDuration"
1274
+ [easing]="easing"
1275
+ [focusedItemId]="focused ? focusedItemId : undefined"
1276
+ [activeItemPath]="activeItemPath()"
1277
+ (itemClick)="onItemClick($event)"
1278
+ (menuFocus)="onMenuFocus($event)"
1279
+ (menuKeydown)="onKeyDown($event)"
1280
+ (itemMouseEnter)="onItemMouseEnter($event)"
1281
+ ></p-slideMenuSub>
634
1282
  </div>
635
- <a #backward (keydown.enter)="onBackwardKeydown($event)" (keydown.space)="onBackwardKeydown($event)" class="p-slidemenu-backward p-menuitem-link" tabindex="0" [style.display]="left ? 'block' : 'none'" (click)="goBack()">
636
- <CaretLeftIcon *ngIf="!backIconTemplate" [styleClass]="'p-slidemenu-backward-icon'" />
1283
+ <a #backward class="p-slidemenu-backward p-menuitem-link" tabindex="0" [style.display]="left ? 'block' : 'none'" (click)="goBack($event)" (keydown)="onNavigationKeyDown($event)" [attr.data-pc-section]="'navigation'">
1284
+ <CaretLeftIcon *ngIf="!backIconTemplate" [styleClass]="'p-slidemenu-backward-icon'" [ngStyle]="{ 'vertical-align': 'middle' }" />
637
1285
  <ng-template *ngTemplateOutlet="backIconTemplate"></ng-template>
638
1286
  <span>{{ backLabel }}</span>
639
1287
  </a>
640
1288
  </div>
641
1289
  </div>
642
- `, isInline: true, styles: [".p-slidemenu{width:12.5rem}.p-slidemenu.p-slidemenu-overlay{position:absolute;top:0;left:0}.p-slidemenu ul{list-style:none;margin:0;padding:0}.p-slidemenu .p-slidemenu-rootlist{position:absolute;top:0}.p-slidemenu .p-submenu-list{display:none;position:absolute;top:0;width:12.5rem}.p-slidemenu .p-menuitem-link{cursor:pointer;display:flex;align-items:center;text-decoration:none;overflow:hidden}.p-slidemenu .p-menuitem-icon,.p-slidemenu .p-menuitem-text{vertical-align:middle}.p-slidemenu .p-menuitem{position:relative}.p-slidemenu .p-menuitem-link .p-submenu-icon:not(svg){margin-left:auto}.p-slidemenu .p-menuitem-link .p-icon-wrapper{margin-left:auto;vertical-align:middle}.p-slidemenu .p-slidemenu-wrapper{position:relative}.p-slidemenu .p-slidemenu-content{overflow-x:hidden;overflow-y:auto;position:relative}.p-slidemenu-backward{position:absolute;bottom:0;width:100%;cursor:pointer;display:none}.p-slidemenu-backward .p-slidemenu-backward-icon,.p-slidemenu-backward span{vertical-align:middle}.p-slidemenu .p-menuitem-active{position:static}.p-slidemenu .p-menuitem-active>.p-submenu>.p-submenu-list{display:block}.p-slidemenu ul:not(.p-active-submenu)>.p-menuitem:not(.p-menuitem-active),.p-slidemenu .p-active-submenu>.p-menuitem-active>.p-submenu>.p-submenu-list{display:none}.p-slidemenu .p-active-submenu>.p-menuitem-active~.p-menuitem{display:block}\n"], dependencies: [{ kind: "directive", type: i0.forwardRef(function () { return i1.NgClass; }), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i0.forwardRef(function () { return i1.NgIf; }), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i0.forwardRef(function () { return i1.NgTemplateOutlet; }), selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i0.forwardRef(function () { return i1.NgStyle; }), selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i0.forwardRef(function () { return CaretLeftIcon; }), selector: "CaretLeftIcon" }, { kind: "component", type: i0.forwardRef(function () { return SlideMenuSub; }), selector: "p-slideMenuSub", inputs: ["item", "root", "backLabel", "menuWidth", "effectDuration", "easing", "index"] }], 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 });
1290
+ `, isInline: true, styles: [".p-slidemenu .p-slidemenu-root-list{position:relative;top:0}.p-slidemenu-overlay{position:absolute;top:0;left:0}.p-slidemenu .p-menuitem-active{position:static}.p-slidemenu .p-slidemenu-wrapper{position:relative}.p-slidemenu ul{margin:0;padding:0;list-style:none}.p-slidemenu .p-submenu-list{position:absolute;min-width:100%;z-index:1;display:none}.p-slidemenu .p-slidemenu-content{overflow-x:hidden;overflow-y:auto;position:relative;height:100%}.p-slidemenu .p-menuitem-link:not(.p-slidemenu-backward){cursor:pointer;display:flex;align-items:center;text-decoration:none;overflow:hidden;position:relative}.p-slidemenu .p-menuitem-text{line-height:1}.p-slidemenu .p-menuitem{position:relative}.p-slidemenu .p-menuitem-link .p-submenu-icon:not(svg){margin-left:auto}.p-slidemenu .p-menuitem-link .p-icon-wrapper{margin-left:auto}.p-slidemenu .p-menuitem-active>p-slidemenusub>.p-submenu-list{display:block;left:100%;top:0}.p-slidemenu .p-menuitem-active>.p-menuitem-content>.p-submenu>.p-submenu-list{display:block}.p-slidemenu ul:not(.p-active-submenu)>.p-menuitem:not(.p-menuitem-active),.p-slidemenu .p-active-submenu>.p-menuitem-active>.p-menuitem-content>.p-submenu>.p-submenu-list{display:none}.p-slidemenu .p-active-submenu>.p-menuitem-active~.p-menuitem{display:block}.p-slidemenu-backward{position:absolute;bottom:0;width:100%;cursor:pointer;display:none}.p-slidemenu-backward .p-slidemenu-backward-icon,.p-slidemenu-backward span{vertical-align:middle}\n"], dependencies: [{ kind: "directive", type: i0.forwardRef(function () { return i1.NgClass; }), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i0.forwardRef(function () { return i1.NgIf; }), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i0.forwardRef(function () { return i1.NgTemplateOutlet; }), selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i0.forwardRef(function () { return i1.NgStyle; }), selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i0.forwardRef(function () { return CaretLeftIcon; }), selector: "CaretLeftIcon" }, { kind: "component", type: i0.forwardRef(function () { return SlideMenuSub; }), selector: "p-slideMenuSub", inputs: ["items", "menuWidth", "root", "easing", "effectDuration", "autoDisplay", "autoZIndex", "baseZIndex", "popup", "menuId", "ariaLabel", "ariaLabelledBy", "level", "focusedItemId", "activeItemPath", "tabindex"], outputs: ["itemClick", "itemMouseEnter", "menuFocus", "menuBlur", "menuKeydown"] }], 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 });
643
1291
  }
644
1292
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: SlideMenu, decorators: [{
645
1293
  type: Component,
646
1294
  args: [{ selector: 'p-slideMenu', template: `
647
1295
  <div
648
1296
  #container
1297
+ [attr.data-pc-section]="'root'"
1298
+ [attr.data-pc-name]="'slidemenu'"
1299
+ [id]="id"
649
1300
  [ngClass]="{ 'p-slidemenu p-component': true, 'p-slidemenu-overlay': popup }"
650
1301
  [class]="styleClass"
651
1302
  [ngStyle]="style"
@@ -657,11 +1308,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImpor
657
1308
  *ngIf="!popup || visible"
658
1309
  >
659
1310
  <div class="p-slidemenu-wrapper" [style.height]="left ? viewportHeight + 'px' : 'auto'" [style.width]="menuWidth + 'px'">
660
- <div #slideMenuContent class="p-slidemenu-content">
661
- <p-slideMenuSub [item]="model" root="root" [index]="0" [menuWidth]="menuWidth" [effectDuration]="effectDuration" [easing]="easing"></p-slideMenuSub>
1311
+ <div #slideMenuContent class="p-slidemenu-content" (focus)="logFocus($event, slideMenuContent)">
1312
+ <p-slideMenuSub
1313
+ #rootmenu
1314
+ [root]="true"
1315
+ [items]="processedItems"
1316
+ [menuId]="id"
1317
+ [tabindex]="!disabled ? tabindex : -1"
1318
+ [ariaLabel]="ariaLabel"
1319
+ [ariaLabelledBy]="ariaLabelledBy"
1320
+ [baseZIndex]="baseZIndex"
1321
+ [autoZIndex]="autoZIndex"
1322
+ [autoDisplay]="autoDisplay"
1323
+ [menuWidth]="menuWidth"
1324
+ [popup]="popup"
1325
+ [effectDuration]="effectDuration"
1326
+ [easing]="easing"
1327
+ [focusedItemId]="focused ? focusedItemId : undefined"
1328
+ [activeItemPath]="activeItemPath()"
1329
+ (itemClick)="onItemClick($event)"
1330
+ (menuFocus)="onMenuFocus($event)"
1331
+ (menuKeydown)="onKeyDown($event)"
1332
+ (itemMouseEnter)="onItemMouseEnter($event)"
1333
+ ></p-slideMenuSub>
662
1334
  </div>
663
- <a #backward (keydown.enter)="onBackwardKeydown($event)" (keydown.space)="onBackwardKeydown($event)" class="p-slidemenu-backward p-menuitem-link" tabindex="0" [style.display]="left ? 'block' : 'none'" (click)="goBack()">
664
- <CaretLeftIcon *ngIf="!backIconTemplate" [styleClass]="'p-slidemenu-backward-icon'" />
1335
+ <a #backward class="p-slidemenu-backward p-menuitem-link" tabindex="0" [style.display]="left ? 'block' : 'none'" (click)="goBack($event)" (keydown)="onNavigationKeyDown($event)" [attr.data-pc-section]="'navigation'">
1336
+ <CaretLeftIcon *ngIf="!backIconTemplate" [styleClass]="'p-slidemenu-backward-icon'" [ngStyle]="{ 'vertical-align': 'middle' }" />
665
1337
  <ng-template *ngTemplateOutlet="backIconTemplate"></ng-template>
666
1338
  <span>{{ backLabel }}</span>
667
1339
  </a>
@@ -669,22 +1341,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImpor
669
1341
  </div>
670
1342
  `, animations: [trigger('overlayAnimation', [transition(':enter', [style({ opacity: 0, transform: 'scaleY(0.8)' }), animate('{{showTransitionParams}}')]), transition(':leave', [animate('{{hideTransitionParams}}', style({ opacity: 0 }))])])], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
671
1343
  class: 'p-element'
672
- }, styles: [".p-slidemenu{width:12.5rem}.p-slidemenu.p-slidemenu-overlay{position:absolute;top:0;left:0}.p-slidemenu ul{list-style:none;margin:0;padding:0}.p-slidemenu .p-slidemenu-rootlist{position:absolute;top:0}.p-slidemenu .p-submenu-list{display:none;position:absolute;top:0;width:12.5rem}.p-slidemenu .p-menuitem-link{cursor:pointer;display:flex;align-items:center;text-decoration:none;overflow:hidden}.p-slidemenu .p-menuitem-icon,.p-slidemenu .p-menuitem-text{vertical-align:middle}.p-slidemenu .p-menuitem{position:relative}.p-slidemenu .p-menuitem-link .p-submenu-icon:not(svg){margin-left:auto}.p-slidemenu .p-menuitem-link .p-icon-wrapper{margin-left:auto;vertical-align:middle}.p-slidemenu .p-slidemenu-wrapper{position:relative}.p-slidemenu .p-slidemenu-content{overflow-x:hidden;overflow-y:auto;position:relative}.p-slidemenu-backward{position:absolute;bottom:0;width:100%;cursor:pointer;display:none}.p-slidemenu-backward .p-slidemenu-backward-icon,.p-slidemenu-backward span{vertical-align:middle}.p-slidemenu .p-menuitem-active{position:static}.p-slidemenu .p-menuitem-active>.p-submenu>.p-submenu-list{display:block}.p-slidemenu ul:not(.p-active-submenu)>.p-menuitem:not(.p-menuitem-active),.p-slidemenu .p-active-submenu>.p-menuitem-active>.p-submenu>.p-submenu-list{display:none}.p-slidemenu .p-active-submenu>.p-menuitem-active~.p-menuitem{display:block}\n"] }]
1344
+ }, styles: [".p-slidemenu .p-slidemenu-root-list{position:relative;top:0}.p-slidemenu-overlay{position:absolute;top:0;left:0}.p-slidemenu .p-menuitem-active{position:static}.p-slidemenu .p-slidemenu-wrapper{position:relative}.p-slidemenu ul{margin:0;padding:0;list-style:none}.p-slidemenu .p-submenu-list{position:absolute;min-width:100%;z-index:1;display:none}.p-slidemenu .p-slidemenu-content{overflow-x:hidden;overflow-y:auto;position:relative;height:100%}.p-slidemenu .p-menuitem-link:not(.p-slidemenu-backward){cursor:pointer;display:flex;align-items:center;text-decoration:none;overflow:hidden;position:relative}.p-slidemenu .p-menuitem-text{line-height:1}.p-slidemenu .p-menuitem{position:relative}.p-slidemenu .p-menuitem-link .p-submenu-icon:not(svg){margin-left:auto}.p-slidemenu .p-menuitem-link .p-icon-wrapper{margin-left:auto}.p-slidemenu .p-menuitem-active>p-slidemenusub>.p-submenu-list{display:block;left:100%;top:0}.p-slidemenu .p-menuitem-active>.p-menuitem-content>.p-submenu>.p-submenu-list{display:block}.p-slidemenu ul:not(.p-active-submenu)>.p-menuitem:not(.p-menuitem-active),.p-slidemenu .p-active-submenu>.p-menuitem-active>.p-menuitem-content>.p-submenu>.p-submenu-list{display:none}.p-slidemenu .p-active-submenu>.p-menuitem-active~.p-menuitem{display:block}.p-slidemenu-backward{position:absolute;bottom:0;width:100%;cursor:pointer;display:none}.p-slidemenu-backward .p-slidemenu-backward-icon,.p-slidemenu-backward span{vertical-align:middle}\n"] }]
673
1345
  }], ctorParameters: function () { return [{ type: Document, decorators: [{
674
1346
  type: Inject,
675
1347
  args: [DOCUMENT]
676
1348
  }] }, { type: undefined, decorators: [{
677
1349
  type: Inject,
678
1350
  args: [PLATFORM_ID]
679
- }] }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i4.PrimeNGConfig }, { type: i4.OverlayService }]; }, propDecorators: { model: [{
680
- type: Input
681
- }], popup: [{
682
- type: Input
683
- }], style: [{
684
- type: Input
685
- }], styleClass: [{
686
- type: Input
687
- }], menuWidth: [{
1351
+ }] }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i5.PrimeNGConfig }, { type: i5.OverlayService }]; }, propDecorators: { menuWidth: [{
688
1352
  type: Input
689
1353
  }], viewportHeight: [{
690
1354
  type: Input
@@ -694,16 +1358,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImpor
694
1358
  type: Input
695
1359
  }], backLabel: [{
696
1360
  type: Input
1361
+ }], disabled: [{
1362
+ type: Input
1363
+ }], tabindex: [{
1364
+ type: Input
1365
+ }], model: [{
1366
+ type: Input
1367
+ }], popup: [{
1368
+ type: Input
1369
+ }], style: [{
1370
+ type: Input
1371
+ }], styleClass: [{
1372
+ type: Input
697
1373
  }], appendTo: [{
698
1374
  type: Input
699
1375
  }], autoZIndex: [{
700
1376
  type: Input
701
1377
  }], baseZIndex: [{
702
1378
  type: Input
1379
+ }], autoDisplay: [{
1380
+ type: Input
703
1381
  }], showTransitionOptions: [{
704
1382
  type: Input
705
1383
  }], hideTransitionOptions: [{
706
1384
  type: Input
1385
+ }], id: [{
1386
+ type: Input
1387
+ }], ariaLabel: [{
1388
+ type: Input
1389
+ }], ariaLabelledBy: [{
1390
+ type: Input
707
1391
  }], onShow: [{
708
1392
  type: Output
709
1393
  }], onHide: [{
@@ -711,25 +1395,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImpor
711
1395
  }], templates: [{
712
1396
  type: ContentChildren,
713
1397
  args: [PrimeTemplate]
714
- }], container: [{
1398
+ }], rootmenu: [{
1399
+ type: ViewChild,
1400
+ args: ['rootmenu']
1401
+ }], containerViewChild: [{
715
1402
  type: ViewChild,
716
1403
  args: ['container']
717
1404
  }], backward: [{
718
1405
  type: ViewChild,
719
1406
  args: ['backward']
720
- }], slideMenuContent: [{
1407
+ }], slideMenuContentViewChild: [{
721
1408
  type: ViewChild,
722
1409
  args: ['slideMenuContent']
723
1410
  }] } });
724
1411
  class SlideMenuModule {
725
1412
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: SlideMenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
726
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.0.2", ngImport: i0, type: SlideMenuModule, declarations: [SlideMenu, SlideMenuSub], imports: [CommonModule, RouterModule, TooltipModule, SharedModule, CaretLeftIcon, CaretRightIcon, AngleRightIcon], exports: [SlideMenu, RouterModule, TooltipModule, SharedModule] });
727
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: SlideMenuModule, imports: [CommonModule, RouterModule, TooltipModule, SharedModule, CaretLeftIcon, CaretRightIcon, AngleRightIcon, RouterModule, TooltipModule, SharedModule] });
1413
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.0.2", ngImport: i0, type: SlideMenuModule, declarations: [SlideMenu, SlideMenuSub], imports: [CommonModule, RouterModule, RippleModule, TooltipModule, AngleRightIcon, SharedModule, CaretLeftIcon], exports: [SlideMenu, RouterModule, TooltipModule, SharedModule] });
1414
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: SlideMenuModule, imports: [CommonModule, RouterModule, RippleModule, TooltipModule, AngleRightIcon, SharedModule, CaretLeftIcon, RouterModule, TooltipModule, SharedModule] });
728
1415
  }
729
1416
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: SlideMenuModule, decorators: [{
730
1417
  type: NgModule,
731
1418
  args: [{
732
- imports: [CommonModule, RouterModule, TooltipModule, SharedModule, CaretLeftIcon, CaretRightIcon, AngleRightIcon],
1419
+ imports: [CommonModule, RouterModule, RippleModule, TooltipModule, AngleRightIcon, SharedModule, CaretLeftIcon],
733
1420
  exports: [SlideMenu, RouterModule, TooltipModule, SharedModule],
734
1421
  declarations: [SlideMenu, SlideMenuSub]
735
1422
  }]