@sapudex/web-components 2.50.0 → 2.52.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 (380) hide show
  1. package/cypress/specs/CountrySelector.cy.tsx +21 -0
  2. package/cypress/specs/List.cy.tsx +119 -10
  3. package/cypress/specs/SelectBox.cy.tsx +414 -70
  4. package/dist/CountrySelector.js +1 -0
  5. package/dist/CountrySelector.js.map +1 -1
  6. package/dist/List.d.ts +10 -0
  7. package/dist/List.js +35 -0
  8. package/dist/List.js.map +1 -1
  9. package/dist/ListGroupHeaderBase.js +3 -0
  10. package/dist/ListGroupHeaderBase.js.map +1 -1
  11. package/dist/ListItem.d.ts +1 -0
  12. package/dist/ListItem.js +11 -3
  13. package/dist/ListItem.js.map +1 -1
  14. package/dist/ListItemBase.d.ts +9 -0
  15. package/dist/ListItemBase.js +12 -0
  16. package/dist/ListItemBase.js.map +1 -1
  17. package/dist/ListSelectAll.js +1 -1
  18. package/dist/ListSelectAll.js.map +1 -1
  19. package/dist/MessageStrip.d.ts +3 -0
  20. package/dist/MessageStrip.js +40 -8
  21. package/dist/MessageStrip.js.map +1 -1
  22. package/dist/Modal.d.ts +1 -0
  23. package/dist/Modal.js +7 -0
  24. package/dist/Modal.js.map +1 -1
  25. package/dist/SearchableListBase.d.ts +10 -0
  26. package/dist/SearchableListBase.js +29 -6
  27. package/dist/SearchableListBase.js.map +1 -1
  28. package/dist/SearchableListBaseTemplate.js +32 -5
  29. package/dist/SearchableListBaseTemplate.js.map +1 -1
  30. package/dist/SelectBase.d.ts +65 -1
  31. package/dist/SelectBase.js +446 -59
  32. package/dist/SelectBase.js.map +1 -1
  33. package/dist/SelectBox.js +24 -2
  34. package/dist/SelectBox.js.map +1 -1
  35. package/dist/SelectBoxTemplate.js +2 -2
  36. package/dist/SelectBoxTemplate.js.map +1 -1
  37. package/dist/assets/{InputSuggestions-DZR626c7.js → InputSuggestions-0wafO-g3.js} +1 -1
  38. package/dist/assets/{ListItemStandardExpandableTextTemplate-D_5VXMzU.js → ListItemStandardExpandableTextTemplate-DoOYtqI8.js} +1 -1
  39. package/dist/assets/{bundle.esm-DuQLY8Jz.js → bundle.esm-DwHZ3nCW.js} +316 -318
  40. package/dist/assets/messagebundle_ar-BRkfjlVF.js +1 -0
  41. package/dist/assets/messagebundle_ar-D5A573iZ.js +1 -0
  42. package/dist/assets/messagebundle_bg-ByA8yRlQ.js +1 -0
  43. package/dist/assets/messagebundle_bg-CIVFOczQ.js +1 -0
  44. package/dist/assets/messagebundle_ca-BR3XuU9o.js +1 -0
  45. package/dist/assets/messagebundle_ca-CnMQ87v0.js +1 -0
  46. package/dist/assets/messagebundle_cnr-C6YhRiS7.js +1 -0
  47. package/dist/assets/messagebundle_cnr-CKZii51E.js +1 -0
  48. package/dist/assets/messagebundle_cs-DcOu8IOK.js +1 -0
  49. package/dist/assets/messagebundle_cs-I7yYpbsI.js +1 -0
  50. package/dist/assets/messagebundle_cy-BxrFUGJ9.js +1 -0
  51. package/dist/assets/messagebundle_cy-iXD_sJ-H.js +1 -0
  52. package/dist/assets/messagebundle_da-BVQHPgwf.js +1 -0
  53. package/dist/assets/messagebundle_da-CMGObFa5.js +1 -0
  54. package/dist/assets/messagebundle_de-Ca8NttFO.js +1 -0
  55. package/dist/assets/messagebundle_el-Cqfj_U5v.js +1 -0
  56. package/dist/assets/messagebundle_el-D9Zgq5tn.js +1 -0
  57. package/dist/assets/messagebundle_en-D0JTZvAf.js +1 -0
  58. package/dist/assets/messagebundle_en-DWqF0cay.js +1 -0
  59. package/dist/assets/messagebundle_en_GB-CGB_FKp4.js +1 -0
  60. package/dist/assets/messagebundle_en_GB-Cl7ekzz2.js +1 -0
  61. package/dist/assets/messagebundle_en_US_sappsd-7UdOh8vN.js +1 -0
  62. package/dist/assets/messagebundle_en_US_sappsd-B8rqsyFQ.js +1 -0
  63. package/dist/assets/messagebundle_en_US_saprigi-9VCo5QY0.js +1 -0
  64. package/dist/assets/messagebundle_en_US_saprigi-DfLzOCPY.js +1 -0
  65. package/dist/assets/messagebundle_en_US_saptrc-DZqYka05.js +1 -0
  66. package/dist/assets/messagebundle_en_US_saptrc-Wh_IysAB.js +1 -0
  67. package/dist/assets/messagebundle_es-DKn8EzzP.js +1 -0
  68. package/dist/assets/messagebundle_es-lf5AJZNW.js +1 -0
  69. package/dist/assets/messagebundle_es_MX-DyYZGjON.js +1 -0
  70. package/dist/assets/messagebundle_es_MX-yBTcvu7u.js +1 -0
  71. package/dist/assets/messagebundle_et-Dz8Ohhcp.js +1 -0
  72. package/dist/assets/messagebundle_et-rMWbS-Nu.js +1 -0
  73. package/dist/assets/messagebundle_fi-Bfbyhuuz.js +1 -0
  74. package/dist/assets/messagebundle_fi-DnXm7LPH.js +1 -0
  75. package/dist/assets/messagebundle_fr-BvbeCfZ-.js +1 -0
  76. package/dist/assets/messagebundle_fr-KQhoZEew.js +1 -0
  77. package/dist/assets/messagebundle_fr_CA-CE2lzYx5.js +1 -0
  78. package/dist/assets/messagebundle_fr_CA-CIhDzHAJ.js +1 -0
  79. package/dist/assets/messagebundle_hi-BRQ9tZ6F.js +1 -0
  80. package/dist/assets/messagebundle_hi-DPwH9vag.js +1 -0
  81. package/dist/assets/messagebundle_hr-BSKQ6zHT.js +1 -0
  82. package/dist/assets/messagebundle_hr-D3gQg5JN.js +1 -0
  83. package/dist/assets/messagebundle_hu-CAA4oM1C.js +1 -0
  84. package/dist/assets/messagebundle_hu-CZNs1K9T.js +1 -0
  85. package/dist/assets/messagebundle_id-9H0uJyXB.js +1 -0
  86. package/dist/assets/messagebundle_id-m6iosVVP.js +1 -0
  87. package/dist/assets/messagebundle_it-BWzxa-Mi.js +1 -0
  88. package/dist/assets/messagebundle_it-Cm_0HF21.js +1 -0
  89. package/dist/assets/messagebundle_iw-DpB2YXTa.js +1 -0
  90. package/dist/assets/messagebundle_iw-NfqePNtD.js +1 -0
  91. package/dist/assets/messagebundle_ja-BCSZcI8t.js +1 -0
  92. package/dist/assets/messagebundle_ja-C-qqwzFf.js +1 -0
  93. package/dist/assets/messagebundle_kk--PGqyTVS.js +1 -0
  94. package/dist/assets/messagebundle_kk-DAlCQkFU.js +1 -0
  95. package/dist/assets/messagebundle_ko-D8mIkPe1.js +1 -0
  96. package/dist/assets/messagebundle_ko-qoWc4ZGG.js +1 -0
  97. package/dist/assets/messagebundle_lt-BIEH02V4.js +1 -0
  98. package/dist/assets/messagebundle_lt-ruMxSuY-.js +1 -0
  99. package/dist/assets/messagebundle_lv-C2om7wu0.js +1 -0
  100. package/dist/assets/messagebundle_lv-Dfrbh1ci.js +1 -0
  101. package/dist/assets/messagebundle_mk-DHvZle6t.js +1 -0
  102. package/dist/assets/messagebundle_mk-l_Kubx1p.js +1 -0
  103. package/dist/assets/messagebundle_ms-CKCmj1p_.js +1 -0
  104. package/dist/assets/messagebundle_ms-IhSEK5ij.js +1 -0
  105. package/dist/assets/messagebundle_nl-BKUpVV-D.js +1 -0
  106. package/dist/assets/messagebundle_nl-BiIb6e5c.js +1 -0
  107. package/dist/assets/messagebundle_nl-DquG38Cj.js +1 -0
  108. package/dist/assets/messagebundle_no-CX23v_jg.js +1 -0
  109. package/dist/assets/messagebundle_no-DFdvykvP.js +1 -0
  110. package/dist/assets/messagebundle_pl-BAeue3mo.js +1 -0
  111. package/dist/assets/messagebundle_pl-iHE_prgN.js +1 -0
  112. package/dist/assets/messagebundle_pt-BpQnTLvl.js +1 -0
  113. package/dist/assets/messagebundle_pt-C_bG3Erm.js +1 -0
  114. package/dist/assets/messagebundle_pt_PT-CR7qXFK-.js +1 -0
  115. package/dist/assets/messagebundle_pt_PT-DyseXKQQ.js +1 -0
  116. package/dist/assets/messagebundle_ro-CHU1E6hv.js +1 -0
  117. package/dist/assets/messagebundle_ro-C_amsd63.js +1 -0
  118. package/dist/assets/messagebundle_ru-Cab4H6Ud.js +1 -0
  119. package/dist/assets/messagebundle_ru-D6JMraBp.js +1 -0
  120. package/dist/assets/messagebundle_sh-DusYn00L.js +1 -0
  121. package/dist/assets/messagebundle_sh-hThvw_lF.js +1 -0
  122. package/dist/assets/messagebundle_sk-BqiUMEcX.js +1 -0
  123. package/dist/assets/messagebundle_sk-CZHfFNQ_.js +1 -0
  124. package/dist/assets/{messagebundle_sl-Bn5tocYe.js → messagebundle_sl-B79d3kfY.js} +1 -1
  125. package/dist/assets/messagebundle_sl-SfAn6n6j.js +1 -0
  126. package/dist/assets/messagebundle_sr-4iz7n4Te.js +1 -0
  127. package/dist/assets/messagebundle_sr-DxELdG62.js +1 -0
  128. package/dist/assets/messagebundle_sv-CPOHCrxs.js +1 -0
  129. package/dist/assets/messagebundle_sv-i6GuWK0l.js +1 -0
  130. package/dist/assets/messagebundle_th-D-kPI3tt.js +1 -0
  131. package/dist/assets/messagebundle_th-D64J-JvN.js +1 -0
  132. package/dist/assets/messagebundle_tr-CuE9DqZT.js +1 -0
  133. package/dist/assets/messagebundle_tr-gTuGftNt.js +1 -0
  134. package/dist/assets/messagebundle_uk-C6JSX-jF.js +1 -0
  135. package/dist/assets/messagebundle_uk-IKxyo-LT.js +1 -0
  136. package/dist/assets/messagebundle_vi-BRdRT5L6.js +1 -0
  137. package/dist/assets/messagebundle_vi-rZGL12-x.js +1 -0
  138. package/dist/assets/messagebundle_zh_CN-L55Y4Dfs.js +1 -0
  139. package/dist/assets/messagebundle_zh_CN-ZalS15WG.js +1 -0
  140. package/dist/assets/messagebundle_zh_TW-BcMzZCW2.js +1 -0
  141. package/dist/assets/messagebundle_zh_TW-sRVDBYOx.js +1 -0
  142. package/dist/assets/parameters-bundle.css-8pAQYERs.js +3 -0
  143. package/dist/assets/{parameters-bundle.css-Dd5ajhZR.js → parameters-bundle.css-BXQ-0CBp.js} +1 -12
  144. package/dist/assets/parameters-bundle.css-B_KvbSAR.js +2 -0
  145. package/dist/assets/{parameters-bundle.css-BVXLOlqR.js → parameters-bundle.css-Bleiw2gk.js} +1 -1
  146. package/dist/assets/{parameters-bundle.css-DH_wndOj.js → parameters-bundle.css-C3eDVARm.js} +1 -1
  147. package/dist/assets/parameters-bundle.css-C7KCPeJ8.js +3 -0
  148. package/dist/assets/{parameters-bundle.css-CWfGvXBZ.js → parameters-bundle.css-CCL9q8h_.js} +1 -1
  149. package/dist/assets/{parameters-bundle.css-BCB-2TTY.js → parameters-bundle.css-CDc9A-MF.js} +1 -1
  150. package/dist/assets/parameters-bundle.css-CLLnzh9T.js +3 -0
  151. package/dist/assets/parameters-bundle.css-CQFZmxYm.js +3 -0
  152. package/dist/assets/parameters-bundle.css-CSUOmZKr.js +3 -0
  153. package/dist/assets/{parameters-bundle.css-CKNWL0nG.js → parameters-bundle.css-CT-eTeTy.js} +1 -12
  154. package/dist/assets/parameters-bundle.css-Ciey0vhA.js +2 -0
  155. package/dist/assets/{parameters-bundle.css-DuHP0Q5Y.js → parameters-bundle.css-Cmk27zY9.js} +6 -9
  156. package/dist/assets/{parameters-bundle.css-yvuwi247.js → parameters-bundle.css-Cv89y49I.js} +1 -1
  157. package/dist/assets/{parameters-bundle.css-BQB0pxRT.js → parameters-bundle.css-Cx9nDxJ1.js} +1 -1
  158. package/dist/assets/{parameters-bundle.css-BBdTemt8.js → parameters-bundle.css-CxjtOlRD.js} +7 -10
  159. package/dist/assets/{parameters-bundle.css-DXuX1n-u.js → parameters-bundle.css-D6dc2la8.js} +1 -1
  160. package/dist/assets/parameters-bundle.css-D7Hj83QD.js +2 -0
  161. package/dist/assets/{parameters-bundle.css-BiSP-Gf0.js → parameters-bundle.css-D7WciSOr.js} +1 -12
  162. package/dist/assets/{parameters-bundle.css-tevTlrPX.js → parameters-bundle.css-D9YZOKyE.js} +1 -1
  163. package/dist/assets/{parameters-bundle.css-CTIq7sCI.js → parameters-bundle.css-DE8FUbIS.js} +1 -1
  164. package/dist/assets/parameters-bundle.css-DJgsxqD8.js +2 -0
  165. package/dist/assets/parameters-bundle.css-DMVuljH3.js +3 -0
  166. package/dist/assets/{parameters-bundle.css-1rRun2sT.js → parameters-bundle.css-DPz62M1p.js} +3 -14
  167. package/dist/assets/parameters-bundle.css-DkHyiuRq.js +3 -0
  168. package/dist/assets/parameters-bundle.css-Dvgwa73x.js +3 -0
  169. package/dist/assets/parameters-bundle.css-V2I5eOdH.js +3 -0
  170. package/dist/assets/{parameters-bundle.css-DUGC7SPT.js → parameters-bundle.css-XYDTPt-n.js} +1 -12
  171. package/dist/assets/{parameters-bundle.css-C90ijvPq.js → parameters-bundle.css-tmGa6wuH.js} +1 -1
  172. package/dist/css/themes/AccordionItem.css +1 -1
  173. package/dist/css/themes/Divider.css +1 -1
  174. package/dist/css/themes/Link.css +1 -1
  175. package/dist/css/themes/ListGroupHeader.css +1 -1
  176. package/dist/css/themes/ListItem.css +1 -1
  177. package/dist/css/themes/MastheadProfileMenu.css +1 -1
  178. package/dist/css/themes/MessageStrip.css +1 -1
  179. package/dist/css/themes/Modal.css +1 -1
  180. package/dist/css/themes/Search.css +1 -1
  181. package/dist/css/themes/SelectBase.css +1 -1
  182. package/dist/css/themes/SelectBox.css +1 -1
  183. package/dist/custom-elements-internal.json +9 -9
  184. package/dist/custom-elements.json +28 -9
  185. package/dist/generated/assets/i18n/messagebundle_nl.json +1 -1
  186. package/dist/generated/templates/ListTemplate.lit.js +1 -1
  187. package/dist/generated/templates/ListTemplate.lit.js.map +1 -1
  188. package/dist/generated/themes/AccordionItem.css.d.ts +1 -1
  189. package/dist/generated/themes/AccordionItem.css.js +1 -1
  190. package/dist/generated/themes/AccordionItem.css.js.map +1 -1
  191. package/dist/generated/themes/Divider.css.d.ts +1 -1
  192. package/dist/generated/themes/Divider.css.js +1 -1
  193. package/dist/generated/themes/Divider.css.js.map +1 -1
  194. package/dist/generated/themes/Link.css.d.ts +1 -1
  195. package/dist/generated/themes/Link.css.js +1 -1
  196. package/dist/generated/themes/Link.css.js.map +1 -1
  197. package/dist/generated/themes/ListGroupHeader.css.d.ts +1 -1
  198. package/dist/generated/themes/ListGroupHeader.css.js +1 -1
  199. package/dist/generated/themes/ListGroupHeader.css.js.map +1 -1
  200. package/dist/generated/themes/ListItem.css.d.ts +1 -1
  201. package/dist/generated/themes/ListItem.css.js +1 -1
  202. package/dist/generated/themes/ListItem.css.js.map +1 -1
  203. package/dist/generated/themes/MastheadProfileMenu.css.d.ts +1 -1
  204. package/dist/generated/themes/MastheadProfileMenu.css.js +1 -1
  205. package/dist/generated/themes/MastheadProfileMenu.css.js.map +1 -1
  206. package/dist/generated/themes/MessageStrip.css.d.ts +1 -1
  207. package/dist/generated/themes/MessageStrip.css.js +1 -1
  208. package/dist/generated/themes/MessageStrip.css.js.map +1 -1
  209. package/dist/generated/themes/Modal.css.d.ts +1 -1
  210. package/dist/generated/themes/Modal.css.js +1 -1
  211. package/dist/generated/themes/Modal.css.js.map +1 -1
  212. package/dist/generated/themes/Search.css.d.ts +1 -1
  213. package/dist/generated/themes/Search.css.js +1 -1
  214. package/dist/generated/themes/Search.css.js.map +1 -1
  215. package/dist/generated/themes/SelectBase.css.d.ts +1 -1
  216. package/dist/generated/themes/SelectBase.css.js +1 -1
  217. package/dist/generated/themes/SelectBase.css.js.map +1 -1
  218. package/dist/generated/themes/SelectBox.css.d.ts +1 -1
  219. package/dist/generated/themes/SelectBox.css.js +1 -1
  220. package/dist/generated/themes/SelectBox.css.js.map +1 -1
  221. package/dist/messagebundle_nl.properties +126 -0
  222. package/dist/types/MessageStrip.d.ts +22 -1
  223. package/dist/types/MessageStrip.js +21 -0
  224. package/dist/types/MessageStrip.js.map +1 -1
  225. package/dist/vscode.html-custom-data.json +13 -2
  226. package/dist/web-types.json +5 -5
  227. package/package.json +8 -8
  228. package/src/CountrySelector.ts +1 -0
  229. package/src/List.hbs +2 -1
  230. package/src/List.ts +36 -0
  231. package/src/ListGroupHeaderBase.ts +3 -0
  232. package/src/ListItem.ts +12 -3
  233. package/src/ListItemBase.ts +11 -0
  234. package/src/ListSelectAll.ts +1 -1
  235. package/src/MessageStrip.ts +41 -9
  236. package/src/Modal.ts +8 -0
  237. package/src/SearchableListBase.ts +31 -8
  238. package/src/SearchableListBaseTemplate.tsx +38 -6
  239. package/src/SelectBase.ts +466 -69
  240. package/src/SelectBox.ts +27 -2
  241. package/src/SelectBoxTemplate.tsx +4 -3
  242. package/src/generated/templates/ListTemplate.lit.ts +1 -1
  243. package/src/generated/themes/AccordionItem.css.ts +1 -1
  244. package/src/generated/themes/Divider.css.ts +1 -1
  245. package/src/generated/themes/Link.css.ts +1 -1
  246. package/src/generated/themes/ListGroupHeader.css.ts +1 -1
  247. package/src/generated/themes/ListItem.css.ts +1 -1
  248. package/src/generated/themes/MastheadProfileMenu.css.ts +1 -1
  249. package/src/generated/themes/MessageStrip.css.ts +1 -1
  250. package/src/generated/themes/Modal.css.ts +1 -1
  251. package/src/generated/themes/Search.css.ts +1 -1
  252. package/src/generated/themes/SelectBase.css.ts +1 -1
  253. package/src/generated/themes/SelectBox.css.ts +1 -1
  254. package/src/i18n/messagebundle_nl.properties +126 -0
  255. package/src/themes/AccordionItem.css +8 -3
  256. package/src/themes/Divider.css +2 -0
  257. package/src/themes/Link.css +20 -2
  258. package/src/themes/ListGroupHeader.css +18 -1
  259. package/src/themes/ListItem.css +2 -1
  260. package/src/themes/MastheadProfileMenu.css +0 -4
  261. package/src/themes/MessageStrip.css +384 -10
  262. package/src/themes/Modal.css +2 -2
  263. package/src/themes/Search.css +6 -4
  264. package/src/themes/SelectBase.css +2 -1
  265. package/src/themes/SelectBox.css +10 -0
  266. package/src/types/MessageStrip.ts +21 -0
  267. package/dist/assets/messagebundle_ar-DcH18L3h.js +0 -1
  268. package/dist/assets/messagebundle_ar-Ic4ckTUt.js +0 -1
  269. package/dist/assets/messagebundle_bg-BOgOglXh.js +0 -1
  270. package/dist/assets/messagebundle_bg-dZrlFeKZ.js +0 -1
  271. package/dist/assets/messagebundle_ca-2bFyG5Ty.js +0 -1
  272. package/dist/assets/messagebundle_ca-B2inwHsb.js +0 -1
  273. package/dist/assets/messagebundle_cnr-CSmWG9_V.js +0 -1
  274. package/dist/assets/messagebundle_cnr-DZsc1R1r.js +0 -1
  275. package/dist/assets/messagebundle_cs-BZXuIszN.js +0 -1
  276. package/dist/assets/messagebundle_cs-Dso9kSig.js +0 -1
  277. package/dist/assets/messagebundle_cy-B66O9oBx.js +0 -1
  278. package/dist/assets/messagebundle_cy-BSiMgZtA.js +0 -1
  279. package/dist/assets/messagebundle_da-CAPY9nnT.js +0 -1
  280. package/dist/assets/messagebundle_da-DTOADw3Y.js +0 -1
  281. package/dist/assets/messagebundle_de-DWsuh-jj.js +0 -1
  282. package/dist/assets/messagebundle_el-ByL7ikpl.js +0 -1
  283. package/dist/assets/messagebundle_el-CwjQKEGb.js +0 -1
  284. package/dist/assets/messagebundle_en-4Wpx2jqf.js +0 -1
  285. package/dist/assets/messagebundle_en-Bi068VCa.js +0 -1
  286. package/dist/assets/messagebundle_en_GB-BEZ3LbT5.js +0 -1
  287. package/dist/assets/messagebundle_en_GB-DKEddq_J.js +0 -1
  288. package/dist/assets/messagebundle_en_US_sappsd-Bc-vQnEr.js +0 -1
  289. package/dist/assets/messagebundle_en_US_sappsd-CEGC_XRQ.js +0 -1
  290. package/dist/assets/messagebundle_en_US_saprigi--hAUIdWq.js +0 -1
  291. package/dist/assets/messagebundle_en_US_saprigi-C_gnMw05.js +0 -1
  292. package/dist/assets/messagebundle_en_US_saptrc-CIbQNg_d.js +0 -1
  293. package/dist/assets/messagebundle_en_US_saptrc-DY0WM5Yp.js +0 -1
  294. package/dist/assets/messagebundle_es-BHY_U2xi.js +0 -1
  295. package/dist/assets/messagebundle_es-vhzI0nML.js +0 -1
  296. package/dist/assets/messagebundle_es_MX-DjJ15Ns4.js +0 -1
  297. package/dist/assets/messagebundle_es_MX-DmINMi1e.js +0 -1
  298. package/dist/assets/messagebundle_et-CpVk1Xin.js +0 -1
  299. package/dist/assets/messagebundle_et-DLssZHh4.js +0 -1
  300. package/dist/assets/messagebundle_fi-DmGIB0sc.js +0 -1
  301. package/dist/assets/messagebundle_fi-YfxQ0aOR.js +0 -1
  302. package/dist/assets/messagebundle_fr-BFMaF4AX.js +0 -1
  303. package/dist/assets/messagebundle_fr-BZ-VJ002.js +0 -1
  304. package/dist/assets/messagebundle_fr_CA-B5jFryz1.js +0 -1
  305. package/dist/assets/messagebundle_fr_CA-hZ2LGeU2.js +0 -1
  306. package/dist/assets/messagebundle_hi-92qX3F1U.js +0 -1
  307. package/dist/assets/messagebundle_hi-DFXk6QGw.js +0 -1
  308. package/dist/assets/messagebundle_hr-CUaLQBjG.js +0 -1
  309. package/dist/assets/messagebundle_hr-selqadPV.js +0 -1
  310. package/dist/assets/messagebundle_hu-BtupF5BC.js +0 -1
  311. package/dist/assets/messagebundle_hu-D_rF_cCp.js +0 -1
  312. package/dist/assets/messagebundle_id-Bvmpblmf.js +0 -1
  313. package/dist/assets/messagebundle_id-P3JSHcmu.js +0 -1
  314. package/dist/assets/messagebundle_it-BINon06x.js +0 -1
  315. package/dist/assets/messagebundle_it-CXnIcrL4.js +0 -1
  316. package/dist/assets/messagebundle_iw-BzixLMjm.js +0 -1
  317. package/dist/assets/messagebundle_iw-Cb6M5XGj.js +0 -1
  318. package/dist/assets/messagebundle_ja-DQ5MCYLw.js +0 -1
  319. package/dist/assets/messagebundle_ja-J8eqPj7N.js +0 -1
  320. package/dist/assets/messagebundle_kk-BIeQLfxu.js +0 -1
  321. package/dist/assets/messagebundle_kk-DIOzUeHN.js +0 -1
  322. package/dist/assets/messagebundle_ko-B9_Ss1b5.js +0 -1
  323. package/dist/assets/messagebundle_ko-BLMVyKh5.js +0 -1
  324. package/dist/assets/messagebundle_lt-CbB2wq2X.js +0 -1
  325. package/dist/assets/messagebundle_lt-RzsUvi_1.js +0 -1
  326. package/dist/assets/messagebundle_lv-6quK3a4e.js +0 -1
  327. package/dist/assets/messagebundle_lv-BQO-79MM.js +0 -1
  328. package/dist/assets/messagebundle_mk-2lJhEAgI.js +0 -1
  329. package/dist/assets/messagebundle_mk-o-SATTof.js +0 -1
  330. package/dist/assets/messagebundle_ms-3Zupz0mA.js +0 -1
  331. package/dist/assets/messagebundle_ms-DnacCQys.js +0 -1
  332. package/dist/assets/messagebundle_nl-BVNQuB_K.js +0 -1
  333. package/dist/assets/messagebundle_nl-DTnHMKsv.js +0 -1
  334. package/dist/assets/messagebundle_nl-etaldyfo.js +0 -1
  335. package/dist/assets/messagebundle_no-BQMw-opH.js +0 -1
  336. package/dist/assets/messagebundle_no-OUP0Fraw.js +0 -1
  337. package/dist/assets/messagebundle_pl-BQW6qi8p.js +0 -1
  338. package/dist/assets/messagebundle_pl-PZiQh0Xy.js +0 -1
  339. package/dist/assets/messagebundle_pt-BlqCbnEN.js +0 -1
  340. package/dist/assets/messagebundle_pt-DEVzhHU_.js +0 -1
  341. package/dist/assets/messagebundle_pt_PT-BV1ec-3v.js +0 -1
  342. package/dist/assets/messagebundle_pt_PT-CL5hgi4Q.js +0 -1
  343. package/dist/assets/messagebundle_ro-D3lrScIy.js +0 -1
  344. package/dist/assets/messagebundle_ro-mHJ-r7ez.js +0 -1
  345. package/dist/assets/messagebundle_ru-BD3A7Zsx.js +0 -1
  346. package/dist/assets/messagebundle_ru-D7z2G7DP.js +0 -1
  347. package/dist/assets/messagebundle_sh-BoaW1EWP.js +0 -1
  348. package/dist/assets/messagebundle_sh-DXM15u1O.js +0 -1
  349. package/dist/assets/messagebundle_sk-Bjnhb-_D.js +0 -1
  350. package/dist/assets/messagebundle_sk-Clc7AaEc.js +0 -1
  351. package/dist/assets/messagebundle_sl-DJj-8V96.js +0 -1
  352. package/dist/assets/messagebundle_sr-Dsio4Srd.js +0 -1
  353. package/dist/assets/messagebundle_sr-w0tnyPzk.js +0 -1
  354. package/dist/assets/messagebundle_sv-B-KDauoz.js +0 -1
  355. package/dist/assets/messagebundle_sv-DCsGSCfn.js +0 -1
  356. package/dist/assets/messagebundle_th-D8qcTN_b.js +0 -1
  357. package/dist/assets/messagebundle_th-rPoqCsGu.js +0 -1
  358. package/dist/assets/messagebundle_tr-DIqpdL9d.js +0 -1
  359. package/dist/assets/messagebundle_tr-Dw7toCgs.js +0 -1
  360. package/dist/assets/messagebundle_uk-CycQpntH.js +0 -1
  361. package/dist/assets/messagebundle_uk-L4kmWPZY.js +0 -1
  362. package/dist/assets/messagebundle_vi-D1-iiI56.js +0 -1
  363. package/dist/assets/messagebundle_vi-wJJaYHj7.js +0 -1
  364. package/dist/assets/messagebundle_zh_CN-CIR_auXr.js +0 -1
  365. package/dist/assets/messagebundle_zh_CN-D3UfRQq7.js +0 -1
  366. package/dist/assets/messagebundle_zh_TW-CG9O1F7p.js +0 -1
  367. package/dist/assets/messagebundle_zh_TW-qc8ADbuf.js +0 -1
  368. package/dist/assets/parameters-bundle.css-BA_cQYjH.js +0 -2
  369. package/dist/assets/parameters-bundle.css-BBLk8nbD.js +0 -3
  370. package/dist/assets/parameters-bundle.css-B_rCq3Nc.js +0 -3
  371. package/dist/assets/parameters-bundle.css-CTw0R0y7.js +0 -2
  372. package/dist/assets/parameters-bundle.css-CV2FCAf_.js +0 -3
  373. package/dist/assets/parameters-bundle.css-CX7V5RGm.js +0 -3
  374. package/dist/assets/parameters-bundle.css-D9AHurfl.js +0 -2
  375. package/dist/assets/parameters-bundle.css-DENVM9pb.js +0 -3
  376. package/dist/assets/parameters-bundle.css-DHLZEUsz.js +0 -3
  377. package/dist/assets/parameters-bundle.css-DUAp19rB.js +0 -3
  378. package/dist/assets/parameters-bundle.css-Dp55UvXM.js +0 -3
  379. package/dist/assets/parameters-bundle.css-DpJfefgg.js +0 -3
  380. package/dist/assets/parameters-bundle.css-YNYQDxyY.js +0 -2
@@ -7,19 +7,21 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import property from "@ui5/webcomponents-base/dist/decorators/property.js";
8
8
  import slot from "@ui5/webcomponents-base/dist/decorators/slot-strict.js";
9
9
  import executeTemplate from "@ui5/webcomponents-base/dist/renderer/executeTemplate.js";
10
- import { isEscape, isDown, isUp, isHome, isEnd, isTabNext, isTabPrevious, isLeft, isRight, } from "@ui5/webcomponents-base/dist/Keys.js";
10
+ import { isEscape, isDown, isUp, isHome, isEnd, isTabNext, isTabPrevious, isLeft, isRight, isEnter, isSpace, } from "@ui5/webcomponents-base/dist/Keys.js";
11
11
  import { getAllAccessibleNameRefTexts } from "@ui5/webcomponents-base/dist/util/AccessibilityTextsHelper.js";
12
+ import { cleanLabel } from "./utils/listItemLabelUtils.js";
12
13
  import "@ui5/webcomponents-icons/dist/decline.js";
13
14
  import "@ui5/webcomponents-icons/dist/navigation-down-arrow.js";
14
- import { COUNTRY_SELECT, STARS } from "./generated/i18n/i18n-defaults.js";
15
+ import { COUNTRY_SELECT, STARS, SELECTED, UNSELECTED, INDETERMINATE, DISABLED, } from "./generated/i18n/i18n-defaults.js";
15
16
  import SearchableListBaseTemplate from "./SearchableListBaseTemplate.js";
16
17
  import CountrySelectorTemplate from "./CountrySelectorTemplate.js";
17
18
  import ResizeHandler from "@ui5/webcomponents-base/delegate/ResizeHandler.js";
18
19
  import UDExSearchableListBase from "./SearchableListBase.js";
19
20
  import UDExValueState from "./types/common.js";
20
- import { getTokensCountText } from "@ui5/webcomponents/dist/Tokenizer.js";
21
+ import Tokenizer, { getTokensCountText } from "@ui5/webcomponents/dist/Tokenizer.js";
21
22
  import isLetterKey from "./utils/isLetterKeyPressed.js";
22
23
  import translate from "./utils/translate.js";
24
+ import { renderFinished } from "@ui5/webcomponents-base/dist/Render.js";
23
25
  /**
24
26
  * @class
25
27
  *
@@ -52,6 +54,22 @@ class UDExSelectBase extends UDExSearchableListBase {
52
54
  * @private
53
55
  */
54
56
  this._requestRender = false;
57
+ /**
58
+ * True while keyboard list navigation is active (aria-activedescendant set).
59
+ * Used in CSS to suppress the input focus ring and show the active item ring.
60
+ *
61
+ * @private
62
+ */
63
+ this._navigating = false;
64
+ /**
65
+ * Text read by screen readers when the active item changes.
66
+ * Announced via an aria-live="assertive" region in the template.
67
+ * This works regardless of shadow DOM / popover teleportation because
68
+ * the live region lives inside SelectBox's own shadow root.
69
+ *
70
+ * @private
71
+ */
72
+ this._liveRegionText = "";
55
73
  this._paneWidthVariableName = "--udex-dropdown-pane-width";
56
74
  this._labelBaseClass = "udex-text-field__label";
57
75
  this._dropdownClass = "udex-select-box__dropdown";
@@ -62,6 +80,7 @@ class UDExSelectBase extends UDExSearchableListBase {
62
80
  this._inputValue = "";
63
81
  this._lastSelectedItemId = "";
64
82
  this._listKeyDownListenerAdded = false;
83
+ this._activeDescendantItem = null;
65
84
  this._handleResizeBound = this._handleResize.bind(this);
66
85
  this._handleListKeyDownBound = this._handleListKeyDownCapture.bind(this);
67
86
  }
@@ -84,6 +103,7 @@ class UDExSelectBase extends UDExSearchableListBase {
84
103
  }
85
104
  }
86
105
  onAfterRendering() {
106
+ super.onAfterRendering();
87
107
  this._popover = this.getPopover();
88
108
  this._search = this.getSearch();
89
109
  this._list = this.getList();
@@ -91,6 +111,10 @@ class UDExSelectBase extends UDExSearchableListBase {
91
111
  this.handleDirection();
92
112
  if (this._list) {
93
113
  this._list._scrollIntoView = "Nearest";
114
+ // Set a stable HTML id on the udex-list host so aria-controls can reference it.
115
+ if (!this._list.id) {
116
+ this._list.id = `${this._id}-list`;
117
+ }
94
118
  }
95
119
  if (this._requestRender) {
96
120
  this._requestRender = false;
@@ -103,6 +127,98 @@ class UDExSelectBase extends UDExSearchableListBase {
103
127
  _handleResize() {
104
128
  this.updatePopoverWidth();
105
129
  }
130
+ /**
131
+ * Given a candidate index, skips over a non-interactive non-collapsible header if needed.
132
+ * Returns the effective target index.
133
+ */
134
+ _skipNonInteractive(items, raw, lastIndex, direction) {
135
+ if (!items[raw]?.nonInteractive || items[raw].collapsible) {
136
+ return raw;
137
+ }
138
+ if (direction === "down") {
139
+ return raw + 1 > lastIndex ? 0 : raw + 1;
140
+ }
141
+ return raw === 0 ? lastIndex : raw - 1;
142
+ }
143
+ /**
144
+ * Sets or clears the aria-activedescendant on the combobox input and updates
145
+ * the aria-live region so JAWS/VoiceOver announce the item name and position.
146
+ * The live region is the primary announcement mechanism because aria-activedescendant
147
+ * across a UI5 Popover (which teleports content to document.body) is unreliable —
148
+ * screen readers cannot follow the ID reference across shadow root boundaries.
149
+ */
150
+ _setActiveDescendant(item, scroll = true) {
151
+ this._activeDescendantItem = item;
152
+ // Query the SelectBox's OWN shadow DOM for all elements bearing the class —
153
+ // this reaches the rendered udex-list-group-header / udex-list-item elements
154
+ // regardless of whether they are the current or a previously stale instance.
155
+ this.shadowRoot?.querySelectorAll("._udex-active-descendant")
156
+ .forEach(el => {
157
+ el.classList.remove("_udex-active-descendant");
158
+ el.removeAttribute("_active-descendant");
159
+ });
160
+ if (!item) {
161
+ this._search.removeAttribute("aria-activedescendant");
162
+ this._liveRegionText = "";
163
+ return;
164
+ }
165
+ item.classList.add("_udex-active-descendant");
166
+ item.setAttribute("_active-descendant", "");
167
+ this._search.setAttribute("aria-activedescendant", item._id);
168
+ // Update the live region with tree-aware position and state so JAWS/VoiceOver
169
+ // announce the active item regardless of whether the popover is teleported to document.body.
170
+ if (this._list) {
171
+ const label = cleanLabel(item.label ?? "");
172
+ const supporting = item.supportingText ? cleanLabel(item.supportingText) : "";
173
+ const stateParts = this._itemStateLabels(item);
174
+ const posText = this._treePositionText(item);
175
+ this._liveRegionText = [label, supporting, posText, ...stateParts].filter(Boolean).join(", ");
176
+ }
177
+ if (scroll && this._list?._scrollIntoView) {
178
+ // Only scroll if the item is not already fully visible in the dropdown.
179
+ const popoverContent = this._popover?.shadowRoot?.querySelector("[part=content]");
180
+ if (popoverContent) {
181
+ const itemRect = item.getBoundingClientRect();
182
+ const containerRect = popoverContent.getBoundingClientRect();
183
+ const isVisible = itemRect.top >= containerRect.top && itemRect.bottom <= containerRect.bottom;
184
+ if (!isVisible) {
185
+ this._list.scrollToItem(item);
186
+ }
187
+ }
188
+ else {
189
+ this._list.scrollToItem(item);
190
+ }
191
+ }
192
+ }
193
+ /**
194
+ * Activates the first navigable item as the aria-activedescendant without moving DOM focus.
195
+ */
196
+ _activateFirstItem() {
197
+ const items = this._list?.getKeyboardNavigationItems();
198
+ if (!items?.length) {
199
+ return;
200
+ }
201
+ const firstIndex = (items[0]?.nonInteractive && !items[0]?.collapsible) ? 1 : 0;
202
+ this._list.setTabIndexByIndex(items, firstIndex);
203
+ this._setActiveDescendant(items[firstIndex], false);
204
+ }
205
+ /**
206
+ * Navigates to the item at the given index, updating aria-activedescendant and _selectedOption.
207
+ */
208
+ _navigateToIndex(items, nextIndex) {
209
+ const currentIndex = this._activeDescendantItem
210
+ ? this._list.getCurrentIndex(items, this._activeDescendantItem)
211
+ : -1;
212
+ if (currentIndex >= 0) {
213
+ this._list.unsetTabIndexByIndex(items, currentIndex);
214
+ }
215
+ this._list.setTabIndexByIndex(items, nextIndex);
216
+ this._selectedOption = items[nextIndex].label;
217
+ if (this.showImageFlags) {
218
+ this.handleImagePosition(items, nextIndex);
219
+ }
220
+ this._setActiveDescendant(items[nextIndex]);
221
+ }
106
222
  handleKeyDownDropdown(e) {
107
223
  const items = this._list?.getKeyboardNavigationItems();
108
224
  if (isLetterKey(e.key)) {
@@ -153,39 +269,40 @@ class UDExSelectBase extends UDExSearchableListBase {
153
269
  if (!items) {
154
270
  return;
155
271
  }
156
- if (isRight(e)) {
272
+ if (isRight(e) || isLeft(e)) {
157
273
  e.preventDefault();
158
- if (this._handleGroupHeaderCollapse(e.target, false)) {
274
+ // Resolve the collapsible group header from the active descendant (not e.target,
275
+ // since DOM focus stays on the input and e.target is the input element).
276
+ const activeHeader = this._activeDescendantItem
277
+ ? this._resolveCollapsibleGroupHeader(this._activeDescendantItem)
278
+ : null;
279
+ if (activeHeader && this._handleGroupHeaderCollapse(activeHeader, isLeft(e))) {
159
280
  return;
160
281
  }
161
- this._handleArrowRightInRow(e.target);
162
- return;
163
- }
164
- if (isLeft(e)) {
165
- e.preventDefault();
166
- if (this._handleGroupHeaderCollapse(e.target, true)) {
167
- return;
282
+ // Fall through to icon-row navigation when focus is on an icon button
283
+ if (isRight(e)) {
284
+ this._handleArrowRightInRow(e.target);
285
+ }
286
+ else {
287
+ this._handleArrowLeftInRow(e.target);
168
288
  }
169
- this._handleArrowLeftInRow(e.target);
170
- return;
171
- }
172
- const iconSlot = this._getIconButtonSlot(e.target);
173
- const effectiveTarget = iconSlot
174
- ? e.target.parentElement
175
- : undefined;
176
- this.handleListNavigationKeys(e, items, effectiveTarget);
177
- }
178
- handleListNavigationKeys(e, items, effectiveTarget) {
179
- const currentSelectedIndex = this._list?.getCurrentIndex(items, effectiveTarget ?? e.target);
180
- const lastItemIndex = items.length - 1;
181
- if (isDown(e)) {
182
- e.preventDefault();
183
- this.handleDownKeyPress(items, currentSelectedIndex, lastItemIndex);
184
289
  return;
185
290
  }
186
- if (isUp(e)) {
291
+ if (isDown(e) || isUp(e)) {
187
292
  e.preventDefault();
188
- this.handleUpKeyPress(items, currentSelectedIndex, lastItemIndex);
293
+ const lastIndex = items.length - 1;
294
+ const currentItem = this._activeDescendantItem;
295
+ const currentIndex = currentItem ? this._list.getCurrentIndex(items, currentItem) : -1;
296
+ let nextIndex;
297
+ if (isDown(e)) {
298
+ const raw = currentIndex + 1 > lastIndex ? 0 : currentIndex + 1;
299
+ nextIndex = this._skipNonInteractive(items, raw, lastIndex, "down");
300
+ }
301
+ else {
302
+ const raw = currentIndex - 1 < 0 ? lastIndex : currentIndex - 1;
303
+ nextIndex = this._skipNonInteractive(items, raw, lastIndex, "up");
304
+ }
305
+ this._navigateToIndex(items, nextIndex);
189
306
  return;
190
307
  }
191
308
  if (isHome(e)) {
@@ -195,21 +312,17 @@ class UDExSelectBase extends UDExSearchableListBase {
195
312
  }
196
313
  if (isEnd(e)) {
197
314
  e.preventDefault();
198
- this.handleEndKeyPress(items, lastItemIndex);
315
+ this.handleEndKeyPress(items, items.length - 1);
199
316
  }
317
+ // Icon-button slot: Up/Down while an icon button is focused (handled by capture listener).
318
+ // _handleListKeyDownCapture fires first via capture; nothing else needed here.
200
319
  }
201
320
  handleEndKeyPress(items, lastItemIndex) {
202
- if (this.showImageFlags) {
203
- this.handleImagePosition(items, lastItemIndex);
204
- }
205
- this._selectedOption = items[lastItemIndex].label;
321
+ this._navigateToIndex(items, lastItemIndex);
206
322
  }
207
323
  handleHomeKeyPress(items) {
208
324
  const firstIndex = (items[0]?.nonInteractive && !items[0]?.collapsible) ? 1 : 0;
209
- this._selectedOption = items[firstIndex].label;
210
- if (this.showImageFlags) {
211
- this.handleImagePosition(items, firstIndex);
212
- }
325
+ this._navigateToIndex(items, firstIndex);
213
326
  }
214
327
  handleDownKeyPress(items, currentSelectedIndex, lastItemIndex) {
215
328
  const nextIndex = currentSelectedIndex + 1;
@@ -257,6 +370,7 @@ class UDExSelectBase extends UDExSearchableListBase {
257
370
  handleEscKeyPress(e) {
258
371
  e.preventDefault();
259
372
  e.stopPropagation();
373
+ this._setActiveDescendant(null);
260
374
  this.closeDropdown();
261
375
  this._search.focus();
262
376
  this._selectedOption = "";
@@ -267,9 +381,30 @@ class UDExSelectBase extends UDExSearchableListBase {
267
381
  this._lastSelectedItemId = this.getDataTokenId(item);
268
382
  this.resetSearchState();
269
383
  if (this.modeSingleSelect) {
384
+ // SingleSelect closes the dropdown — clear active descendant.
385
+ this._setActiveDescendant(null);
270
386
  this._search.focus();
271
387
  this.closeDropdown();
388
+ return;
272
389
  }
390
+ // MultiSelect: ensure active descendant tracks the interacted item so there
391
+ // is only one ring. Find the rendered item in the navigation list by matching
392
+ // data-token-id (the source item's _id set by the template) since e.detail.item
393
+ // is the source element, not the rendered udex-list-item.
394
+ const tokenId = this.getDataTokenId(item);
395
+ const navItems = this._list?.getKeyboardNavigationItems();
396
+ const renderedItem = navItems?.find(i => (i.getAttribute("data-token-id") ?? i._id) === tokenId);
397
+ if (renderedItem && renderedItem !== this._activeDescendantItem) {
398
+ this._setActiveDescendant(renderedItem);
399
+ }
400
+ // Return DOM focus to the input so the clicked item loses its :focus ring.
401
+ // Without this, the browser keeps focus on the item (from the click) and a
402
+ // second ring appears when arrow keys move _activeDescendantItem elsewhere.
403
+ this._search.focus();
404
+ // Re-announce with the updated checked/unchecked state. The rendered item's
405
+ // `selected` prop is updated on the next render cycle (template re-render),
406
+ // so we wait for it before re-reading state labels.
407
+ renderFinished().then(() => this._announceCurrentOrFirst()).catch(() => { });
273
408
  }
274
409
  onKeyDownSearch(e) {
275
410
  const items = this._list?.getKeyboardNavigationItems();
@@ -281,31 +416,135 @@ class UDExSelectBase extends UDExSearchableListBase {
281
416
  const isEscAndPopoverOpened = isEscape(e) && popoverOpened;
282
417
  const isDownAndPopoverClosed = isDown(e) && !popoverOpened;
283
418
  const isDownAndPopoverOpened = isDown(e) && popoverOpened;
419
+ const isUpAndPopoverOpened = isUp(e) && popoverOpened;
420
+ // Tab while popup is open: move focus to the first footer element if one exists,
421
+ // otherwise close the dropdown and move past the component.
422
+ if (popoverOpened && isTabNext(e)) {
423
+ e.preventDefault();
424
+ if (this.hasFooter) {
425
+ this._setActiveDescendant(null);
426
+ (this._firstFocusableIn(this.footer[0]) ?? this.footer[0])?.focus();
427
+ }
428
+ else {
429
+ this.closeDropdown();
430
+ this._moveFocusAfterComponent();
431
+ }
432
+ return;
433
+ }
434
+ // Shift+Tab while popup is open: close the dropdown.
435
+ // DOM focus stays on the search input throughout (our aria-activedescendant model
436
+ // never moves focus away from the input), so no explicit re-focus is needed.
437
+ if (popoverOpened && isTabPrevious(e)) {
438
+ e.preventDefault();
439
+ this._setActiveDescendant(null);
440
+ this.closeDropdown();
441
+ return;
442
+ }
284
443
  if (!hasItems) {
285
444
  return;
286
445
  }
287
446
  const firstIndex = (items[0]?.nonInteractive && !items[0]?.collapsible) ? 1 : 0;
288
- const firstItem = items[firstIndex];
289
447
  if (isEscAndPopoverOpened) {
290
448
  return this.closeDropdown();
291
449
  }
292
450
  if (isDownAndPopoverClosed) {
293
451
  e.preventDefault();
294
452
  this.openDropdown();
295
- this.focusFirstItem();
296
- this._selectedOption = firstItem.label;
453
+ this._activateFirstItem();
297
454
  if (this.showImageFlags) {
298
- this.handleImagePosition(items, 0);
455
+ this.handleImagePosition(items, firstIndex);
299
456
  }
300
457
  return;
301
458
  }
302
459
  if (isDownAndPopoverOpened) {
303
460
  e.preventDefault();
304
- if (this.showImageFlags) {
305
- this.handleImagePosition(items, 0);
461
+ if (this._activeDescendantItem) {
462
+ const lastIndex = items.length - 1;
463
+ const currentIndex = this._list.getCurrentIndex(items, this._activeDescendantItem);
464
+ const raw = currentIndex + 1 > lastIndex ? 0 : currentIndex + 1;
465
+ const nextIndex = this._skipNonInteractive(items, raw, lastIndex, "down");
466
+ this._navigateToIndex(items, nextIndex);
467
+ }
468
+ else {
469
+ this._activateFirstItem();
470
+ // Also update _selectedOption so the input reflects the active item.
471
+ const activeIdx = (items[0]?.nonInteractive && !items[0]?.collapsible) ? 1 : 0;
472
+ this._selectedOption = items[activeIdx].label;
473
+ if (this.showImageFlags) {
474
+ this.handleImagePosition(items, activeIdx);
475
+ }
306
476
  }
307
- this._selectedOption = firstItem.label;
308
- return this.focusFirstItem();
477
+ return;
478
+ }
479
+ if (isUpAndPopoverOpened) {
480
+ e.preventDefault();
481
+ if (this._activeDescendantItem) {
482
+ const lastIndex = items.length - 1;
483
+ const currentIndex = this._list.getCurrentIndex(items, this._activeDescendantItem);
484
+ const raw = currentIndex - 1 < 0 ? lastIndex : currentIndex - 1;
485
+ const nextIndex = this._skipNonInteractive(items, raw, lastIndex, "up");
486
+ this._navigateToIndex(items, nextIndex);
487
+ }
488
+ else {
489
+ this._navigateToIndex(items, items.length - 1);
490
+ }
491
+ return;
492
+ }
493
+ if (popoverOpened && isHome(e)) {
494
+ e.preventDefault();
495
+ const homeIndex = (items[0]?.nonInteractive && !items[0]?.collapsible) ? 1 : 0;
496
+ this._navigateToIndex(items, homeIndex);
497
+ return;
498
+ }
499
+ if (popoverOpened && isEnd(e)) {
500
+ e.preventDefault();
501
+ this._navigateToIndex(items, items.length - 1);
502
+ return;
503
+ }
504
+ // Enter/Space: select the active descendant item (or toggle for MultiSelect).
505
+ if (popoverOpened && this._activeDescendantItem && (isEnter(e) || isSpace(e))) {
506
+ e.preventDefault();
507
+ const activeItem = this._activeDescendantItem;
508
+ if (activeItem.isGroup) {
509
+ // Group header: fire header-press (same event the click handler fires) so
510
+ // handleHeaderPress → onHeaderPress → handleGroupHeaderSelection runs.
511
+ activeItem.fireDecoratorEvent("header-press", { item: activeItem });
512
+ }
513
+ else {
514
+ // Leaf item: fire item-press so the list handles selection consistently.
515
+ // Do NOT toggle .selected directly — handleItemClick (called via onItemPress)
516
+ // handles the toggle, and double-toggling would be a no-op.
517
+ activeItem.fireDecoratorEvent("item-press", {
518
+ selected: activeItem.selected,
519
+ item: activeItem,
520
+ });
521
+ }
522
+ return;
523
+ }
524
+ // Left/Right: collapse/expand the active group header when popup is open.
525
+ if (popoverOpened && (isLeft(e) || isRight(e))) {
526
+ e.preventDefault();
527
+ const activeHeader = this._activeDescendantItem
528
+ ? this._resolveCollapsibleGroupHeader(this._activeDescendantItem)
529
+ : null;
530
+ if (activeHeader) {
531
+ this._handleGroupHeaderCollapse(activeHeader, isLeft(e));
532
+ return;
533
+ }
534
+ // Fall through to icon-row navigation when the active item has icon slots.
535
+ if (this._activeDescendantItem) {
536
+ if (isRight(e)) {
537
+ this._handleArrowRightInRow(this._activeDescendantItem);
538
+ }
539
+ else {
540
+ this._handleArrowLeftInRow(this._activeDescendantItem);
541
+ }
542
+ }
543
+ return;
544
+ }
545
+ // Sync _selectedOption display for the first item (used when popover just opened via click).
546
+ if (!this._activeDescendantItem && hasItems) {
547
+ this._selectedOption = items[firstIndex].label;
309
548
  }
310
549
  }
311
550
  handleSearchChange(e) {
@@ -319,6 +558,14 @@ class UDExSelectBase extends UDExSearchableListBase {
319
558
  this.openDropdown();
320
559
  }
321
560
  }
561
+ onSearch(value) {
562
+ super.onSearch(value);
563
+ // Route search result count into the shared live region so SelectBox
564
+ // only needs one aria-live span (no separate polite span in the template).
565
+ if (this._accSearchResultInfo) {
566
+ this._liveRegionText = this._accSearchResultInfo;
567
+ }
568
+ }
322
569
  handleDirection() {
323
570
  const directionStyles = window.getComputedStyle(this).getPropertyValue("direction");
324
571
  this._direction = directionStyles || "ltr";
@@ -334,11 +581,81 @@ class UDExSelectBase extends UDExSearchableListBase {
334
581
  this.fireEventDropdownBeforeOpen();
335
582
  }
336
583
  handleDropdownOpen() {
337
- if (!this.activeItem) {
584
+ // Scroll to the previously selected/active item if there is one,
585
+ // otherwise scroll to top. Do NOT pre-activate any item — that is done
586
+ // by the first ArrowDown so that ArrowDown[1]=item[0], ArrowDown[2]=item[1].
587
+ if (this.activeItem) {
588
+ const items = this._list?.getKeyboardNavigationItems();
589
+ const active = items?.find(i => !i.isGroup && i.selected);
590
+ if (active && this._list?._scrollIntoView) {
591
+ this._list.scrollToItem(active);
592
+ }
593
+ else {
594
+ this._dropdownScrollToTop();
595
+ }
596
+ }
597
+ else {
338
598
  this._dropdownScrollToTop();
339
599
  }
600
+ // Announce the visually focused item (fake focus outline on first item).
601
+ // Using polite politeness — it waits for the AT to finish announcing
602
+ // "expanded" before reading the item, so no timeout is needed.
603
+ // Clear first so the mutation fires even if the text is unchanged from
604
+ // the previous open, then populate after render completes.
605
+ this._liveRegionText = "";
606
+ renderFinished().then(() => this._announceCurrentOrFirst()).catch(() => { });
340
607
  this.fireEventDropdownOpen();
341
608
  }
609
+ /**
610
+ * Announces the currently active descendant item (if set), or the first
611
+ * navigable item as a fallback. Used on open and after state changes.
612
+ */
613
+ _announceCurrentOrFirst() {
614
+ const items = this._list?.getKeyboardNavigationItems();
615
+ if (!items?.length) {
616
+ return;
617
+ }
618
+ const item = this._activeDescendantItem ?? items.find(i => !i.nonInteractive || i.collapsible) ?? items[0];
619
+ if (!item) {
620
+ return;
621
+ }
622
+ const label = cleanLabel(item.label ?? "");
623
+ const stateParts = this._itemStateLabels(item);
624
+ const posText = this._treePositionText(item);
625
+ this._liveRegionText = [label, posText, ...stateParts].filter(Boolean).join(", ");
626
+ }
627
+ /**
628
+ * Returns the positional announcement text for an item, tree-aware when the
629
+ * list has groups. Matches the JAWS reading pattern of FilterMenu:
630
+ * group header → "level 0, X of Y" (Y = total navigable groups)
631
+ * group child → "level 1, X of Y" (Y = siblings in that group)
632
+ * flat item → "X of Y" (Y = total items, no level prefix)
633
+ */
634
+ _treePositionText(item) {
635
+ if (!this.isTreeStructure) {
636
+ const items = this._list?.getKeyboardNavigationItems() ?? [];
637
+ const pos = items.indexOf(item);
638
+ return pos >= 0 ? `${pos + 1} of ${items.length}` : "";
639
+ }
640
+ if (item.isGroup) {
641
+ // Position among navigable group headers.
642
+ const groups = (this._list?.getKeyboardNavigationItems() ?? []).filter(i => i.isGroup);
643
+ const pos = groups.indexOf(item);
644
+ return pos >= 0 ? `level 0, ${pos + 1} of ${groups.length}` : "level 0";
645
+ }
646
+ // Child item — find parent group and count siblings visible in navigation.
647
+ const parentGroup = item.parentElement;
648
+ if (parentGroup?.isGroup) {
649
+ const navItems = this._list?.getKeyboardNavigationItems() ?? [];
650
+ const siblings = navItems.filter(i => !i.isGroup && i.parentElement === parentGroup);
651
+ const pos = siblings.indexOf(item);
652
+ return pos >= 0 ? `level 1, ${pos + 1} of ${siblings.length}` : "level 1";
653
+ }
654
+ // Fallback: flat position.
655
+ const all = this._list?.getKeyboardNavigationItems() ?? [];
656
+ const pos = all.indexOf(item);
657
+ return pos >= 0 ? `${pos + 1} of ${all.length}` : "";
658
+ }
342
659
  fireEventDropdownBeforeOClose() {
343
660
  this.fireDecoratorEvent("before-close");
344
661
  }
@@ -372,11 +689,14 @@ class UDExSelectBase extends UDExSearchableListBase {
372
689
  this._popover.opener = this._trigger;
373
690
  this._popover.open = true;
374
691
  this._open = true;
692
+ this._navigating = true;
693
+ this._focused = false;
375
694
  }
376
695
  closeDropdown() {
377
696
  if (this._popover.open) {
378
697
  this._open = false;
379
698
  this._popover.open = false;
699
+ this._navigating = false;
380
700
  }
381
701
  }
382
702
  inputFocusIn() {
@@ -436,11 +756,13 @@ class UDExSelectBase extends UDExSearchableListBase {
436
756
  if (collapse && !header.collapsed) {
437
757
  header.collapsed = true;
438
758
  this._list.setCollapsedItems(true, header);
759
+ renderFinished().then(() => this._announceCurrentOrFirst()).catch(() => { });
439
760
  return true;
440
761
  }
441
762
  if (!collapse && header.collapsed) {
442
763
  header.collapsed = false;
443
764
  this._list.setCollapsedItems(false, header);
765
+ renderFinished().then(() => this._announceCurrentOrFirst()).catch(() => { });
444
766
  return true;
445
767
  }
446
768
  // Target is a collapsible header but already in the requested state — still consume
@@ -467,7 +789,12 @@ class UDExSelectBase extends UDExSearchableListBase {
467
789
  const iconSlot = this._getIconButtonSlot(target);
468
790
  if (!iconSlot) {
469
791
  const firstIcon = target.querySelector("[slot=\"firstIcon\"]");
470
- firstIcon?.focus();
792
+ if (firstIcon) {
793
+ // Entering icon row: clear the active descendant ring so the list item
794
+ // doesn't show two simultaneous outlines alongside the icon's :focus ring.
795
+ this._setActiveDescendant(null);
796
+ firstIcon.focus();
797
+ }
471
798
  return;
472
799
  }
473
800
  if (iconSlot === "firstIcon") {
@@ -492,7 +819,18 @@ class UDExSelectBase extends UDExSearchableListBase {
492
819
  firstIcon?.focus();
493
820
  }
494
821
  else if (iconSlot === "firstIcon") {
495
- this._list.focusItem(parentItem);
822
+ // Return to the list item: restore the active descendant ring and return
823
+ // DOM focus to the input so the icon's :focus ring is cleared.
824
+ const navItems = this._list?.getKeyboardNavigationItems();
825
+ const tokenId = this.getDataTokenId(parentItem);
826
+ const renderedItem = navItems?.find(i => (i.getAttribute("data-token-id") ?? i._id) === tokenId);
827
+ if (renderedItem) {
828
+ this._setActiveDescendant(renderedItem);
829
+ }
830
+ else {
831
+ this._list.focusItem(parentItem);
832
+ }
833
+ this._search.focus();
496
834
  }
497
835
  }
498
836
  _handleListKeyDownCapture(e) {
@@ -533,7 +871,7 @@ class UDExSelectBase extends UDExSearchableListBase {
533
871
  }
534
872
  this._list.unsetTabIndexByIndex(items, currentIndex);
535
873
  this._list.setTabIndexByIndex(items, targetIndex);
536
- this._list.focusItem(items[targetIndex]);
874
+ this._setActiveDescendant(items[targetIndex]);
537
875
  this._selectedOption = items[targetIndex].label;
538
876
  }
539
877
  _focusLastListItem() {
@@ -543,15 +881,11 @@ class UDExSelectBase extends UDExSearchableListBase {
543
881
  return;
544
882
  }
545
883
  const lastIndex = items.length - 1;
546
- const lastItem = items[lastIndex];
547
884
  this._list.setTabIndexByIndex(items, lastIndex);
548
- this._selectedOption = lastItem.label;
549
- if (lastItem.isGroup) {
550
- this._list.focusHeader(lastItem);
551
- }
552
- else {
553
- this._list.focusItem(lastItem);
554
- }
885
+ this._selectedOption = items[lastIndex].label;
886
+ this._setActiveDescendant(items[lastIndex]);
887
+ // Return DOM focus to the search input (aria-activedescendant model).
888
+ this._search.focus();
555
889
  }
556
890
  _firstFocusableIn(el) {
557
891
  if (!(el instanceof HTMLElement)) {
@@ -580,11 +914,49 @@ class UDExSelectBase extends UDExSearchableListBase {
580
914
  };
581
915
  findAndFocus(this);
582
916
  }
917
+ /**
918
+ * Builds the state portion of the live region announcement for a navigation item.
919
+ * Returns an array of state strings (e.g. ["collapsed", "Checked"]) to be joined
920
+ * with the label and position. Handles:
921
+ * - collapsible group headers: expanded / collapsed
922
+ * - MultiSelect: Checked / Unchecked / Indeterminate
923
+ * - SingleSelect (tree): Selected / Unselected
924
+ * - disabled: Disabled
925
+ */
926
+ _itemStateLabels(item) {
927
+ const parts = [];
928
+ if (item.collapsible) {
929
+ // Use plain English — matches what AT announce for aria-expanded.
930
+ parts.push(item.expanded ? "expanded" : "collapsed");
931
+ }
932
+ if (item.disabled) {
933
+ parts.push(translate(UDExSearchableListBase, DISABLED));
934
+ }
935
+ else if (item.modeMultiSelect || (item.isGroup && this.modeMultiSelect)) {
936
+ if (item.indeterminate) {
937
+ parts.push(translate(UDExSearchableListBase, INDETERMINATE));
938
+ }
939
+ else {
940
+ parts.push(translate(UDExSearchableListBase, item.selected ? SELECTED : UNSELECTED));
941
+ }
942
+ }
943
+ else if (this.isTreeStructure && item.selected) {
944
+ // SingleSelect tree: only announce "Selected" when the item is actually selected.
945
+ parts.push(translate(UDExSearchableListBase, SELECTED));
946
+ }
947
+ return parts;
948
+ }
583
949
  get ariaDescribedbyText() {
584
950
  if (this.modeSingleSelect) {
585
- return this._selectedOption;
951
+ return this._navigating ? "" : this._selectedOption;
586
952
  }
587
953
  const tags = this.selectedItems.filter(item => !item.isGroup);
954
+ // Tokenizer.i18nBundle may not be loaded yet on direct page load.
955
+ // Return empty string until the bundle is available; the component re-renders
956
+ // once i18n is ready and will pick up the correct text.
957
+ if (!Tokenizer.i18nBundle) {
958
+ return "";
959
+ }
588
960
  return getTokensCountText(tags.length);
589
961
  }
590
962
  get trigger() {
@@ -624,6 +996,15 @@ class UDExSelectBase extends UDExSearchableListBase {
624
996
  get listboxRole() {
625
997
  return this._listBoxRole;
626
998
  }
999
+ get listAriaControlsId() {
1000
+ return this._list?.id || this.popoverId;
1001
+ }
1002
+ get _activeDescendantMode() {
1003
+ return true;
1004
+ }
1005
+ get isTreeStructure() {
1006
+ return this._filteredItems.some(e => e.isGroup);
1007
+ }
627
1008
  get hideDropdownSearch() {
628
1009
  return true;
629
1010
  }
@@ -686,6 +1067,12 @@ __decorate([
686
1067
  __decorate([
687
1068
  property({ type: Boolean, noAttribute: true })
688
1069
  ], UDExSelectBase.prototype, "_requestRender", void 0);
1070
+ __decorate([
1071
+ property({ type: Boolean })
1072
+ ], UDExSelectBase.prototype, "_navigating", void 0);
1073
+ __decorate([
1074
+ property({ type: String, noAttribute: true })
1075
+ ], UDExSelectBase.prototype, "_liveRegionText", void 0);
689
1076
  __decorate([
690
1077
  slot({ type: HTMLElement })
691
1078
  ], UDExSelectBase.prototype, "footer", void 0);