primevue 3.15.0 → 3.16.2

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 (387) hide show
  1. package/autocomplete/AutoComplete.d.ts +182 -38
  2. package/autocomplete/AutoComplete.vue +636 -342
  3. package/autocomplete/autocomplete.cjs.js +745 -416
  4. package/autocomplete/autocomplete.cjs.min.js +1 -1
  5. package/autocomplete/autocomplete.esm.js +747 -418
  6. package/autocomplete/autocomplete.esm.min.js +1 -1
  7. package/autocomplete/autocomplete.js +745 -416
  8. package/autocomplete/autocomplete.min.js +1 -1
  9. package/button/Button.vue +4 -1
  10. package/button/button.cjs.js +5 -1
  11. package/button/button.cjs.min.js +1 -1
  12. package/button/button.esm.js +5 -1
  13. package/button/button.esm.min.js +1 -1
  14. package/button/button.js +5 -1
  15. package/button/button.min.js +1 -1
  16. package/calendar/Calendar.d.ts +51 -12
  17. package/calendar/Calendar.vue +259 -114
  18. package/calendar/calendar.cjs.js +414 -220
  19. package/calendar/calendar.cjs.min.js +1 -1
  20. package/calendar/calendar.esm.js +415 -221
  21. package/calendar/calendar.esm.min.js +1 -1
  22. package/calendar/calendar.js +414 -220
  23. package/calendar/calendar.min.js +1 -1
  24. package/carousel/Carousel.vue +25 -0
  25. package/carousel/carousel.cjs.js +25 -0
  26. package/carousel/carousel.cjs.min.js +1 -1
  27. package/carousel/carousel.esm.js +25 -0
  28. package/carousel/carousel.esm.min.js +1 -1
  29. package/carousel/carousel.js +25 -0
  30. package/carousel/carousel.min.js +1 -1
  31. package/cascadeselect/CascadeSelect.d.ts +97 -17
  32. package/cascadeselect/CascadeSelect.vue +560 -135
  33. package/cascadeselect/CascadeSelectSub.vue +48 -129
  34. package/cascadeselect/cascadeselect.cjs.js +670 -306
  35. package/cascadeselect/cascadeselect.cjs.min.js +1 -1
  36. package/cascadeselect/cascadeselect.esm.js +672 -308
  37. package/cascadeselect/cascadeselect.esm.min.js +1 -1
  38. package/cascadeselect/cascadeselect.js +670 -306
  39. package/cascadeselect/cascadeselect.min.js +1 -1
  40. package/checkbox/Checkbox.d.ts +40 -4
  41. package/checkbox/Checkbox.vue +50 -13
  42. package/checkbox/checkbox.cjs.js +64 -23
  43. package/checkbox/checkbox.cjs.min.js +1 -1
  44. package/checkbox/checkbox.esm.js +65 -24
  45. package/checkbox/checkbox.esm.min.js +1 -1
  46. package/checkbox/checkbox.js +64 -23
  47. package/checkbox/checkbox.min.js +1 -1
  48. package/chips/Chips.d.ts +36 -12
  49. package/chips/Chips.vue +116 -22
  50. package/chips/chips.cjs.js +149 -37
  51. package/chips/chips.cjs.min.js +1 -1
  52. package/chips/chips.esm.js +150 -38
  53. package/chips/chips.esm.min.js +1 -1
  54. package/chips/chips.js +150 -39
  55. package/chips/chips.min.js +1 -1
  56. package/colorpicker/ColorPicker.d.ts +3 -6
  57. package/colorpicker/ColorPicker.vue +1 -5
  58. package/colorpicker/colorpicker.cjs.js +2 -7
  59. package/colorpicker/colorpicker.cjs.min.js +1 -1
  60. package/colorpicker/colorpicker.esm.js +2 -7
  61. package/colorpicker/colorpicker.esm.min.js +1 -1
  62. package/colorpicker/colorpicker.js +2 -7
  63. package/colorpicker/colorpicker.min.js +1 -1
  64. package/column/Column.d.ts +4 -0
  65. package/column/Column.vue +4 -0
  66. package/column/column.cjs.js +4 -0
  67. package/column/column.cjs.min.js +1 -1
  68. package/column/column.esm.js +4 -0
  69. package/column/column.esm.min.js +1 -1
  70. package/column/column.js +4 -0
  71. package/column/column.min.js +1 -1
  72. package/config/PrimeVue.d.ts +42 -0
  73. package/config/config.cjs.js +35 -4
  74. package/config/config.cjs.min.js +1 -1
  75. package/config/config.esm.js +35 -4
  76. package/config/config.esm.min.js +1 -1
  77. package/config/config.js +35 -4
  78. package/config/config.min.js +1 -1
  79. package/confirmdialog/ConfirmDialog.vue +4 -1
  80. package/confirmdialog/confirmdialog.cjs.js +6 -2
  81. package/confirmdialog/confirmdialog.cjs.min.js +1 -1
  82. package/confirmdialog/confirmdialog.esm.js +6 -2
  83. package/confirmdialog/confirmdialog.esm.min.js +1 -1
  84. package/confirmdialog/confirmdialog.js +6 -2
  85. package/confirmdialog/confirmdialog.min.js +1 -1
  86. package/contextmenu/ContextMenu.d.ts +1 -1
  87. package/contextmenu/ContextMenuSub.vue +3 -3
  88. package/contextmenu/contextmenu.cjs.js +14 -8
  89. package/contextmenu/contextmenu.cjs.min.js +1 -1
  90. package/contextmenu/contextmenu.esm.js +15 -9
  91. package/contextmenu/contextmenu.esm.min.js +1 -1
  92. package/contextmenu/contextmenu.js +14 -8
  93. package/contextmenu/contextmenu.min.js +1 -1
  94. package/core/core.js +1128 -772
  95. package/core/core.min.js +12 -12
  96. package/datatable/BodyCell.vue +11 -2
  97. package/datatable/DataTable.vue +23 -2
  98. package/datatable/datatable.cjs.js +34 -4
  99. package/datatable/datatable.cjs.min.js +1 -1
  100. package/datatable/datatable.esm.js +34 -4
  101. package/datatable/datatable.esm.min.js +1 -1
  102. package/datatable/datatable.js +34 -4
  103. package/datatable/datatable.min.js +1 -1
  104. package/dialog/Dialog.d.ts +5 -1
  105. package/dropdown/Dropdown.d.ts +92 -38
  106. package/dropdown/Dropdown.vue +538 -399
  107. package/dropdown/dropdown.cjs.js +657 -486
  108. package/dropdown/dropdown.cjs.min.js +1 -1
  109. package/dropdown/dropdown.esm.js +659 -488
  110. package/dropdown/dropdown.esm.min.js +1 -1
  111. package/dropdown/dropdown.js +657 -486
  112. package/dropdown/dropdown.min.js +1 -1
  113. package/editor/Editor.d.ts +32 -0
  114. package/editor/Editor.vue +15 -1
  115. package/editor/editor.cjs.js +15 -1
  116. package/editor/editor.cjs.min.js +1 -1
  117. package/editor/editor.esm.js +15 -1
  118. package/editor/editor.esm.min.js +1 -1
  119. package/editor/editor.js +15 -1
  120. package/editor/editor.min.js +1 -1
  121. package/inputmask/InputMask.vue +9 -6
  122. package/inputmask/inputmask.cjs.js +14 -6
  123. package/inputmask/inputmask.cjs.min.js +1 -1
  124. package/inputmask/inputmask.esm.js +15 -7
  125. package/inputmask/inputmask.esm.min.js +1 -1
  126. package/inputmask/inputmask.js +14 -6
  127. package/inputmask/inputmask.min.js +1 -1
  128. package/inputnumber/InputNumber.d.ts +31 -7
  129. package/inputnumber/InputNumber.vue +53 -20
  130. package/inputnumber/inputnumber.cjs.js +75 -29
  131. package/inputnumber/inputnumber.cjs.min.js +1 -1
  132. package/inputnumber/inputnumber.esm.js +76 -30
  133. package/inputnumber/inputnumber.esm.min.js +1 -1
  134. package/inputnumber/inputnumber.js +75 -29
  135. package/inputnumber/inputnumber.min.js +1 -1
  136. package/inputswitch/InputSwitch.d.ts +24 -8
  137. package/inputswitch/InputSwitch.vue +27 -12
  138. package/inputswitch/inputswitch.cjs.js +38 -20
  139. package/inputswitch/inputswitch.cjs.min.js +1 -1
  140. package/inputswitch/inputswitch.esm.js +39 -21
  141. package/inputswitch/inputswitch.esm.min.js +1 -1
  142. package/inputswitch/inputswitch.js +38 -20
  143. package/inputswitch/inputswitch.min.js +1 -1
  144. package/inputtext/InputText.vue +1 -2
  145. package/inputtext/inputtext.cjs.js +3 -4
  146. package/inputtext/inputtext.cjs.min.js +1 -1
  147. package/inputtext/inputtext.esm.js +4 -5
  148. package/inputtext/inputtext.esm.min.js +1 -1
  149. package/inputtext/inputtext.js +3 -4
  150. package/inputtext/inputtext.min.js +1 -1
  151. package/knob/Knob.d.ts +12 -0
  152. package/knob/Knob.vue +62 -2
  153. package/knob/knob.cjs.js +73 -5
  154. package/knob/knob.cjs.min.js +1 -1
  155. package/knob/knob.esm.js +73 -5
  156. package/knob/knob.esm.min.js +1 -1
  157. package/knob/knob.js +73 -5
  158. package/knob/knob.min.js +1 -1
  159. package/listbox/Listbox.d.ts +53 -7
  160. package/listbox/Listbox.vue +500 -135
  161. package/listbox/listbox.cjs.js +597 -193
  162. package/listbox/listbox.cjs.min.js +1 -1
  163. package/listbox/listbox.esm.js +599 -195
  164. package/listbox/listbox.esm.min.js +1 -1
  165. package/listbox/listbox.js +597 -193
  166. package/listbox/listbox.min.js +1 -1
  167. package/menu/Menu.d.ts +1 -1
  168. package/menu/Menuitem.vue +2 -2
  169. package/menu/menu.cjs.js +12 -6
  170. package/menu/menu.cjs.min.js +1 -1
  171. package/menu/menu.esm.js +13 -7
  172. package/menu/menu.esm.min.js +1 -1
  173. package/menu/menu.js +12 -6
  174. package/menu/menu.min.js +1 -1
  175. package/menubar/MenubarSub.vue +3 -3
  176. package/menubar/menubar.cjs.js +14 -8
  177. package/menubar/menubar.cjs.min.js +1 -1
  178. package/menubar/menubar.esm.js +15 -9
  179. package/menubar/menubar.esm.min.js +1 -1
  180. package/menubar/menubar.js +14 -8
  181. package/menubar/menubar.min.js +1 -1
  182. package/menuitem/MenuItem.d.ts +1 -1
  183. package/multiselect/MultiSelect.d.ts +111 -51
  184. package/multiselect/MultiSelect.vue +629 -338
  185. package/multiselect/multiselect.cjs.js +748 -428
  186. package/multiselect/multiselect.cjs.min.js +1 -1
  187. package/multiselect/multiselect.esm.js +750 -430
  188. package/multiselect/multiselect.esm.min.js +1 -1
  189. package/multiselect/multiselect.js +748 -428
  190. package/multiselect/multiselect.min.js +1 -1
  191. package/overlaypanel/OverlayPanel.d.ts +1 -1
  192. package/overlaypanel/OverlayPanel.vue +14 -2
  193. package/overlaypanel/overlaypanel.cjs.js +14 -2
  194. package/overlaypanel/overlaypanel.cjs.min.js +1 -1
  195. package/overlaypanel/overlaypanel.esm.js +14 -2
  196. package/overlaypanel/overlaypanel.esm.min.js +1 -1
  197. package/overlaypanel/overlaypanel.js +14 -2
  198. package/overlaypanel/overlaypanel.min.js +1 -1
  199. package/package.json +2 -2
  200. package/paginator/Paginator.d.ts +2 -2
  201. package/password/Password.d.ts +36 -8
  202. package/password/Password.vue +50 -14
  203. package/password/password.cjs.js +69 -24
  204. package/password/password.cjs.min.js +1 -1
  205. package/password/password.esm.js +71 -26
  206. package/password/password.esm.min.js +1 -1
  207. package/password/password.js +69 -24
  208. package/password/password.min.js +1 -1
  209. package/picklist/PickList.d.ts +8 -0
  210. package/picklist/PickList.vue +10 -2
  211. package/picklist/picklist.cjs.js +68 -50
  212. package/picklist/picklist.cjs.min.js +1 -1
  213. package/picklist/picklist.esm.js +69 -51
  214. package/picklist/picklist.esm.min.js +1 -1
  215. package/picklist/picklist.js +68 -50
  216. package/picklist/picklist.min.js +1 -1
  217. package/portal/Portal.d.ts +1 -1
  218. package/radiobutton/RadioButton.d.ts +28 -4
  219. package/radiobutton/RadioButton.vue +36 -11
  220. package/radiobutton/radiobutton.cjs.js +49 -23
  221. package/radiobutton/radiobutton.cjs.min.js +1 -1
  222. package/radiobutton/radiobutton.esm.js +50 -24
  223. package/radiobutton/radiobutton.esm.min.js +1 -1
  224. package/radiobutton/radiobutton.js +49 -23
  225. package/radiobutton/radiobutton.min.js +1 -1
  226. package/rating/Rating.d.ts +4 -0
  227. package/rating/Rating.vue +61 -7
  228. package/rating/rating.cjs.js +90 -16
  229. package/rating/rating.cjs.min.js +1 -1
  230. package/rating/rating.esm.js +91 -17
  231. package/rating/rating.esm.min.js +1 -1
  232. package/rating/rating.js +90 -16
  233. package/rating/rating.min.js +1 -1
  234. package/resources/primevue.css +8 -0
  235. package/resources/primevue.min.css +1 -1
  236. package/resources/themes/arya-blue/theme.css +82 -40
  237. package/resources/themes/arya-green/theme.css +82 -40
  238. package/resources/themes/arya-orange/theme.css +82 -40
  239. package/resources/themes/arya-purple/theme.css +82 -40
  240. package/resources/themes/bootstrap4-dark-blue/theme.css +82 -40
  241. package/resources/themes/bootstrap4-dark-purple/theme.css +82 -40
  242. package/resources/themes/bootstrap4-light-blue/theme.css +82 -40
  243. package/resources/themes/bootstrap4-light-purple/theme.css +82 -40
  244. package/resources/themes/fluent-light/theme.css +82 -40
  245. package/resources/themes/lara-dark-blue/theme.css +82 -40
  246. package/resources/themes/lara-dark-indigo/theme.css +82 -40
  247. package/resources/themes/lara-dark-purple/theme.css +82 -40
  248. package/resources/themes/lara-dark-teal/theme.css +82 -40
  249. package/resources/themes/lara-light-blue/theme.css +82 -40
  250. package/resources/themes/lara-light-indigo/theme.css +82 -40
  251. package/resources/themes/lara-light-purple/theme.css +82 -40
  252. package/resources/themes/lara-light-teal/theme.css +82 -40
  253. package/resources/themes/luna-amber/theme.css +82 -40
  254. package/resources/themes/luna-blue/theme.css +82 -40
  255. package/resources/themes/luna-green/theme.css +82 -40
  256. package/resources/themes/luna-pink/theme.css +82 -40
  257. package/resources/themes/md-dark-deeppurple/theme.css +82 -40
  258. package/resources/themes/md-dark-indigo/theme.css +82 -40
  259. package/resources/themes/md-light-deeppurple/theme.css +82 -40
  260. package/resources/themes/md-light-indigo/theme.css +82 -40
  261. package/resources/themes/mdc-dark-deeppurple/theme.css +82 -40
  262. package/resources/themes/mdc-dark-indigo/theme.css +82 -40
  263. package/resources/themes/mdc-light-deeppurple/theme.css +82 -40
  264. package/resources/themes/mdc-light-indigo/theme.css +82 -40
  265. package/resources/themes/nova/theme.css +82 -40
  266. package/resources/themes/nova-accent/theme.css +82 -40
  267. package/resources/themes/nova-alt/theme.css +82 -40
  268. package/resources/themes/nova-vue/theme.css +82 -40
  269. package/resources/themes/rhea/theme.css +82 -40
  270. package/resources/themes/saga-blue/theme.css +82 -40
  271. package/resources/themes/saga-green/theme.css +82 -40
  272. package/resources/themes/saga-orange/theme.css +82 -40
  273. package/resources/themes/saga-purple/theme.css +82 -40
  274. package/resources/themes/tailwind-light/theme.css +82 -40
  275. package/resources/themes/vela-blue/theme.css +82 -40
  276. package/resources/themes/vela-green/theme.css +82 -40
  277. package/resources/themes/vela-orange/theme.css +82 -40
  278. package/resources/themes/vela-purple/theme.css +82 -40
  279. package/ripple/ripple.cjs.js +1 -0
  280. package/ripple/ripple.cjs.min.js +1 -1
  281. package/ripple/ripple.esm.js +1 -0
  282. package/ripple/ripple.esm.min.js +1 -1
  283. package/ripple/ripple.js +1 -0
  284. package/ripple/ripple.min.js +1 -1
  285. package/selectbutton/SelectButton.d.ts +6 -2
  286. package/selectbutton/SelectButton.vue +89 -12
  287. package/selectbutton/selectbutton.cjs.js +97 -22
  288. package/selectbutton/selectbutton.cjs.min.js +1 -1
  289. package/selectbutton/selectbutton.esm.js +99 -24
  290. package/selectbutton/selectbutton.esm.min.js +1 -1
  291. package/selectbutton/selectbutton.js +97 -22
  292. package/selectbutton/selectbutton.min.js +1 -1
  293. package/slider/Slider.d.ts +9 -1
  294. package/slider/Slider.vue +50 -34
  295. package/slider/slider.cjs.js +59 -38
  296. package/slider/slider.cjs.min.js +1 -1
  297. package/slider/slider.esm.js +59 -38
  298. package/slider/slider.esm.min.js +1 -1
  299. package/slider/slider.js +59 -38
  300. package/slider/slider.min.js +1 -1
  301. package/splitbutton/SplitButton.d.ts +1 -1
  302. package/splitter/Splitter.vue +30 -1
  303. package/splitter/splitter.cjs.js +30 -1
  304. package/splitter/splitter.cjs.min.js +1 -1
  305. package/splitter/splitter.esm.js +30 -1
  306. package/splitter/splitter.esm.min.js +1 -1
  307. package/splitter/splitter.js +30 -1
  308. package/splitter/splitter.min.js +1 -1
  309. package/textarea/Textarea.vue +1 -2
  310. package/textarea/textarea.cjs.js +3 -5
  311. package/textarea/textarea.cjs.min.js +1 -1
  312. package/textarea/textarea.esm.js +4 -6
  313. package/textarea/textarea.esm.min.js +1 -1
  314. package/textarea/textarea.js +3 -5
  315. package/textarea/textarea.min.js +1 -1
  316. package/tieredmenu/TieredMenu.d.ts +1 -1
  317. package/tieredmenu/TieredMenuSub.vue +3 -3
  318. package/tieredmenu/tieredmenu.cjs.js +14 -8
  319. package/tieredmenu/tieredmenu.cjs.min.js +1 -1
  320. package/tieredmenu/tieredmenu.esm.js +15 -9
  321. package/tieredmenu/tieredmenu.esm.min.js +1 -1
  322. package/tieredmenu/tieredmenu.js +14 -8
  323. package/tieredmenu/tieredmenu.min.js +1 -1
  324. package/timeline/Timeline.d.ts +10 -1
  325. package/timeline/Timeline.vue +1 -1
  326. package/timeline/timeline.cjs.js +5 -1
  327. package/timeline/timeline.cjs.min.js +1 -1
  328. package/timeline/timeline.esm.js +5 -1
  329. package/timeline/timeline.esm.min.js +1 -1
  330. package/timeline/timeline.js +5 -1
  331. package/timeline/timeline.min.js +1 -1
  332. package/togglebutton/ToggleButton.d.ts +42 -0
  333. package/togglebutton/ToggleButton.vue +44 -7
  334. package/togglebutton/togglebutton.cjs.js +59 -13
  335. package/togglebutton/togglebutton.cjs.min.js +1 -1
  336. package/togglebutton/togglebutton.esm.js +60 -14
  337. package/togglebutton/togglebutton.esm.min.js +1 -1
  338. package/togglebutton/togglebutton.js +59 -13
  339. package/togglebutton/togglebutton.min.js +1 -1
  340. package/tooltip/tooltip.cjs.js +20 -11
  341. package/tooltip/tooltip.cjs.min.js +1 -1
  342. package/tooltip/tooltip.esm.js +21 -12
  343. package/tooltip/tooltip.esm.min.js +1 -1
  344. package/tooltip/tooltip.js +20 -11
  345. package/tooltip/tooltip.min.js +1 -1
  346. package/tree/Tree.vue +5 -1
  347. package/tree/TreeNode.vue +20 -19
  348. package/tree/tree.cjs.js +47 -32
  349. package/tree/tree.cjs.min.js +1 -1
  350. package/tree/tree.esm.js +47 -32
  351. package/tree/tree.esm.min.js +1 -1
  352. package/tree/tree.js +47 -32
  353. package/tree/tree.min.js +1 -1
  354. package/treeselect/TreeSelect.d.ts +26 -10
  355. package/treeselect/TreeSelect.vue +52 -29
  356. package/treeselect/treeselect.cjs.js +74 -41
  357. package/treeselect/treeselect.cjs.min.js +1 -1
  358. package/treeselect/treeselect.esm.js +76 -43
  359. package/treeselect/treeselect.esm.min.js +1 -1
  360. package/treeselect/treeselect.js +74 -41
  361. package/treeselect/treeselect.min.js +1 -1
  362. package/tristatecheckbox/TriStateCheckbox.d.ts +20 -4
  363. package/tristatecheckbox/TriStateCheckbox.vue +52 -15
  364. package/tristatecheckbox/tristatecheckbox.cjs.js +67 -26
  365. package/tristatecheckbox/tristatecheckbox.cjs.min.js +1 -1
  366. package/tristatecheckbox/tristatecheckbox.esm.js +68 -27
  367. package/tristatecheckbox/tristatecheckbox.esm.min.js +1 -1
  368. package/tristatecheckbox/tristatecheckbox.js +67 -26
  369. package/tristatecheckbox/tristatecheckbox.min.js +1 -1
  370. package/utils/Utils.d.ts +3 -2
  371. package/utils/utils.cjs.js +239 -173
  372. package/utils/utils.cjs.min.js +1 -1
  373. package/utils/utils.esm.js +239 -173
  374. package/utils/utils.esm.min.js +1 -1
  375. package/utils/utils.js +239 -173
  376. package/utils/utils.min.js +1 -1
  377. package/vetur-attributes.json +612 -136
  378. package/vetur-tags.json +180 -59
  379. package/virtualscroller/VirtualScroller.d.ts +10 -0
  380. package/virtualscroller/VirtualScroller.vue +18 -17
  381. package/virtualscroller/virtualscroller.cjs.js +22 -20
  382. package/virtualscroller/virtualscroller.cjs.min.js +1 -1
  383. package/virtualscroller/virtualscroller.esm.js +22 -20
  384. package/virtualscroller/virtualscroller.esm.min.js +1 -1
  385. package/virtualscroller/virtualscroller.js +22 -20
  386. package/virtualscroller/virtualscroller.min.js +1 -1
  387. package/web-types.json +1745 -338
@@ -9,7 +9,7 @@ this.primevue.listbox = (function (utils, api, Ripple, VirtualScroller, vue) {
9
9
 
10
10
  var script = {
11
11
  name: 'Listbox',
12
- emits: ['update:modelValue', 'change', 'filter'],
12
+ emits: ['update:modelValue', 'change', 'focus', 'blur', 'filter'],
13
13
  props: {
14
14
  modelValue: null,
15
15
  options: Array,
@@ -34,6 +34,27 @@ this.primevue.listbox = (function (utils, api, Ripple, VirtualScroller, vue) {
34
34
  type: Array,
35
35
  default: null
36
36
  },
37
+ filterInputProps: null,
38
+ virtualScrollerOptions: {
39
+ type: Object,
40
+ default: null
41
+ },
42
+ autoOptionFocus: {
43
+ type: Boolean,
44
+ default: true
45
+ },
46
+ filterMessage: {
47
+ type: String,
48
+ default: null
49
+ },
50
+ selectionMessage: {
51
+ type: String,
52
+ default: null
53
+ },
54
+ emptySelectionMessage: {
55
+ type: String,
56
+ default: null
57
+ },
37
58
  emptyFilterMessage: {
38
59
  type: String,
39
60
  default: null
@@ -42,17 +63,44 @@ this.primevue.listbox = (function (utils, api, Ripple, VirtualScroller, vue) {
42
63
  type: String,
43
64
  default: null
44
65
  },
45
- virtualScrollerOptions: {
46
- type: Object,
66
+ tabindex: {
67
+ type: Number,
68
+ default: 0
69
+ },
70
+ 'aria-label': {
71
+ type: String,
72
+ default: null
73
+ },
74
+ 'aria-labelledby': {
75
+ type: String,
47
76
  default: null
48
77
  }
49
78
  },
50
- optionTouched: false,
79
+ list: null,
51
80
  virtualScroller: null,
81
+ optionTouched: false,
82
+ startRangeIndex: -1,
83
+ searchTimeout: null,
84
+ searchValue: '',
85
+ selectOnFocus: false,
86
+ focusOnHover: false,
52
87
  data() {
53
88
  return {
54
- filterValue: null
55
- };
89
+ id: utils.UniqueComponentId(),
90
+ filterValue: null,
91
+ focused: false,
92
+ focusedOptionIndex: -1
93
+ }
94
+ },
95
+ watch: {
96
+ options() {
97
+ this.autoUpdateModel();
98
+ }
99
+ },
100
+ mounted() {
101
+ this.id = this.$attrs.id || this.id;
102
+
103
+ this.autoUpdateModel();
56
104
  },
57
105
  methods: {
58
106
  getOptionIndex(index, fn) {
@@ -64,14 +112,14 @@ this.primevue.listbox = (function (utils, api, Ripple, VirtualScroller, vue) {
64
112
  getOptionValue(option) {
65
113
  return this.optionValue ? utils.ObjectUtils.resolveFieldData(option, this.optionValue) : option;
66
114
  },
67
- getOptionRenderKey(option) {
68
- return this.dataKey ? utils.ObjectUtils.resolveFieldData(option, this.dataKey) : this.getOptionLabel(option);
115
+ getOptionRenderKey(option, index) {
116
+ return (this.dataKey ? utils.ObjectUtils.resolveFieldData(option, this.dataKey) : this.getOptionLabel(option)) + '_' + index;
69
117
  },
70
118
  isOptionDisabled(option) {
71
119
  return this.optionDisabled ? utils.ObjectUtils.resolveFieldData(option, this.optionDisabled) : false;
72
120
  },
73
- getOptionGroupRenderKey(optionGroup) {
74
- return utils.ObjectUtils.resolveFieldData(optionGroup, this.optionGroupLabel);
121
+ isOptionGroup(option) {
122
+ return this.optionGroupLabel && option.optionGroup && option.group;
75
123
  },
76
124
  getOptionGroupLabel(optionGroup) {
77
125
  return utils.ObjectUtils.resolveFieldData(optionGroup, this.optionGroupLabel);
@@ -79,17 +127,116 @@ this.primevue.listbox = (function (utils, api, Ripple, VirtualScroller, vue) {
79
127
  getOptionGroupChildren(optionGroup) {
80
128
  return utils.ObjectUtils.resolveFieldData(optionGroup, this.optionGroupChildren);
81
129
  },
82
- onOptionSelect(event, option) {
130
+ getAriaPosInset(index) {
131
+ return (this.optionGroupLabel ? index - this.visibleOptions.slice(0, index).filter(option => this.isOptionGroup(option)).length : index) + 1;
132
+ },
133
+ onFirstHiddenFocus() {
134
+ this.list.focus();
135
+
136
+ const firstFocusableEl = utils.DomHandler.getFirstFocusableElement(this.$el, ':not(.p-hidden-focusable)');
137
+ this.$refs.lastHiddenFocusableElement.tabIndex = utils.ObjectUtils.isEmpty(firstFocusableEl) ? -1 : undefined;
138
+ this.$refs.firstHiddenFocusableElement.tabIndex = -1;
139
+ },
140
+ onLastHiddenFocus(event) {
141
+ const relatedTarget = event.relatedTarget;
142
+
143
+ if (relatedTarget === this.list) {
144
+ const firstFocusableEl = utils.DomHandler.getFirstFocusableElement(this.$el, ':not(.p-hidden-focusable)');
145
+ firstFocusableEl && firstFocusableEl.focus();
146
+ this.$refs.firstHiddenFocusableElement.tabIndex = undefined;
147
+ }
148
+ else {
149
+ this.$refs.firstHiddenFocusableElement.focus();
150
+ }
151
+
152
+ this.$refs.lastHiddenFocusableElement.tabIndex = -1;
153
+ },
154
+ onFocusout(event) {
155
+ if (!this.$el.contains(event.relatedTarget) && this.$refs.lastHiddenFocusableElement && this.$refs.firstHiddenFocusableElement) {
156
+ this.$refs.lastHiddenFocusableElement.tabIndex = this.$refs.firstHiddenFocusableElement.tabIndex = undefined;
157
+ }
158
+ },
159
+ onListFocus(event) {
160
+ this.focused = true;
161
+ this.focusedOptionIndex = this.autoOptionFocus ? this.findFirstFocusedOptionIndex() : -1;
162
+ this.$emit('focus', event);
163
+ },
164
+ onListBlur(event) {
165
+ this.focused = false;
166
+ this.focusedOptionIndex = this.startRangeIndex = -1;
167
+ this.searchValue = '';
168
+ this.$emit('blur', event);
169
+ },
170
+ onListKeyDown(event) {
171
+ switch (event.code) {
172
+ case 'ArrowDown':
173
+ this.onArrowDownKey(event);
174
+ break;
175
+
176
+ case 'ArrowUp':
177
+ this.onArrowUpKey(event);
178
+ break;
179
+
180
+ case 'Home':
181
+ this.onHomeKey(event);
182
+ break;
183
+
184
+ case 'End':
185
+ this.onEndKey(event);
186
+ break;
187
+
188
+ case 'PageDown':
189
+ this.onPageDownKey(event);
190
+ break;
191
+
192
+ case 'PageUp':
193
+ this.onPageUpKey(event);
194
+ break;
195
+
196
+ case 'Enter':
197
+ case 'Space':
198
+ this.onSpaceKey(event);
199
+ break;
200
+
201
+ case 'Tab':
202
+ //NOOP
203
+ break;
204
+
205
+ case 'ShiftLeft':
206
+ case 'ShiftRight':
207
+ this.onShiftKey(event);
208
+ break;
209
+
210
+ default:
211
+ if (event.code === 'KeyA' && this.multiple && (event.metaKey || event.ctrlKey)) {
212
+ const value = this.visibleOptions.filter(option => this.isValidOption(option)).map(option => this.getOptionValue(option));
213
+ this.updateModel(event, value);
214
+
215
+ event.preventDefault();
216
+ break;
217
+ }
218
+
219
+ if (utils.ObjectUtils.isPrintableCharacter(event.key)) {
220
+ this.searchOptions(event, event.key);
221
+ event.preventDefault();
222
+ }
223
+
224
+ break;
225
+ }
226
+ },
227
+ onOptionSelect(event, option, index = -1) {
83
228
  if (this.disabled || this.isOptionDisabled(option)) {
84
229
  return;
85
230
  }
86
231
 
87
- if(this.multiple)
88
- this.onOptionSelectMultiple(event, option);
89
- else
90
- this.onOptionSelectSingle(event, option);
91
-
232
+ this.multiple ? this.onOptionSelectMultiple(event, option) : this.onOptionSelectSingle(event, option);
92
233
  this.optionTouched = false;
234
+ index !== -1 && (this.focusedOptionIndex = index);
235
+ },
236
+ onOptionMouseMove(event, index) {
237
+ if (this.focusOnHover) {
238
+ this.changeFocusedOptionIndex(event, index);
239
+ }
93
240
  },
94
241
  onOptionTouchEnd() {
95
242
  if (this.disabled) {
@@ -129,7 +276,6 @@ this.primevue.listbox = (function (utils, api, Ripple, VirtualScroller, vue) {
129
276
  },
130
277
  onOptionSelectMultiple(event, option) {
131
278
  let selected = this.isSelected(option);
132
- let valueChanged = false;
133
279
  let value = null;
134
280
  let metaSelection = this.optionTouched ? false : this.metaKeySelection;
135
281
 
@@ -137,133 +283,320 @@ this.primevue.listbox = (function (utils, api, Ripple, VirtualScroller, vue) {
137
283
  let metaKey = (event.metaKey || event.ctrlKey);
138
284
 
139
285
  if (selected) {
140
- if(metaKey)
141
- value = this.removeOption(option);
142
- else
143
- value = [this.getOptionValue(option)];
144
-
145
- valueChanged = true;
286
+ value = metaKey ? this.removeOption(option) : [this.getOptionValue(option)];
146
287
  }
147
288
  else {
148
289
  value = (metaKey) ? this.modelValue || [] : [];
149
290
  value = [...value, this.getOptionValue(option)];
150
- valueChanged = true;
151
291
  }
152
292
  }
153
293
  else {
154
- if (selected)
155
- value = this.removeOption(option);
156
- else
157
- value = [...this.modelValue || [], this.getOptionValue(option)];
158
-
159
- valueChanged = true;
294
+ value = selected ? this.removeOption(option) : [...this.modelValue || [], this.getOptionValue(option)];
160
295
  }
161
296
 
162
- if(valueChanged) {
297
+ this.updateModel(event, value);
298
+ },
299
+ onOptionSelectRange(event, start = -1, end = -1) {
300
+ start === -1 && (start = this.findNearestSelectedOptionIndex(end, true));
301
+ end === -1 && (end = this.findNearestSelectedOptionIndex(start));
302
+
303
+ if (start !== -1 && end !== -1) {
304
+ const rangeStart = Math.min(start, end);
305
+ const rangeEnd = Math.max(start, end);
306
+ const value = this.visibleOptions.slice(rangeStart, rangeEnd + 1).filter(option => this.isValidOption(option)).map(option => this.getOptionValue(option));
307
+
163
308
  this.updateModel(event, value);
164
309
  }
165
310
  },
166
- isSelected(option) {
167
- let selected = false;
168
- let optionValue = this.getOptionValue(option);
169
-
170
- if (this.multiple) {
171
- if (this.modelValue) {
172
- for (let val of this.modelValue) {
173
- if (utils.ObjectUtils.equals(val, optionValue, this.equalityKey)) {
174
- selected = true;
175
- break;
176
- }
177
- }
311
+ onFilterChange(event) {
312
+ this.$emit('filter', {originalEvent: event, value: event.target.value});
313
+ this.focusedOptionIndex = this.startRangeIndex = -1;
314
+ },
315
+ onFilterBlur() {
316
+ this.focusedOptionIndex = this.startRangeIndex = -1;
317
+ },
318
+ onFilterKeyDown(event) {
319
+ switch (event.code) {
320
+ case 'ArrowDown':
321
+ this.onArrowDownKey(event);
322
+ break;
323
+
324
+ case 'ArrowUp':
325
+ this.onArrowUpKey(event);
326
+ break;
327
+
328
+ case 'ArrowLeft':
329
+ case 'ArrowRight':
330
+ this.onArrowLeftKey(event, true);
331
+ break;
332
+
333
+ case 'Home':
334
+ this.onHomeKey(event, true);
335
+ break;
336
+
337
+ case 'End':
338
+ this.onEndKey(event, true);
339
+ break;
340
+
341
+ case 'Enter':
342
+ this.onEnterKey(event);
343
+ break;
344
+
345
+ case 'ShiftLeft':
346
+ case 'ShiftRight':
347
+ this.onShiftKey(event);
348
+ break;
349
+ }
350
+ },
351
+ onArrowDownKey(event) {
352
+ const optionIndex = this.focusedOptionIndex !== -1 ? this.findNextOptionIndex(this.focusedOptionIndex) : this.findFirstFocusedOptionIndex();
353
+
354
+ if (this.multiple && event.shiftKey) {
355
+ this.onOptionSelectRange(event, this.startRangeIndex, optionIndex);
356
+ }
357
+
358
+ this.changeFocusedOptionIndex(event, optionIndex);
359
+ event.preventDefault();
360
+ },
361
+ onArrowUpKey(event) {
362
+ const optionIndex = this.focusedOptionIndex !== -1 ? this.findPrevOptionIndex(this.focusedOptionIndex) : this.findLastFocusedOptionIndex();
363
+
364
+ if (this.multiple && event.shiftKey) {
365
+ this.onOptionSelectRange(event, optionIndex, this.startRangeIndex);
366
+ }
367
+
368
+ this.changeFocusedOptionIndex(event, optionIndex);
369
+ event.preventDefault();
370
+ },
371
+ onArrowLeftKey(event, pressedInInputText = false) {
372
+ pressedInInputText && (this.focusedOptionIndex = -1);
373
+ },
374
+ onHomeKey(event, pressedInInputText = false) {
375
+ if (pressedInInputText) {
376
+ event.currentTarget.setSelectionRange(0, 0);
377
+ this.focusedOptionIndex = -1;
378
+ }
379
+ else {
380
+ let metaKey = event.metaKey || event.ctrlKey;
381
+ let optionIndex = this.findFirstOptionIndex();
382
+
383
+ if (this.multiple && event.shiftKey && metaKey) {
384
+ this.onOptionSelectRange(event, optionIndex, this.startRangeIndex);
178
385
  }
386
+
387
+ this.changeFocusedOptionIndex(event, optionIndex);
388
+ }
389
+
390
+ event.preventDefault();
391
+ },
392
+ onEndKey(event, pressedInInputText = false) {
393
+ if (pressedInInputText) {
394
+ const target = event.currentTarget;
395
+ const len = target.value.length;
396
+ target.setSelectionRange(len, len);
397
+ this.focusedOptionIndex = -1;
179
398
  }
180
399
  else {
181
- selected = utils.ObjectUtils.equals(this.modelValue, optionValue, this.equalityKey);
400
+ let metaKey = event.metaKey || event.ctrlKey;
401
+ let optionIndex = this.findLastOptionIndex();
402
+
403
+ if (this.multiple && event.shiftKey && metaKey) {
404
+ this.onOptionSelectRange(event, this.startRangeIndex, optionIndex);
405
+ }
406
+
407
+ this.changeFocusedOptionIndex(event, optionIndex);
182
408
  }
183
409
 
184
- return selected;
410
+ event.preventDefault();
185
411
  },
186
- removeOption(option) {
187
- return this.modelValue.filter(val => !utils.ObjectUtils.equals(val, this.getOptionValue(option), this.equalityKey));
412
+ onPageUpKey(event) {
413
+ this.scrollInView(0);
414
+ event.preventDefault();
188
415
  },
189
- updateModel(event, value) {
190
- this.$emit('update:modelValue', value);
191
- this.$emit('change', {originalEvent: event, value: value});
416
+ onPageDownKey(event) {
417
+ this.scrollInView(this.visibleOptions.length - 1);
418
+ event.preventDefault();
192
419
  },
193
- onOptionKeyDown(event, option) {
194
- let item = event.currentTarget;
420
+ onEnterKey(event) {
421
+ if (this.focusedOptionIndex !== -1) {
422
+ if (this.multiple && event.shiftKey)
423
+ this.onOptionSelectRange(event, this.focusedOptionIndex);
424
+ else
425
+ this.onOptionSelect(event, this.visibleOptions[this.focusedOptionIndex]);
426
+ }
195
427
 
196
- switch (event.which) {
197
- //down
198
- case 40:
199
- var nextItem = this.findNextItem(item);
200
- if(nextItem) {
201
- nextItem.focus();
202
- }
428
+ event.preventDefault();
429
+ },
430
+ onSpaceKey(event) {
431
+ this.onEnterKey(event);
432
+ },
433
+ onShiftKey() {
434
+ this.startRangeIndex = this.focusedOptionIndex;
435
+ },
436
+ isOptionMatched(option) {
437
+ return this.isValidOption(option) && this.getOptionLabel(option).toLocaleLowerCase(this.filterLocale).startsWith(this.searchValue.toLocaleLowerCase(this.filterLocale));
438
+ },
439
+ isValidOption(option) {
440
+ return option && !(this.isOptionDisabled(option) || this.isOptionGroup(option));
441
+ },
442
+ isValidSelectedOption(option) {
443
+ return this.isValidOption(option) && this.isSelected(option);
444
+ },
445
+ isSelected(option) {
446
+ const optionValue = this.getOptionValue(option);
447
+
448
+ if (this.multiple)
449
+ return (this.modelValue || []).some(value => utils.ObjectUtils.equals(value, optionValue, this.equalityKey));
450
+ else
451
+ return utils.ObjectUtils.equals(this.modelValue, optionValue, this.equalityKey);
452
+ },
453
+ findFirstOptionIndex() {
454
+ return this.visibleOptions.findIndex(option => this.isValidOption(option));
455
+ },
456
+ findLastOptionIndex() {
457
+ return utils.ObjectUtils.findLastIndex(this.visibleOptions, option => this.isValidOption(option));
458
+ },
459
+ findNextOptionIndex(index) {
460
+ const matchedOptionIndex = index < (this.visibleOptions.length - 1) ? this.visibleOptions.slice(index + 1).findIndex(option => this.isValidOption(option)) : -1;
461
+ return matchedOptionIndex > -1 ? matchedOptionIndex + index + 1 : index;
462
+ },
463
+ findPrevOptionIndex(index) {
464
+ const matchedOptionIndex = index > 0 ? utils.ObjectUtils.findLastIndex(this.visibleOptions.slice(0, index), option => this.isValidOption(option)) : -1;
465
+ return matchedOptionIndex > -1 ? matchedOptionIndex : index;
466
+ },
467
+ findFirstSelectedOptionIndex() {
468
+ return this.hasSelectedOption ? this.visibleOptions.findIndex(option => this.isValidSelectedOption(option)) : -1;
469
+ },
470
+ findLastSelectedOptionIndex() {
471
+ return this.hasSelectedOption ? utils.ObjectUtils.findLastIndex(this.visibleOptions, option => this.isValidSelectedOption(option)) : -1;
472
+ },
473
+ findNextSelectedOptionIndex(index) {
474
+ const matchedOptionIndex = this.hasSelectedOption && index < (this.visibleOptions.length - 1) ? this.visibleOptions.slice(index + 1).findIndex(option => this.isValidSelectedOption(option)) : -1;
475
+ return matchedOptionIndex > -1 ? matchedOptionIndex + index + 1 : -1;
476
+ },
477
+ findPrevSelectedOptionIndex(index) {
478
+ const matchedOptionIndex = this.hasSelectedOption && index > 0 ? utils.ObjectUtils.findLastIndex(this.visibleOptions.slice(0, index), option => this.isValidSelectedOption(option)) : -1;
479
+ return matchedOptionIndex > -1 ? matchedOptionIndex : -1;
480
+ },
481
+ findNearestSelectedOptionIndex(index, firstCheckUp = false) {
482
+ let matchedOptionIndex = -1;
203
483
 
204
- event.preventDefault();
205
- break;
484
+ if (this.hasSelectedOption) {
485
+ if (firstCheckUp) {
486
+ matchedOptionIndex = this.findPrevSelectedOptionIndex(index);
487
+ matchedOptionIndex = matchedOptionIndex === -1 ? this.findNextSelectedOptionIndex(index) : matchedOptionIndex;
488
+ }
489
+ else {
490
+ matchedOptionIndex = this.findNextSelectedOptionIndex(index);
491
+ matchedOptionIndex = matchedOptionIndex === -1 ? this.findPrevSelectedOptionIndex(index) : matchedOptionIndex;
492
+ }
493
+ }
206
494
 
207
- //up
208
- case 38:
209
- var prevItem = this.findPrevItem(item);
210
- if(prevItem) {
211
- prevItem.focus();
212
- }
495
+ return matchedOptionIndex > -1 ? matchedOptionIndex : index;
496
+ },
497
+ findFirstFocusedOptionIndex() {
498
+ const selectedIndex = this.findFirstSelectedOptionIndex();
499
+ return selectedIndex < 0 ? this.findFirstOptionIndex() : selectedIndex;
500
+ },
501
+ findLastFocusedOptionIndex() {
502
+ const selectedIndex = this.findLastSelectedOptionIndex();
503
+ return selectedIndex < 0 ? this.findLastOptionIndex() : selectedIndex;
504
+ },
505
+ searchOptions(event, char) {
506
+ this.searchValue = (this.searchValue || '') + char;
507
+
508
+ let optionIndex = -1;
509
+ if (this.focusedOptionIndex !== -1) {
510
+ optionIndex = this.visibleOptions.slice(this.focusedOptionIndex).findIndex(option => this.isOptionMatched(option));
511
+ optionIndex = optionIndex === -1 ? this.visibleOptions.slice(0, this.focusedOptionIndex).findIndex(option => this.isOptionMatched(option)) : optionIndex + this.focusedOptionIndex;
512
+ }
513
+ else {
514
+ optionIndex = this.visibleOptions.findIndex(option => this.isOptionMatched(option));
515
+ }
213
516
 
214
- event.preventDefault();
215
- break;
517
+ if (optionIndex === -1 && this.focusedOptionIndex === -1) {
518
+ optionIndex = this.findFirstFocusedOptionIndex();
519
+ }
216
520
 
217
- //enter
218
- case 13:
219
- this.onOptionSelect(event, option);
220
- event.preventDefault();
221
- break;
521
+ if (optionIndex !== -1) {
522
+ this.changeFocusedOptionIndex(event, optionIndex);
222
523
  }
524
+
525
+ if (this.searchTimeout) {
526
+ clearTimeout(this.searchTimeout);
527
+ }
528
+
529
+ this.searchTimeout = setTimeout(() => {
530
+ this.searchValue = '';
531
+ this.searchTimeout = null;
532
+ }, 500);
533
+ },
534
+ removeOption(option) {
535
+ return this.modelValue.filter(val => !utils.ObjectUtils.equals(val, this.getOptionValue(option), this.equalityKey));
223
536
  },
224
- findNextItem(item) {
225
- let nextItem = item.nextElementSibling;
537
+ changeFocusedOptionIndex(event, index) {
538
+ if (this.focusedOptionIndex !== index) {
539
+ this.focusedOptionIndex = index;
540
+ this.scrollInView();
226
541
 
227
- if (nextItem)
228
- return utils.DomHandler.hasClass(nextItem, 'p-disabled') || utils.DomHandler.hasClass(nextItem, 'p-listbox-item-group') ? this.findNextItem(nextItem) : nextItem;
229
- else
230
- return null;
542
+ if (this.selectOnFocus && !this.multiple) {
543
+ this.updateModel(event, this.getOptionValue(this.visibleOptions[index]));
544
+ }
545
+ }
546
+ },
547
+ scrollInView(index = -1) {
548
+ const id = index !== -1 ? `${this.id}_${index}` : this.focusedOptionId;
549
+ const element = utils.DomHandler.findSingle(this.list, `li[id="${id}"]`);
550
+ if (element) {
551
+ element.scrollIntoView && element.scrollIntoView({ block: 'nearest', inline: 'nearest' });
552
+ }
553
+ else if (!this.virtualScrollerDisabled) {
554
+ this.virtualScroller && this.virtualScroller.scrollToIndex(index !== -1 ? index : this.focusedOptionIndex);
555
+ }
556
+ },
557
+ autoUpdateModel() {
558
+ if (this.selectOnFocus && this.autoOptionFocus && !this.hasSelectedOption) {
559
+ this.focusedOptionIndex = this.findFirstFocusedOptionIndex();
560
+ const value = this.getOptionValue(this.visibleOptions[this.focusedOptionIndex]);
561
+ this.updateModel(null, this.multiple ? [value] : value);
562
+ }
563
+ },
564
+ updateModel(event, value) {
565
+ this.$emit('update:modelValue', value);
566
+ this.$emit('change', { originalEvent: event, value });
231
567
  },
232
- findPrevItem(item) {
233
- let prevItem = item.previousElementSibling;
568
+ flatOptions(options) {
569
+ return (options || []).reduce((result, option, index) => {
570
+ result.push({ optionGroup: option, group: true, index });
234
571
 
235
- if (prevItem)
236
- return utils.DomHandler.hasClass(prevItem, 'p-disabled') || utils.DomHandler.hasClass(prevItem, 'p-listbox-item-group') ? this.findPrevItem(prevItem) : prevItem;
237
- else
238
- return null;
572
+ const optionGroupChildren = this.getOptionGroupChildren(option);
573
+ optionGroupChildren && optionGroupChildren.forEach(o => result.push(o));
574
+
575
+ return result;
576
+ }, []);
239
577
  },
240
- onFilterChange(event) {
241
- this.$emit('filter', {originalEvent: event, value: event.target.value});
578
+ listRef(el, contentRef) {
579
+ this.list = el;
580
+ contentRef && contentRef(el); // For VirtualScroller
242
581
  },
243
582
  virtualScrollerRef(el) {
244
583
  this.virtualScroller = el;
245
584
  }
246
585
  },
247
586
  computed: {
587
+ containerClass() {
588
+ return ['p-listbox p-component', {
589
+ 'p-focus': this.focused,
590
+ 'p-disabled': this.disabled
591
+ }];
592
+ },
248
593
  visibleOptions() {
249
- if (this.filterValue) {
250
- if (this.optionGroupLabel) {
251
- let filteredGroups = [];
252
- for (let optgroup of this.options) {
253
- let filteredSubOptions = api.FilterService.filter(this.getOptionGroupChildren(optgroup), this.searchFields, this.filterValue, this.filterMatchMode, this.filterLocale);
254
- if (filteredSubOptions && filteredSubOptions.length) {
255
- filteredGroups.push({...optgroup, ...{items: filteredSubOptions}});
256
- }
257
- }
258
- return filteredGroups
259
- }
260
- else {
261
- return api.FilterService.filter(this.options, this.searchFields, this.filterValue, 'contains', this.filterLocale);
262
- }
263
- }
264
- else {
265
- return this.options;
266
- }
594
+ const options = this.optionGroupLabel ? this.flatOptions(this.options) : (this.options || []);
595
+
596
+ return this.filterValue ? api.FilterService.filter(options, this.searchFields, this.filterValue, this.filterMatchMode, this.filterLocale) : options;
597
+ },
598
+ hasSelectedOption() {
599
+ return utils.ObjectUtils.isNotEmpty(this.modelValue);
267
600
  },
268
601
  equalityKey() {
269
602
  return this.optionValue ? null : this.dataKey;
@@ -271,11 +604,32 @@ this.primevue.listbox = (function (utils, api, Ripple, VirtualScroller, vue) {
271
604
  searchFields() {
272
605
  return this.filterFields || [this.optionLabel];
273
606
  },
607
+ filterResultMessageText() {
608
+ return utils.ObjectUtils.isNotEmpty(this.visibleOptions) ? this.filterMessageText.replaceAll('{0}', this.visibleOptions.length) : this.emptyFilterMessageText;
609
+ },
610
+ filterMessageText() {
611
+ return this.filterMessage || this.$primevue.config.locale.searchMessage || '';
612
+ },
274
613
  emptyFilterMessageText() {
275
- return this.emptyFilterMessage || this.$primevue.config.locale.emptyFilterMessage;
614
+ return this.emptyFilterMessage || this.$primevue.config.locale.emptySearchMessage || this.$primevue.config.locale.emptyFilterMessage || '';
276
615
  },
277
616
  emptyMessageText() {
278
- return this.emptyMessage || this.$primevue.config.locale.emptyMessage;
617
+ return this.emptyMessage || this.$primevue.config.locale.emptyMessage || '';
618
+ },
619
+ selectionMessageText() {
620
+ return this.selectionMessage || this.$primevue.config.locale.selectionMessage || '';
621
+ },
622
+ emptySelectionMessageText() {
623
+ return this.emptySelectionMessage || this.$primevue.config.locale.emptySelectionMessage || '';
624
+ },
625
+ selectedMessageText() {
626
+ return this.hasSelectedOption ? this.selectionMessageText.replaceAll('{0}', this.multiple ? this.modelValue.length : '1') : this.emptySelectionMessageText;
627
+ },
628
+ focusedOptionId() {
629
+ return this.focusedOptionIndex !== -1 ? `${this.id}_${this.focusedOptionIndex}` : null;
630
+ },
631
+ ariaSetSize() {
632
+ return this.visibleOptions.filter(option => !this.isOptionGroup(option)).length;
279
633
  },
280
634
  virtualScrollerDisabled() {
281
635
  return !this.virtualScrollerOptions;
@@ -289,141 +643,183 @@ this.primevue.listbox = (function (utils, api, Ripple, VirtualScroller, vue) {
289
643
  }
290
644
  };
291
645
 
292
- const _hoisted_1 = { class: "p-listbox p-component" };
293
- const _hoisted_2 = {
646
+ const _hoisted_1 = ["id"];
647
+ const _hoisted_2 = ["tabindex"];
648
+ const _hoisted_3 = {
294
649
  key: 0,
295
650
  class: "p-listbox-header"
296
651
  };
297
- const _hoisted_3 = { class: "p-listbox-filter-container" };
298
- const _hoisted_4 = ["placeholder"];
299
- const _hoisted_5 = /*#__PURE__*/vue.createElementVNode("span", { class: "p-listbox-filter-icon pi pi-search" }, null, -1);
300
- const _hoisted_6 = ["tabindex", "onClick", "onKeydown", "aria-label", "aria-selected"];
301
- const _hoisted_7 = { class: "p-listbox-item-group" };
302
- const _hoisted_8 = ["tabindex", "onClick", "onKeydown", "aria-label", "aria-selected"];
303
- const _hoisted_9 = {
304
- key: 2,
305
- class: "p-listbox-empty-message"
652
+ const _hoisted_4 = { class: "p-listbox-filter-container" };
653
+ const _hoisted_5 = ["placeholder", "aria-owns", "aria-activedescendant", "tabindex"];
654
+ const _hoisted_6 = /*#__PURE__*/vue.createElementVNode("span", { class: "p-listbox-filter-icon pi pi-search" }, null, -1);
655
+ const _hoisted_7 = {
656
+ role: "status",
657
+ "aria-live": "polite",
658
+ class: "p-hidden-accessible"
306
659
  };
307
- const _hoisted_10 = {
308
- key: 3,
309
- class: "p-listbox-empty-message"
660
+ const _hoisted_8 = ["id", "aria-multiselectable", "aria-label", "aria-labelledby", "aria-activedescendant", "aria-disabled"];
661
+ const _hoisted_9 = ["id"];
662
+ const _hoisted_10 = ["id", "aria-label", "aria-selected", "aria-disabled", "aria-setsize", "aria-posinset", "onClick", "onMousemove"];
663
+ const _hoisted_11 = {
664
+ key: 0,
665
+ class: "p-listbox-empty-message",
666
+ role: "option"
667
+ };
668
+ const _hoisted_12 = {
669
+ key: 1,
670
+ class: "p-listbox-empty-message",
671
+ role: "option"
672
+ };
673
+ const _hoisted_13 = {
674
+ key: 0,
675
+ role: "status",
676
+ "aria-live": "polite",
677
+ class: "p-hidden-accessible"
678
+ };
679
+ const _hoisted_14 = {
680
+ role: "status",
681
+ "aria-live": "polite",
682
+ class: "p-hidden-accessible"
310
683
  };
684
+ const _hoisted_15 = ["tabindex"];
311
685
 
312
686
  function render(_ctx, _cache, $props, $setup, $data, $options) {
313
687
  const _component_VirtualScroller = vue.resolveComponent("VirtualScroller");
314
688
  const _directive_ripple = vue.resolveDirective("ripple");
315
689
 
316
- return (vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
690
+ return (vue.openBlock(), vue.createElementBlock("div", {
691
+ id: $data.id,
692
+ class: vue.normalizeClass($options.containerClass),
693
+ onFocusout: _cache[10] || (_cache[10] = (...args) => ($options.onFocusout && $options.onFocusout(...args)))
694
+ }, [
695
+ vue.createElementVNode("span", {
696
+ ref: "firstHiddenFocusableElement",
697
+ role: "presentation",
698
+ "aria-hidden": "true",
699
+ class: "p-hidden-accessible p-hidden-focusable",
700
+ tabindex: !$props.disabled ? $props.tabindex : -1,
701
+ onFocus: _cache[0] || (_cache[0] = (...args) => ($options.onFirstHiddenFocus && $options.onFirstHiddenFocus(...args)))
702
+ }, null, 40, _hoisted_2),
317
703
  vue.renderSlot(_ctx.$slots, "header", {
318
704
  value: $props.modelValue,
319
705
  options: $options.visibleOptions
320
706
  }),
321
707
  ($props.filter)
322
- ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2, [
323
- vue.createElementVNode("div", _hoisted_3, [
324
- vue.withDirectives(vue.createElementVNode("input", {
708
+ ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3, [
709
+ vue.createElementVNode("div", _hoisted_4, [
710
+ vue.withDirectives(vue.createElementVNode("input", vue.mergeProps({
711
+ ref: "filterInput",
325
712
  type: "text",
326
713
  class: "p-listbox-filter p-inputtext p-component",
327
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (($data.filterValue) = $event)),
714
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = $event => (($data.filterValue) = $event)),
328
715
  placeholder: $props.filterPlaceholder,
329
- onInput: _cache[1] || (_cache[1] = (...args) => ($options.onFilterChange && $options.onFilterChange(...args)))
330
- }, null, 40, _hoisted_4), [
716
+ role: "searchbox",
717
+ autocomplete: "off",
718
+ "aria-owns": $data.id + '_list',
719
+ "aria-activedescendant": $options.focusedOptionId,
720
+ tabindex: !$props.disabled && !$data.focused ? $props.tabindex : -1,
721
+ onInput: _cache[2] || (_cache[2] = (...args) => ($options.onFilterChange && $options.onFilterChange(...args))),
722
+ onBlur: _cache[3] || (_cache[3] = (...args) => ($options.onFilterBlur && $options.onFilterBlur(...args))),
723
+ onKeydown: _cache[4] || (_cache[4] = (...args) => ($options.onFilterKeyDown && $options.onFilterKeyDown(...args)))
724
+ }, $props.filterInputProps), null, 16, _hoisted_5), [
331
725
  [vue.vModelText, $data.filterValue]
332
726
  ]),
333
- _hoisted_5
334
- ])
727
+ _hoisted_6
728
+ ]),
729
+ vue.createElementVNode("span", _hoisted_7, vue.toDisplayString($options.filterResultMessageText), 1)
335
730
  ]))
336
731
  : vue.createCommentVNode("", true),
337
732
  vue.createElementVNode("div", {
733
+ ref: "listWrapper",
338
734
  class: "p-listbox-list-wrapper",
339
735
  style: vue.normalizeStyle($props.listStyle)
340
736
  }, [
341
737
  vue.createVNode(_component_VirtualScroller, vue.mergeProps({ ref: $options.virtualScrollerRef }, $props.virtualScrollerOptions, {
342
738
  style: $props.listStyle,
343
739
  items: $options.visibleOptions,
740
+ tabindex: -1,
344
741
  disabled: $options.virtualScrollerDisabled
345
742
  }), vue.createSlots({
346
- content: vue.withCtx(({ styleClass, contentRef, items, getItemOptions, contentStyle }) => [
743
+ content: vue.withCtx(({ styleClass, contentRef, items, getItemOptions, contentStyle, itemSize }) => [
347
744
  vue.createElementVNode("ul", {
348
- ref: contentRef,
745
+ ref: (el) => $options.listRef(el, contentRef),
746
+ id: $data.id + '_list',
349
747
  class: vue.normalizeClass(['p-listbox-list', styleClass]),
350
748
  style: vue.normalizeStyle(contentStyle),
749
+ tabindex: -1,
351
750
  role: "listbox",
352
- "aria-multiselectable": "multiple"
751
+ "aria-multiselectable": $props.multiple,
752
+ "aria-label": _ctx.ariaLabel,
753
+ "aria-labelledby": _ctx.ariaLabelledby,
754
+ "aria-activedescendant": $data.focused ? $options.focusedOptionId : undefined,
755
+ "aria-disabled": $props.disabled,
756
+ onFocus: _cache[6] || (_cache[6] = (...args) => ($options.onListFocus && $options.onListFocus(...args))),
757
+ onBlur: _cache[7] || (_cache[7] = (...args) => ($options.onListBlur && $options.onListBlur(...args))),
758
+ onKeydown: _cache[8] || (_cache[8] = (...args) => ($options.onListKeyDown && $options.onListKeyDown(...args)))
353
759
  }, [
354
- (!$props.optionGroupLabel)
355
- ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 0 }, vue.renderList(items, (option, i) => {
356
- return vue.withDirectives((vue.openBlock(), vue.createElementBlock("li", {
357
- tabindex: $options.isOptionDisabled(option) ? null : '0',
358
- class: vue.normalizeClass(['p-listbox-item', {'p-highlight': $options.isSelected(option), 'p-disabled': $options.isOptionDisabled(option)}]),
359
- key: $options.getOptionRenderKey(option),
360
- onClick: $event => ($options.onOptionSelect($event, option)),
361
- onTouchend: _cache[2] || (_cache[2] = $event => ($options.onOptionTouchEnd())),
362
- onKeydown: $event => ($options.onOptionKeyDown($event, option)),
363
- role: "option",
364
- "aria-label": $options.getOptionLabel(option),
365
- "aria-selected": $options.isSelected(option)
366
- }, [
367
- vue.renderSlot(_ctx.$slots, "option", {
368
- option: option,
369
- index: $options.getOptionIndex(i, getItemOptions)
370
- }, () => [
371
- vue.createTextVNode(vue.toDisplayString($options.getOptionLabel(option)), 1)
372
- ])
373
- ], 42, _hoisted_6)), [
374
- [_directive_ripple]
375
- ])
376
- }), 128))
377
- : (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 1 }, vue.renderList(items, (optionGroup, i) => {
378
- return (vue.openBlock(), vue.createElementBlock(vue.Fragment, {
379
- key: $options.getOptionGroupRenderKey(optionGroup)
380
- }, [
381
- vue.createElementVNode("li", _hoisted_7, [
760
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(items, (option, i) => {
761
+ return (vue.openBlock(), vue.createElementBlock(vue.Fragment, {
762
+ key: $options.getOptionRenderKey(option, $options.getOptionIndex(i, getItemOptions))
763
+ }, [
764
+ ($options.isOptionGroup(option))
765
+ ? (vue.openBlock(), vue.createElementBlock("li", {
766
+ key: 0,
767
+ id: $data.id + '_' + $options.getOptionIndex(i, getItemOptions),
768
+ style: vue.normalizeStyle({height: itemSize ? itemSize + 'px' : undefined}),
769
+ class: "p-listbox-item-group",
770
+ role: "option"
771
+ }, [
382
772
  vue.renderSlot(_ctx.$slots, "optiongroup", {
383
- option: optionGroup,
773
+ option: option.optionGroup,
384
774
  index: $options.getOptionIndex(i, getItemOptions)
385
775
  }, () => [
386
- vue.createTextVNode(vue.toDisplayString($options.getOptionGroupLabel(optionGroup)), 1)
776
+ vue.createTextVNode(vue.toDisplayString($options.getOptionGroupLabel(option.optionGroup)), 1)
387
777
  ])
388
- ]),
389
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList($options.getOptionGroupChildren(optionGroup), (option, i) => {
390
- return vue.withDirectives((vue.openBlock(), vue.createElementBlock("li", {
391
- tabindex: $options.isOptionDisabled(option) ? null : '0',
392
- class: vue.normalizeClass(['p-listbox-item', {'p-highlight': $options.isSelected(option), 'p-disabled': $options.isOptionDisabled(option)}]),
393
- key: $options.getOptionRenderKey(option),
394
- onClick: $event => ($options.onOptionSelect($event, option)),
395
- onTouchend: _cache[3] || (_cache[3] = $event => ($options.onOptionTouchEnd())),
396
- onKeydown: $event => ($options.onOptionKeyDown($event, option)),
397
- role: "option",
398
- "aria-label": $options.getOptionLabel(option),
399
- "aria-selected": $options.isSelected(option)
400
- }, [
401
- vue.renderSlot(_ctx.$slots, "option", {
402
- option: option,
403
- index: $options.getOptionIndex(i, getItemOptions)
404
- }, () => [
405
- vue.createTextVNode(vue.toDisplayString($options.getOptionLabel(option)), 1)
406
- ])
407
- ], 42, _hoisted_8)), [
408
- [_directive_ripple]
778
+ ], 12, _hoisted_9))
779
+ : vue.withDirectives((vue.openBlock(), vue.createElementBlock("li", {
780
+ key: 1,
781
+ id: $data.id + '_' + $options.getOptionIndex(i, getItemOptions),
782
+ style: vue.normalizeStyle({height: itemSize ? itemSize + 'px' : undefined}),
783
+ class: vue.normalizeClass(['p-listbox-item', {'p-highlight': $options.isSelected(option), 'p-focus': $data.focusedOptionIndex === $options.getOptionIndex(i, getItemOptions), 'p-disabled': $options.isOptionDisabled(option)}]),
784
+ role: "option",
785
+ "aria-label": $options.getOptionLabel(option),
786
+ "aria-selected": $options.isSelected(option),
787
+ "aria-disabled": $options.isOptionDisabled(option),
788
+ "aria-setsize": $options.ariaSetSize,
789
+ "aria-posinset": $options.getAriaPosInset($options.getOptionIndex(i, getItemOptions)),
790
+ onClick: $event => ($options.onOptionSelect($event, option, $options.getOptionIndex(i, getItemOptions))),
791
+ onMousemove: $event => ($options.onOptionMouseMove($event, $options.getOptionIndex(i, getItemOptions))),
792
+ onTouchend: _cache[5] || (_cache[5] = $event => ($options.onOptionTouchEnd()))
793
+ }, [
794
+ vue.renderSlot(_ctx.$slots, "option", {
795
+ option: option,
796
+ index: $options.getOptionIndex(i, getItemOptions)
797
+ }, () => [
798
+ vue.createTextVNode(vue.toDisplayString($options.getOptionLabel(option)), 1)
409
799
  ])
410
- }), 128))
411
- ], 64))
412
- }), 128)),
800
+ ], 46, _hoisted_10)), [
801
+ [_directive_ripple]
802
+ ])
803
+ ], 64))
804
+ }), 128)),
413
805
  ($data.filterValue && (!items || (items && items.length === 0)))
414
- ? (vue.openBlock(), vue.createElementBlock("li", _hoisted_9, [
806
+ ? (vue.openBlock(), vue.createElementBlock("li", _hoisted_11, [
415
807
  vue.renderSlot(_ctx.$slots, "emptyfilter", {}, () => [
416
808
  vue.createTextVNode(vue.toDisplayString($options.emptyFilterMessageText), 1)
417
809
  ])
418
810
  ]))
419
811
  : ((!$props.options || ($props.options && $props.options.length === 0)))
420
- ? (vue.openBlock(), vue.createElementBlock("li", _hoisted_10, [
812
+ ? (vue.openBlock(), vue.createElementBlock("li", _hoisted_12, [
421
813
  vue.renderSlot(_ctx.$slots, "empty", {}, () => [
422
814
  vue.createTextVNode(vue.toDisplayString($options.emptyMessageText), 1)
423
815
  ])
424
816
  ]))
425
817
  : vue.createCommentVNode("", true)
426
- ], 6)
818
+ ], 46, _hoisted_8),
819
+ ((!$props.options || ($props.options && $props.options.length === 0)))
820
+ ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_13, vue.toDisplayString($options.emptyMessageText), 1))
821
+ : vue.createCommentVNode("", true),
822
+ vue.createElementVNode("span", _hoisted_14, vue.toDisplayString($options.selectedMessageText), 1)
427
823
  ]),
428
824
  _: 2
429
825
  }, [
@@ -440,8 +836,16 @@ this.primevue.listbox = (function (utils, api, Ripple, VirtualScroller, vue) {
440
836
  vue.renderSlot(_ctx.$slots, "footer", {
441
837
  value: $props.modelValue,
442
838
  options: $options.visibleOptions
443
- })
444
- ]))
839
+ }),
840
+ vue.createElementVNode("span", {
841
+ ref: "lastHiddenFocusableElement",
842
+ role: "presentation",
843
+ "aria-hidden": "true",
844
+ class: "p-hidden-accessible p-hidden-focusable",
845
+ tabindex: !$props.disabled ? $props.tabindex : -1,
846
+ onFocus: _cache[9] || (_cache[9] = (...args) => ($options.onLastHiddenFocus && $options.onLastHiddenFocus(...args)))
847
+ }, null, 40, _hoisted_15)
848
+ ], 42, _hoisted_1))
445
849
  }
446
850
 
447
851
  function styleInject(css, ref) {