@sapudex/web-components 2.60.0 → 2.62.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 (385) hide show
  1. package/cypress/specs/AccordionSpotlight.cy.tsx +43 -2
  2. package/cypress/specs/Carousel.cy.tsx +134 -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/SecondaryNavigationDesktop.cy.tsx +52 -3
  8. package/cypress/specs/SelectBox.cy.tsx +276 -136
  9. package/cypress/specs/SelectBoxAccessibility.cy.tsx +3109 -0
  10. package/cypress/specs/SideNavigation.cy.tsx +509 -0
  11. package/cypress/specs/Table.cy.tsx +90 -0
  12. package/cypress/specs/TagGroup.cy.tsx +168 -0
  13. package/cypress/support/component-imports.instrumented.ts +6 -0
  14. package/cypress/support/component-imports.src.ts +6 -0
  15. package/dist/AccordionSpotlight.d.ts +7 -2
  16. package/dist/AccordionSpotlight.js +31 -6
  17. package/dist/AccordionSpotlight.js.map +1 -1
  18. package/dist/AccordionSpotlightItem.d.ts +3 -1
  19. package/dist/AccordionSpotlightItem.js +3 -1
  20. package/dist/AccordionSpotlightItem.js.map +1 -1
  21. package/dist/Carousel.d.ts +2 -0
  22. package/dist/Carousel.js +35 -4
  23. package/dist/Carousel.js.map +1 -1
  24. package/dist/CountrySelector.js +1 -3
  25. package/dist/CountrySelector.js.map +1 -1
  26. package/dist/List.d.ts +2 -0
  27. package/dist/List.js +22 -4
  28. package/dist/List.js.map +1 -1
  29. package/dist/ListGroupHeader.js +5 -1
  30. package/dist/ListGroupHeader.js.map +1 -1
  31. package/dist/ListGroupHeaderBase.d.ts +2 -0
  32. package/dist/ListGroupHeaderBase.js +15 -2
  33. package/dist/ListGroupHeaderBase.js.map +1 -1
  34. package/dist/ListGroupHeaderTemplate.js +14 -22
  35. package/dist/ListGroupHeaderTemplate.js.map +1 -1
  36. package/dist/ListItem.d.ts +1 -2
  37. package/dist/ListItem.js +14 -12
  38. package/dist/ListItem.js.map +1 -1
  39. package/dist/ListItemBase.d.ts +5 -0
  40. package/dist/ListItemBase.js +11 -1
  41. package/dist/ListItemBase.js.map +1 -1
  42. package/dist/ListItemTemplate.js +1 -1
  43. package/dist/ListItemTemplate.js.map +1 -1
  44. package/dist/ListSelectAllTemplate.js +1 -1
  45. package/dist/ListSelectAllTemplate.js.map +1 -1
  46. package/dist/ListTemplate.js +2 -1
  47. package/dist/ListTemplate.js.map +1 -1
  48. package/dist/Pagination.d.ts +0 -1
  49. package/dist/Pagination.js +2 -2
  50. package/dist/Pagination.js.map +1 -1
  51. package/dist/Search.d.ts +13 -3
  52. package/dist/Search.js +36 -11
  53. package/dist/Search.js.map +1 -1
  54. package/dist/SearchableListBase.d.ts +2 -0
  55. package/dist/SearchableListBase.js +13 -3
  56. package/dist/SearchableListBase.js.map +1 -1
  57. package/dist/SearchableListBaseTemplate.js +42 -34
  58. package/dist/SearchableListBaseTemplate.js.map +1 -1
  59. package/dist/SecondaryNavigation.d.ts +2 -1
  60. package/dist/SecondaryNavigation.js.map +1 -1
  61. package/dist/SecondaryNavigationItem.js +12 -6
  62. package/dist/SecondaryNavigationItem.js.map +1 -1
  63. package/dist/SecondaryNavigationTemplate.js +1 -2
  64. package/dist/SecondaryNavigationTemplate.js.map +1 -1
  65. package/dist/SelectBase.d.ts +18 -33
  66. package/dist/SelectBase.js +125 -140
  67. package/dist/SelectBase.js.map +1 -1
  68. package/dist/SelectBox.d.ts +3 -0
  69. package/dist/SelectBox.js +19 -7
  70. package/dist/SelectBox.js.map +1 -1
  71. package/dist/SelectBoxTemplate.js +3 -3
  72. package/dist/SelectBoxTemplate.js.map +1 -1
  73. package/dist/SideNavigation.d.ts +23 -0
  74. package/dist/SideNavigation.js +39 -0
  75. package/dist/SideNavigation.js.map +1 -1
  76. package/dist/SideNavigationItem.d.ts +10 -0
  77. package/dist/SideNavigationItem.js +69 -0
  78. package/dist/SideNavigationItem.js.map +1 -1
  79. package/dist/SideNavigationItemTemplate.d.ts +2 -0
  80. package/dist/SideNavigationItemTemplate.js +15 -0
  81. package/dist/SideNavigationItemTemplate.js.map +1 -0
  82. package/dist/SideNavigationMobile.js +1 -2
  83. package/dist/SideNavigationMobile.js.map +1 -1
  84. package/dist/SideNavigationMobileTemplate.js +1 -1
  85. package/dist/SideNavigationMobileTemplate.js.map +1 -1
  86. package/dist/SideNavigationSubItem.d.ts +23 -0
  87. package/dist/SideNavigationSubItem.js +105 -1
  88. package/dist/SideNavigationSubItem.js.map +1 -1
  89. package/dist/SideNavigationSubItemTemplate.d.ts +2 -0
  90. package/dist/SideNavigationSubItemTemplate.js +9 -0
  91. package/dist/SideNavigationSubItemTemplate.js.map +1 -0
  92. package/dist/Table.js +1 -1
  93. package/dist/Table.js.map +1 -1
  94. package/dist/TableCell.d.ts +8 -2
  95. package/dist/TableCell.js +13 -11
  96. package/dist/TableCell.js.map +1 -1
  97. package/dist/TableCellBase.d.ts +2 -1
  98. package/dist/TableCellBase.js +9 -0
  99. package/dist/TableCellBase.js.map +1 -1
  100. package/dist/TableHeaderCell.d.ts +0 -1
  101. package/dist/TableHeaderCell.js +0 -4
  102. package/dist/TableHeaderCell.js.map +1 -1
  103. package/dist/TableRow.d.ts +10 -0
  104. package/dist/TableRow.js +23 -0
  105. package/dist/TableRow.js.map +1 -1
  106. package/dist/TagGroup.d.ts +3 -0
  107. package/dist/TagGroup.js +31 -0
  108. package/dist/TagGroup.js.map +1 -1
  109. package/dist/TagGroupTemplate.js +1 -1
  110. package/dist/TagGroupTemplate.js.map +1 -1
  111. package/dist/UploadItem.js +3 -4
  112. package/dist/UploadItem.js.map +1 -1
  113. package/dist/assets/{InputSuggestions-DyNcKgip.js → InputSuggestions-BPKrPqPb.js} +1 -1
  114. package/dist/assets/{ListItemStandardExpandableTextTemplate-qdKPzaOQ.js → ListItemStandardExpandableTextTemplate-DkdOcCxC.js} +1 -1
  115. package/dist/assets/{bundle.esm-sUYwSJOp.js → bundle.esm-17Yt5gDr.js} +234 -235
  116. package/dist/css/themes/AccordionSpotlight.css +1 -1
  117. package/dist/css/themes/Contact.css +1 -1
  118. package/dist/css/themes/EventRibbon.css +1 -1
  119. package/dist/css/themes/Feed.css +1 -1
  120. package/dist/css/themes/HeroBanner.css +1 -1
  121. package/dist/css/themes/ImageGridCloud.css +1 -1
  122. package/dist/css/themes/ImageGridTicker.css +1 -1
  123. package/dist/css/themes/ImageGridTickerItem.css +1 -1
  124. package/dist/css/themes/LinkList.css +1 -1
  125. package/dist/css/themes/ListGroupHeader.css +1 -1
  126. package/dist/css/themes/MastheadCountrySelector.css +1 -1
  127. package/dist/css/themes/MastheadItem.css +1 -1
  128. package/dist/css/themes/MastheadMenu.css +1 -1
  129. package/dist/css/themes/MastheadMenuItem.css +1 -1
  130. package/dist/css/themes/MastheadMobileMenu.css +1 -1
  131. package/dist/css/themes/MastheadProfileMenu.css +1 -1
  132. package/dist/css/themes/MastheadShell.css +1 -1
  133. package/dist/css/themes/MessageStrip.css +1 -1
  134. package/dist/css/themes/Modal.css +1 -1
  135. package/dist/css/themes/PromoTile.css +1 -1
  136. package/dist/css/themes/Quote.css +1 -1
  137. package/dist/css/themes/Review.css +1 -1
  138. package/dist/css/themes/ReviewItem.css +1 -1
  139. package/dist/css/themes/SecondaryNavigation.css +1 -1
  140. package/dist/css/themes/SecondaryNavigationItem.css +1 -1
  141. package/dist/css/themes/SelectBase.css +1 -1
  142. package/dist/css/themes/SideNavigation.css +1 -1
  143. package/dist/css/themes/SideNavigationItem.css +1 -1
  144. package/dist/css/themes/SideNavigationMobile.css +1 -1
  145. package/dist/css/themes/SideNavigationSubItem.css +1 -1
  146. package/dist/css/themes/TabNavigation.css +1 -1
  147. package/dist/css/themes/Table.css +1 -1
  148. package/dist/css/themes/TableCellBase.css +1 -1
  149. package/dist/css/themes/Upload.css +1 -1
  150. package/dist/css/themes/UploadItem.css +1 -1
  151. package/dist/custom-elements-internal.json +162 -19
  152. package/dist/custom-elements.json +151 -26
  153. package/dist/generated/i18n/i18n-defaults.d.ts +2 -1
  154. package/dist/generated/i18n/i18n-defaults.js +2 -1
  155. package/dist/generated/i18n/i18n-defaults.js.map +1 -1
  156. package/dist/generated/themes/AccordionSpotlight.css.d.ts +1 -1
  157. package/dist/generated/themes/AccordionSpotlight.css.js +1 -1
  158. package/dist/generated/themes/AccordionSpotlight.css.js.map +1 -1
  159. package/dist/generated/themes/Contact.css.d.ts +1 -1
  160. package/dist/generated/themes/Contact.css.js +1 -1
  161. package/dist/generated/themes/Contact.css.js.map +1 -1
  162. package/dist/generated/themes/EventRibbon.css.d.ts +1 -1
  163. package/dist/generated/themes/EventRibbon.css.js +1 -1
  164. package/dist/generated/themes/EventRibbon.css.js.map +1 -1
  165. package/dist/generated/themes/Feed.css.d.ts +1 -1
  166. package/dist/generated/themes/Feed.css.js +1 -1
  167. package/dist/generated/themes/Feed.css.js.map +1 -1
  168. package/dist/generated/themes/HeroBanner.css.d.ts +1 -1
  169. package/dist/generated/themes/HeroBanner.css.js +1 -1
  170. package/dist/generated/themes/HeroBanner.css.js.map +1 -1
  171. package/dist/generated/themes/ImageGridCloud.css.d.ts +1 -1
  172. package/dist/generated/themes/ImageGridCloud.css.js +1 -1
  173. package/dist/generated/themes/ImageGridCloud.css.js.map +1 -1
  174. package/dist/generated/themes/ImageGridTicker.css.d.ts +1 -1
  175. package/dist/generated/themes/ImageGridTicker.css.js +1 -1
  176. package/dist/generated/themes/ImageGridTicker.css.js.map +1 -1
  177. package/dist/generated/themes/ImageGridTickerItem.css.d.ts +1 -1
  178. package/dist/generated/themes/ImageGridTickerItem.css.js +1 -1
  179. package/dist/generated/themes/ImageGridTickerItem.css.js.map +1 -1
  180. package/dist/generated/themes/LinkList.css.d.ts +1 -1
  181. package/dist/generated/themes/LinkList.css.js +1 -1
  182. package/dist/generated/themes/LinkList.css.js.map +1 -1
  183. package/dist/generated/themes/ListGroupHeader.css.d.ts +1 -1
  184. package/dist/generated/themes/ListGroupHeader.css.js +1 -1
  185. package/dist/generated/themes/ListGroupHeader.css.js.map +1 -1
  186. package/dist/generated/themes/MastheadCountrySelector.css.d.ts +1 -1
  187. package/dist/generated/themes/MastheadCountrySelector.css.js +1 -1
  188. package/dist/generated/themes/MastheadCountrySelector.css.js.map +1 -1
  189. package/dist/generated/themes/MastheadItem.css.d.ts +1 -1
  190. package/dist/generated/themes/MastheadItem.css.js +1 -1
  191. package/dist/generated/themes/MastheadItem.css.js.map +1 -1
  192. package/dist/generated/themes/MastheadMenu.css.d.ts +1 -1
  193. package/dist/generated/themes/MastheadMenu.css.js +1 -1
  194. package/dist/generated/themes/MastheadMenu.css.js.map +1 -1
  195. package/dist/generated/themes/MastheadMenuItem.css.d.ts +1 -1
  196. package/dist/generated/themes/MastheadMenuItem.css.js +1 -1
  197. package/dist/generated/themes/MastheadMenuItem.css.js.map +1 -1
  198. package/dist/generated/themes/MastheadMobileMenu.css.d.ts +1 -1
  199. package/dist/generated/themes/MastheadMobileMenu.css.js +1 -1
  200. package/dist/generated/themes/MastheadMobileMenu.css.js.map +1 -1
  201. package/dist/generated/themes/MastheadProfileMenu.css.d.ts +1 -1
  202. package/dist/generated/themes/MastheadProfileMenu.css.js +1 -1
  203. package/dist/generated/themes/MastheadProfileMenu.css.js.map +1 -1
  204. package/dist/generated/themes/MastheadShell.css.d.ts +1 -1
  205. package/dist/generated/themes/MastheadShell.css.js +1 -1
  206. package/dist/generated/themes/MastheadShell.css.js.map +1 -1
  207. package/dist/generated/themes/MessageStrip.css.d.ts +1 -1
  208. package/dist/generated/themes/MessageStrip.css.js +1 -1
  209. package/dist/generated/themes/MessageStrip.css.js.map +1 -1
  210. package/dist/generated/themes/Modal.css.d.ts +1 -1
  211. package/dist/generated/themes/Modal.css.js +1 -1
  212. package/dist/generated/themes/Modal.css.js.map +1 -1
  213. package/dist/generated/themes/PromoTile.css.d.ts +1 -1
  214. package/dist/generated/themes/PromoTile.css.js +1 -1
  215. package/dist/generated/themes/PromoTile.css.js.map +1 -1
  216. package/dist/generated/themes/Quote.css.d.ts +1 -1
  217. package/dist/generated/themes/Quote.css.js +1 -1
  218. package/dist/generated/themes/Quote.css.js.map +1 -1
  219. package/dist/generated/themes/Review.css.d.ts +1 -1
  220. package/dist/generated/themes/Review.css.js +1 -1
  221. package/dist/generated/themes/Review.css.js.map +1 -1
  222. package/dist/generated/themes/ReviewItem.css.d.ts +1 -1
  223. package/dist/generated/themes/ReviewItem.css.js +1 -1
  224. package/dist/generated/themes/ReviewItem.css.js.map +1 -1
  225. package/dist/generated/themes/SecondaryNavigation.css.d.ts +1 -1
  226. package/dist/generated/themes/SecondaryNavigation.css.js +1 -1
  227. package/dist/generated/themes/SecondaryNavigation.css.js.map +1 -1
  228. package/dist/generated/themes/SecondaryNavigationItem.css.d.ts +1 -1
  229. package/dist/generated/themes/SecondaryNavigationItem.css.js +1 -1
  230. package/dist/generated/themes/SecondaryNavigationItem.css.js.map +1 -1
  231. package/dist/generated/themes/SelectBase.css.d.ts +1 -1
  232. package/dist/generated/themes/SelectBase.css.js +1 -1
  233. package/dist/generated/themes/SelectBase.css.js.map +1 -1
  234. package/dist/generated/themes/SideNavigation.css.d.ts +1 -1
  235. package/dist/generated/themes/SideNavigation.css.js +1 -1
  236. package/dist/generated/themes/SideNavigation.css.js.map +1 -1
  237. package/dist/generated/themes/SideNavigationItem.css.d.ts +1 -1
  238. package/dist/generated/themes/SideNavigationItem.css.js +1 -1
  239. package/dist/generated/themes/SideNavigationItem.css.js.map +1 -1
  240. package/dist/generated/themes/SideNavigationMobile.css.d.ts +1 -1
  241. package/dist/generated/themes/SideNavigationMobile.css.js +1 -1
  242. package/dist/generated/themes/SideNavigationMobile.css.js.map +1 -1
  243. package/dist/generated/themes/SideNavigationSubItem.css.d.ts +1 -1
  244. package/dist/generated/themes/SideNavigationSubItem.css.js +1 -1
  245. package/dist/generated/themes/SideNavigationSubItem.css.js.map +1 -1
  246. package/dist/generated/themes/TabNavigation.css.d.ts +1 -1
  247. package/dist/generated/themes/TabNavigation.css.js +1 -1
  248. package/dist/generated/themes/TabNavigation.css.js.map +1 -1
  249. package/dist/generated/themes/Table.css.d.ts +1 -1
  250. package/dist/generated/themes/Table.css.js +1 -1
  251. package/dist/generated/themes/Table.css.js.map +1 -1
  252. package/dist/generated/themes/TableCellBase.css.d.ts +1 -1
  253. package/dist/generated/themes/TableCellBase.css.js +1 -1
  254. package/dist/generated/themes/TableCellBase.css.js.map +1 -1
  255. package/dist/generated/themes/Upload.css.d.ts +1 -1
  256. package/dist/generated/themes/Upload.css.js +1 -1
  257. package/dist/generated/themes/Upload.css.js.map +1 -1
  258. package/dist/generated/themes/UploadItem.css.d.ts +1 -1
  259. package/dist/generated/themes/UploadItem.css.js +1 -1
  260. package/dist/generated/themes/UploadItem.css.js.map +1 -1
  261. package/dist/messagebundle.properties +3 -0
  262. package/dist/types/Table.d.ts +6 -2
  263. package/dist/types/Table.js +7 -2
  264. package/dist/types/Table.js.map +1 -1
  265. package/dist/vscode.html-custom-data.json +48 -7
  266. package/dist/web-types.json +88 -14
  267. package/package.json +1 -1
  268. package/run-cypress.js +8 -1
  269. package/src/AccordionSpotlight.ts +35 -6
  270. package/src/AccordionSpotlightItem.ts +3 -1
  271. package/src/Carousel.ts +39 -4
  272. package/src/CountrySelector.ts +1 -3
  273. package/src/List.ts +21 -4
  274. package/src/ListGroupHeader.ts +5 -1
  275. package/src/ListGroupHeaderBase.ts +16 -2
  276. package/src/ListGroupHeaderTemplate.tsx +29 -47
  277. package/src/ListItem.ts +14 -13
  278. package/src/ListItemBase.ts +14 -1
  279. package/src/ListItemTemplate.tsx +4 -4
  280. package/src/ListSelectAllTemplate.tsx +10 -8
  281. package/src/ListTemplate.tsx +14 -10
  282. package/src/Pagination.ts +2 -3
  283. package/src/Search.ts +48 -13
  284. package/src/SearchableListBase.ts +15 -3
  285. package/src/SearchableListBaseTemplate.tsx +51 -37
  286. package/src/SecondaryNavigation.ts +2 -1
  287. package/src/SecondaryNavigationItem.ts +14 -6
  288. package/src/SecondaryNavigationTemplate.tsx +4 -6
  289. package/src/SelectBase.ts +131 -145
  290. package/src/SelectBox.ts +21 -7
  291. package/src/SelectBoxTemplate.tsx +10 -9
  292. package/src/SideNavigation.ts +35 -0
  293. package/src/SideNavigationItem.ts +77 -0
  294. package/src/SideNavigationItemTemplate.tsx +97 -0
  295. package/src/SideNavigationMobile.ts +1 -2
  296. package/src/SideNavigationMobileTemplate.tsx +2 -1
  297. package/src/SideNavigationSubItem.ts +119 -2
  298. package/src/SideNavigationSubItemTemplate.tsx +57 -0
  299. package/src/Table.ts +1 -2
  300. package/src/TableCell.ts +9 -12
  301. package/src/TableCellBase.ts +10 -1
  302. package/src/TableHeaderCell.ts +0 -5
  303. package/src/TableRow.ts +20 -0
  304. package/src/TagGroup.ts +32 -0
  305. package/src/TagGroupTemplate.tsx +1 -1
  306. package/src/UploadItem.ts +3 -5
  307. package/src/generated/i18n/i18n-defaults.ts +2 -2
  308. package/src/generated/themes/AccordionSpotlight.css.ts +1 -1
  309. package/src/generated/themes/Contact.css.ts +1 -1
  310. package/src/generated/themes/EventRibbon.css.ts +1 -1
  311. package/src/generated/themes/Feed.css.ts +1 -1
  312. package/src/generated/themes/HeroBanner.css.ts +1 -1
  313. package/src/generated/themes/ImageGridCloud.css.ts +1 -1
  314. package/src/generated/themes/ImageGridTicker.css.ts +1 -1
  315. package/src/generated/themes/ImageGridTickerItem.css.ts +1 -1
  316. package/src/generated/themes/LinkList.css.ts +1 -1
  317. package/src/generated/themes/ListGroupHeader.css.ts +1 -1
  318. package/src/generated/themes/MastheadCountrySelector.css.ts +1 -1
  319. package/src/generated/themes/MastheadItem.css.ts +1 -1
  320. package/src/generated/themes/MastheadMenu.css.ts +1 -1
  321. package/src/generated/themes/MastheadMenuItem.css.ts +1 -1
  322. package/src/generated/themes/MastheadMobileMenu.css.ts +1 -1
  323. package/src/generated/themes/MastheadProfileMenu.css.ts +1 -1
  324. package/src/generated/themes/MastheadShell.css.ts +1 -1
  325. package/src/generated/themes/MessageStrip.css.ts +1 -1
  326. package/src/generated/themes/Modal.css.ts +1 -1
  327. package/src/generated/themes/PromoTile.css.ts +1 -1
  328. package/src/generated/themes/Quote.css.ts +1 -1
  329. package/src/generated/themes/Review.css.ts +1 -1
  330. package/src/generated/themes/ReviewItem.css.ts +1 -1
  331. package/src/generated/themes/SecondaryNavigation.css.ts +1 -1
  332. package/src/generated/themes/SecondaryNavigationItem.css.ts +1 -1
  333. package/src/generated/themes/SelectBase.css.ts +1 -1
  334. package/src/generated/themes/SideNavigation.css.ts +1 -1
  335. package/src/generated/themes/SideNavigationItem.css.ts +1 -1
  336. package/src/generated/themes/SideNavigationMobile.css.ts +1 -1
  337. package/src/generated/themes/SideNavigationSubItem.css.ts +1 -1
  338. package/src/generated/themes/TabNavigation.css.ts +1 -1
  339. package/src/generated/themes/Table.css.ts +1 -1
  340. package/src/generated/themes/TableCellBase.css.ts +1 -1
  341. package/src/generated/themes/Upload.css.ts +1 -1
  342. package/src/generated/themes/UploadItem.css.ts +1 -1
  343. package/src/i18n/messagebundle.properties +3 -0
  344. package/src/themes/AccordionSpotlight.css +11 -8
  345. package/src/themes/Contact.css +1 -1
  346. package/src/themes/EventRibbon.css +4 -4
  347. package/src/themes/Feed.css +2 -2
  348. package/src/themes/HeroBanner.css +3 -3
  349. package/src/themes/ImageGridCloud.css +1 -1
  350. package/src/themes/ImageGridTicker.css +1 -1
  351. package/src/themes/ImageGridTickerItem.css +1 -1
  352. package/src/themes/LinkList.css +4 -4
  353. package/src/themes/ListGroupHeader.css +2 -43
  354. package/src/themes/MastheadCountrySelector.css +1 -1
  355. package/src/themes/MastheadItem.css +4 -4
  356. package/src/themes/MastheadMenu.css +1 -1
  357. package/src/themes/MastheadMenuItem.css +1 -1
  358. package/src/themes/MastheadMobileMenu.css +2 -2
  359. package/src/themes/MastheadProfileMenu.css +1 -1
  360. package/src/themes/MastheadShell.css +4 -4
  361. package/src/themes/MessageStrip.css +7 -2
  362. package/src/themes/Modal.css +1 -1
  363. package/src/themes/PromoTile.css +4 -3
  364. package/src/themes/Quote.css +2 -2
  365. package/src/themes/Review.css +2 -2
  366. package/src/themes/ReviewItem.css +2 -2
  367. package/src/themes/SecondaryNavigation.css +1 -2
  368. package/src/themes/SecondaryNavigationItem.css +3 -6
  369. package/src/themes/SelectBase.css +1 -1
  370. package/src/themes/SideNavigation.css +31 -8
  371. package/src/themes/SideNavigationItem.css +100 -22
  372. package/src/themes/SideNavigationMobile.css +65 -20
  373. package/src/themes/SideNavigationSubItem.css +15 -54
  374. package/src/themes/TabNavigation.css +2 -2
  375. package/src/themes/Table.css +7 -2
  376. package/src/themes/TableCellBase.css +8 -0
  377. package/src/themes/Upload.css +1 -1
  378. package/src/themes/UploadItem.css +1 -1
  379. package/src/types/Table.ts +6 -2
  380. package/dist/css/themes/SideNavigationMobileDropdown.css +0 -1
  381. package/dist/generated/themes/SideNavigationMobileDropdown.css.d.ts +0 -2
  382. package/dist/generated/themes/SideNavigationMobileDropdown.css.js +0 -8
  383. package/dist/generated/themes/SideNavigationMobileDropdown.css.js.map +0 -1
  384. package/src/generated/themes/SideNavigationMobileDropdown.css.ts +0 -9
  385. package/src/themes/SideNavigationMobileDropdown.css +0 -29
@@ -2,6 +2,29 @@ import { UDExSelectBox, UDExSelectBoxSelectAll, UDExSelectBoxGroupHeader, UDExSe
2
2
  import { UDExListItemSize, UDExListMode, UDExListStyleType } from "../../src/types/List.js";
3
3
  import { UDExAvatarShape, UDExAvatarSize } from "../../src/Avatar.js";
4
4
  import UDExStatusBadgeValueState from "../../src/types/StatusBadgeValueState.js";
5
+ import { renderFinished } from "@ui5/webcomponents-base/dist/Render.js";
6
+
7
+ function UDExAssertActiveItem(UDExIndex: number) {
8
+ cy.get("#select-box").shadow().find("[udex-list-item]").eq(UDExIndex).should($item => {
9
+ expect($item).to.have.attr("_active-descendant");
10
+ expect($item).to.have.class("_udex-active-descendant");
11
+ }).then($item => {
12
+ cy.get("#select-box").shadow().find("[_active-descendant]").should("have.length", 1).and($active => {
13
+ expect($active[0]).to.equal($item[0]);
14
+ });
15
+ cy.get("#select-box").shadow().find("._udex-active-descendant").should("have.length", 1).and($highlight => {
16
+ expect($highlight[0]).to.equal($item[0]);
17
+ });
18
+ cy.get("#select-box").shadow().find('input[role="combobox"]')
19
+ .should("have.attr", "aria-activedescendant", $item[0].id);
20
+ });
21
+ cy.get("#select-box").shadow().find("[udex-list-item]").eq(UDExIndex).should("not.be.focused");
22
+ cy.get("#select-box").shadow().find('input[role="combobox"]').should("be.focused").should($input => {
23
+ const UDExRoot = $input[0].getRootNode() as ShadowRoot;
24
+ expect($input[0].ownerDocument.activeElement).to.equal(UDExRoot.host);
25
+ expect(UDExRoot.activeElement).to.equal($input[0]);
26
+ });
27
+ }
5
28
 
6
29
  const selectBoxWithRating = <div style="width: 350px; position:relative;"><UDExSelectBox
7
30
  id="select-box"
@@ -373,25 +396,38 @@ describe("SelectBox", () => {
373
396
  .should("have.attr", "open");
374
397
  });
375
398
 
399
+ // Updated: closed ArrowDown announces expanded and highlights the first item; the next press advances silently.
376
400
  it("dropdown opens on pressing the `ArrowDown` key on the search", () => {
377
401
  cy.mount(fullComponent);
378
402
  cy.get("#select-box").shadow()
379
403
  .find(".udex-text-field__search")
380
- .click()
404
+ .focus()
381
405
  .realPress("ArrowDown");
382
406
 
383
407
  cy.get("#select-box").shadow()
384
408
  .find(".udex-select-box__dropdown")
385
409
  .should("have.attr","open");
410
+ cy.get("#select-box").shadow().find('input[role="combobox"]')
411
+ .should("be.focused").and("have.attr", "aria-expanded", "true");
412
+ UDExAssertActiveItem(0);
413
+ cy.get("#select-box").shadow().find('[aria-live="polite"]').should("have.length", 1).and("have.text", "expanded");
414
+
415
+ cy.realPress("ArrowDown");
416
+ UDExAssertActiveItem(1);
417
+ cy.get("#select-box").shadow().find('[aria-live="polite"]').should("have.text", "");
386
418
  });
387
419
 
420
+ // Updated: Escape clears the immediately active item and status; reopening re-announces expanded before navigation.
388
421
  it("dropdown closes on pressing the `Escape`", () => {
389
422
  cy.mount(fullComponent);
390
423
  cy.get("#select-box").shadow()
391
424
  .find(".udex-text-field__search")
392
- .click()
425
+ .focus()
393
426
  .realPress("ArrowDown");
394
427
 
428
+ cy.get("#select-box").shadow().find(".udex-select-box__dropdown").should("have.attr", "open");
429
+ UDExAssertActiveItem(0);
430
+
395
431
  cy.get("#select-box").shadow()
396
432
  .find(".udex-text-field__search")
397
433
  .realPress("Escape");
@@ -399,6 +435,19 @@ describe("SelectBox", () => {
399
435
  cy.get("#select-box").shadow()
400
436
  .find(".udex-select-box__dropdown")
401
437
  .should("not.have.attr","open");
438
+ cy.get("#select-box").shadow().find('input[role="combobox"]')
439
+ .should("be.focused").and("have.attr", "aria-expanded", "false");
440
+ cy.get("#select-box").shadow().find('input[role="combobox"]').should("not.have.attr", "aria-activedescendant");
441
+ cy.get("#select-box").shadow().find("[_active-descendant], ._udex-active-descendant").should("not.exist");
442
+ cy.get("#select-box").shadow().find('[aria-live="polite"]').should("have.text", "");
443
+
444
+ cy.realPress("ArrowDown");
445
+ cy.get("#select-box").shadow().find(".udex-select-box__dropdown").should("have.attr", "open");
446
+ cy.get("#select-box").shadow().find('input[role="combobox"]').should("have.attr", "aria-expanded", "true");
447
+ UDExAssertActiveItem(0);
448
+ cy.get("#select-box").shadow().find('[aria-live="polite"]').should("have.length", 1).and("have.text", "expanded");
449
+ cy.realPress("ArrowDown");
450
+ UDExAssertActiveItem(1);
402
451
  });
403
452
 
404
453
  it("sets option label when Arrow Down key press on the list items", () => {
@@ -547,14 +596,31 @@ describe("SelectBox", () => {
547
596
  .should("have.attr", "_active-descendant");
548
597
  });
549
598
 
550
- it("SingleSelect mode - opening the dropdown with ArrowDown focuses the selected item", () => {
599
+ // Updated: plain preselected options remain a listbox; opening announces expanded before silent ArrowDown navigation.
600
+ it("SingleSelect mode - ArrowDown opens with the selected item active and the next ArrowDown activates the next item", () => {
551
601
  cy.mount(singleSelectPreselected);
552
602
  cy.get("#select-box").shadow().find(".udex-text-field__search").focus();
553
603
  cy.realPress("ArrowDown");
554
604
 
605
+ cy.get("#select-box").shadow().find('input[role="combobox"]').should("have.attr", "aria-haspopup", "listbox");
606
+ cy.get("#select-box").shadow().find("[udex-list]").should("have.attr", "role", "listbox");
555
607
  cy.get("#select-box").shadow().find(".udex-select-box__dropdown").should("have.attr", "open");
608
+ cy.get("#select-box").shadow().find('input[role="combobox"]')
609
+ .should("be.focused").and("have.attr", "aria-expanded", "true");
610
+ UDExAssertActiveItem(2);
611
+ cy.get("#select-box").shadow().find('[aria-live="polite"]').should("have.length", 1).and("have.text", "expanded");
556
612
  cy.get("#select-box").shadow().find("[udex-list-item]").eq(2)
557
613
  .should("have.attr", "_active-descendant");
614
+ cy.get("#select-box").shadow().find("[udex-list-item]").eq(0)
615
+ .should("not.have.attr", "_active-descendant");
616
+
617
+ cy.realPress("ArrowDown");
618
+ UDExAssertActiveItem(3);
619
+ cy.get("#select-box").shadow().find("[udex-list-item]").eq(2)
620
+ .should("not.have.attr", "_active-descendant");
621
+ cy.get("#select-box").find("[udex-select-box-item][selected]").should("have.length", 1).and("have.attr", "label", "Java");
622
+ cy.get("#select-box").shadow().find('[aria-live="polite"]').should("have.text", "");
623
+ cy.get("#select-box").shadow().find('input[role="combobox"]').should("be.focused");
558
624
  });
559
625
 
560
626
  it("SingleSelect mode - reopening restores focus to the previously selected item", () => {
@@ -571,12 +637,17 @@ describe("SelectBox", () => {
571
637
 
572
638
  it("MultiSelect mode - navigation label is cleared from input after Tab closes the dropdown", () => {
573
639
  cy.mount(multiSelect);
574
- cy.get("#select-box").shadow()
575
- .find(".udex-text-field__search")
576
- .click()
577
- .realPress("ArrowDown");
640
+ cy.get("#select-box").shadow().find(".udex-text-field__search").click();
641
+
642
+ // Wait for the dropdown to finish opening with the first item (JavaScript) focused before
643
+ // navigating, otherwise ArrowDown races the open and is consumed by it instead of advancing.
644
+ cy.get("#select-box").shadow().find(".udex-select-box__dropdown").should("have.attr", "open");
645
+ cy.get("#select-box").shadow().find("[udex-list-item]").eq(0)
646
+ .should("have.attr", "_active-descendant");
647
+
648
+ // The first item (JavaScript) is focused, so this ArrowDown advances to Python.
649
+ cy.realPress("ArrowDown");
578
650
 
579
- // Opening focuses the first item (JavaScript), so the first ArrowDown advances to Python.
580
651
  cy.get("#select-box").shadow()
581
652
  .find(".udex-text-field__single-label")
582
653
  .should("have.text", "Python");
@@ -588,6 +659,33 @@ describe("SelectBox", () => {
588
659
  .should("not.exist");
589
660
  });
590
661
 
662
+ it("SingleSelect mode - Tab without opening dropdown shows no label in input", () => {
663
+ cy.mount(shortComponent);
664
+ cy.get("#select-box").shadow().find(".udex-text-field__search").focus();
665
+ cy.realPress("Tab");
666
+ cy.get("#select-box").shadow()
667
+ .find(".udex-text-field__single-label")
668
+ .should("not.exist");
669
+ });
670
+
671
+ it("SingleSelect mode - Tab without opening dropdown preserves previously selected item in input", () => {
672
+ cy.mount(singleSelectPreselected);
673
+ cy.get("#select-box").shadow().find(".udex-text-field__search").focus();
674
+ cy.realPress("Tab");
675
+ cy.get("#select-box").shadow()
676
+ .find(".udex-text-field__single-label")
677
+ .should("have.text", "Java");
678
+ });
679
+
680
+ it("MultiSelect mode - Tab without opening dropdown shows no label in input", () => {
681
+ cy.mount(multiSelect);
682
+ cy.get("#select-box").shadow().find(".udex-text-field__search").focus();
683
+ cy.realPress("Tab");
684
+ cy.get("#select-box").shadow()
685
+ .find(".udex-text-field__single-label")
686
+ .should("not.exist");
687
+ });
688
+
591
689
  it("MultiSelect mode - opening the dropdown with a mouse click focuses the first item", () => {
592
690
  cy.mount(multiSelect);
593
691
  cy.get("#select-box").shadow().find(".udex-text-field__trigger").click();
@@ -597,14 +695,27 @@ describe("SelectBox", () => {
597
695
  .should("have.attr", "_active-descendant");
598
696
  });
599
697
 
600
- it("MultiSelect mode - opening the dropdown with ArrowDown focuses the first item", () => {
698
+ // Updated: keyboard opening announces expanded with the first item active; ArrowDown advances silently to the second.
699
+ it("MultiSelect mode - ArrowDown opens with the first item active and the next ArrowDown activates the next item", () => {
601
700
  cy.mount(multiSelect);
602
701
  cy.get("#select-box").shadow().find(".udex-text-field__search").focus();
603
702
  cy.realPress("ArrowDown");
604
703
 
605
704
  cy.get("#select-box").shadow().find(".udex-select-box__dropdown").should("have.attr", "open");
705
+ cy.get("#select-box").shadow().find('input[role="combobox"]')
706
+ .should("be.focused").and("have.attr", "aria-expanded", "true");
707
+ UDExAssertActiveItem(0);
708
+ cy.get("#select-box").shadow().find('[aria-live="polite"]').should("have.length", 1).and("have.text", "expanded");
606
709
  cy.get("#select-box").shadow().find("[udex-list-item]").eq(0)
607
710
  .should("have.attr", "_active-descendant");
711
+
712
+ cy.realPress("ArrowDown");
713
+ UDExAssertActiveItem(1);
714
+ cy.get("#select-box").shadow().find("[udex-list-item]").eq(0)
715
+ .should("not.have.attr", "_active-descendant");
716
+ cy.get("#select-box").find("[udex-select-box-item][selected]").should("not.exist");
717
+ cy.get("#select-box").shadow().find('[aria-live="polite"]').should("have.text", "");
718
+ cy.get("#select-box").shadow().find('input[role="combobox"]').should("be.focused");
608
719
  });
609
720
 
610
721
  it("MultiSelect mode - selected items do not steal focus from the first item on open", () => {
@@ -1158,9 +1269,10 @@ describe("SelectBox", () => {
1158
1269
  cy.get("@select").shadow().find(".udex-text-field__trigger").as("trigger")
1159
1270
 
1160
1271
  cy.get("@select").shadow()
1161
- .find("udex-list")
1162
- .find("udex-list-select-all").shadow()
1163
- .find(".udex-list__group-header")
1272
+ .find("[udex-list]")
1273
+ .find("[udex-list-select-all]").shadow()
1274
+ .find('[udex-list-item][part="group-item"]').shadow()
1275
+ .find('[part="title"]')
1164
1276
  .should("have.text", "Select All");
1165
1277
  });
1166
1278
 
@@ -2829,10 +2941,13 @@ describe("SelectBox", () => {
2829
2941
  .find("[udex-list]").should("have.attr", "aria-multiselectable", "true");
2830
2942
  });
2831
2943
 
2832
- it("inner list div has role=\"tree\"", () => {
2944
+ // Updated: the host owns the tree; its shadow container must not create a second tree.
2945
+ it("inner list div is transparent when the host owns the tree role", () => {
2946
+ cy.get("#select-box-tree-regression").shadow()
2947
+ .find("[udex-list]").should("have.attr", "role", "tree");
2833
2948
  cy.get("#select-box-tree-regression").shadow()
2834
2949
  .find("[udex-list]").shadow()
2835
- .find("#udex-list").should("have.attr", "role", "tree");
2950
+ .find("#udex-list").should("have.attr", "role", "none");
2836
2951
  });
2837
2952
 
2838
2953
  it("group header host has _tree-mode attribute", () => {
@@ -2848,11 +2963,13 @@ describe("SelectBox", () => {
2848
2963
  .should("have.attr", "role", "treeitem");
2849
2964
  });
2850
2965
 
2851
- it("child items have aria-checked on the host (MultiSelect tree)", () => {
2966
+ // Updated: selectable popup treeitems expose only Boolean aria-selected on the host.
2967
+ it("child items have Boolean aria-selected and no aria-checked on the host (MultiSelect tree)", () => {
2852
2968
  cy.get("#select-box-tree-regression").shadow()
2853
- .find("udex-list-group-header")
2854
- .find("udex-list-item").eq(0)
2855
- .should("have.attr", "aria-checked", "false");
2969
+ .find("[udex-list-group-header]")
2970
+ .find("[udex-list-item]").eq(0)
2971
+ .should("have.attr", "aria-selected", "false")
2972
+ .and("not.have.attr", "aria-checked");
2856
2973
  });
2857
2974
 
2858
2975
  it("child items' inner [part=item] div is role=\"presentation\" (host carries the role)", () => {
@@ -2862,7 +2979,8 @@ describe("SelectBox", () => {
2862
2979
  .find("[part=item]").should("have.attr", "role", "presentation");
2863
2980
  });
2864
2981
 
2865
- it("child items' checkbox is aria-hidden (tree mode, JAWS uses host aria-checked)", () => {
2982
+ // Updated: decorative checkboxes remain hidden; native selection is owned by the treeitem host.
2983
+ it("child items' checkbox is aria-hidden (tree mode uses host aria-selected)", () => {
2866
2984
  cy.get("#select-box-tree-regression").shadow()
2867
2985
  .find("udex-list-group-header")
2868
2986
  .find("udex-list-item").eq(0).shadow()
@@ -2870,91 +2988,121 @@ describe("SelectBox", () => {
2870
2988
  });
2871
2989
  });
2872
2990
 
2873
- // Covers the aria-live="polite" region that announces the active item
2874
- // during keyboard navigation. _setActiveDescendant(item) sets _liveRegionText to
2875
- // "Label, X of Y"; _setActiveDescendant(null) (on close/Escape) resets it to "".
2876
- describe("Select Box live region announcements", () => {
2877
- it("populates the live region with 'Label, X of Y' when ArrowDown activates an item", () => {
2878
- cy.mount(shortComponent);
2879
- cy.get("#select-box").shadow()
2880
- .find(".udex-text-field__search")
2881
- .click();
2991
+ // Updated: expanded active groups open silently; other hosts keep the popup fallback, never live item metadata.
2992
+ describe("Select Box supplemental announcements without label echo", () => {
2993
+ const UDExCombobox = () => cy.get("#select-box").shadow().find('input[role="combobox"]');
2994
+ const UDExStatus = () => cy.get("#select-box").shadow().find('[aria-live="polite"]');
2995
+ const UDExActiveHost = () => cy.get("#select-box").shadow().find("[_active-descendant]");
2996
+
2997
+ function UDExAssertActiveHost(UDExRole: string, UDExLabel: string, UDExPosition: number, UDExSize: number, UDExExpectedStatus: "" | "expanded", UDExLevel?: number, UDExAccessibleName = UDExLabel) {
2998
+ UDExActiveHost().should($host => {
2999
+ expect($host).to.have.length(1);
3000
+ expect($host).to.have.attr("role", UDExRole);
3001
+ expect($host).to.have.attr("aria-posinset", String(UDExPosition));
3002
+ expect($host).to.have.attr("aria-setsize", String(UDExSize));
3003
+ expect($host).to.have.attr("aria-label", UDExAccessibleName);
3004
+ if (UDExLevel !== undefined) {
3005
+ expect($host).to.have.attr("aria-level", String(UDExLevel));
3006
+ } else {
3007
+ expect($host).not.to.have.attr("aria-level");
3008
+ }
3009
+ if ($host.is("[udex-list-group-header]")) {
3010
+ expect($host).to.have.attr("aria-label", UDExLabel);
3011
+ } else {
3012
+ expect($host).to.have.attr("label", UDExLabel);
3013
+ }
3014
+ }).then($host => {
3015
+ UDExCombobox().should($input => {
3016
+ const UDExRoot = $input[0].getRootNode() as ShadowRoot;
3017
+ expect($input).to.have.attr("aria-activedescendant", $host[0].id);
3018
+ expect(UDExRoot.getElementById($host[0].id)).to.equal($host[0]);
3019
+ expect(Array.from(UDExRoot.querySelectorAll("[id]")).filter(UDExElement => UDExElement.id === $host[0].id))
3020
+ .to.deep.equal([$host[0]]);
3021
+ });
3022
+ });
3023
+ // Preserve rendered title checks in addition to the complete host aria-label.
3024
+ UDExActiveHost().then($host => {
3025
+ if ($host.is("[udex-list-item]")) {
3026
+ cy.wrap($host).shadow().find(".udex-list__content-wrap").should("have.attr", "aria-label", UDExLabel);
3027
+ cy.wrap($host).shadow().find('[part="title"]').should("have.text", UDExLabel);
3028
+ }
3029
+ });
3030
+ UDExCombobox().should("be.focused");
3031
+ // Updated: drain pending live-region rendering so an empty expectation cannot pass prematurely.
3032
+ cy.then(() => renderFinished());
3033
+ UDExStatus().should($status => {
3034
+ expect($status).to.have.length(1);
3035
+ expect($status.text()).to.equal(UDExExpectedStatus);
3036
+ const UDExSelectBox = ($status[0].getRootNode() as ShadowRoot).host;
3037
+ UDExSelectBox.querySelectorAll("[udex-select-box-item], [udex-select-box-group-header]").forEach(UDExItem => {
3038
+ ["label", "supporting-text", "additional-text"].forEach(UDExAttribute => {
3039
+ const UDExName = UDExItem.getAttribute(UDExAttribute);
3040
+ if (UDExName) {
3041
+ expect($status.text(), `status excludes ${UDExAttribute}: ${UDExName}`).not.to.contain(UDExName);
3042
+ }
3043
+ });
3044
+ });
3045
+ });
3046
+ }
2882
3047
 
2883
- // Opening activates the first item "JavaScript" (shortComponent has 6 items).
2884
- cy.get("#select-box").shadow()
2885
- .find('[aria-live="polite"]')
2886
- .invoke("text")
2887
- .should("match", /^JavaScript, 1 of 6$/);
3048
+ // Updated: actionable opening is expanded-only, with level-1 positions and complete names retained natively.
3049
+ it("announces only expanded on flat actionable opening while retaining the complete native name and position", () => {
3050
+ cy.mount(shortComponent);
3051
+ UDExCombobox().realClick();
3052
+ UDExAssertActiveHost("treeitem", "JavaScript", 1, 6, "expanded", 1, "JavaScript Additional Text");
3053
+ UDExCombobox().should("have.attr", "aria-haspopup", "tree");
3054
+ cy.get("#select-box").shadow().find("[udex-list]").should("have.attr", "role", "tree");
3055
+ UDExActiveHost().should("not.have.attr", "aria-expanded");
3056
+ UDExActiveHost().should("have.attr", "aria-selected", "false");
2888
3057
  });
2889
3058
 
2890
- // Added: covers _treePositionText — for a grouped SelectBox the announcement
2891
- // carries the tree position. ArrowDown activates the group header ("level 0");
2892
- // a further ArrowDown reaches its first child ("level 1").
2893
- it("uses tree positional text ('level 0' for the group header, 'level 1' for its child)", () => {
3059
+ // Updated: the expanded group supplies native state; opening and child navigation have no live metadata.
3060
+ it("keeps live status empty on expanded-group opening and child navigation with native positions and selection", () => {
2894
3061
  cy.mount(groupHeaderCollapsible);
2895
- cy.get("#select-box").shadow()
2896
- .find(".udex-text-field__search")
2897
- .click();
2898
-
2899
- // Opening activates the group header -> tree text reports "level 0".
2900
- cy.get("#select-box").shadow()
2901
- .find('[aria-live="polite"]')
2902
- .invoke("text")
2903
- .should("contain", "level 0");
2904
-
2905
- // A further ArrowDown reaches the first child -> tree text reports "level 1".
2906
- cy.get("#select-box").shadow()
2907
- .find(".udex-text-field__search")
2908
- .realPress("ArrowDown");
2909
-
2910
- cy.get("#select-box").shadow()
2911
- .find('[aria-live="polite"]')
2912
- .invoke("text")
2913
- .should("contain", "level 1");
3062
+ UDExCombobox().realClick();
3063
+ UDExAssertActiveHost("treeitem", "Programming Languages", 1, 1, "", 1);
3064
+ UDExActiveHost().should("have.attr", "aria-expanded", "true");
3065
+ UDExActiveHost().should("have.attr", "aria-selected", "false").and("not.have.attr", "aria-checked");
3066
+ cy.realPress("ArrowDown");
3067
+ UDExAssertActiveHost("treeitem", "JavaScript", 1, 2, "", 2, "JavaScript Frontend web development");
3068
+ UDExActiveHost().should("have.attr", "aria-selected", "false").and("not.have.attr", "aria-checked");
2914
3069
  });
2915
3070
 
2916
- it("clears the live region text when the dropdown closes on Escape", () => {
3071
+ // Updated: actionable opening is expanded-only; navigation is silent even on hosts without icons.
3072
+ it("announces expanded on actionable opening, keeps navigation silent and clears the active descendant on Escape", () => {
2917
3073
  cy.mount(shortComponent);
2918
- cy.get("#select-box").shadow()
2919
- .find(".udex-text-field__search")
2920
- .click()
2921
- .realPress("ArrowDown");
2922
-
2923
- // Precondition: the live region is populated by the navigation above.
2924
- cy.get("#select-box").shadow()
2925
- .find('[aria-live="polite"]')
2926
- .invoke("text")
2927
- .should("not.be.empty");
2928
-
2929
- cy.get("#select-box").shadow()
2930
- .find(".udex-text-field__search")
2931
- .realPress("Escape");
3074
+ UDExCombobox().realClick();
3075
+ UDExAssertActiveHost("treeitem", "JavaScript", 1, 6, "expanded", 1, "JavaScript Additional Text");
3076
+ cy.realPress("ArrowDown");
3077
+ UDExAssertActiveHost("treeitem", "Python", 2, 6, "", 1);
3078
+ UDExActiveHost().should("have.attr", "aria-selected", "false");
3079
+ UDExActiveHost().should("not.have.attr", "aria-expanded");
3080
+ cy.realPress("Escape");
2932
3081
 
2933
3082
  cy.get("#select-box").shadow()
2934
3083
  .find(".udex-select-box__dropdown")
2935
3084
  .should("not.have.attr", "open");
2936
-
2937
- // _setActiveDescendant(null) resets _liveRegionText to "".
2938
- cy.get("#select-box").shadow()
2939
- .find('[aria-live="polite"]')
2940
- .invoke("text")
2941
- .should("equal", "");
3085
+ UDExActiveHost().should("not.exist");
3086
+ UDExCombobox().should("not.have.attr", "aria-activedescendant");
3087
+ UDExCombobox().should("be.focused");
3088
+ UDExStatus().should("have.text", "");
2942
3089
  });
2943
3090
 
2944
- it("appends 'Unselected' to the live region for an unchecked MultiSelect item", () => {
3091
+ // Updated: plain flat MultiSelect announces expanded only on opening; option navigation remains silent.
3092
+ it("announces expanded on flat unselected MultiSelect opening and keeps navigation status silent", () => {
2945
3093
  cy.mount(multiSelect);
2946
- cy.get("#select-box").shadow()
2947
- .find(".udex-text-field__search")
2948
- .click()
2949
- .realPress("ArrowDown");
2950
-
2951
- // First MultiSelect item is not selected -> state suffix is "Unselected".
2952
- cy.get("#select-box").shadow()
2953
- .find('[aria-live="polite"]')
2954
- .should("contain.text", "Unselected");
3094
+ UDExCombobox().realClick();
3095
+ UDExCombobox().should("have.attr", "aria-haspopup", "listbox");
3096
+ cy.get("#select-box").shadow().find("[udex-list]").should("have.attr", "role", "listbox");
3097
+ UDExAssertActiveHost("option", "JavaScript", 1, 15, "expanded", undefined, "JavaScript Frontend web development");
3098
+ cy.realPress("ArrowDown");
3099
+ UDExAssertActiveHost("option", "Python", 2, 15, "", undefined, "Python Used in data analysis");
3100
+ UDExActiveHost().should("have.attr", "aria-selected", "false");
3101
+ UDExActiveHost().should("not.have.attr", "aria-checked");
2955
3102
  });
2956
3103
 
2957
- it("appends 'Selected' to the live region for a checked MultiSelect item", () => {
3104
+ // Updated: preselection remains native; opening announces expanded without repeating the selected option's name.
3105
+ it("announces only expanded when a preselected flat MultiSelect option is initially active", () => {
2958
3106
  const checkedMultiSelect = <div style="width: 350px; position:relative;">
2959
3107
  <UDExSelectBox
2960
3108
  id="select-box"
@@ -2968,18 +3116,15 @@ describe("SelectBox", () => {
2968
3116
  </div>;
2969
3117
 
2970
3118
  cy.mount(checkedMultiSelect);
2971
- cy.get("#select-box").shadow()
2972
- .find(".udex-text-field__search")
2973
- .click();
2974
-
2975
- // Opening activates the first MultiSelect item, which is pre-selected -> state
2976
- // suffix is "Selected".
2977
- cy.get("#select-box").shadow()
2978
- .find('[aria-live="polite"]')
2979
- .should("contain.text", "Selected");
3119
+ UDExCombobox().realClick();
3120
+ UDExAssertActiveHost("option", "JavaScript", 1, 3, "expanded", undefined, "JavaScript Frontend web development");
3121
+ UDExActiveHost().should("have.attr", "aria-selected", "true");
3122
+ UDExActiveHost().should("not.have.attr", "aria-checked");
3123
+ cy.get("#select-box").find('[udex-select-box-item][label="JavaScript"]').should("have.attr", "selected");
2980
3124
  });
2981
3125
 
2982
- it("appends 'collapsed' to the live region for a collapsed collapsible group header", () => {
3126
+ // Updated: an initially collapsed header still needs the expanded popup fallback; its native group stays collapsed.
3127
+ it("announces only expanded on pointer opening of a collapsed group and retains native header state", () => {
2983
3128
  const collapsedGroupHeader = <div style="width: 350px; position:relative;">
2984
3129
  <UDExSelectBox
2985
3130
  id="select-box"
@@ -2993,34 +3138,25 @@ describe("SelectBox", () => {
2993
3138
  </div>;
2994
3139
 
2995
3140
  cy.mount(collapsedGroupHeader);
2996
- cy.get("#select-box").shadow()
2997
- .find(".udex-text-field__search")
2998
- .click()
2999
- .realPress("ArrowDown");
3000
-
3001
- // ArrowDown activates the collapsed group header -> tree text reports
3002
- // "level 0" and the state suffix is "collapsed".
3003
- cy.get("#select-box").shadow()
3004
- .find('[aria-live="polite"]')
3005
- .invoke("text")
3006
- .should("contain", "level 0")
3007
- .and("contain", "collapsed");
3141
+ UDExCombobox().realClick();
3142
+ UDExAssertActiveHost("treeitem", "Programming Languages", 1, 1, "expanded", 1);
3143
+ UDExActiveHost().should("have.attr", "aria-expanded", "false");
3144
+ cy.realPress("ArrowDown");
3145
+ UDExAssertActiveHost("treeitem", "Programming Languages", 1, 1, "", 1);
3146
+ UDExActiveHost().should("have.attr", "aria-expanded", "false");
3147
+ UDExActiveHost().should("have.attr", "aria-selected", "false").and("not.have.attr", "aria-checked");
3148
+ UDExActiveHost().should("have.attr", "collapsed");
3008
3149
  });
3009
3150
 
3010
- it("appends 'expanded' to the live region for an expanded collapsible group header", () => {
3151
+ // Updated: native expanded-header state replaces the popup fallback, rather than duplicating expansion live.
3152
+ it("keeps live status empty on pointer opening and retains native expanded header state", () => {
3011
3153
  // groupHeaderCollapsible starts expanded (no `collapsed` attribute).
3012
3154
  cy.mount(groupHeaderCollapsible);
3013
- cy.get("#select-box").shadow()
3014
- .find(".udex-text-field__search")
3015
- .click();
3016
-
3017
- // Opening activates the expanded group header -> tree text reports
3018
- // "level 0" and the state suffix is "expanded".
3019
- cy.get("#select-box").shadow()
3020
- .find('[aria-live="polite"]')
3021
- .invoke("text")
3022
- .should("contain", "level 0")
3023
- .and("contain", "expanded");
3155
+ UDExCombobox().realClick();
3156
+ UDExAssertActiveHost("treeitem", "Programming Languages", 1, 1, "", 1);
3157
+ UDExActiveHost().should("have.attr", "aria-expanded", "true");
3158
+ UDExActiveHost().should("have.attr", "aria-selected", "false").and("not.have.attr", "aria-checked");
3159
+ UDExActiveHost().should("not.have.attr", "collapsed");
3024
3160
  });
3025
3161
  });
3026
3162
 
@@ -3151,14 +3287,10 @@ describe("SelectBox", () => {
3151
3287
  });
3152
3288
  });
3153
3289
 
3154
- // When focus lands on the body div of a collapsible single-select group header
3155
- // (tabindex="0"), SelectBox.handleInputFocusOut detects it — either by the
3156
- // udex-list__group-content class on the raw body div, or by checking isGroup +
3157
- // collapsible + !modeMultiSelect on the shadow-DOM-retargeted HOST element —
3158
- // sets the group header as the active descendant, and redirects DOM focus back
3159
- // to the search input.
3290
+ // Host-ARIA group rows have no tab stop. Clicking their body must activate the
3291
+ // header directly while DOM focus stays on the combobox input.
3160
3292
  describe("Select Box collapsible single-select group header click", () => {
3161
- it("clicking the body of a collapsible single-select group header returns DOM focus to the search input", () => {
3293
+ it("clicking the body of a collapsible single-select group header keeps DOM focus on the search input", () => {
3162
3294
  cy.mount(groupHeaderCollapsibleSingleSelect);
3163
3295
  cy.get("#select-box").shadow().find(".udex-text-field__trigger").click();
3164
3296
 
@@ -3166,8 +3298,10 @@ describe("SelectBox", () => {
3166
3298
  .find(".udex-select-box__dropdown")
3167
3299
  .should("have.attr", "open");
3168
3300
 
3169
- // realClick fires native browser events so the body div receives real focus,
3170
- // triggering the focusout on the search input with a valid relatedTarget.
3301
+ cy.get("#select-box").shadow().find(".udex-text-field__search").then($input => {
3302
+ $input[0].addEventListener("blur", cy.stub().as("headerClickBlur"));
3303
+ });
3304
+ // Use native mouse events to catch transient focus loss.
3171
3305
  // Click left side to avoid the collapse icon on the right.
3172
3306
  cy.get("#select-box").shadow()
3173
3307
  .find("[udex-list-group-header]")
@@ -3175,14 +3309,13 @@ describe("SelectBox", () => {
3175
3309
  .find("div[part='group-item'].udex-list__group-content")
3176
3310
  .realClick({ position: "left" });
3177
3311
 
3178
- // handleInputFocusOut detects the group header HOST (via isGroup + collapsible +
3179
- // !modeMultiSelect after shadow DOM retargeting) and calls _search.focus().
3180
3312
  cy.get("#select-box").shadow()
3181
3313
  .find(".udex-text-field__search")
3182
3314
  .should("be.focused");
3315
+ cy.get("@headerClickBlur").should("not.have.been.called");
3183
3316
  });
3184
3317
 
3185
- it("clicking the body returns focus after click and arrow navigation uses the group header as starting point", () => {
3318
+ it("clicking the body activates the header and arrow navigation uses it as starting point", () => {
3186
3319
  cy.mount(groupHeaderCollapsibleSingleSelect);
3187
3320
  cy.get("#select-box").shadow().find(".udex-text-field__trigger").click();
3188
3321
 
@@ -3190,8 +3323,13 @@ describe("SelectBox", () => {
3190
3323
  .find(".udex-select-box__dropdown")
3191
3324
  .should("have.attr", "open");
3192
3325
 
3193
- // realClick fires native browser events so the body div receives real focus,
3194
- // triggering the focusout on the search input with a valid relatedTarget.
3326
+ // Start on a leaf so this checks pointer activation rather than initial
3327
+ // dropdown activation accidentally supplying the same group header.
3328
+ cy.get("#select-box").shadow().find("[_active-descendant]").should("have.length", 1);
3329
+ cy.realPress("End");
3330
+ cy.get("#select-box").shadow().find("[udex-list-item]").eq(1)
3331
+ .should("have.attr", "_active-descendant");
3332
+
3195
3333
  // Click left side to avoid the collapse icon on the right.
3196
3334
  cy.get("#select-box").shadow()
3197
3335
  .find("[udex-list-group-header]")
@@ -3202,6 +3340,8 @@ describe("SelectBox", () => {
3202
3340
  cy.get("#select-box").shadow()
3203
3341
  .find(".udex-text-field__search")
3204
3342
  .should("be.focused");
3343
+ cy.get("#select-box").shadow().find("[udex-list-group-header]")
3344
+ .should("have.attr", "_active-descendant");
3205
3345
 
3206
3346
  // ArrowDown (via onKeyDownSearch) advances from the group header active
3207
3347
  // descendant to the FIRST list item (United States) — not back to item 0 /