@sapudex/web-components 2.61.0 → 2.63.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 (467) hide show
  1. package/cypress/specs/AccordionSpotlight.cy.tsx +43 -2
  2. package/cypress/specs/Carousel.cy.tsx +88 -0
  3. package/cypress/specs/CountrySelector.cy.tsx +233 -6
  4. package/cypress/specs/FilterMenu.cy.tsx +39 -45
  5. package/cypress/specs/List.cy.tsx +624 -10
  6. package/cypress/specs/ListItem.cy.tsx +50 -0
  7. package/cypress/specs/MastheadCountrySelector.cy.tsx +177 -0
  8. package/cypress/specs/SelectBox.cy.tsx +239 -131
  9. package/cypress/specs/SelectBoxAccessibility.cy.tsx +3109 -0
  10. package/cypress/specs/SideNavigation.cy.tsx +49 -0
  11. package/cypress/specs/SideNavigationMobile.cy.tsx +69 -0
  12. package/cypress/specs/TagGroup.cy.tsx +168 -0
  13. package/cypress/support/component-imports.instrumented.ts +4 -0
  14. package/cypress/support/component-imports.src.ts +4 -0
  15. package/dist/AccordionItemTemplate.js +1 -1
  16. package/dist/AccordionItemTemplate.js.map +1 -1
  17. package/dist/AccordionSpotlight.d.ts +7 -2
  18. package/dist/AccordionSpotlight.js +31 -6
  19. package/dist/AccordionSpotlight.js.map +1 -1
  20. package/dist/AccordionSpotlightItem.d.ts +3 -1
  21. package/dist/AccordionSpotlightItem.js +3 -1
  22. package/dist/AccordionSpotlightItem.js.map +1 -1
  23. package/dist/Carousel.d.ts +1 -0
  24. package/dist/Carousel.js +19 -3
  25. package/dist/Carousel.js.map +1 -1
  26. package/dist/CountrySelector.js +1 -3
  27. package/dist/CountrySelector.js.map +1 -1
  28. package/dist/List.d.ts +2 -0
  29. package/dist/List.js +22 -4
  30. package/dist/List.js.map +1 -1
  31. package/dist/ListGroupHeader.js +5 -1
  32. package/dist/ListGroupHeader.js.map +1 -1
  33. package/dist/ListGroupHeaderBase.d.ts +2 -0
  34. package/dist/ListGroupHeaderBase.js +15 -2
  35. package/dist/ListGroupHeaderBase.js.map +1 -1
  36. package/dist/ListGroupHeaderTemplate.js +14 -22
  37. package/dist/ListGroupHeaderTemplate.js.map +1 -1
  38. package/dist/ListItem.d.ts +1 -2
  39. package/dist/ListItem.js +14 -12
  40. package/dist/ListItem.js.map +1 -1
  41. package/dist/ListItemBase.d.ts +5 -0
  42. package/dist/ListItemBase.js +11 -1
  43. package/dist/ListItemBase.js.map +1 -1
  44. package/dist/ListItemTemplate.js +1 -1
  45. package/dist/ListItemTemplate.js.map +1 -1
  46. package/dist/ListSelectAllTemplate.js +1 -1
  47. package/dist/ListSelectAllTemplate.js.map +1 -1
  48. package/dist/ListTemplate.js +2 -1
  49. package/dist/ListTemplate.js.map +1 -1
  50. package/dist/MastheadCountrySelector.d.ts +14 -0
  51. package/dist/MastheadCountrySelector.js +6 -0
  52. package/dist/MastheadCountrySelector.js.map +1 -1
  53. package/dist/MastheadCountrySelectorTemplate.js +1 -1
  54. package/dist/MastheadCountrySelectorTemplate.js.map +1 -1
  55. package/dist/MessageStrip.d.ts +1 -0
  56. package/dist/MessageStrip.js +6 -0
  57. package/dist/MessageStrip.js.map +1 -1
  58. package/dist/Search.d.ts +13 -3
  59. package/dist/Search.js +36 -11
  60. package/dist/Search.js.map +1 -1
  61. package/dist/SearchTemplate.js +1 -1
  62. package/dist/SearchTemplate.js.map +1 -1
  63. package/dist/SearchableListBase.d.ts +2 -0
  64. package/dist/SearchableListBase.js +13 -3
  65. package/dist/SearchableListBase.js.map +1 -1
  66. package/dist/SearchableListBaseTemplate.js +42 -33
  67. package/dist/SearchableListBaseTemplate.js.map +1 -1
  68. package/dist/SelectBase.d.ts +18 -33
  69. package/dist/SelectBase.js +124 -139
  70. package/dist/SelectBase.js.map +1 -1
  71. package/dist/SelectBox.d.ts +3 -0
  72. package/dist/SelectBox.js +19 -7
  73. package/dist/SelectBox.js.map +1 -1
  74. package/dist/SelectBoxTemplate.js +3 -3
  75. package/dist/SelectBoxTemplate.js.map +1 -1
  76. package/dist/SideNavigation.d.ts +9 -0
  77. package/dist/SideNavigation.js +9 -0
  78. package/dist/SideNavigation.js.map +1 -1
  79. package/dist/SideNavigationItem.js +2 -0
  80. package/dist/SideNavigationItem.js.map +1 -1
  81. package/dist/SideNavigationItemTemplate.d.ts +2 -0
  82. package/dist/SideNavigationItemTemplate.js +15 -0
  83. package/dist/SideNavigationItemTemplate.js.map +1 -0
  84. package/dist/SideNavigationMobile.d.ts +19 -0
  85. package/dist/SideNavigationMobile.js +33 -3
  86. package/dist/SideNavigationMobile.js.map +1 -1
  87. package/dist/SideNavigationMobileTemplate.js +1 -2
  88. package/dist/SideNavigationMobileTemplate.js.map +1 -1
  89. package/dist/SideNavigationSubItem.d.ts +4 -1
  90. package/dist/SideNavigationSubItem.js +22 -10
  91. package/dist/SideNavigationSubItem.js.map +1 -1
  92. package/dist/SideNavigationSubItemTemplate.js +1 -2
  93. package/dist/SideNavigationSubItemTemplate.js.map +1 -1
  94. package/dist/SideNavigationTemplate.d.ts +2 -0
  95. package/dist/SideNavigationTemplate.js +6 -0
  96. package/dist/SideNavigationTemplate.js.map +1 -0
  97. package/dist/TagGroup.d.ts +3 -0
  98. package/dist/TagGroup.js +31 -0
  99. package/dist/TagGroup.js.map +1 -1
  100. package/dist/TagGroupTemplate.js +1 -1
  101. package/dist/TagGroupTemplate.js.map +1 -1
  102. package/dist/assets/{InputSuggestions-1OnUn6pM.js → InputSuggestions-6S5UueXO.js} +2 -2
  103. package/dist/assets/{ListItemStandardExpandableTextTemplate-CoBAMp_v.js → ListItemStandardExpandableTextTemplate-OidrwM_d.js} +2 -2
  104. package/dist/assets/{bundle.esm-BqaVWFKf.js → bundle.esm-DaFsZANO.js} +237 -239
  105. package/dist/assets/messagebundle_ar-22dGHdkl.js +1 -0
  106. package/dist/assets/messagebundle_ar-DbxuUDUB.js +1 -0
  107. package/dist/assets/messagebundle_bg-CaaOz5e4.js +1 -0
  108. package/dist/assets/messagebundle_bg-QOUvq6-8.js +1 -0
  109. package/dist/assets/messagebundle_ca-D-8eSg1w.js +1 -0
  110. package/dist/assets/messagebundle_ca-jsUpFfNJ.js +1 -0
  111. package/dist/assets/messagebundle_cnr-BdSolJRo.js +1 -0
  112. package/dist/assets/messagebundle_cnr-rtr9Ox4O.js +1 -0
  113. package/dist/assets/messagebundle_cs-CbM7zJ23.js +1 -0
  114. package/dist/assets/messagebundle_cy-D5E7e9o1.js +1 -0
  115. package/dist/assets/messagebundle_cy-hajQLyoj.js +1 -0
  116. package/dist/assets/messagebundle_da-C3PD-hWQ.js +1 -0
  117. package/dist/assets/messagebundle_da-DFzvQYW2.js +1 -0
  118. package/dist/assets/messagebundle_de-C106E9io.js +1 -0
  119. package/dist/assets/messagebundle_de-C36z5lgV.js +1 -0
  120. package/dist/assets/messagebundle_el-BLHqa1_J.js +1 -0
  121. package/dist/assets/messagebundle_el-k8W9FVQI.js +1 -0
  122. package/dist/assets/messagebundle_en-ClXds397.js +1 -0
  123. package/dist/assets/messagebundle_en-DgPtAFO8.js +1 -0
  124. package/dist/assets/messagebundle_en_GB-DxulA9qE.js +1 -0
  125. package/dist/assets/messagebundle_en_GB-LxAIZigF.js +1 -0
  126. package/dist/assets/{messagebundle_en_US_sappsd-Se8GgI58.js → messagebundle_en_US_sappsd-TZz2y4pV.js} +1 -1
  127. package/dist/assets/messagebundle_en_US_sappsd-oE0A2op2.js +1 -0
  128. package/dist/assets/messagebundle_en_US_saprigi-C6FsbpF8.js +1 -0
  129. package/dist/assets/{messagebundle_en_US_saprigi-CbfvaHUL.js → messagebundle_en_US_saprigi-CkPhuOLS.js} +1 -1
  130. package/dist/assets/messagebundle_en_US_saptrc-CFSYKuS7.js +1 -0
  131. package/dist/assets/messagebundle_en_US_saptrc-CNZe1wPP.js +1 -0
  132. package/dist/assets/messagebundle_es-C3ijAvKG.js +1 -0
  133. package/dist/assets/messagebundle_es-wi4P-8Bo.js +1 -0
  134. package/dist/assets/messagebundle_es_MX-JEoOD2AD.js +1 -0
  135. package/dist/assets/messagebundle_es_MX-qDQ65ei9.js +1 -0
  136. package/dist/assets/messagebundle_et-C3wgDmm9.js +1 -0
  137. package/dist/assets/messagebundle_et-D4r4iubd.js +1 -0
  138. package/dist/assets/messagebundle_fi-BjyQcbRb.js +1 -0
  139. package/dist/assets/messagebundle_fi-CivJKH9k.js +1 -0
  140. package/dist/assets/messagebundle_fr-BxDSBfD5.js +1 -0
  141. package/dist/assets/messagebundle_fr-JN2VAe-b.js +1 -0
  142. package/dist/assets/messagebundle_fr_CA-FkrcsWH5.js +1 -0
  143. package/dist/assets/messagebundle_fr_CA-phd0XOeR.js +1 -0
  144. package/dist/assets/messagebundle_hi-B_pehoTp.js +1 -0
  145. package/dist/assets/messagebundle_hi-CVOoC3dA.js +1 -0
  146. package/dist/assets/messagebundle_hr-BYS-ya62.js +1 -0
  147. package/dist/assets/messagebundle_hr-DHuCJjK8.js +1 -0
  148. package/dist/assets/messagebundle_hu-Crn0Y1hl.js +1 -0
  149. package/dist/assets/messagebundle_hu-DJL3QHT4.js +1 -0
  150. package/dist/assets/messagebundle_id-BJEG-7Up.js +1 -0
  151. package/dist/assets/messagebundle_id-CgbG2IVb.js +1 -0
  152. package/dist/assets/messagebundle_it-B-E3gO1k.js +1 -0
  153. package/dist/assets/messagebundle_it-DHwy0JuE.js +1 -0
  154. package/dist/assets/messagebundle_iw-BFfL9nZy.js +1 -0
  155. package/dist/assets/messagebundle_iw-BgyHu_0a.js +1 -0
  156. package/dist/assets/messagebundle_ja-BDNEwBMO.js +1 -0
  157. package/dist/assets/messagebundle_ja-eyoqeb4r.js +1 -0
  158. package/dist/assets/messagebundle_kk-BA_1qhYv.js +1 -0
  159. package/dist/assets/messagebundle_kk-CTAXqbPN.js +1 -0
  160. package/dist/assets/messagebundle_ko-C1tsjQMn.js +1 -0
  161. package/dist/assets/messagebundle_ko-CkiNi7iV.js +1 -0
  162. package/dist/assets/messagebundle_lt-Dp0c8r7p.js +1 -0
  163. package/dist/assets/{messagebundle_lt-BGK5mpcm.js → messagebundle_lt-bNum-ekg.js} +1 -1
  164. package/dist/assets/messagebundle_lv-B9UWTGX9.js +1 -0
  165. package/dist/assets/messagebundle_lv-D02PBhtR.js +1 -0
  166. package/dist/assets/messagebundle_mk--Xt_Ciey.js +1 -0
  167. package/dist/assets/messagebundle_mk-D6s2Tr95.js +1 -0
  168. package/dist/assets/messagebundle_ms-BAqsvtp5.js +1 -0
  169. package/dist/assets/messagebundle_ms-BobJaFPp.js +1 -0
  170. package/dist/assets/messagebundle_nl-BJCykHj1.js +1 -0
  171. package/dist/assets/messagebundle_nl-Dj7LaMyb.js +1 -0
  172. package/dist/assets/messagebundle_no-CR_uQXUz.js +1 -0
  173. package/dist/assets/messagebundle_no-CnwJbEW8.js +1 -0
  174. package/dist/assets/messagebundle_pl-D6FQ-6EC.js +1 -0
  175. package/dist/assets/messagebundle_pl-eJC2NE6N.js +1 -0
  176. package/dist/assets/messagebundle_pt-CbdPbTKR.js +1 -0
  177. package/dist/assets/messagebundle_pt-n8LcOyWG.js +1 -0
  178. package/dist/assets/messagebundle_pt_PT-B17ziKL9.js +1 -0
  179. package/dist/assets/messagebundle_pt_PT-BVpS4lrC.js +1 -0
  180. package/dist/assets/messagebundle_ro-C0jrNva4.js +1 -0
  181. package/dist/assets/messagebundle_ro-ixITTbJt.js +1 -0
  182. package/dist/assets/messagebundle_ru-Bh6RMNe2.js +1 -0
  183. package/dist/assets/messagebundle_ru-Dbxms1Xm.js +1 -0
  184. package/dist/assets/messagebundle_sh-CMDXUWge.js +1 -0
  185. package/dist/assets/messagebundle_sh-Cb-sVI_0.js +1 -0
  186. package/dist/assets/messagebundle_sk-DZkkgRSd.js +1 -0
  187. package/dist/assets/{messagebundle_sk-CXOF1RuF.js → messagebundle_sk-Dqb_XwMg.js} +1 -1
  188. package/dist/assets/messagebundle_sl-DIl-2Lb1.js +1 -0
  189. package/dist/assets/messagebundle_sl-Dx6UWXni.js +1 -0
  190. package/dist/assets/messagebundle_sr-DstlyDjZ.js +1 -0
  191. package/dist/assets/messagebundle_sr-yQWBd9jR.js +1 -0
  192. package/dist/assets/messagebundle_sv-Dr2hDyEO.js +1 -0
  193. package/dist/assets/messagebundle_sv-iHKWgaRg.js +1 -0
  194. package/dist/assets/messagebundle_th-DbWfCb5y.js +1 -0
  195. package/dist/assets/messagebundle_th-yLU2SE6L.js +1 -0
  196. package/dist/assets/messagebundle_tr-CIoGg6uY.js +1 -0
  197. package/dist/assets/messagebundle_tr-lAQvvdUi.js +1 -0
  198. package/dist/assets/messagebundle_uk-DIBItAKu.js +1 -0
  199. package/dist/assets/messagebundle_uk-j_sqGY4D.js +1 -0
  200. package/dist/assets/messagebundle_vi-C40OW2eC.js +1 -0
  201. package/dist/assets/messagebundle_vi-xWTpoKPI.js +1 -0
  202. package/dist/assets/messagebundle_zh_CN-CmeOlVfl.js +1 -0
  203. package/dist/assets/messagebundle_zh_CN-U8Z0kuQb.js +1 -0
  204. package/dist/assets/messagebundle_zh_TW-B_1_vc8O.js +1 -0
  205. package/dist/assets/messagebundle_zh_TW-hwHN6ElU.js +1 -0
  206. package/dist/assets/{parameters-bundle.css-Cv89y49I.js → parameters-bundle.css-2ZsUlBNO.js} +299 -151
  207. package/dist/assets/parameters-bundle.css-31Bw5XOG.js +2 -0
  208. package/dist/assets/parameters-bundle.css-BJp4ZvSQ.js +2 -0
  209. package/dist/assets/{parameters-bundle.css-vNsSPPU5.js → parameters-bundle.css-BKlkVfkE.js} +742 -494
  210. package/dist/assets/parameters-bundle.css-BMOU75LU.js +2 -0
  211. package/dist/assets/parameters-bundle.css-BZF5sWSb.js +1 -0
  212. package/dist/assets/{parameters-bundle.css-DmEWEk0u.js → parameters-bundle.css-Bf1GOISM.js} +786 -513
  213. package/dist/assets/parameters-bundle.css-BpWLGMCI.js +2 -0
  214. package/dist/assets/parameters-bundle.css-BsoxE2UF.js +2 -0
  215. package/dist/assets/parameters-bundle.css-CAhrGUcA.js +2 -0
  216. package/dist/assets/{parameters-bundle.css-C3eDVARm.js → parameters-bundle.css-CDJt5bvS.js} +176 -89
  217. package/dist/assets/parameters-bundle.css-CIr3BQBD.js +2 -0
  218. package/dist/assets/parameters-bundle.css-CVUmNgQM.js +2 -0
  219. package/dist/assets/parameters-bundle.css-C_pu3Dce.js +2 -0
  220. package/dist/assets/parameters-bundle.css-ChtqHIDX.js +2 -0
  221. package/dist/assets/parameters-bundle.css-CvaMQVtq.js +1 -0
  222. package/dist/assets/parameters-bundle.css-Cwz89dEH.js +2 -0
  223. package/dist/assets/parameters-bundle.css-CyCovTbK.js +2 -0
  224. package/dist/assets/parameters-bundle.css-Cyf5K2-Q.js +2 -0
  225. package/dist/assets/parameters-bundle.css-DdDLbfHl.js +2 -0
  226. package/dist/assets/{parameters-bundle.css-C5V2Zp_F.js → parameters-bundle.css-Dfz9lgd6.js} +131 -95
  227. package/dist/assets/{parameters-bundle.css-K-MvKimD.js → parameters-bundle.css-DjW0INFD.js} +139 -88
  228. package/dist/assets/parameters-bundle.css-JyFiyY-_.js +2 -0
  229. package/dist/assets/parameters-bundle.css-tf-z7jv9.js +2 -0
  230. package/dist/css/themes/AccordionSpotlight.css +1 -1
  231. package/dist/css/themes/ListGroupHeader.css +1 -1
  232. package/dist/css/themes/MastheadShell.css +1 -1
  233. package/dist/css/themes/SideNavigation.css +1 -1
  234. package/dist/css/themes/SideNavigationItem.css +1 -1
  235. package/dist/css/themes/SideNavigationMobile.css +1 -1
  236. package/dist/css/themes/SideNavigationSubItem.css +1 -1
  237. package/dist/css/themes/Slider.css +1 -1
  238. package/dist/css/themes/Table.css +1 -1
  239. package/dist/css/themes/sap_fiori_3/parameters-bundle.css +0 -1
  240. package/dist/css/themes/sap_glow/parameters-bundle.css +0 -1
  241. package/dist/css/themes/sap_horizon/parameters-bundle.css +0 -1
  242. package/dist/custom-elements-internal.json +1443 -7
  243. package/dist/custom-elements.json +1497 -28
  244. package/dist/generated/assets/themes/sap_fiori_3/parameters-bundle.css.json +1 -1
  245. package/dist/generated/assets/themes/sap_glow/parameters-bundle.css.json +1 -1
  246. package/dist/generated/assets/themes/sap_horizon/parameters-bundle.css.json +1 -1
  247. package/dist/generated/i18n/i18n-defaults.d.ts +2 -1
  248. package/dist/generated/i18n/i18n-defaults.js +2 -1
  249. package/dist/generated/i18n/i18n-defaults.js.map +1 -1
  250. package/dist/generated/themes/AccordionSpotlight.css.d.ts +1 -1
  251. package/dist/generated/themes/AccordionSpotlight.css.js +1 -1
  252. package/dist/generated/themes/AccordionSpotlight.css.js.map +1 -1
  253. package/dist/generated/themes/ListGroupHeader.css.d.ts +1 -1
  254. package/dist/generated/themes/ListGroupHeader.css.js +1 -1
  255. package/dist/generated/themes/ListGroupHeader.css.js.map +1 -1
  256. package/dist/generated/themes/MastheadShell.css.d.ts +1 -1
  257. package/dist/generated/themes/MastheadShell.css.js +1 -1
  258. package/dist/generated/themes/MastheadShell.css.js.map +1 -1
  259. package/dist/generated/themes/SideNavigation.css.d.ts +1 -1
  260. package/dist/generated/themes/SideNavigation.css.js +1 -1
  261. package/dist/generated/themes/SideNavigation.css.js.map +1 -1
  262. package/dist/generated/themes/SideNavigationItem.css.d.ts +1 -1
  263. package/dist/generated/themes/SideNavigationItem.css.js +1 -1
  264. package/dist/generated/themes/SideNavigationItem.css.js.map +1 -1
  265. package/dist/generated/themes/SideNavigationMobile.css.d.ts +1 -1
  266. package/dist/generated/themes/SideNavigationMobile.css.js +1 -1
  267. package/dist/generated/themes/SideNavigationMobile.css.js.map +1 -1
  268. package/dist/generated/themes/SideNavigationSubItem.css.d.ts +1 -1
  269. package/dist/generated/themes/SideNavigationSubItem.css.js +1 -1
  270. package/dist/generated/themes/SideNavigationSubItem.css.js.map +1 -1
  271. package/dist/generated/themes/Slider.css.d.ts +1 -1
  272. package/dist/generated/themes/Slider.css.js +1 -1
  273. package/dist/generated/themes/Slider.css.js.map +1 -1
  274. package/dist/generated/themes/Table.css.d.ts +1 -1
  275. package/dist/generated/themes/Table.css.js +1 -1
  276. package/dist/generated/themes/Table.css.js.map +1 -1
  277. package/dist/generated/themes/sap_fiori_3/parameters-bundle.css.d.ts +1 -1
  278. package/dist/generated/themes/sap_fiori_3/parameters-bundle.css.js +1 -1
  279. package/dist/generated/themes/sap_fiori_3/parameters-bundle.css.js.map +1 -1
  280. package/dist/generated/themes/sap_glow/parameters-bundle.css.d.ts +1 -1
  281. package/dist/generated/themes/sap_glow/parameters-bundle.css.js +1 -1
  282. package/dist/generated/themes/sap_glow/parameters-bundle.css.js.map +1 -1
  283. package/dist/generated/themes/sap_horizon/parameters-bundle.css.d.ts +1 -1
  284. package/dist/generated/themes/sap_horizon/parameters-bundle.css.js +1 -1
  285. package/dist/generated/themes/sap_horizon/parameters-bundle.css.js.map +1 -1
  286. package/dist/messagebundle.properties +3 -0
  287. package/dist/vscode.html-custom-data.json +16 -6
  288. package/dist/web-types.json +41 -11
  289. package/package.json +8 -8
  290. package/src/AccordionItemTemplate.tsx +1 -0
  291. package/src/AccordionSpotlight.ts +35 -6
  292. package/src/AccordionSpotlightItem.ts +3 -1
  293. package/src/Carousel.ts +22 -3
  294. package/src/CountrySelector.ts +1 -3
  295. package/src/List.ts +21 -4
  296. package/src/ListGroupHeader.ts +5 -1
  297. package/src/ListGroupHeaderBase.ts +16 -2
  298. package/src/ListGroupHeaderTemplate.tsx +29 -47
  299. package/src/ListItem.ts +14 -13
  300. package/src/ListItemBase.ts +14 -1
  301. package/src/ListItemTemplate.tsx +4 -4
  302. package/src/ListSelectAllTemplate.tsx +10 -8
  303. package/src/ListTemplate.tsx +14 -10
  304. package/src/MastheadCountrySelector.ts +18 -0
  305. package/src/MastheadCountrySelectorTemplate.tsx +2 -0
  306. package/src/MessageStrip.ts +7 -0
  307. package/src/Search.ts +48 -13
  308. package/src/SearchTemplate.tsx +3 -1
  309. package/src/SearchableListBase.ts +15 -3
  310. package/src/SearchableListBaseTemplate.tsx +54 -39
  311. package/src/SelectBase.ts +130 -144
  312. package/src/SelectBox.ts +21 -7
  313. package/src/SelectBoxTemplate.tsx +10 -9
  314. package/src/SideNavigation.ts +17 -0
  315. package/src/SideNavigationItem.ts +2 -0
  316. package/src/SideNavigationItemTemplate.tsx +97 -0
  317. package/src/SideNavigationMobile.ts +53 -2
  318. package/src/SideNavigationMobileTemplate.tsx +3 -5
  319. package/src/SideNavigationSubItem.ts +19 -6
  320. package/src/SideNavigationSubItemTemplate.tsx +10 -7
  321. package/src/SideNavigationTemplate.tsx +17 -0
  322. package/src/TagGroup.ts +32 -0
  323. package/src/TagGroupTemplate.tsx +1 -1
  324. package/src/generated/i18n/i18n-defaults.ts +2 -2
  325. package/src/generated/themes/AccordionSpotlight.css.ts +1 -1
  326. package/src/generated/themes/ListGroupHeader.css.ts +1 -1
  327. package/src/generated/themes/MastheadShell.css.ts +1 -1
  328. package/src/generated/themes/SideNavigation.css.ts +1 -1
  329. package/src/generated/themes/SideNavigationItem.css.ts +1 -1
  330. package/src/generated/themes/SideNavigationMobile.css.ts +1 -1
  331. package/src/generated/themes/SideNavigationSubItem.css.ts +1 -1
  332. package/src/generated/themes/Slider.css.ts +1 -1
  333. package/src/generated/themes/Table.css.ts +1 -1
  334. package/src/generated/themes/sap_fiori_3/parameters-bundle.css.ts +1 -1
  335. package/src/generated/themes/sap_glow/parameters-bundle.css.ts +1 -1
  336. package/src/generated/themes/sap_horizon/parameters-bundle.css.ts +1 -1
  337. package/src/i18n/messagebundle.properties +3 -0
  338. package/src/themes/AccordionSpotlight.css +9 -9
  339. package/src/themes/ListGroupHeader.css +2 -43
  340. package/src/themes/MastheadShell.css +13 -1
  341. package/src/themes/SideNavigation.css +43 -8
  342. package/src/themes/SideNavigationItem.css +56 -6
  343. package/src/themes/SideNavigationMobile.css +62 -15
  344. package/src/themes/SideNavigationSubItem.css +14 -109
  345. package/src/themes/Slider.css +25 -11
  346. package/src/themes/Table.css +6 -1
  347. package/dist/assets/messagebundle_ar-C3EXytoC.js +0 -1
  348. package/dist/assets/messagebundle_ar-DmZrrjEF.js +0 -1
  349. package/dist/assets/messagebundle_bg-BaZ97Q_b.js +0 -1
  350. package/dist/assets/messagebundle_bg-CgU7GPvK.js +0 -1
  351. package/dist/assets/messagebundle_ca-BwjVUbUA.js +0 -1
  352. package/dist/assets/messagebundle_ca-YiUGbO_8.js +0 -1
  353. package/dist/assets/messagebundle_cnr-CN2hPZIN.js +0 -1
  354. package/dist/assets/messagebundle_cnr-zdEdPJvc.js +0 -1
  355. package/dist/assets/messagebundle_cs-CGbnEjza.js +0 -1
  356. package/dist/assets/messagebundle_cy-BF0YH9Iz.js +0 -1
  357. package/dist/assets/messagebundle_cy-CUiGsjO6.js +0 -1
  358. package/dist/assets/messagebundle_da-CWKLQJiq.js +0 -1
  359. package/dist/assets/messagebundle_da-bTkr4pUc.js +0 -1
  360. package/dist/assets/messagebundle_de-BmnClk4G.js +0 -1
  361. package/dist/assets/messagebundle_de-vB6qhgvG.js +0 -1
  362. package/dist/assets/messagebundle_el-DKdItEgW.js +0 -1
  363. package/dist/assets/messagebundle_el-Gv1Ly8aj.js +0 -1
  364. package/dist/assets/messagebundle_en-DbKo-Dkl.js +0 -1
  365. package/dist/assets/messagebundle_en-DcV886MF.js +0 -1
  366. package/dist/assets/messagebundle_en_GB-Be93_Z4H.js +0 -1
  367. package/dist/assets/messagebundle_en_GB-CFh7e8hQ.js +0 -1
  368. package/dist/assets/messagebundle_en_US_sappsd-HCarC-Yr.js +0 -1
  369. package/dist/assets/messagebundle_en_US_saprigi-CCHFk7YZ.js +0 -1
  370. package/dist/assets/messagebundle_en_US_saptrc-B8AIRzlo.js +0 -1
  371. package/dist/assets/messagebundle_en_US_saptrc-yJ3PcdEm.js +0 -1
  372. package/dist/assets/messagebundle_es-BH-a8BxO.js +0 -1
  373. package/dist/assets/messagebundle_es-Dt93wbGV.js +0 -1
  374. package/dist/assets/messagebundle_es_MX-BedlYlF3.js +0 -1
  375. package/dist/assets/messagebundle_es_MX-COPqooo9.js +0 -1
  376. package/dist/assets/messagebundle_et-BsYgDw46.js +0 -1
  377. package/dist/assets/messagebundle_et-UwpqUE-p.js +0 -1
  378. package/dist/assets/messagebundle_fi-BN3UWEz0.js +0 -1
  379. package/dist/assets/messagebundle_fi-Cwf7Puui.js +0 -1
  380. package/dist/assets/messagebundle_fr-43w09LAE.js +0 -1
  381. package/dist/assets/messagebundle_fr-CVRaf9_H.js +0 -1
  382. package/dist/assets/messagebundle_fr_CA-BM04X6xU.js +0 -1
  383. package/dist/assets/messagebundle_fr_CA-CdnVYumi.js +0 -1
  384. package/dist/assets/messagebundle_hi-DfeonbAH.js +0 -1
  385. package/dist/assets/messagebundle_hi-JRJlP9Uh.js +0 -1
  386. package/dist/assets/messagebundle_hr-CKOnn34q.js +0 -1
  387. package/dist/assets/messagebundle_hr-CbyIBlH3.js +0 -1
  388. package/dist/assets/messagebundle_hu-DF1gQudE.js +0 -1
  389. package/dist/assets/messagebundle_hu-D_IQ9kTy.js +0 -1
  390. package/dist/assets/messagebundle_id-B0K1usj4.js +0 -1
  391. package/dist/assets/messagebundle_id-gDJYoaGq.js +0 -1
  392. package/dist/assets/messagebundle_it-B80_R2Ih.js +0 -1
  393. package/dist/assets/messagebundle_it-CVqU4g6t.js +0 -1
  394. package/dist/assets/messagebundle_iw-BoelOIS4.js +0 -1
  395. package/dist/assets/messagebundle_iw-iMDtLxaa.js +0 -1
  396. package/dist/assets/messagebundle_ja-BlRbv4vb.js +0 -1
  397. package/dist/assets/messagebundle_ja-BrDH-19-.js +0 -1
  398. package/dist/assets/messagebundle_kk-C7VPek1-.js +0 -1
  399. package/dist/assets/messagebundle_kk-DhAT_bim.js +0 -1
  400. package/dist/assets/messagebundle_ko-CIqP8x6n.js +0 -1
  401. package/dist/assets/messagebundle_ko-DgD6uyZ5.js +0 -1
  402. package/dist/assets/messagebundle_lt-BV0kKrY0.js +0 -1
  403. package/dist/assets/messagebundle_lv-5IcjoxWD.js +0 -1
  404. package/dist/assets/messagebundle_lv-DDBi7iKe.js +0 -1
  405. package/dist/assets/messagebundle_mk-BUrn04sZ.js +0 -1
  406. package/dist/assets/messagebundle_mk-P5veRdg2.js +0 -1
  407. package/dist/assets/messagebundle_ms-9VDLR5en.js +0 -1
  408. package/dist/assets/messagebundle_ms-CB8sQUg2.js +0 -1
  409. package/dist/assets/messagebundle_nl-BaAgPO7h.js +0 -1
  410. package/dist/assets/messagebundle_nl-f1Up3dB9.js +0 -1
  411. package/dist/assets/messagebundle_no-C-_ldp7o.js +0 -1
  412. package/dist/assets/messagebundle_no-DRSqWQ-C.js +0 -1
  413. package/dist/assets/messagebundle_pl-BQoPaokq.js +0 -1
  414. package/dist/assets/messagebundle_pl-DBO1atMe.js +0 -1
  415. package/dist/assets/messagebundle_pt-BNEglYxa.js +0 -1
  416. package/dist/assets/messagebundle_pt-DgAMHmW-.js +0 -1
  417. package/dist/assets/messagebundle_pt_PT-BtYzp9KB.js +0 -1
  418. package/dist/assets/messagebundle_pt_PT-D1Ef8kUU.js +0 -1
  419. package/dist/assets/messagebundle_ro-CuDPp2fe.js +0 -1
  420. package/dist/assets/messagebundle_ro-D591wJ6f.js +0 -1
  421. package/dist/assets/messagebundle_ru-D0NridWi.js +0 -1
  422. package/dist/assets/messagebundle_ru-I8YLCfrn.js +0 -1
  423. package/dist/assets/messagebundle_sh-BswdbSRi.js +0 -1
  424. package/dist/assets/messagebundle_sh-Dw2y_oct.js +0 -1
  425. package/dist/assets/messagebundle_sk-BG4S4ZVk.js +0 -1
  426. package/dist/assets/messagebundle_sl-CAnJO_8X.js +0 -1
  427. package/dist/assets/messagebundle_sl-kpVWxIp_.js +0 -1
  428. package/dist/assets/messagebundle_sr-BTWvO8VQ.js +0 -1
  429. package/dist/assets/messagebundle_sr-VJmRSdj4.js +0 -1
  430. package/dist/assets/messagebundle_sv-B-RCgnW_.js +0 -1
  431. package/dist/assets/messagebundle_sv-Bd4wCcDb.js +0 -1
  432. package/dist/assets/messagebundle_th-CMHmLdI3.js +0 -1
  433. package/dist/assets/messagebundle_th-CZ1imsCy.js +0 -1
  434. package/dist/assets/messagebundle_tr-BfWAYIdW.js +0 -1
  435. package/dist/assets/messagebundle_tr-D-BnBirv.js +0 -1
  436. package/dist/assets/messagebundle_uk-DhxIThVl.js +0 -1
  437. package/dist/assets/messagebundle_uk-HU8hI0yj.js +0 -1
  438. package/dist/assets/messagebundle_vi-BUTqUKd4.js +0 -1
  439. package/dist/assets/messagebundle_vi-D1El4_Wj.js +0 -1
  440. package/dist/assets/messagebundle_zh_CN-Dt0azUea.js +0 -1
  441. package/dist/assets/messagebundle_zh_CN-Ofgx2uXY.js +0 -1
  442. package/dist/assets/messagebundle_zh_TW-5lv7yYS1.js +0 -1
  443. package/dist/assets/messagebundle_zh_TW-LSErOAsd.js +0 -1
  444. package/dist/assets/parameters-bundle.css-B68EyCuR.js +0 -278
  445. package/dist/assets/parameters-bundle.css-BkJSEiFx.js +0 -278
  446. package/dist/assets/parameters-bundle.css-CI4HNvFw.js +0 -1
  447. package/dist/assets/parameters-bundle.css-COeynv6D.js +0 -277
  448. package/dist/assets/parameters-bundle.css-CRa5DITh.js +0 -1
  449. package/dist/assets/parameters-bundle.css-CnIzAMdG.js +0 -3
  450. package/dist/assets/parameters-bundle.css-CsV5qbZp.js +0 -3
  451. package/dist/assets/parameters-bundle.css-DCvHNL3s.js +0 -3
  452. package/dist/assets/parameters-bundle.css-DK40uKOQ.js +0 -3
  453. package/dist/assets/parameters-bundle.css-DMfTAqMv.js +0 -2
  454. package/dist/assets/parameters-bundle.css-DO35k9r0.js +0 -2
  455. package/dist/assets/parameters-bundle.css-Df7wtRW4.js +0 -2
  456. package/dist/assets/parameters-bundle.css-DvAfqdlT.js +0 -3
  457. package/dist/assets/parameters-bundle.css-KoXGNyLG.js +0 -3
  458. package/dist/assets/parameters-bundle.css-P_M_rm9z.js +0 -3
  459. package/dist/assets/parameters-bundle.css-UJIxXHL5.js +0 -2
  460. package/dist/assets/parameters-bundle.css-co26r5Nz.js +0 -3
  461. package/dist/assets/parameters-bundle.css-uT62L0va.js +0 -3
  462. package/dist/css/themes/SideNavigationMobileDropdown.css +0 -1
  463. package/dist/generated/themes/SideNavigationMobileDropdown.css.d.ts +0 -2
  464. package/dist/generated/themes/SideNavigationMobileDropdown.css.js +0 -8
  465. package/dist/generated/themes/SideNavigationMobileDropdown.css.js.map +0 -1
  466. package/src/generated/themes/SideNavigationMobileDropdown.css.ts +0 -9
  467. package/src/themes/SideNavigationMobileDropdown.css +0 -36
@@ -362,18 +362,27 @@ describe("List - collapsible group header uses tree pattern", () => {
362
362
  .find(".udex-list__group-content").should("have.attr", "role", "treeitem");
363
363
  });
364
364
 
365
- it("SingleSelect collapsible header: nests the role=\"group\" content region inside the treeitem (conformant tree)", () => {
365
+ // Updated: the header owns a same-shadow sibling group without including its leaves in the visible label.
366
+ it("SingleSelect collapsible header: owns the sibling content group without nesting its slot", () => {
366
367
  cy.mount(collapsibleListSingleSelect);
367
368
  cy.get("#group-header-collapsible").shadow()
368
- .find(".udex-list__group-list > .udex-list__group-content--nested[role='treeitem']").should("exist");
369
- // The content region is a descendant of the treeitem, not a sibling.
370
- cy.get("#group-header-collapsible").shadow()
371
- .find(".udex-list__group-content--nested[role='treeitem'] .udex-list__group-list__content[role='group']").should("exist");
372
- cy.get("#group-header-collapsible").shadow()
373
- .find(".udex-list__group-list > .udex-list__group-list__content[role='group']").should("not.exist");
374
- // The visible header row wrapper now sits inside the treeitem.
375
- cy.get("#group-header-collapsible").shadow()
376
- .find(".udex-list__group-content--nested[role='treeitem'] > .udex-list__group-header-row").should("exist");
369
+ .find(".udex-list__group-list > .udex-list__group-content.udex-list__group-header-wrap[role='treeitem']")
370
+ .should(UDExHeader => {
371
+ const UDExRow = UDExHeader[0];
372
+ const UDExShadow = UDExRow.getRootNode() as ShadowRoot;
373
+ const UDExOwnedId = UDExRow.getAttribute("aria-owns");
374
+ expect(UDExOwnedId).to.match(/^\S+$/);
375
+ expect(UDExRow.getAttribute("aria-controls")).to.equal(UDExOwnedId);
376
+ const UDExGroups = UDExShadow.querySelectorAll(`[id="${UDExOwnedId}"]`);
377
+ expect(UDExGroups).to.have.length(1);
378
+ const UDExGroup = UDExGroups[0];
379
+ expect(UDExGroup.matches(".udex-list__group-list__content[role=group]")).to.equal(true);
380
+ expect(UDExGroup.getRootNode()).to.equal(UDExShadow);
381
+ expect(UDExGroup.parentElement).to.equal(UDExRow.parentElement);
382
+ expect(UDExRow.nextElementSibling).to.equal(UDExGroup);
383
+ expect(UDExRow.querySelector("slot, [role=group], [udex-list-item]")).to.equal(null);
384
+ expect(UDExGroup.querySelector("slot")!.assignedElements()).to.have.length(2);
385
+ });
377
386
  });
378
387
 
379
388
  it("child items expose accessible-role=\"treeitem\" on the host", () => {
@@ -448,6 +457,59 @@ describe("List - flat MultiSelect selection announcement", () => {
448
457
  });
449
458
  });
450
459
 
460
+ describe("List component - accessible role attribute reflection", () => {
461
+ it("preserves the default listbox role for standalone lists", () => {
462
+ cy.mount(<UDExList><UDExListItem>Item 1</UDExListItem></UDExList>);
463
+
464
+ cy.get("[udex-list]").should("have.attr", "accessible-role", "listbox");
465
+ cy.get("[udex-list]").shadow().find("#udex-list").should("have.attr", "role", "listbox");
466
+ });
467
+
468
+ it("reflects an empty role configuration when the host owns the role", () => {
469
+ cy.mount(<UDExList role="tree" accessibleRole=""><UDExListItem>Item 1</UDExListItem></UDExList>);
470
+
471
+ cy.get("[udex-list]").should("have.attr", "role", "tree").and("have.attr", "accessible-role", "");
472
+ cy.get("[udex-list]").shadow().find("#udex-list").should("have.attr", "role", "none");
473
+ });
474
+
475
+ it("updates the inner role when an explicit attribute is set", () => {
476
+ cy.mount(<UDExList><UDExListItem>Item 1</UDExListItem></UDExList>);
477
+
478
+ cy.get("[udex-list]").shadow().find("#udex-list").should("have.attr", "role", "listbox");
479
+ cy.get("[udex-list]").invoke("attr", "accessible-role", "tree");
480
+ cy.get("[udex-list]").shadow().find("#udex-list").should("have.attr", "role", "tree");
481
+ });
482
+ });
483
+
484
+ describe("ListItem - removing an explicit accessible role", () => {
485
+ (["SingleSelect", "MultiSelect", "SingleContent"] as const).forEach(UDExMode => {
486
+ it(`${UDExMode}: restores fallback roles and selection semantics after removeAttr`, () => {
487
+ cy.mount(<UDExListItem mode={UDExMode} accessibleRole="treeitem">Item 1</UDExListItem>);
488
+ const UDExRole = UDExMode === "SingleContent" ? "listitem" : "option";
489
+ const UDExRow = () => cy.get("[udex-list-item]").shadow().find("[part=item]");
490
+
491
+ UDExRow().should("have.attr", "role", "treeitem");
492
+ cy.get("[udex-list-item]").should("have.prop", "effectiveRole", "treeitem");
493
+ // Attribute removal resets accessibleRole to null, not an empty string.
494
+ cy.get("[udex-list-item]").invoke("removeAttr", "accessible-role");
495
+ cy.get("[udex-list-item]").should(UDExItem => {
496
+ expect(UDExItem).not.to.have.attr("accessible-role");
497
+ expect(UDExItem).to.have.prop("roleItem", UDExRole);
498
+ expect(UDExItem).to.have.prop("effectiveRole", "option");
499
+ });
500
+ UDExRow().should(UDExItem => {
501
+ expect(UDExItem).to.have.attr("role", UDExRole);
502
+ expect(UDExItem).not.to.have.attr("aria-checked");
503
+ if (UDExMode === "SingleContent") {
504
+ expect(UDExItem).not.to.have.attr("aria-selected");
505
+ } else {
506
+ expect(UDExItem).to.have.attr("aria-selected", "false");
507
+ }
508
+ });
509
+ });
510
+ });
511
+ });
512
+
451
513
  describe("List component - SingleContent accessible name", () => {
452
514
  it("uses accessible-name as aria-label when only accessible-name is set", () => {
453
515
  cy.mount(
@@ -547,3 +609,555 @@ describe("List component - selection modes keep listbox/option role", () => {
547
609
  });
548
610
  });
549
611
  });
612
+
613
+ describe("List - standalone grouped MultiSelect keyboard regressions", () => {
614
+ const UDExHeaderRow = (UDExId = "keyboard-group-1") =>
615
+ cy.get(`[udex-list-group-header]#${UDExId}`).shadow()
616
+ .find("[udex-list-item]#group-heading").shadow().find("[part=item]");
617
+ const UDExLeafRow = (UDExId: string) =>
618
+ cy.get(`[udex-list-item]#${UDExId}`).shadow().find("[part=item]");
619
+
620
+ const UDExAssertRovingTabStop = (UDExActiveId: string) => {
621
+ cy.get("[udex-list]#keyboard-list").find("[udex-list-group-header]").each(UDExGroup => {
622
+ UDExHeaderRow(UDExGroup[0].id)
623
+ .should("have.attr", "tabindex", UDExGroup[0].id === UDExActiveId ? "0" : "-1");
624
+ });
625
+ cy.get("[udex-list]#keyboard-list").find("[udex-list-item]").each(UDExItem => {
626
+ UDExLeafRow(UDExItem[0].id)
627
+ .should("have.attr", "tabindex", UDExItem[0].id === UDExActiveId ? "0" : "-1");
628
+ });
629
+ };
630
+
631
+ beforeEach(() => {
632
+ cy.mount(
633
+ <div id="list-keyboard-fixture">
634
+ <button id="before-list" type="button">Before list</button>
635
+ <UDExList id="keyboard-list" mode="MultiSelect" accessible-name="Grouped choices">
636
+ <UDExListGroupHeader id="keyboard-group-1" label="First group">
637
+ <UDExListItem id="keyboard-alpha" label="Alpha" />
638
+ <UDExListItem id="keyboard-disabled" label="Unavailable" disabled />
639
+ <UDExListItem id="keyboard-beta" label="Beta" />
640
+ </UDExListGroupHeader>
641
+ <UDExListGroupHeader id="keyboard-group-2" label="Second group">
642
+ <UDExListItem id="keyboard-gamma" label="Gamma" />
643
+ </UDExListGroupHeader>
644
+ </UDExList>
645
+ <button id="after-list" type="button">After list</button>
646
+ </div>
647
+ );
648
+ cy.get("#list-keyboard-fixture").then(UDExFixture => {
649
+ UDExFixture[0].addEventListener("selection-change", cy.stub().as("selectionChange"));
650
+ });
651
+
652
+ // Native entry is essential: focusing a row directly masks a missing tabindex.
653
+ UDExHeaderRow().should("exist");
654
+ cy.get("#before-list").realClick().should("be.focused");
655
+ cy.realPress("Tab");
656
+ UDExHeaderRow().should("be.focused");
657
+ });
658
+
659
+ it("Tab reaches the first actual shadow header row with option semantics", () => {
660
+ cy.get("[udex-list]#keyboard-list").shadow().find("#udex-list")
661
+ .should("have.attr", "role", "listbox");
662
+ UDExHeaderRow().should("have.attr", "role", "option");
663
+ UDExHeaderRow().should("have.attr", "aria-selected", "false");
664
+ UDExHeaderRow().find("[part=title]").should("have.text", "First group");
665
+ cy.get("@selectionChange").should("not.have.been.called");
666
+ });
667
+
668
+ it("ArrowDown visits enabled children, skips the disabled child and reaches the next header", () => {
669
+ cy.realPress("ArrowDown");
670
+ UDExLeafRow("keyboard-alpha").should("be.focused");
671
+ cy.realPress("ArrowDown");
672
+ UDExLeafRow("keyboard-beta").should("be.focused");
673
+ UDExLeafRow("keyboard-disabled").should("have.attr", "aria-disabled", "true");
674
+ UDExLeafRow("keyboard-disabled").should("have.attr", "tabindex", "-1");
675
+ cy.realPress("ArrowDown");
676
+ UDExHeaderRow("keyboard-group-2").should("be.focused");
677
+ cy.realPress("ArrowDown");
678
+ UDExLeafRow("keyboard-gamma").should("be.focused");
679
+ cy.get("@selectionChange").should("not.have.been.called");
680
+ });
681
+
682
+ it("ArrowUp returns through headers and enabled children while skipping the disabled child", () => {
683
+ cy.realPress("End");
684
+ UDExLeafRow("keyboard-gamma").should("be.focused");
685
+ cy.realPress("ArrowUp");
686
+ UDExHeaderRow("keyboard-group-2").should("be.focused");
687
+ cy.realPress("ArrowUp");
688
+ UDExLeafRow("keyboard-beta").should("be.focused");
689
+ cy.realPress("ArrowUp");
690
+ UDExLeafRow("keyboard-alpha").should("be.focused");
691
+ cy.realPress("ArrowUp");
692
+ UDExHeaderRow().should("be.focused");
693
+ cy.get("@selectionChange").should("not.have.been.called");
694
+ });
695
+
696
+ it("Home and End move between the first header and last enabled leaf without selecting", () => {
697
+ cy.realPress("End");
698
+ UDExLeafRow("keyboard-gamma").should("be.focused");
699
+ cy.realPress("Home");
700
+ UDExHeaderRow().should("be.focused");
701
+ cy.get("@selectionChange").should("not.have.been.called");
702
+ });
703
+
704
+ it("keeps one roving row tabindex and lets Tab leave the list", () => {
705
+ UDExAssertRovingTabStop("keyboard-group-1");
706
+ cy.realPress("End");
707
+ UDExLeafRow("keyboard-gamma").should("be.focused");
708
+ UDExAssertRovingTabStop("keyboard-gamma");
709
+ cy.realPress("Tab");
710
+ cy.get("#after-list").should("be.focused");
711
+ });
712
+
713
+ (["Space", "Enter"] as const).forEach(UDExKey => {
714
+ it(`${UDExKey} toggles the focused leaf and bubbles its selection-change event`, () => {
715
+ cy.realPress("ArrowDown");
716
+ UDExLeafRow("keyboard-alpha").should("be.focused");
717
+ cy.realPress(UDExKey);
718
+ UDExLeafRow("keyboard-alpha").should("have.attr", "aria-selected", "true");
719
+ UDExLeafRow("keyboard-beta").should("have.attr", "aria-selected", "false");
720
+ UDExLeafRow("keyboard-disabled").should("have.attr", "aria-selected", "false");
721
+ cy.get("@selectionChange").should("have.been.calledOnce")
722
+ .its("firstCall.args.0.detail.item.id").should("equal", "keyboard-alpha");
723
+
724
+ cy.realPress(UDExKey);
725
+ UDExLeafRow("keyboard-alpha").should("have.attr", "aria-selected", "false");
726
+ UDExLeafRow("keyboard-alpha").should("be.focused");
727
+ cy.get("@selectionChange").should("have.been.calledTwice")
728
+ .its("lastCall.args.0.detail.item.id").should("equal", "keyboard-alpha");
729
+ });
730
+
731
+ it(`${UDExKey} toggles only the focused group's enabled children`, () => {
732
+ cy.realPress(UDExKey);
733
+ UDExLeafRow("keyboard-alpha").should("have.attr", "aria-selected", "true");
734
+ UDExLeafRow("keyboard-beta").should("have.attr", "aria-selected", "true");
735
+ UDExLeafRow("keyboard-disabled").should("have.attr", "aria-selected", "false");
736
+ UDExLeafRow("keyboard-gamma").should("have.attr", "aria-selected", "false");
737
+ UDExHeaderRow().should("be.focused");
738
+
739
+ cy.realPress(UDExKey);
740
+ UDExLeafRow("keyboard-alpha").should("have.attr", "aria-selected", "false");
741
+ UDExLeafRow("keyboard-beta").should("have.attr", "aria-selected", "false");
742
+ UDExHeaderRow().should("be.focused");
743
+ });
744
+ });
745
+ });
746
+
747
+ describe("List - SingleSelect collapsible header names and ownership", () => {
748
+ const UDExHeaderRow = (UDExIndex = 0) =>
749
+ cy.get("[udex-list-group-header]").eq(UDExIndex).shadow()
750
+ .find(".udex-list__group-content.udex-list__group-header-wrap");
751
+
752
+ [false, true].forEach(UDExRichLabel => {
753
+ ["", "Digital Builders"].forEach(UDExSupportingText => {
754
+ it(`names a ${UDExRichLabel ? "rich" : "plain"} heading ${UDExSupportingText ? "with" : "without"} supporting text, excluding leaves and the chevron`, () => {
755
+ cy.mount(
756
+ <UDExList mode="SingleSelect">
757
+ <UDExListGroupHeader
758
+ collapsible
759
+ label={UDExRichLabel ? "<b>Programming</b> Languages" : "Programming Languages"}
760
+ supporting-text={UDExSupportingText}>
761
+ <UDExListItem label="JavaScript" />
762
+ <UDExListItem label="Python" />
763
+ </UDExListGroupHeader>
764
+ </UDExList>
765
+ );
766
+
767
+ UDExHeaderRow().find("#group-heading").should("have.text", "Programming Languages");
768
+ if (UDExRichLabel) {
769
+ UDExHeaderRow().find("#group-heading b").should("have.text", "Programming");
770
+ }
771
+ if (UDExSupportingText) {
772
+ UDExHeaderRow().find("#group-supporting-text").should("have.text", UDExSupportingText);
773
+ } else {
774
+ UDExHeaderRow().find("#group-supporting-text").should("not.exist");
775
+ }
776
+ UDExHeaderRow().find("[udex-button].udex-list__group-heading__icon").should("exist");
777
+ UDExHeaderRow().should(UDExHeader => {
778
+ expect(UDExHeader).to.have.attr("role", "treeitem");
779
+ expect(UDExHeader).to.have.attr("tabindex", "0");
780
+ expect(UDExHeader).to.have.attr("aria-labelledby", UDExSupportingText
781
+ ? "group-heading group-supporting-text" : "group-heading");
782
+ // Resolve the name sources in this shadow root, not via document-global IDs.
783
+ const UDExShadow = UDExHeader[0].getRootNode() as ShadowRoot;
784
+ const UDExName = UDExHeader.attr("aria-labelledby")!.split(" ").map(UDExId => {
785
+ const UDExLabels = UDExShadow.querySelectorAll(`[id="${UDExId}"]`);
786
+ expect(UDExLabels).to.have.length(1);
787
+ expect(UDExHeader[0].contains(UDExLabels[0])).to.equal(true);
788
+ return UDExLabels[0].textContent!.trim();
789
+ }).join(" ");
790
+ expect(UDExName).to.equal(
791
+ ["Programming Languages", UDExSupportingText].filter(Boolean).join(" ")
792
+ );
793
+ expect(UDExHeader[0].querySelector(".udex-list__header")!.textContent!
794
+ .replace(/\s+/g, " ").trim()).to.equal(UDExName);
795
+ expect(UDExHeader[0].querySelector("slot, [role=group], [udex-list-item]")).to.equal(null);
796
+ expect(UDExHeader.text()).not.to.contain("JavaScript");
797
+ expect(UDExHeader.text()).not.to.contain("Python");
798
+ });
799
+ });
800
+ });
801
+ });
802
+
803
+ it("keeps unique same-shadow ownership and leaf focus through keyboard collapse and expansion", () => {
804
+ cy.mount(
805
+ <div>
806
+ <button id="before-owned-list" type="button">Before list</button>
807
+ <UDExList mode="SingleSelect" accessible-name="Grouped choices">
808
+ <UDExListGroupHeader collapsible label="First group">
809
+ <UDExListItem id="owned-leaf" label="Alpha" />
810
+ </UDExListGroupHeader>
811
+ <UDExListGroupHeader collapsible collapsed label="Second group">
812
+ <UDExListItem label="Beta" />
813
+ </UDExListGroupHeader>
814
+ </UDExList>
815
+ </div>
816
+ );
817
+
818
+ UDExHeaderRow().should("have.attr", "aria-expanded", "true");
819
+ UDExHeaderRow(1).should("have.attr", "aria-expanded", "false");
820
+ UDExHeaderRow().invoke("attr", "aria-owns").then(UDExFirstId => {
821
+ UDExHeaderRow(1).invoke("attr", "aria-owns").then(UDExSecondId => {
822
+ expect(UDExSecondId).to.match(/^\S+$/).and.not.equal(UDExFirstId);
823
+ const UDExAssertOwnership = () => {
824
+ cy.get("[udex-list-group-header]").each((UDExHost, UDExIndex) => {
825
+ cy.wrap(UDExHost).shadow().find(".udex-list__group-content").should(UDExHeader => {
826
+ const UDExRow = UDExHeader[0];
827
+ const UDExOwnedId = UDExRow.getAttribute("aria-owns");
828
+ expect(UDExOwnedId).to.equal([UDExFirstId, UDExSecondId][UDExIndex]);
829
+ expect(UDExRow.getAttribute("aria-controls")).to.equal(UDExOwnedId);
830
+ const UDExShadow = UDExHost[0].shadowRoot!;
831
+ expect(UDExRow.getRootNode()).to.equal(UDExShadow);
832
+ const UDExGroups = UDExShadow.querySelectorAll(`[id="${UDExOwnedId}"]`);
833
+ expect(UDExGroups).to.have.length(1);
834
+ expect(UDExGroups[0].matches(".udex-list__group-list__content[role=group]")).to.equal(true);
835
+ expect(UDExRow.nextElementSibling).to.equal(UDExGroups[0]);
836
+ expect(UDExRow.querySelector("slot, [role=group]")).to.equal(null);
837
+ expect(UDExGroups[0].querySelector("slot")!.assignedElements()).to.have.length(1);
838
+ });
839
+ });
840
+ };
841
+
842
+ UDExAssertOwnership();
843
+ cy.get("#before-owned-list").realClick().should("be.focused");
844
+ cy.realPress("Tab");
845
+ UDExHeaderRow().should("be.focused");
846
+ cy.realPress("ArrowLeft");
847
+ UDExHeaderRow().should("have.attr", "aria-expanded", "false");
848
+ UDExHeaderRow().should("be.focused");
849
+ cy.get("[udex-list-item]#owned-leaf").should("have.attr", "collapsed");
850
+ UDExAssertOwnership();
851
+
852
+ cy.realPress("ArrowDown");
853
+ UDExHeaderRow(1).should("be.focused");
854
+ cy.realPress("ArrowUp");
855
+ UDExHeaderRow().should("be.focused");
856
+ cy.realPress("ArrowRight");
857
+ UDExHeaderRow().should("have.attr", "aria-expanded", "true");
858
+ UDExHeaderRow().should("be.focused");
859
+ cy.get("[udex-list-item]#owned-leaf").should("not.have.attr", "collapsed");
860
+ UDExAssertOwnership();
861
+ cy.realPress("ArrowDown");
862
+ cy.get("[udex-list-item]#owned-leaf").shadow().find("[part=item]").should("be.focused");
863
+ cy.realPress("ArrowUp");
864
+ UDExHeaderRow().should("be.focused");
865
+ });
866
+ });
867
+ });
868
+
869
+ it("omits inner ownership and duplicate semantics in SelectBox-style host-ARIA mode", () => {
870
+ cy.mount(
871
+ <UDExList mode="SingleSelect">
872
+ <UDExListGroupHeader collapsible label="Host-owned group" _useHostAriaRole={true}>
873
+ <UDExListItem label="Alpha" />
874
+ </UDExListGroupHeader>
875
+ </UDExList>
876
+ );
877
+
878
+ UDExHeaderRow().should(UDExHeader => {
879
+ expect(UDExHeader).to.have.attr("role", "presentation");
880
+ ["aria-owns", "aria-controls", "aria-expanded", "aria-labelledby", "tabindex"].forEach(UDExAttribute => {
881
+ expect(UDExHeader).not.to.have.attr(UDExAttribute);
882
+ });
883
+ });
884
+ cy.get("[udex-list-group-header]").shadow()
885
+ .find(".udex-list__group-list > .udex-list__group-list__content[role=group] slot").should("exist");
886
+ });
887
+ });
888
+
889
+ describe("List - MultiSelect header host-ARIA Boolean binding regressions", () => {
890
+ const UDExLayouts = [
891
+ { name: "noncollapsible", collapsible: false, collapsed: false },
892
+ { name: "collapsible expanded", collapsible: true, collapsed: false },
893
+ { name: "collapsible collapsed", collapsible: true, collapsed: true },
894
+ ];
895
+
896
+ UDExLayouts.forEach(UDExLayout => {
897
+ [false, true].forEach(UDExHostAriaMode => {
898
+ // Updated: the nested host must remain transparent; only its actual row exposes tree state.
899
+ it(`${UDExLayout.name}: propagates _useHostAriaRole=${UDExHostAriaMode} to the nested header row`, () => {
900
+ cy.mount(
901
+ <div>
902
+ <button id="before-binding-list" type="button">Before list</button>
903
+ <UDExList mode="MultiSelect">
904
+ <UDExListGroupHeader
905
+ label="Binding group"
906
+ collapsible={UDExLayout.collapsible}
907
+ collapsed={UDExLayout.collapsed}
908
+ _useHostAriaRole={UDExHostAriaMode}>
909
+ <UDExListItem label="Child" />
910
+ </UDExListGroupHeader>
911
+ </UDExList>
912
+ </div>
913
+ );
914
+
915
+ cy.get("[udex-list-group-header]").should("have.prop", "_useHostAriaRole", UDExHostAriaMode);
916
+ const UDExNestedHeader = () => cy.get("[udex-list-group-header]").shadow().find("[udex-list-item]#group-heading");
917
+ UDExNestedHeader().should(UDExHeader => {
918
+ expect(UDExHeader).to.have.prop("_useHostAriaRole", UDExHostAriaMode);
919
+ expect(UDExHeader).to.have.attr("role", "none");
920
+ expect(UDExHeader[0].getAttributeNames().filter(UDExAttribute => UDExAttribute.startsWith("aria-")),
921
+ "presentational host omits all ARIA naming/state attributes").to.deep.equal([]);
922
+ // A false Boolean must be absent, never the present attribute string "false".
923
+ if (UDExHostAriaMode) {
924
+ expect(UDExHeader).to.have.attr("_use-host-aria-role");
925
+ } else {
926
+ expect(UDExHeader).not.to.have.attr("_use-host-aria-role");
927
+ }
928
+ });
929
+ UDExNestedHeader().shadow().find("[part=item]").should(UDExRow => {
930
+ if (UDExHostAriaMode) {
931
+ expect(UDExRow).to.have.attr("role", "presentation");
932
+ ["tabindex", "aria-selected", "aria-checked", "aria-expanded"].forEach(UDExAttribute => {
933
+ expect(UDExRow).not.to.have.attr(UDExAttribute);
934
+ });
935
+ } else {
936
+ expect(UDExRow).to.have.attr("role", UDExLayout.collapsible ? "treeitem" : "option");
937
+ expect(UDExRow).to.have.attr("tabindex", "0");
938
+ if (UDExLayout.collapsible) {
939
+ expect(UDExRow).to.have.attr("aria-expanded", String(!UDExLayout.collapsed));
940
+ expect(UDExRow).to.have.attr("aria-checked", "false");
941
+ expect(UDExRow).not.to.have.attr("aria-selected");
942
+ } else {
943
+ expect(UDExRow).not.to.have.attr("aria-expanded");
944
+ }
945
+ }
946
+ });
947
+
948
+ if (!UDExHostAriaMode) {
949
+ cy.get("#before-binding-list").realClick().should("be.focused");
950
+ cy.realPress("Tab");
951
+ UDExNestedHeader().shadow().find("[part=item]").should("be.focused");
952
+ }
953
+ });
954
+ });
955
+ });
956
+ });
957
+
958
+ describe("List - grouped SingleContent regressions", () => {
959
+ const UDExGroupedList = (
960
+ UDExMode: "SingleContent" | "SingleSelect" | "MultiSelect" = "SingleContent",
961
+ UDExMixed = false
962
+ ) => (
963
+ <div id="sc-grouped-fixture">
964
+ <button id="before-sc-grouped" type="button">Before list</button>
965
+ <UDExList id="sc-grouped-list" mode={UDExMode} accessible-name="Grouped information">
966
+ <UDExListGroupHeader id="sc-grouped-expanded" collapsible label="First group" supportingText="Details">
967
+ <UDExListItem id="sc-grouped-alpha" label="Alpha" />
968
+ </UDExListGroupHeader>
969
+ <UDExListGroupHeader id="sc-grouped-second" collapsible={!UDExMixed} collapsed={!UDExMixed} label="Second group">
970
+ <UDExListItem label="Beta" />
971
+ </UDExListGroupHeader>
972
+ {UDExMixed && <UDExListItem label="Ungrouped item" />}
973
+ </UDExList>
974
+ <button id="after-sc-grouped" type="button">After list</button>
975
+ </div>
976
+ );
977
+ const UDExInnerList = () => cy.get("#sc-grouped-list").shadow().find("#udex-list");
978
+ const UDExHeaderRow = () => cy.get("#sc-grouped-expanded").shadow().find(".udex-list__group-content");
979
+ const UDExSelectionSemantics = [
980
+ '[role="tree"]', '[role="treeitem"]', '[role="listbox"]', '[role="option"]',
981
+ "[aria-selected]", "[aria-checked]", "[aria-multiselectable]", "[aria-owns]",
982
+ ].join(", ");
983
+
984
+ const UDExAssertContentList = () => {
985
+ UDExInnerList().should("have.attr", "role", "list");
986
+ cy.get("#sc-grouped-list").shadow().find(UDExSelectionSemantics).should("not.exist");
987
+ cy.get("#sc-grouped-list").find("[udex-list-group-header]").each(UDExGroup => {
988
+ cy.wrap(UDExGroup).should(UDExHost => {
989
+ expect(UDExHost).to.have.prop("_treeMode", false);
990
+ expect(UDExHost).not.to.have.attr("_list-managed-tree-mode");
991
+ });
992
+ cy.wrap(UDExGroup).shadow().find(".udex-list__group").should("have.attr", "role", "listitem");
993
+ cy.wrap(UDExGroup).shadow().find('.udex-list__group[role="listitem"] [role="list"] > slot')
994
+ .should("have.length", 1).should(UDExSlot => {
995
+ expect((UDExSlot[0] as HTMLSlotElement).assignedElements())
996
+ .to.deep.equal(Array.from(UDExGroup[0].children));
997
+ });
998
+ cy.wrap(UDExGroup).shadow().find(UDExSelectionSemantics).should("not.exist");
999
+ });
1000
+ cy.get("#sc-grouped-list").find("[udex-list-item]").each(UDExItem => {
1001
+ cy.wrap(UDExItem).should(UDExHost => {
1002
+ expect(UDExHost).to.have.prop("mode", "SingleContent");
1003
+ expect(UDExHost).to.have.prop("accessibleRole", "");
1004
+ expect(UDExHost).not.to.have.attr("_list-managed-role");
1005
+ });
1006
+ cy.wrap(UDExItem).shadow().find("[part=item]").should("have.attr", "role", "listitem");
1007
+ cy.wrap(UDExItem).shadow().find(UDExSelectionSemantics).should("not.exist");
1008
+ });
1009
+ };
1010
+
1011
+ [false, true].forEach(UDExMixed => {
1012
+ it(`${UDExMixed ? "mixed groups and an ungrouped leaf" : "expanded and collapsed groups"} use nested lists without selection semantics`, () => {
1013
+ cy.mount(UDExGroupedList("SingleContent", UDExMixed));
1014
+ UDExAssertContentList();
1015
+ UDExInnerList().should("have.attr", "aria-label", "Grouped information");
1016
+ UDExHeaderRow().should(UDExHeader => {
1017
+ const UDExRow = UDExHeader[0];
1018
+ const UDExShadow = UDExRow.getRootNode() as ShadowRoot;
1019
+ expect(UDExHeader).to.have.attr("role", "button");
1020
+ expect(UDExHeader).to.have.attr("aria-expanded", "true");
1021
+ expect(UDExHeader).to.have.attr("aria-labelledby", "group-heading group-supporting-text");
1022
+ const UDExLabels = UDExRow.getAttribute("aria-labelledby")!.split(" ")
1023
+ .map(UDExId => UDExShadow.getElementById(UDExId)!.textContent!.trim());
1024
+ expect(UDExLabels.join(" ")).to.equal("First group Details");
1025
+ const UDExContent = UDExShadow.getElementById(UDExRow.getAttribute("aria-controls")!);
1026
+ expect(UDExContent).to.equal(UDExRow.nextElementSibling);
1027
+ expect(UDExContent!.getAttribute("role")).to.equal("list");
1028
+ expect(UDExRow.querySelector("slot, [role=list]")).to.equal(null);
1029
+ });
1030
+ if (!UDExMixed) {
1031
+ cy.get("#sc-grouped-second").shadow().find(".udex-list__group-content")
1032
+ .should("have.attr", "role", "button").and("have.attr", "aria-expanded", "false");
1033
+ }
1034
+ });
1035
+ });
1036
+
1037
+ it("Tab enters the collapse button; Enter, Space and Left/Right toggle it without selecting or losing focus", () => {
1038
+ cy.mount(UDExGroupedList());
1039
+ cy.get("#sc-grouped-fixture").then(UDExFixture => {
1040
+ UDExFixture[0].addEventListener("selection-change", cy.stub().as("scSelectionChange"));
1041
+ });
1042
+ UDExHeaderRow().should("have.attr", "role", "button");
1043
+ cy.get("#before-sc-grouped").realClick().should("be.focused");
1044
+ cy.realPress("Tab");
1045
+ UDExHeaderRow().should("be.focused");
1046
+
1047
+ (["Enter", "Space", "ArrowLeft"] as const).forEach(UDExKey => {
1048
+ cy.realPress(UDExKey);
1049
+ UDExHeaderRow().should("have.attr", "aria-expanded", "false");
1050
+ UDExHeaderRow().should("be.focused");
1051
+ cy.get("#sc-grouped-expanded").should("have.attr", "collapsed");
1052
+ cy.get("#sc-grouped-alpha").should("have.attr", "collapsed");
1053
+ cy.realPress(UDExKey === "ArrowLeft" ? "ArrowRight" : UDExKey);
1054
+ UDExHeaderRow().should("have.attr", "aria-expanded", "true");
1055
+ UDExHeaderRow().should("be.focused");
1056
+ cy.get("#sc-grouped-expanded").should("not.have.attr", "collapsed");
1057
+ cy.get("#sc-grouped-alpha").should("not.have.attr", "collapsed");
1058
+ });
1059
+ cy.realPress("Tab");
1060
+ cy.get("#sc-grouped-second").shadow().find(".udex-list__group-content").should("be.focused");
1061
+ cy.realPress("Tab");
1062
+ cy.get("#after-sc-grouped").should("be.focused");
1063
+ cy.get("@scSelectionChange").should("not.have.been.called");
1064
+ UDExAssertContentList();
1065
+ });
1066
+
1067
+ (["SingleSelect", "MultiSelect"] as const).forEach(UDExMode => {
1068
+ it(`${UDExMode} -> SingleContent -> ${UDExMode} clears List-owned tree semantics and rebuilds them`, () => {
1069
+ cy.mount(UDExGroupedList(UDExMode));
1070
+ const UDExAssertSelectionTree = () => {
1071
+ UDExInnerList().should("have.attr", "role", "tree");
1072
+ cy.get("#sc-grouped-list").find("[udex-list-group-header]").each(UDExGroup => {
1073
+ cy.wrap(UDExGroup).should(UDExHost => {
1074
+ expect(UDExHost).to.have.prop("_treeMode", true);
1075
+ expect(UDExHost).to.have.attr("_list-managed-tree-mode");
1076
+ });
1077
+ cy.wrap(UDExGroup).shadow().find(".udex-list__group").should("have.attr", "role", "none");
1078
+ cy.wrap(UDExGroup).shadow().find('[role="group"] > slot').should("have.length", 1);
1079
+ if (UDExMode === "MultiSelect") {
1080
+ cy.wrap(UDExGroup).shadow().find("[udex-list-item]#group-heading").shadow()
1081
+ .find("[part=item]").should("have.attr", "role", "treeitem");
1082
+ } else {
1083
+ cy.wrap(UDExGroup).shadow().find(".udex-list__group-content").should("have.attr", "role", "treeitem");
1084
+ }
1085
+ });
1086
+ cy.get("#sc-grouped-list").find("[udex-list-item]").each(UDExItem => {
1087
+ cy.wrap(UDExItem).should(UDExHost => {
1088
+ expect(UDExHost).to.have.prop("accessibleRole", "treeitem");
1089
+ expect(UDExHost).to.have.attr("_list-managed-role");
1090
+ });
1091
+ cy.wrap(UDExItem).shadow().find("[part=item]").should("have.attr", "role", "treeitem")
1092
+ .and("have.attr", UDExMode === "MultiSelect" ? "aria-checked" : "aria-selected", "false");
1093
+ });
1094
+ };
1095
+ UDExAssertSelectionTree();
1096
+ cy.get("#sc-grouped-list").invoke("prop", "mode", "SingleContent");
1097
+ UDExAssertContentList();
1098
+ UDExHeaderRow().should("have.attr", "role", "button");
1099
+ cy.get("#sc-grouped-list").invoke("prop", "mode", UDExMode);
1100
+ UDExAssertSelectionTree();
1101
+ });
1102
+ });
1103
+
1104
+ it("clears List-owned tree modes when the last collapsible group is removed", () => {
1105
+ cy.mount(UDExGroupedList("MultiSelect", true));
1106
+ UDExInnerList().should("have.attr", "role", "tree");
1107
+ cy.get("#sc-grouped-list").find("[udex-list-group-header]")
1108
+ .should("have.length", 2).each(UDExGroup => {
1109
+ cy.wrap(UDExGroup).should("have.attr", "_list-managed-tree-mode");
1110
+ });
1111
+ cy.get("#sc-grouped-expanded").invoke("prop", "collapsible", false).should("not.have.attr", "collapsible");
1112
+ // Re-render the List after changing its slotted group's configuration.
1113
+ cy.get("#sc-grouped-list").invoke("prop", "accessibleName", "Updated grouped information");
1114
+ UDExInnerList().should("have.attr", "role", "listbox");
1115
+ UDExInnerList().should("have.attr", "aria-multiselectable", "true");
1116
+ cy.get("#sc-grouped-list").find("[udex-list-group-header]").each(UDExGroup => {
1117
+ cy.wrap(UDExGroup).should(UDExHost => {
1118
+ expect(UDExHost).to.have.prop("_treeMode", false);
1119
+ expect(UDExHost).not.to.have.attr("_list-managed-tree-mode");
1120
+ });
1121
+ cy.wrap(UDExGroup).shadow().find("[udex-list-item]#group-heading").shadow()
1122
+ .find("[part=item]").should("have.attr", "role", "option");
1123
+ });
1124
+ cy.get("#sc-grouped-list").find("[udex-list-item]").each(UDExItem => {
1125
+ cy.wrap(UDExItem).should("not.have.attr", "_list-managed-role");
1126
+ cy.wrap(UDExItem).should("have.prop", "accessibleRole", "");
1127
+ cy.wrap(UDExItem).shadow().find("[part=item]").should("have.attr", "role", "option");
1128
+ });
1129
+ });
1130
+
1131
+ it("preserves externally supplied tree mode and host-owned roles in SingleContent", () => {
1132
+ cy.mount(
1133
+ <UDExList id="sc-host-tree" mode="SingleContent" role="tree" accessibleRole="">
1134
+ <UDExListGroupHeader collapsible label="Host-owned group" role="treeitem" aria-label="Host-owned group"
1135
+ aria-expanded="true" _treeMode={true} _useHostAriaRole={true}>
1136
+ <UDExListItem label="Alpha" role="treeitem" accessibleRole="treeitem" _useHostAriaRole={true} />
1137
+ </UDExListGroupHeader>
1138
+ </UDExList>
1139
+ );
1140
+ cy.get("#sc-host-tree").should("have.attr", "role", "tree");
1141
+ cy.get("#sc-host-tree").shadow().find("#udex-list").should("have.attr", "role", "none");
1142
+ cy.get("#sc-host-tree").find("[udex-list-group-header]").should(UDExGroup => {
1143
+ expect(UDExGroup).to.have.prop("_treeMode", true);
1144
+ expect(UDExGroup).to.have.prop("_useHostAriaRole", true);
1145
+ expect(UDExGroup).to.have.attr("role", "treeitem");
1146
+ expect(UDExGroup).to.have.attr("aria-expanded", "true");
1147
+ expect(UDExGroup).not.to.have.attr("_list-managed-tree-mode");
1148
+ }).shadow().find(".udex-list__group-content").should(UDExHeader => {
1149
+ expect(UDExHeader).to.have.attr("role", "presentation");
1150
+ ["tabindex", "aria-expanded", "aria-controls", "aria-labelledby", "aria-owns"].forEach(UDExAttribute => {
1151
+ expect(UDExHeader).not.to.have.attr(UDExAttribute);
1152
+ });
1153
+ });
1154
+ cy.get("#sc-host-tree").find("[udex-list-group-header]").shadow()
1155
+ .find('.udex-list__group[role="presentation"] [role="group"] > slot').should("have.length", 1);
1156
+ cy.get("#sc-host-tree").find("[udex-list-item]").should(UDExItem => {
1157
+ expect(UDExItem).to.have.attr("role", "treeitem");
1158
+ expect(UDExItem).to.have.prop("accessibleRole", "treeitem");
1159
+ expect(UDExItem).to.have.prop("_useHostAriaRole", true);
1160
+ expect(UDExItem).not.to.have.attr("_list-managed-role");
1161
+ }).shadow().find("[part=item]").should("have.attr", "role", "presentation");
1162
+ });
1163
+ });