primevue 3.17.0 → 3.18.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 (316) hide show
  1. package/LICENSE.md +1 -1
  2. package/accordion/Accordion.vue +4 -4
  3. package/accordion/accordion.cjs.js +4 -4
  4. package/accordion/accordion.cjs.min.js +1 -1
  5. package/accordion/accordion.esm.js +4 -4
  6. package/accordion/accordion.esm.min.js +1 -1
  7. package/accordion/accordion.js +5 -5
  8. package/accordion/accordion.min.js +1 -1
  9. package/api/api.cjs.js +24 -2
  10. package/api/api.cjs.min.js +1 -1
  11. package/api/api.esm.js +24 -2
  12. package/api/api.esm.min.js +1 -1
  13. package/api/api.js +24 -2
  14. package/api/api.min.js +1 -1
  15. package/autocomplete/AutoComplete.d.ts +10 -0
  16. package/autocomplete/AutoComplete.vue +14 -6
  17. package/autocomplete/autocomplete.cjs.js +18 -10
  18. package/autocomplete/autocomplete.cjs.min.js +1 -1
  19. package/autocomplete/autocomplete.esm.js +16 -8
  20. package/autocomplete/autocomplete.esm.min.js +1 -1
  21. package/autocomplete/autocomplete.js +17 -9
  22. package/autocomplete/autocomplete.min.js +1 -1
  23. package/breadcrumb/Breadcrumb.d.ts +9 -1
  24. package/breadcrumb/Breadcrumb.vue +14 -5
  25. package/breadcrumb/BreadcrumbItem.vue +9 -3
  26. package/breadcrumb/breadcrumb.cjs.js +25 -14
  27. package/breadcrumb/breadcrumb.cjs.min.js +1 -1
  28. package/breadcrumb/breadcrumb.esm.js +25 -14
  29. package/breadcrumb/breadcrumb.esm.min.js +1 -1
  30. package/breadcrumb/breadcrumb.js +25 -14
  31. package/breadcrumb/breadcrumb.min.js +1 -1
  32. package/button/Button.vue +6 -3
  33. package/button/button.cjs.js +6 -3
  34. package/button/button.cjs.min.js +1 -1
  35. package/button/button.esm.js +6 -3
  36. package/button/button.esm.min.js +1 -1
  37. package/button/button.js +6 -3
  38. package/button/button.min.js +1 -1
  39. package/calendar/Calendar.vue +71 -26
  40. package/calendar/calendar.cjs.js +140 -95
  41. package/calendar/calendar.cjs.min.js +1 -1
  42. package/calendar/calendar.esm.js +138 -93
  43. package/calendar/calendar.esm.min.js +1 -1
  44. package/calendar/calendar.js +139 -94
  45. package/calendar/calendar.min.js +1 -1
  46. package/cascadeselect/CascadeSelect.d.ts +10 -0
  47. package/cascadeselect/CascadeSelect.vue +13 -4
  48. package/cascadeselect/CascadeSelectSub.vue +18 -13
  49. package/cascadeselect/cascadeselect.cjs.js +39 -26
  50. package/cascadeselect/cascadeselect.cjs.min.js +1 -1
  51. package/cascadeselect/cascadeselect.esm.js +38 -25
  52. package/cascadeselect/cascadeselect.esm.min.js +1 -1
  53. package/cascadeselect/cascadeselect.js +39 -26
  54. package/cascadeselect/cascadeselect.min.js +1 -1
  55. package/config/PrimeVue.d.ts +4 -1
  56. package/config/config.cjs.js +5 -2
  57. package/config/config.cjs.min.js +1 -1
  58. package/config/config.esm.js +5 -2
  59. package/config/config.esm.min.js +1 -1
  60. package/config/config.js +6 -3
  61. package/config/config.min.js +1 -1
  62. package/contextmenu/ContextMenu.d.ts +41 -2
  63. package/contextmenu/ContextMenu.vue +440 -33
  64. package/contextmenu/ContextMenuSub.vue +119 -98
  65. package/contextmenu/contextmenu.cjs.js +619 -194
  66. package/contextmenu/contextmenu.cjs.min.js +1 -1
  67. package/contextmenu/contextmenu.esm.js +620 -195
  68. package/contextmenu/contextmenu.esm.min.js +1 -1
  69. package/contextmenu/contextmenu.js +620 -195
  70. package/contextmenu/contextmenu.min.js +1 -1
  71. package/core/core.js +1369 -675
  72. package/core/core.min.js +10 -10
  73. package/datatable/DataTable.d.ts +1 -2
  74. package/datatable/DataTable.vue +3 -3
  75. package/datatable/datatable.cjs.js +2334 -2334
  76. package/datatable/datatable.cjs.min.js +1 -1
  77. package/datatable/datatable.esm.js +2319 -2319
  78. package/datatable/datatable.esm.min.js +1 -1
  79. package/datatable/datatable.js +2319 -2319
  80. package/datatable/datatable.min.js +1 -1
  81. package/dock/Dock.d.ts +33 -2
  82. package/dock/Dock.vue +18 -2
  83. package/dock/DockSub.vue +206 -53
  84. package/dock/dock.cjs.js +261 -90
  85. package/dock/dock.cjs.min.js +1 -1
  86. package/dock/dock.esm.js +261 -90
  87. package/dock/dock.esm.min.js +1 -1
  88. package/dock/dock.js +262 -92
  89. package/dock/dock.min.js +1 -1
  90. package/dropdown/Dropdown.d.ts +15 -0
  91. package/dropdown/Dropdown.vue +19 -7
  92. package/dropdown/dropdown.cjs.js +37 -24
  93. package/dropdown/dropdown.cjs.min.js +1 -1
  94. package/dropdown/dropdown.esm.js +36 -23
  95. package/dropdown/dropdown.esm.min.js +1 -1
  96. package/dropdown/dropdown.js +36 -23
  97. package/dropdown/dropdown.min.js +1 -1
  98. package/fileupload/FileContent.vue +51 -0
  99. package/fileupload/FileUpload.d.ts +21 -1
  100. package/fileupload/FileUpload.vue +62 -48
  101. package/fileupload/fileupload.cjs.js +214 -115
  102. package/fileupload/fileupload.cjs.min.js +1 -1
  103. package/fileupload/fileupload.esm.js +214 -115
  104. package/fileupload/fileupload.esm.min.js +1 -1
  105. package/fileupload/fileupload.js +214 -115
  106. package/fileupload/fileupload.min.js +1 -1
  107. package/galleria/GalleriaThumbnails.vue +2 -2
  108. package/galleria/galleria.cjs.js +1 -1
  109. package/galleria/galleria.cjs.min.js +1 -1
  110. package/galleria/galleria.esm.js +1 -1
  111. package/galleria/galleria.esm.min.js +1 -1
  112. package/galleria/galleria.js +1 -1
  113. package/galleria/galleria.min.js +1 -1
  114. package/inlinemessage/inlinemessage.cjs.js +1 -2
  115. package/inlinemessage/inlinemessage.cjs.min.js +1 -1
  116. package/inlinemessage/inlinemessage.esm.js +1 -2
  117. package/inlinemessage/inlinemessage.esm.min.js +1 -1
  118. package/inlinemessage/inlinemessage.js +1 -2
  119. package/inlinemessage/inlinemessage.min.js +1 -1
  120. package/inputnumber/InputNumber.vue +11 -4
  121. package/inputnumber/inputnumber.cjs.js +12 -5
  122. package/inputnumber/inputnumber.cjs.min.js +1 -1
  123. package/inputnumber/inputnumber.esm.js +11 -4
  124. package/inputnumber/inputnumber.esm.min.js +1 -1
  125. package/inputnumber/inputnumber.js +12 -6
  126. package/inputnumber/inputnumber.min.js +1 -1
  127. package/listbox/Listbox.d.ts +5 -0
  128. package/listbox/Listbox.vue +5 -1
  129. package/listbox/listbox.cjs.js +25 -20
  130. package/listbox/listbox.cjs.min.js +1 -1
  131. package/listbox/listbox.esm.js +25 -20
  132. package/listbox/listbox.esm.min.js +1 -1
  133. package/listbox/listbox.js +25 -20
  134. package/listbox/listbox.min.js +1 -1
  135. package/megamenu/MegaMenu.d.ts +29 -2
  136. package/megamenu/MegaMenu.vue +486 -228
  137. package/megamenu/MegaMenuSub.vue +231 -0
  138. package/megamenu/megamenu.cjs.js +818 -377
  139. package/megamenu/megamenu.cjs.min.js +1 -1
  140. package/megamenu/megamenu.esm.js +820 -379
  141. package/megamenu/megamenu.esm.min.js +1 -1
  142. package/megamenu/megamenu.js +818 -377
  143. package/megamenu/megamenu.min.js +1 -1
  144. package/menu/Menu.d.ts +25 -2
  145. package/menu/Menu.vue +182 -18
  146. package/menu/Menuitem.vue +35 -28
  147. package/menu/menu.cjs.js +293 -114
  148. package/menu/menu.cjs.min.js +1 -1
  149. package/menu/menu.esm.js +293 -114
  150. package/menu/menu.esm.min.js +1 -1
  151. package/menu/menu.js +293 -114
  152. package/menu/menu.min.js +1 -1
  153. package/menubar/Menubar.d.ts +14 -2
  154. package/menubar/Menubar.vue +526 -15
  155. package/menubar/MenubarSub.vue +105 -238
  156. package/menubar/menubar.cjs.js +691 -316
  157. package/menubar/menubar.cjs.min.js +1 -1
  158. package/menubar/menubar.esm.js +693 -318
  159. package/menubar/menubar.esm.min.js +1 -1
  160. package/menubar/menubar.js +691 -316
  161. package/menubar/menubar.min.js +1 -1
  162. package/multiselect/MultiSelect.d.ts +25 -0
  163. package/multiselect/MultiSelect.vue +31 -11
  164. package/multiselect/multiselect.cjs.js +58 -37
  165. package/multiselect/multiselect.cjs.min.js +1 -1
  166. package/multiselect/multiselect.esm.js +57 -36
  167. package/multiselect/multiselect.esm.min.js +1 -1
  168. package/multiselect/multiselect.js +57 -36
  169. package/multiselect/multiselect.min.js +1 -1
  170. package/package.json +3 -3
  171. package/paginator/Paginator.d.ts +2 -2
  172. package/paginator/Paginator.vue +118 -23
  173. package/paginator/paginator.cjs.js +277 -182
  174. package/paginator/paginator.cjs.min.js +1 -1
  175. package/paginator/paginator.esm.js +278 -183
  176. package/paginator/paginator.esm.min.js +1 -1
  177. package/paginator/paginator.js +278 -184
  178. package/paginator/paginator.min.js +1 -1
  179. package/panelmenu/PanelMenu.d.ts +32 -1
  180. package/panelmenu/PanelMenu.vue +189 -83
  181. package/panelmenu/PanelMenuList.vue +335 -0
  182. package/panelmenu/PanelMenuSub.vue +124 -85
  183. package/panelmenu/panelmenu.cjs.js +1383 -285
  184. package/panelmenu/panelmenu.cjs.min.js +1 -1
  185. package/panelmenu/panelmenu.esm.js +1380 -286
  186. package/panelmenu/panelmenu.esm.min.js +1 -1
  187. package/panelmenu/panelmenu.js +1383 -286
  188. package/panelmenu/panelmenu.min.js +1 -1
  189. package/password/Password.vue +5 -4
  190. package/password/password.cjs.js +6 -5
  191. package/password/password.cjs.min.js +1 -1
  192. package/password/password.esm.js +5 -4
  193. package/password/password.esm.min.js +1 -1
  194. package/password/password.js +6 -5
  195. package/password/password.min.js +1 -1
  196. package/resources/primevue.css +21 -2
  197. package/resources/primevue.min.css +1 -1
  198. package/resources/themes/arya-blue/theme.css +317 -270
  199. package/resources/themes/arya-green/theme.css +317 -270
  200. package/resources/themes/arya-orange/theme.css +317 -270
  201. package/resources/themes/arya-purple/theme.css +317 -270
  202. package/resources/themes/bootstrap4-dark-blue/theme.css +332 -285
  203. package/resources/themes/bootstrap4-dark-purple/theme.css +332 -285
  204. package/resources/themes/bootstrap4-light-blue/theme.css +345 -298
  205. package/resources/themes/bootstrap4-light-purple/theme.css +345 -298
  206. package/resources/themes/fluent-light/theme.css +327 -280
  207. package/resources/themes/lara-dark-blue/theme.css +320 -273
  208. package/resources/themes/lara-dark-indigo/theme.css +320 -273
  209. package/resources/themes/lara-dark-purple/theme.css +320 -273
  210. package/resources/themes/lara-dark-teal/theme.css +320 -273
  211. package/resources/themes/lara-light-blue/theme.css +344 -297
  212. package/resources/themes/lara-light-indigo/theme.css +344 -297
  213. package/resources/themes/lara-light-purple/theme.css +344 -297
  214. package/resources/themes/lara-light-teal/theme.css +344 -297
  215. package/resources/themes/luna-amber/theme.css +348 -301
  216. package/resources/themes/luna-blue/theme.css +348 -301
  217. package/resources/themes/luna-green/theme.css +348 -301
  218. package/resources/themes/luna-pink/theme.css +348 -301
  219. package/resources/themes/md-dark-deeppurple/theme.css +367 -298
  220. package/resources/themes/md-dark-indigo/theme.css +367 -298
  221. package/resources/themes/md-light-deeppurple/theme.css +367 -298
  222. package/resources/themes/md-light-indigo/theme.css +367 -298
  223. package/resources/themes/mdc-dark-deeppurple/theme.css +367 -298
  224. package/resources/themes/mdc-dark-indigo/theme.css +367 -298
  225. package/resources/themes/mdc-light-deeppurple/theme.css +367 -298
  226. package/resources/themes/mdc-light-indigo/theme.css +367 -298
  227. package/resources/themes/nova/theme.css +312 -265
  228. package/resources/themes/nova-accent/theme.css +312 -265
  229. package/resources/themes/nova-alt/theme.css +312 -265
  230. package/resources/themes/nova-vue/theme.css +312 -265
  231. package/resources/themes/rhea/theme.css +312 -265
  232. package/resources/themes/saga-blue/theme.css +324 -277
  233. package/resources/themes/saga-green/theme.css +324 -277
  234. package/resources/themes/saga-orange/theme.css +324 -277
  235. package/resources/themes/saga-purple/theme.css +324 -277
  236. package/resources/themes/tailwind-light/theme.css +336 -289
  237. package/resources/themes/vela-blue/theme.css +324 -277
  238. package/resources/themes/vela-green/theme.css +324 -277
  239. package/resources/themes/vela-orange/theme.css +324 -277
  240. package/resources/themes/vela-purple/theme.css +324 -277
  241. package/ripple/ripple.cjs.js +12 -0
  242. package/ripple/ripple.cjs.min.js +1 -1
  243. package/ripple/ripple.esm.js +12 -0
  244. package/ripple/ripple.esm.min.js +1 -1
  245. package/ripple/ripple.js +12 -0
  246. package/ripple/ripple.min.js +1 -1
  247. package/speeddial/SpeedDial.vue +21 -16
  248. package/speeddial/speeddial.cjs.js +34 -27
  249. package/speeddial/speeddial.cjs.min.js +1 -1
  250. package/speeddial/speeddial.esm.js +34 -27
  251. package/speeddial/speeddial.esm.min.js +1 -1
  252. package/speeddial/speeddial.js +34 -27
  253. package/speeddial/speeddial.min.js +1 -1
  254. package/steps/Steps.vue +108 -9
  255. package/steps/steps.cjs.js +111 -20
  256. package/steps/steps.cjs.min.js +1 -1
  257. package/steps/steps.esm.js +112 -21
  258. package/steps/steps.esm.min.js +1 -1
  259. package/steps/steps.js +111 -20
  260. package/steps/steps.min.js +1 -1
  261. package/styleclass/styleclass.cjs.js +1 -1
  262. package/styleclass/styleclass.cjs.min.js +1 -1
  263. package/styleclass/styleclass.esm.js +1 -1
  264. package/styleclass/styleclass.esm.min.js +1 -1
  265. package/styleclass/styleclass.js +1 -1
  266. package/styleclass/styleclass.min.js +1 -1
  267. package/tabmenu/TabMenu.d.ts +9 -1
  268. package/tabmenu/TabMenu.vue +135 -6
  269. package/tabmenu/tabmenu.cjs.js +137 -17
  270. package/tabmenu/tabmenu.cjs.min.js +1 -1
  271. package/tabmenu/tabmenu.esm.js +137 -17
  272. package/tabmenu/tabmenu.esm.min.js +1 -1
  273. package/tabmenu/tabmenu.js +138 -18
  274. package/tabmenu/tabmenu.min.js +1 -1
  275. package/tabview/TabView.vue +2 -2
  276. package/tabview/tabview.cjs.js +2 -2
  277. package/tabview/tabview.cjs.min.js +1 -1
  278. package/tabview/tabview.esm.js +2 -2
  279. package/tabview/tabview.esm.min.js +1 -1
  280. package/tabview/tabview.js +3 -3
  281. package/tabview/tabview.min.js +1 -1
  282. package/tieredmenu/TieredMenu.d.ts +46 -3
  283. package/tieredmenu/TieredMenu.vue +482 -48
  284. package/tieredmenu/TieredMenuSub.vue +111 -204
  285. package/tieredmenu/tieredmenu.cjs.js +656 -320
  286. package/tieredmenu/tieredmenu.cjs.min.js +1 -1
  287. package/tieredmenu/tieredmenu.esm.js +657 -321
  288. package/tieredmenu/tieredmenu.esm.min.js +1 -1
  289. package/tieredmenu/tieredmenu.js +657 -321
  290. package/tieredmenu/tieredmenu.min.js +1 -1
  291. package/toast/Toast.vue +5 -3
  292. package/toast/ToastMessage.vue +5 -3
  293. package/toast/toast.cjs.js +19 -15
  294. package/toast/toast.cjs.min.js +1 -1
  295. package/toast/toast.esm.js +18 -14
  296. package/toast/toast.esm.min.js +1 -1
  297. package/toast/toast.js +19 -15
  298. package/toast/toast.min.js +1 -1
  299. package/togglebutton/ToggleButton.vue +42 -7
  300. package/togglebutton/togglebutton.cjs.js +42 -6
  301. package/togglebutton/togglebutton.cjs.min.js +1 -1
  302. package/togglebutton/togglebutton.esm.js +42 -6
  303. package/togglebutton/togglebutton.esm.min.js +1 -1
  304. package/togglebutton/togglebutton.js +42 -6
  305. package/togglebutton/togglebutton.min.js +1 -1
  306. package/tree/Tree.d.ts +8 -0
  307. package/utils/Utils.d.ts +3 -0
  308. package/utils/utils.cjs.js +26 -0
  309. package/utils/utils.cjs.min.js +1 -1
  310. package/utils/utils.esm.js +26 -0
  311. package/utils/utils.esm.min.js +1 -1
  312. package/utils/utils.js +26 -0
  313. package/utils/utils.min.js +1 -1
  314. package/vetur-attributes.json +175 -3
  315. package/vetur-tags.json +54 -11
  316. package/web-types.json +675 -51
@@ -0,0 +1,335 @@
1
+ <template>
2
+ <PanelMenuSub
3
+ :id="panelId + '_list'"
4
+ class="p-panelmenu-root-list"
5
+ role="tree"
6
+ :tabindex="-1"
7
+ :aria-activedescendant="focused ? focusedItemId : undefined"
8
+ :panelId="panelId"
9
+ :focusedItemId="focused ? focusedItemId : undefined"
10
+ :items="processedItems"
11
+ :template="template"
12
+ :activeItemPath="activeItemPath"
13
+ :exact="exact"
14
+ @focus="onFocus"
15
+ @blur="onBlur"
16
+ @keydown="onKeyDown"
17
+ @item-toggle="onItemToggle"
18
+ />
19
+ </template>
20
+
21
+ <script>
22
+ import { ObjectUtils } from 'primevue/utils';
23
+ import DomHandler from '../utils/DomHandler';
24
+ import PanelMenuSub from './PanelMenuSub.vue';
25
+
26
+ export default {
27
+ name: 'PanelMenuList',
28
+ emits: ['item-toggle', 'header-focus'],
29
+ props: {
30
+ panelId: {
31
+ type: String,
32
+ default: null
33
+ },
34
+ items: {
35
+ type: Array,
36
+ default: null
37
+ },
38
+ template: {
39
+ type: Function,
40
+ default: null
41
+ },
42
+ expandedKeys: {
43
+ type: Object,
44
+ default: null
45
+ },
46
+ exact: {
47
+ type: Boolean,
48
+ default: true
49
+ }
50
+ },
51
+ data() {
52
+ return {
53
+ focused: false,
54
+ focusedItem: null,
55
+ activeItemPath: []
56
+ };
57
+ },
58
+ watch: {
59
+ expandedKeys(newValue) {
60
+ this.autoUpdateActiveItemPath(newValue);
61
+ }
62
+ },
63
+ mounted() {
64
+ this.autoUpdateActiveItemPath(this.expandedKeys);
65
+ },
66
+ methods: {
67
+ getItemProp(processedItem, name) {
68
+ return processedItem && processedItem.item ? ObjectUtils.getItemValue(processedItem.item[name]) : undefined;
69
+ },
70
+ isItemVisible(processedItem) {
71
+ return this.getItemProp(processedItem, 'visible') !== false;
72
+ },
73
+ isItemDisabled(processedItem) {
74
+ return this.getItemProp(processedItem, 'disabled');
75
+ },
76
+ isItemActive(processedItem) {
77
+ return this.activeItemPath.some((path) => path.key === processedItem.parentKey);
78
+ },
79
+ isItemGroup(processedItem) {
80
+ return ObjectUtils.isNotEmpty(processedItem.items);
81
+ },
82
+ onFocus(event) {
83
+ this.focused = true;
84
+ this.focusedItem = this.focusedItem || (this.isElementInPanel(event, event.relatedTarget) ? this.findFirstItem() : this.findLastItem());
85
+ },
86
+ onBlur() {
87
+ this.focused = false;
88
+ this.focusedItem = null;
89
+ },
90
+ onKeyDown(event) {
91
+ switch (event.code) {
92
+ case 'ArrowDown':
93
+ this.onArrowDownKey(event);
94
+ break;
95
+
96
+ case 'ArrowUp':
97
+ this.onArrowUpKey(event);
98
+ break;
99
+
100
+ case 'ArrowLeft':
101
+ this.onArrowLeftKey(event);
102
+ break;
103
+
104
+ case 'ArrowRight':
105
+ this.onArrowRightKey(event);
106
+ break;
107
+
108
+ case 'Home':
109
+ this.onHomeKey(event);
110
+ break;
111
+
112
+ case 'End':
113
+ this.onEndKey(event);
114
+ break;
115
+
116
+ case 'Space':
117
+ this.onSpaceKey(event);
118
+ break;
119
+
120
+ case 'Enter':
121
+ this.onEnterKey(event);
122
+ break;
123
+
124
+ case 'Escape':
125
+ case 'Tab':
126
+ case 'PageDown':
127
+ case 'PageUp':
128
+ case 'Backspace':
129
+ case 'ShiftLeft':
130
+ case 'ShiftRight':
131
+ //NOOP
132
+ break;
133
+
134
+ default:
135
+ break;
136
+ }
137
+ },
138
+ onArrowDownKey(event) {
139
+ const processedItem = ObjectUtils.isNotEmpty(this.focusedItem) ? this.findNextItem(this.focusedItem) : this.findFirstItem();
140
+
141
+ this.changeFocusedItem({ originalEvent: event, processedItem, focusOnNext: true });
142
+ event.preventDefault();
143
+ },
144
+ onArrowUpKey(event) {
145
+ const processedItem = ObjectUtils.isNotEmpty(this.focusedItem) ? this.findPrevItem(this.focusedItem) : this.findLastItem();
146
+
147
+ this.changeFocusedItem({ originalEvent: event, processedItem, selfCheck: true });
148
+ event.preventDefault();
149
+ },
150
+ onArrowLeftKey(event) {
151
+ if (ObjectUtils.isNotEmpty(this.focusedItem)) {
152
+ const matched = this.activeItemPath.some((p) => p.key === this.focusedItem.key);
153
+
154
+ if (matched) {
155
+ this.activeItemPath = this.activeItemPath.filter((p) => p.key !== this.focusedItem.key);
156
+ } else {
157
+ this.focusedItem = ObjectUtils.isNotEmpty(this.focusedItem.parent) ? this.focusedItem.parent : this.focusedItem;
158
+ }
159
+
160
+ event.preventDefault();
161
+ }
162
+ },
163
+ onArrowRightKey(event) {
164
+ if (ObjectUtils.isNotEmpty(this.focusedItem)) {
165
+ const grouped = this.isItemGroup(this.focusedItem);
166
+
167
+ if (grouped) {
168
+ const matched = this.activeItemPath.some((p) => p.key === this.focusedItem.key);
169
+
170
+ if (matched) {
171
+ this.onArrowDownKey(event);
172
+ } else {
173
+ this.activeItemPath = this.activeItemPath.filter((p) => p.parentKey !== this.focusedItem.parentKey);
174
+ this.activeItemPath.push(this.focusedItem);
175
+ }
176
+ }
177
+
178
+ event.preventDefault();
179
+ }
180
+ },
181
+ onHomeKey(event) {
182
+ this.changeFocusedItem({ originalEvent: event, processedItem: this.findFirstItem(), allowHeaderFocus: false });
183
+ event.preventDefault();
184
+ },
185
+ onEndKey(event) {
186
+ this.changeFocusedItem({ originalEvent: event, processedItem: this.findLastItem(), focusOnNext: true, allowHeaderFocus: false });
187
+ event.preventDefault();
188
+ },
189
+ onEnterKey(event) {
190
+ if (ObjectUtils.isNotEmpty(this.focusedItem)) {
191
+ const element = DomHandler.findSingle(this.$el, `li[id="${`${this.focusedItemId}`}"]`);
192
+ const anchorElement = element && DomHandler.findSingle(element, '.p-menuitem-link');
193
+
194
+ anchorElement ? anchorElement.click() : element && element.click();
195
+ }
196
+
197
+ event.preventDefault();
198
+ },
199
+ onSpaceKey(event) {
200
+ this.onEnterKey(event);
201
+ },
202
+ onItemToggle(event) {
203
+ const { processedItem, expanded } = event;
204
+
205
+ if (this.expandedKeys) {
206
+ this.$emit('item-toggle', { item: processedItem.item, expanded });
207
+ } else {
208
+ this.activeItemPath = this.activeItemPath.filter((p) => p.parentKey !== processedItem.parentKey);
209
+ expanded && this.activeItemPath.push(processedItem);
210
+ }
211
+
212
+ this.focusedItem = processedItem;
213
+ DomHandler.focus(this.$el);
214
+ },
215
+ isElementInPanel(event, element) {
216
+ const panel = event.currentTarget.closest('.p-panelmenu-panel');
217
+
218
+ return panel && panel.contains(element);
219
+ },
220
+ isVisibleItem(processedItem) {
221
+ return !!processedItem && (processedItem.level === 0 || this.isItemActive(processedItem)) && this.isItemVisible(processedItem);
222
+ },
223
+ isValidItem(processedItem) {
224
+ return !!processedItem && !this.isItemDisabled(processedItem);
225
+ },
226
+ findFirstItem() {
227
+ return this.visibleItems.find((processedItem) => this.isValidItem(processedItem));
228
+ },
229
+ findLastItem() {
230
+ return ObjectUtils.findLast(this.visibleItems, (processedItem) => this.isValidItem(processedItem));
231
+ },
232
+ findNextItem(processedItem) {
233
+ const index = this.visibleItems.findIndex((item) => item.key === processedItem.key);
234
+ const matchedItem = index < this.visibleItems.length - 1 ? this.visibleItems.slice(index + 1).find((pItem) => this.isValidItem(pItem)) : undefined;
235
+
236
+ return matchedItem || processedItem;
237
+ },
238
+ findPrevItem(processedItem) {
239
+ const index = this.visibleItems.findIndex((item) => item.key === processedItem.key);
240
+ const matchedItem = index > 0 ? ObjectUtils.findLast(this.visibleItems.slice(0, index), (pItem) => this.isValidItem(pItem)) : undefined;
241
+
242
+ return matchedItem || processedItem;
243
+ },
244
+ changeFocusedItem(event) {
245
+ const { originalEvent, processedItem, focusOnNext, selfCheck, allowHeaderFocus = true } = event;
246
+
247
+ if (ObjectUtils.isNotEmpty(this.focusedItem) && this.focusedItem.key !== processedItem.key) {
248
+ this.focusedItem = processedItem;
249
+ this.scrollInView();
250
+ } else if (allowHeaderFocus) {
251
+ this.$emit('header-focus', { originalEvent, focusOnNext, selfCheck });
252
+ }
253
+ },
254
+ scrollInView() {
255
+ const element = DomHandler.findSingle(this.$el, `li[id="${`${this.focusedItemId}`}"]`);
256
+
257
+ if (element) {
258
+ element.scrollIntoView && element.scrollIntoView({ block: 'nearest', inline: 'start' });
259
+ }
260
+ },
261
+ autoUpdateActiveItemPath(expandedKeys) {
262
+ this.activeItemPath = Object.entries(expandedKeys || {}).reduce((acc, [key, val]) => {
263
+ if (val) {
264
+ const processedItem = this.findProcessedItemByItemKey(key);
265
+
266
+ processedItem && acc.push(processedItem);
267
+ }
268
+
269
+ return acc;
270
+ }, []);
271
+ },
272
+ findProcessedItemByItemKey(key, processedItems, level = 0) {
273
+ processedItems = processedItems || (level === 0 && this.processedItems);
274
+
275
+ if (!processedItems) return null;
276
+
277
+ for (let i = 0; i < processedItems.length; i++) {
278
+ const processedItem = processedItems[i];
279
+
280
+ if (this.getItemProp(processedItem, 'key') === key) return processedItem;
281
+
282
+ const matchedItem = this.findProcessedItemByItemKey(key, processedItem.items, level + 1);
283
+
284
+ if (matchedItem) return matchedItem;
285
+ }
286
+ },
287
+ createProcessedItems(items, level = 0, parent = {}, parentKey = '') {
288
+ const processedItems = [];
289
+
290
+ items &&
291
+ items.forEach((item, index) => {
292
+ const key = (parentKey !== '' ? parentKey + '_' : '') + index;
293
+ const newItem = {
294
+ item,
295
+ index,
296
+ level,
297
+ key,
298
+ parent,
299
+ parentKey
300
+ };
301
+
302
+ newItem['items'] = this.createProcessedItems(item.items, level + 1, newItem, key);
303
+ processedItems.push(newItem);
304
+ });
305
+
306
+ return processedItems;
307
+ },
308
+ flatItems(processedItems, processedFlattenItems = []) {
309
+ processedItems &&
310
+ processedItems.forEach((processedItem) => {
311
+ if (this.isVisibleItem(processedItem)) {
312
+ processedFlattenItems.push(processedItem);
313
+ this.flatItems(processedItem.items, processedFlattenItems);
314
+ }
315
+ });
316
+
317
+ return processedFlattenItems;
318
+ }
319
+ },
320
+ computed: {
321
+ processedItems() {
322
+ return this.createProcessedItems(this.items || []);
323
+ },
324
+ visibleItems() {
325
+ return this.flatItems(this.processedItems);
326
+ },
327
+ focusedItemId() {
328
+ return ObjectUtils.isNotEmpty(this.focusedItem) ? `${this.panelId}_${this.focusedItem.key}` : null;
329
+ }
330
+ },
331
+ components: {
332
+ PanelMenuSub: PanelMenuSub
333
+ }
334
+ };
335
+ </script>
@@ -1,57 +1,87 @@
1
1
  <template>
2
- <ul class="p-submenu-list" role="tree">
3
- <template v-for="(item, i) of model" :key="label(item) + i.toString()">
4
- <li v-if="visible(item) && !item.separator" role="none" :class="getItemClass(item)" :style="item.style">
5
- <template v-if="!template">
6
- <router-link v-if="item.to && !disabled(item)" v-slot="{ navigate, href, isActive: isRouterActive, isExactActive }" :to="item.to" custom>
7
- <a :href="href" :class="linkClass(item, { isActive: isRouterActive, isExactActive })" @click="onItemClick($event, item, navigate)" role="treeitem" :aria-expanded="isActive(item)">
8
- <span :class="['p-menuitem-icon', item.icon]"></span>
9
- <span class="p-menuitem-text">{{ label(item) }}</span>
2
+ <ul class="p-submenu-list">
3
+ <template v-for="(processedItem, index) of items" :key="getItemKey(processedItem)">
4
+ <li
5
+ v-if="isItemVisible(processedItem) && !getItemProp(processedItem, 'separator')"
6
+ :id="getItemId(processedItem)"
7
+ :style="getItemProp(processedItem, 'style')"
8
+ :class="getItemClass(processedItem)"
9
+ role="treeitem"
10
+ :aria-label="getItemLabel(processedItem)"
11
+ :aria-expanded="isItemGroup(processedItem) ? isItemActive(processedItem) : undefined"
12
+ :aria-level="level + 1"
13
+ :aria-setsize="getAriaSetSize()"
14
+ :aria-posinset="getAriaPosInset(index)"
15
+ >
16
+ <div class="p-menuitem-content" @click="onItemClick($event, processedItem)">
17
+ <template v-if="!template">
18
+ <router-link v-if="getItemProp(processedItem, 'to') && !isItemDisabled(processedItem)" v-slot="{ navigate, href, isActive, isExactActive }" :to="getItemProp(processedItem, 'to')" custom>
19
+ <a v-ripple :href="href" :class="getItemActionClass(processedItem, { isActive, isExactActive })" tabindex="-1" aria-hidden="true" @click="onItemActionClick($event, navigate)">
20
+ <span v-if="getItemProp(processedItem, 'icon')" :class="getItemIconClass(processedItem)"></span>
21
+ <span class="p-menuitem-text">{{ getItemLabel(processedItem) }}</span>
22
+ </a>
23
+ </router-link>
24
+ <a v-else v-ripple :href="getItemProp(processedItem, 'url')" :class="getItemActionClass(processedItem)" :target="getItemProp(processedItem, 'target')" tabindex="-1" aria-hidden="true">
25
+ <span v-if="isItemGroup(processedItem)" :class="getItemToggleIconClass(processedItem)"></span>
26
+ <span v-if="getItemProp(processedItem, 'icon')" :class="getItemIconClass(processedItem)"></span>
27
+ <span class="p-menuitem-text">{{ getItemLabel(processedItem) }}</span>
10
28
  </a>
11
- </router-link>
12
- <a
13
- v-else
14
- :href="item.url"
15
- :class="linkClass(item)"
16
- :target="item.target"
17
- @click="onItemClick($event, item)"
18
- @keydown="onItemKeydown($event, item)"
19
- role="treeitem"
20
- :aria-expanded="isActive(item)"
21
- :tabindex="disabled(item) ? null : '0'"
22
- >
23
- <span v-if="item.items" :class="getSubmenuIcon(item)"></span>
24
- <span :class="['p-menuitem-icon', item.icon]"></span>
25
- <span class="p-menuitem-text">{{ label(item) }}</span>
26
- </a>
27
- </template>
28
- <component v-else :is="template" :item="item"></component>
29
+ </template>
30
+ <component v-else :is="template" :item="processedItem.item"></component>
31
+ </div>
29
32
  <transition name="p-toggleable-content">
30
- <div v-show="isActive(item)" class="p-toggleable-content">
31
- <PanelMenuSub v-if="visible(item) && item.items" :key="label(item) + '_sub_'" :model="item.items" :template="template" :expandedKeys="expandedKeys" @item-toggle="$emit('item-toggle', $event)" :exact="exact" />
33
+ <div v-show="isItemActive(processedItem)" class="p-toggleable-content">
34
+ <PanelMenuSub
35
+ v-if="isItemVisible(processedItem) && isItemGroup(processedItem)"
36
+ :id="getItemId(processedItem) + '_list'"
37
+ role="group"
38
+ :panelId="panelId"
39
+ :focusedItemId="focusedItemId"
40
+ :items="processedItem.items"
41
+ :level="level + 1"
42
+ :template="template"
43
+ :activeItemPath="activeItemPath"
44
+ :exact="exact"
45
+ @item-toggle="onItemToggle"
46
+ />
32
47
  </div>
33
48
  </transition>
34
49
  </li>
35
- <li v-if="visible(item) && item.separator" :key="'separator' + i.toString()" :class="['p-menu-separator', item.class]" :style="item.style"></li>
50
+ <li v-if="isItemVisible(processedItem) && getItemProp(processedItem, 'separator')" :style="getItemProp(processedItem, 'style')" :class="getSeparatorItemClass(processedItem)" role="separator"></li>
36
51
  </template>
37
52
  </ul>
38
53
  </template>
39
54
 
40
55
  <script>
56
+ import Ripple from 'primevue/ripple';
57
+ import { ObjectUtils } from 'primevue/utils';
58
+
41
59
  export default {
42
60
  name: 'PanelMenuSub',
43
61
  emits: ['item-toggle'],
44
62
  props: {
45
- model: {
46
- type: null,
63
+ panelId: {
64
+ type: String,
65
+ default: null
66
+ },
67
+ focusedItemId: {
68
+ type: String,
69
+ default: null
70
+ },
71
+ items: {
72
+ type: Array,
47
73
  default: null
48
74
  },
75
+ level: {
76
+ type: Number,
77
+ default: 0
78
+ },
49
79
  template: {
50
80
  type: Function,
51
81
  default: null
52
82
  },
53
- expandedKeys: {
54
- type: null,
83
+ activeItemPath: {
84
+ type: Object,
55
85
  default: null
56
86
  },
57
87
  exact: {
@@ -59,74 +89,83 @@ export default {
59
89
  default: true
60
90
  }
61
91
  },
62
- data() {
63
- return {
64
- activeItem: null
65
- };
66
- },
67
92
  methods: {
68
- onItemClick(event, item, navigate) {
69
- if (this.isActive(item) && this.activeItem === null) {
70
- this.activeItem = item;
71
- }
72
-
73
- if (this.disabled(item)) {
74
- event.preventDefault();
75
-
76
- return;
77
- }
78
-
79
- if (item.command) {
80
- item.command({
81
- originalEvent: event,
82
- item: item
83
- });
84
- }
85
-
86
- if (this.activeItem && this.activeItem === item) this.activeItem = null;
87
- else this.activeItem = item;
88
-
89
- this.$emit('item-toggle', { item: item, expanded: this.activeItem != null });
93
+ getItemId(processedItem) {
94
+ return `${this.panelId}_${processedItem.key}`;
95
+ },
96
+ getItemKey(processedItem) {
97
+ return this.getItemId(processedItem);
98
+ },
99
+ getItemProp(processedItem, name) {
100
+ return processedItem && processedItem.item ? ObjectUtils.getItemValue(processedItem.item[name]) : undefined;
101
+ },
102
+ getItemLabel(processedItem) {
103
+ return this.getItemProp(processedItem, 'label');
104
+ },
105
+ isItemActive(processedItem) {
106
+ return this.activeItemPath.some((path) => path.key === processedItem.key);
107
+ },
108
+ isItemVisible(processedItem) {
109
+ return this.getItemProp(processedItem, 'visible') !== false;
110
+ },
111
+ isItemDisabled(processedItem) {
112
+ return this.getItemProp(processedItem, 'disabled');
113
+ },
114
+ isItemFocused(processedItem) {
115
+ return this.focusedItemId === this.getItemId(processedItem);
116
+ },
117
+ isItemGroup(processedItem) {
118
+ return ObjectUtils.isNotEmpty(processedItem.items);
119
+ },
120
+ onItemClick(event, processedItem) {
121
+ const command = this.getItemProp(processedItem, 'command');
90
122
 
91
- if (item.to && navigate) {
92
- navigate(event);
93
- }
123
+ command && command({ originalEvent: event, item: processedItem.item });
124
+ this.$emit('item-toggle', { processedItem, expanded: !this.isItemActive(processedItem) });
125
+ },
126
+ onItemToggle(event) {
127
+ this.$emit('item-toggle', event);
128
+ },
129
+ onItemActionClick(event, navigate) {
130
+ navigate && navigate(event);
131
+ },
132
+ getAriaSetSize() {
133
+ return this.items.filter((processedItem) => this.isItemVisible(processedItem) && !this.getItemProp(processedItem, 'separator')).length;
94
134
  },
95
- onItemKeydown(event, item) {
96
- if (event.which === 13) {
97
- this.onItemClick(event, item);
98
- }
135
+ getAriaPosInset(index) {
136
+ return index - this.items.slice(0, index).filter((processedItem) => this.isItemVisible(processedItem) && this.getItemProp(processedItem, 'separator')).length + 1;
99
137
  },
100
- getItemClass(item) {
101
- return ['p-menuitem', item.className];
138
+ getItemClass(processedItem) {
139
+ return [
140
+ 'p-menuitem',
141
+ this.getItemProp(processedItem, 'class'),
142
+ {
143
+ 'p-focus': this.isItemFocused(processedItem),
144
+ 'p-disabled': this.isItemDisabled(processedItem)
145
+ }
146
+ ];
102
147
  },
103
- linkClass(item, routerProps) {
148
+ getItemActionClass(processedItem, routerProps) {
104
149
  return [
105
150
  'p-menuitem-link',
106
151
  {
107
- 'p-disabled': this.disabled(item),
108
152
  'router-link-active': routerProps && routerProps.isActive,
109
153
  'router-link-active-exact': this.exact && routerProps && routerProps.isExactActive
110
154
  }
111
155
  ];
112
156
  },
113
- isActive(item) {
114
- return this.expandedKeys ? this.expandedKeys[item.key] : item === this.activeItem;
157
+ getItemIconClass(processedItem) {
158
+ return ['p-menuitem-icon', this.getItemProp(processedItem, 'icon')];
115
159
  },
116
- getSubmenuIcon(item) {
117
- const active = this.isActive(item);
118
-
119
- return ['p-panelmenu-icon pi pi-fw', { 'pi-angle-right': !active, 'pi-angle-down': active }];
120
- },
121
- visible(item) {
122
- return typeof item.visible === 'function' ? item.visible() : item.visible !== false;
160
+ getItemToggleIconClass(processedItem) {
161
+ return ['p-submenu-icon', this.isItemActive(processedItem) ? 'pi pi-fw pi-chevron-down' : 'pi pi-fw pi-chevron-right'];
123
162
  },
124
- disabled(item) {
125
- return typeof item.disabled === 'function' ? item.disabled() : item.disabled;
126
- },
127
- label(item) {
128
- return typeof item.label === 'function' ? item.label() : item.label;
163
+ getSeparatorItemClass(processedItem) {
164
+ return ['p-menuitem-separator', this.getItemProp(processedItem, 'class')];
129
165
  }
166
+ },
167
+ directives: {
168
+ ripple: Ripple
130
169
  }
131
170
  };
132
171
  </script>