@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
package/src/Search.ts CHANGED
@@ -333,7 +333,10 @@ class UDExSearch extends UI5Element {
333
333
  labelPrefix!: string;
334
334
 
335
335
  /**
336
- * Defines display the suggestion popover in the component.
336
+ * Enables the suggestion popover to open automatically as the user types.
337
+ * The popover opens when the input has 2 or more characters and closes when cleared.
338
+ * Use this property for automatic, input-driven popover management.
339
+ * For programmatic control from the host application, use <code>openSuggestionPopup</code> instead.
337
340
  *
338
341
  * @default false
339
342
  * @public
@@ -371,7 +374,12 @@ class UDExSearch extends UI5Element {
371
374
  showPopoverWhenClickedIntoInput!: boolean;
372
375
 
373
376
  /**
374
- * Defines open suggestion popover.
377
+ * Programmatically controls the visibility of the suggestion popover.
378
+ * Set to <code>true</code> to open the popover; set to <code>false</code> to close it.
379
+ * Use this property when the host application needs to control the popover state manually,
380
+ * for example after receiving an asynchronous API response.
381
+ * The <code>suggestionList</code> property must be populated with data for suggestions to appear.
382
+ * Use either this property or <code>showSuggestedPopover</code> — avoid using both simultaneously.
375
383
  *
376
384
  * @default false
377
385
  * @public
@@ -563,6 +571,9 @@ class UDExSearch extends UI5Element {
563
571
  @property({ type: Boolean })
564
572
  _isTouched!: boolean;
565
573
 
574
+ private _openSuggestionHandled = false;
575
+ private _intersectionObserver?: IntersectionObserver;
576
+
566
577
  @i18n("@sapudex/web-components")
567
578
  static i18nBundle: I18nBundle;
568
579
 
@@ -576,11 +587,22 @@ class UDExSearch extends UI5Element {
576
587
  this.isNotMozillaFirefoxIOS = !this.isMozillaFirefox("FxiOS");
577
588
  this.initSpeechRecognition();
578
589
  ResizeHandler.register(this, this._handleResizeBound);
590
+ this._intersectionObserver = new IntersectionObserver(entries => {
591
+ entries.forEach(entry => {
592
+ if (entry.isIntersecting && this.openSuggestionPopup) {
593
+ this._openSuggestionHandled = false;
594
+ this.handleOpenSuggestionPopover();
595
+ }
596
+ });
597
+ });
598
+ this._intersectionObserver.observe(this);
579
599
  }
580
600
 
581
601
  onExitDOM(): void {
582
602
  ResizeHandler.deregister(this, this._handleResizeBound);
583
603
  this.removeEventListener("dropdown-trigger-event", () => { });
604
+ this._intersectionObserver?.disconnect();
605
+ this._intersectionObserver = undefined;
584
606
  }
585
607
 
586
608
  initSpeechRecognition(): void {
@@ -633,6 +655,7 @@ class UDExSearch extends UI5Element {
633
655
 
634
656
  setPopoverState(changeInfo: ChangeInfo): void {
635
657
  if (changeInfo.name === "openSuggestionPopup") {
658
+ this._openSuggestionHandled = false;
636
659
  this.handlePopoverTrigger(changeInfo.newValue as boolean);
637
660
  }
638
661
  }
@@ -651,8 +674,8 @@ class UDExSearch extends UI5Element {
651
674
  }
652
675
  }
653
676
 
654
- setSuggestedRecommendedLists(value: string): void {
655
- if (this.showSuggestedPopover && value) {
677
+ setSuggestedRecommendedLists(value: string, handleClose = true): void {
678
+ if ((this.showSuggestedPopover || this.openSuggestionPopup) && value) {
656
679
  const parsedData: SuggestionRecommendLists = JSON.parse(value);
657
680
  const hasDataLabels = this.hasDataLabel(parsedData);
658
681
 
@@ -661,7 +684,7 @@ class UDExSearch extends UI5Element {
661
684
  this.suggestedList = this.getListWithSuggestion(this.getSuggestedList(hasDataLabels, parsedData), "suggested");
662
685
  this.recommendedList = this.getListWithSuggestion(this.getRecommendedList(hasDataLabels, parsedData), "recommended");
663
686
  }
664
- if (!this.shouldShowPopover(parsedData, hasDataLabels)) {
687
+ if (handleClose && !this.shouldShowPopover(parsedData, hasDataLabels)) {
665
688
  this.onClosePopover();
666
689
  this.resetSuggestedRecommendedLists();
667
690
  }
@@ -864,7 +887,7 @@ class UDExSearch extends UI5Element {
864
887
  }
865
888
 
866
889
  onOpenPopover(): void {
867
- if (this.showSuggestedPopover) {
890
+ if (this.showSuggestedPopover || this.openSuggestionPopup) {
868
891
  if (!this.Suggestion) {
869
892
  retryUntilSuccessful(() => this.Suggestion, this.retryDelay, this.maxRetryAttempts, this.unsuccessfulRetryMessage)
870
893
  .then(() => {
@@ -884,8 +907,8 @@ class UDExSearch extends UI5Element {
884
907
  }
885
908
 
886
909
  onClosePopover(): void {
887
- if (this.showSuggestedPopover) {
888
- this.Suggestion!.close();
910
+ if (this.showSuggestedPopover || this.open) {
911
+ this.Suggestion?.close();
889
912
  this.handleAriaExpanded();
890
913
  this.open = false;
891
914
  this.fireDecoratorEvent("suggestion-popover-closed");
@@ -897,15 +920,18 @@ class UDExSearch extends UI5Element {
897
920
  }
898
921
 
899
922
  get rootClasses(): string {
900
- if (this.mode === Mode.HomeSearch && this.showSuggestedPopover && this.open) {
923
+ if (this.mode === Mode.HomeSearch && (this.showSuggestedPopover) && this.open) {
901
924
  return this.isSuggestionPopoverTop ? "udex-search__root--show-popover-top" : "udex-search__root--show-popover";
902
925
  }
903
926
  return "";
904
927
  }
905
928
 
906
929
  onBeforeRendering(): void {
907
- if (this.showSuggestedPopover) {
930
+ if (this.showSuggestedPopover || this.openSuggestionPopup) {
908
931
  this.enableSuggestions();
932
+ if (this.suggestionList && !this.suggestedList?.length && !this.recommendedList?.length) {
933
+ this.setSuggestedRecommendedLists(this.suggestionList, false);
934
+ }
909
935
  }
910
936
 
911
937
  if (this.isHomeSearchWithPrefixMode && this.dropdownPrefix.length) {
@@ -976,7 +1002,7 @@ class UDExSearch extends UI5Element {
976
1002
  }
977
1003
 
978
1004
  onAfterRendering(): void {
979
- if (this.showSuggestedPopover) {
1005
+ if (this.showSuggestedPopover || this.openSuggestionPopup) {
980
1006
  const prefixPopover = this.getPrefixPopover();
981
1007
 
982
1008
  if (this.Suggestion?.popover) {
@@ -998,9 +1024,18 @@ class UDExSearch extends UI5Element {
998
1024
  }
999
1025
 
1000
1026
  handleOpenSuggestionPopover() {
1001
- if (this.openSuggestionPopup) {
1027
+ if (this.openSuggestionPopup && !this._openSuggestionHandled) {
1028
+ this._openSuggestionHandled = true;
1002
1029
  this.Suggestion?._getSuggestionPopover();
1003
- this.handlePopoverTrigger(this.openSuggestionPopup);
1030
+ // Defer to the next animation frame so the opener element has a resolved
1031
+ // layout before UI5 Popover calculates its position. Without this, opening
1032
+ // during onAfterRendering (which runs in a microtask, before layout) causes
1033
+ // the popover to anchor at 0,0 — appearing detached from the search input.
1034
+ requestAnimationFrame(() => {
1035
+ if (this.openSuggestionPopup) {
1036
+ this.handlePopoverTrigger(this.openSuggestionPopup);
1037
+ }
1038
+ });
1004
1039
  }
1005
1040
  }
1006
1041
 
@@ -851,15 +851,23 @@ class UDExSearchableListBase extends UI5Element {
851
851
  }
852
852
 
853
853
  get roleForGroupList(): string {
854
- // Host is always transparent; the shadow-inner div carries the widget role
855
- // (tree/listbox) via accessibleRoleForList.
856
- return "none";
854
+ // Active-descendant items carry their roles on their hosts; their owning
855
+ // container must do the same, regardless of the selection mode.
856
+ return this._activeDescendantMode ? this.accessibleRoleForList : "none";
857
+ }
858
+
859
+ /** @private Accessible name for a host-owned popup list. */
860
+ get listAccessibleName(): string {
861
+ return "";
857
862
  }
858
863
 
859
864
  get accessibleRoleForList(): string {
860
865
  if (this.isTreeStructure) {
861
866
  return "tree";
862
867
  }
868
+ if (this.mode === UDExListMode.SingleContent) {
869
+ return "list";
870
+ }
863
871
  if (this.isPerGroupListbox) {
864
872
  // Each group is its own role="listbox" (see ListGroupHeaderTemplate); the outer
865
873
  // container must be transparent, otherwise the per-group listboxes would be nested
@@ -891,6 +899,10 @@ class UDExSearchableListBase extends UI5Element {
891
899
  return "treeitem";
892
900
  }
893
901
 
902
+ if (this.mode === UDExListMode.SingleContent) {
903
+ return "listitem";
904
+ }
905
+
894
906
  if (this.accessibleRoleForList === "listbox") {
895
907
  return "option";
896
908
  }
@@ -8,8 +8,11 @@ import UDExList from "./List.js";
8
8
  import UDExListItem from "./ListItem.js";
9
9
  import UDExListGroupHeader from "./ListGroupHeader.js";
10
10
  import UDExListSelectAll from "./ListSelectAll.js";
11
+ import { UDExListMode } from "./types/List.js";
11
12
  import type { AriaRole } from "@ui5/webcomponents-base/dist/types.js";
12
13
  import { cleanLabel } from "./utils/listItemLabelUtils.js";
14
+ import { INDETERMINATE, SELECT_ALL } from "./generated/i18n/i18n-defaults.js";
15
+ import translate from "./utils/translate.js";
13
16
 
14
17
  export default function SearchableListBaseTemplate(this: UDExSearchableListBase) {
15
18
  return (
@@ -49,8 +52,12 @@ export default function SearchableListBaseTemplate(this: UDExSearchableListBase)
49
52
  <UDExList
50
53
  id="udex-list"
51
54
  role={this.roleForGroupList as AriaRole}
52
- accessible-role={this.accessibleRoleForList}
53
- {...(this.isTreeStructure && this.modeMultiSelect ? { "aria-multiselectable": "true" } : {})}
55
+ {...(this._activeDescendantMode ? {
56
+ "aria-label": this.listAccessibleName,
57
+ accessibleName: this.listAccessibleName,
58
+ } : {})}
59
+ accessibleRole={this._activeDescendantMode ? "" : this.accessibleRoleForList}
60
+ {...((this.isTreeStructure || this._activeDescendantMode) && this.modeMultiSelect ? { "aria-multiselectable": "true" } : {})}
54
61
  class="udex-filter-menu__list"
55
62
  controlled={this.isControlled}
56
63
  mode={this.mode}
@@ -59,7 +66,7 @@ export default function SearchableListBaseTemplate(this: UDExSearchableListBase)
59
66
  {this._filteredItems.map((processedItem, index) => (
60
67
  processedItem.isGroup
61
68
  ? renderGroup.call(this, processedItem, index)
62
- : renderListItem(processedItem.item as UDExListItem, index, "none", this.listItemRole, this.fireFirstIconClickEvent, this.fireSecondIconClickEvent, this._activeDescendantMode, this.isTreeStructure, this.modeMultiSelect)
69
+ : renderListItem(processedItem.item as UDExListItem, index, "none", this.listItemRole, this.fireFirstIconClickEvent, this.fireSecondIconClickEvent, this._activeDescendantMode, this.isTreeStructure, this._activeDescendantMode ? index + 1 : undefined, this._activeDescendantMode ? this._filteredItems.length : undefined)
63
70
  ))}
64
71
  </UDExList>
65
72
  )}
@@ -76,9 +83,14 @@ function renderGroup(this: UDExSearchableListBase, processedItem: UDExProcessedI
76
83
  function renderSelectAll(this: UDExSearchableListBase, processedItem: UDExProcessedItem, index: number) {
77
84
  const { item, groupItems } = processedItem;
78
85
  const header = item as UDExListGroupHeaderBase;
86
+ const label = item.label && item.label !== "undefined" ? item.label : translate(UDExListSelectAll, SELECT_ALL);
79
87
  return (
80
88
  <UDExListSelectAll
81
89
  key={index}
90
+ id={item._id}
91
+ {...UDExGroupHostAria.call(this, header, index, label)}
92
+ mode={this.mode}
93
+ _treeMode={this.isTreeStructure}
82
94
  _additional-class-name={this.additionalClassName}
83
95
  data-token-id={item._id}
84
96
  label={item.label}
@@ -90,26 +102,38 @@ function renderSelectAll(this: UDExSearchableListBase, processedItem: UDExProces
90
102
  onFirstIconClick={this.fireFirstIconClickEvent}
91
103
  onSecondIconClick={this.fireSecondIconClickEvent}>
92
104
  {groupItems.map((child, i) =>
93
- renderListItem(child as UDExListItem, i, this.listItemRole, undefined, this.fireFirstIconClickEvent, this.fireSecondIconClickEvent, this._activeDescendantMode, this.isTreeStructure, this.modeMultiSelect)
105
+ renderListItem(child as UDExListItem, i, this.listItemRole, this._activeDescendantMode && this.isTreeStructure ? "treeitem" : undefined, this.fireFirstIconClickEvent, this.fireSecondIconClickEvent, this._activeDescendantMode, this.isTreeStructure, this._activeDescendantMode ? i + 1 : undefined, this._activeDescendantMode ? groupItems.length : undefined)
94
106
  )}
95
107
  </UDExListSelectAll>
96
108
  );
97
109
  }
98
110
 
111
+ function UDExGroupHostAria(this: UDExSearchableListBase, header: UDExListGroupHeaderBase, index: number, label = header.label) {
112
+ return this._activeDescendantMode ? {
113
+ role: (this.isTreeStructure ? "treeitem" : "option") as AriaRole,
114
+ "aria-label": [label, header.supportingText].filter(Boolean).map(UDExText => cleanLabel(UDExText)).join(" "),
115
+ "aria-level": this.isTreeStructure ? 1 : undefined,
116
+ "aria-posinset": index + 1,
117
+ "aria-setsize": this._filteredItems.length,
118
+ "aria-selected": this.modeSingleSelect || this.modeMultiSelect ? String(header.selected && !header.indeterminate) : undefined,
119
+ // aria-selected is Boolean, not tri-state. Describe partial group selection
120
+ // separately rather than exposing the same selection as both checked and selected.
121
+ "aria-description": this.modeMultiSelect && header.indeterminate ? translate(UDExListSelectAll, INDETERMINATE) : undefined,
122
+ "aria-disabled": header.disabled ? "true" : undefined,
123
+ "aria-expanded": header.collapsible ? String(header.expanded) : undefined,
124
+ "_use-host-aria-role": true,
125
+ } : { role: "none" as AriaRole };
126
+ }
127
+
99
128
  function renderGroupHeader(this: UDExSearchableListBase, processedItem: UDExProcessedItem, index: number) {
100
129
  const { item, groupItems } = processedItem;
101
130
  const header = item as UDExListGroupHeaderBase;
102
131
  const childAccessibleRole = this.isTreeStructure ? "treeitem" : undefined;
103
- // Position among sibling group headers, for the explicit tree-position attributes below.
132
+ // Explicit positions for real-focus MultiSelect group headers.
104
133
  const treeGroups = this.isTreeStructure ? this._filteredItems.filter(p => p.isGroup) : [];
105
134
  const groupPosInSet = treeGroups.indexOf(processedItem) + 1;
106
135
  const groupSetSize = treeGroups.length;
107
- // Explicit per-group tree position for the FilterMenu (real-focus) treeitems. Scoped to
108
- // MultiSelect only: the SingleSelect tree is now conformantly nested (role="group" inside
109
- // the parent treeitem) so JAWS/NVDA count children natively — explicit values there just
110
- // confuse JAWS. MultiSelect still uses the malformed sibling structure until Phase 2, so it
111
- // keeps the explicit override. Not applied in aria-activedescendant mode (SelectBox announces
112
- // position via its own live region — see [[project_selectbox_aria_live_region]]).
136
+ // Keep the existing real-focus position overrides separate from host-owned ARIA.
113
137
  const treePositionAttrs = (!this._activeDescendantMode && this.isTreeStructure && this.modeMultiSelect) ? {
114
138
  "_aria-pos-in-set": groupPosInSet,
115
139
  "_aria-set-size": groupSetSize,
@@ -120,23 +144,16 @@ function renderGroupHeader(this: UDExSearchableListBase, processedItem: UDExProc
120
144
  // the shadow DOM's div.udex-list__group provides the single role="group" with
121
145
  // aria-labelledby="group-heading" in non-tree mode; in tree mode the treeitem is
122
146
  // on the focusable div inside the shadow.
123
- const hostAriaAttrs = this._activeDescendantMode ? {
124
- role: (this.isTreeStructure ? "treeitem" : "option") as AriaRole,
125
- "aria-label": cleanLabel(item.label ?? ""),
126
- "aria-selected": (this.modeMultiSelect ? undefined : (item.selected ? "true" : "false")) as string | undefined,
127
- "aria-checked": (this.modeMultiSelect ? (header.indeterminate ? "mixed" : (item.selected ? "true" : "false")) : undefined) as string | undefined,
128
- "aria-disabled": item.disabled ? "true" as string : undefined,
129
- "aria-expanded": header.collapsible ? (header.expanded ? "true" as string : "false" as string) : undefined,
130
- "_use-host-aria-role": true,
131
- } : { role: "none" as AriaRole };
147
+ const hostAriaAttrs = UDExGroupHostAria.call(this, header, index);
132
148
  return (
133
149
  <UDExListGroupHeader
134
150
  key={index}
135
151
  id={item._id}
136
152
  {...hostAriaAttrs}
137
153
  {...treePositionAttrs}
138
- _tree-mode={this.isTreeStructure || undefined}
139
- _group-as-listbox={this.isPerGroupListbox || undefined}
154
+ _treeMode={this.isTreeStructure}
155
+ _groupAsListbox={this.isPerGroupListbox}
156
+ mode={this.mode}
140
157
  {...(index === 0 ? { "_no-border": "" } : {})}
141
158
  _additional-class-name="udex-searchable-list__header"
142
159
  class={this.groupClassName}
@@ -155,7 +172,7 @@ function renderGroupHeader(this: UDExSearchableListBase, processedItem: UDExProc
155
172
  onAccordionIconClick={this.handleAccordionIconClick}
156
173
  indeterminate={header.indeterminate}>
157
174
  {groupItems.map((child, i) =>
158
- renderListItem(child as UDExListItem, i, "none", childAccessibleRole, this.fireFirstIconClickEvent, this.fireSecondIconClickEvent, this._activeDescendantMode, this.isTreeStructure, this.modeMultiSelect, i + 1, groupItems.length)
175
+ renderListItem(child as UDExListItem, i, "none", childAccessibleRole, this.fireFirstIconClickEvent, this.fireSecondIconClickEvent, this._activeDescendantMode, this.isTreeStructure, i + 1, groupItems.length)
159
176
  )}
160
177
  </UDExListGroupHeader>
161
178
  );
@@ -170,34 +187,31 @@ function renderListItem(
170
187
  onSecondIconClick: (e: CustomEvent) => void,
171
188
  activeDescendantMode?: boolean,
172
189
  isTreeStructure?: boolean,
173
- modeMultiSelect?: boolean,
174
190
  posInSet?: number,
175
191
  setSize?: number,
176
192
  ) {
177
193
  // In aria-activedescendant mode (SelectBox), role + ARIA state must be on the
178
194
  // host element so screen readers can reach them via the aria-activedescendant pointer.
179
195
  const effectiveRole = accessibleRole ?? (role !== "none" ? role : undefined) ?? "option";
196
+ const selectable = item.mode !== UDExListMode.SingleContent;
180
197
  const hostRole = activeDescendantMode ? (effectiveRole as AriaRole) : (role as AriaRole);
181
198
  const hostAriaAttrs = activeDescendantMode ? {
182
- "aria-label": "test",
183
- // option role (listbox): always aria-selected; treeitem + MultiSelect: aria-checked only
184
- "aria-selected": (effectiveRole !== "treeitem" || !modeMultiSelect) ? (item.selected ? "true" : "false") as string : undefined,
185
- "aria-checked": (effectiveRole === "treeitem" && !!modeMultiSelect) ? (item.indeterminate ? "mixed" : (item.selected ? "true" : "false")) as string : undefined,
199
+ // Rating-only options need a host name too, rather than a name derived from
200
+ // descendants that can include the decorative checkbox's selection label.
201
+ "aria-label": [item.label, item.supportingText, item.additionalText, item.hasRating ? item.ratingAriaLabel : undefined]
202
+ .filter(Boolean).map(UDExText => cleanLabel(UDExText!)).join(" ") || undefined,
203
+ // Native position metadata replaces the duplicate spoken live-region summary.
204
+ "aria-level": isTreeStructure ? ((item.parentElement as UDExListGroupHeaderBase | null)?.isGroup ? 2 : 1) : undefined,
205
+ "aria-posinset": posInSet,
206
+ "aria-setsize": setSize,
207
+ "aria-selected": selectable && (effectiveRole === "option" || effectiveRole === "treeitem") ? String(item.selected) : undefined,
186
208
  "aria-disabled": item.disabled ? "true" as string : undefined,
187
209
  "_use-host-aria-role": true,
188
210
  ...(accessibleRole ? { "accessible-role": accessibleRole } : {}),
189
211
  } : {
190
212
  ...(accessibleRole ? { "accessible-role": accessibleRole } : {}),
191
213
  };
192
- // Explicit per-group position for FilterMenu real-focus items. Applied whenever
193
- // posInSet/setSize are provided (i.e. items inside a group header), across all
194
- // modes except aria-activedescendant (SelectBox uses its own live region):
195
- // • Non-tree grouped listbox (SingleSelect non-collapsible): options get per-group
196
- // counts since native shadow-DOM counting is unreliable for nested custom elements.
197
- // • SingleSelect conformant-nested tree: explicit values match the native structural
198
- // count, so JAWS trusts and re-announces on every arrow step (not just group entry).
199
- // • MultiSelect sibling tree (Phase 2 pending): keeps the fix-20 override.
200
- // Not applied in aria-activedescendant mode (SelectBox — see [[project_selectbox_aria_live_region]]).
214
+ // Real-focus grouped children keep their position on the inner focusable row.
201
215
  const treePositionAttrs = (!activeDescendantMode && posInSet != null && setSize != null) ? {
202
216
  "_aria-pos-in-set": posInSet,
203
217
  "_aria-set-size": setSize,
@@ -21,6 +21,7 @@ import { BreakpointUtils } from "./utils/Breakpoints.js";
21
21
  import parseArrayFromString from "./utils/parseArrayFromString.js";
22
22
  import AnalyticsName from "./types/AnalyticsName.js";
23
23
  import translate from "./utils/translate.js";
24
+ import type { RelativeValue } from "./utils/parseRelativeUnits.js";
24
25
 
25
26
  // Styles
26
27
  import SecondaryNavigationCss from "./generated/themes/SecondaryNavigation.css.js";
@@ -180,7 +181,7 @@ class UDExSecondaryNavigation extends UI5Element {
180
181
  * @public
181
182
  */
182
183
  @property({ type: String })
183
- maxDropdownHeight!: string;
184
+ maxDropdownHeight!: RelativeValue;
184
185
 
185
186
  @property({ type: Boolean, noAttribute: true })
186
187
  _selectedMore!: boolean;
@@ -32,6 +32,11 @@ type UDExSecondaryNavigationItemSubItemClickEventDetail = {
32
32
  originalEvent: PointerEvent | KeyboardEvent
33
33
  }
34
34
 
35
+ const DROPDOWN_MAX_HEIGHT_VAR = {
36
+ desktop: "--udex-secondary-navigation-item-dropdown-desktop-max-height",
37
+ mobile: "--udex-secondary-navigation-item-dropdown-mobile-max-height",
38
+ } as const;
39
+
35
40
  /**
36
41
  * @class
37
42
  *
@@ -394,24 +399,27 @@ class UDExSecondaryNavigationItem extends UDExSecondaryNavigationItemBase {
394
399
  setDesktopDropdownMaxHeight(): void {
395
400
  const { top } = this.dropdown.getBoundingClientRect();
396
401
  const maxHeight = window.innerHeight - top - DESKTOP_DROPDOWN_BOTTOM_GAP;
397
- this.style.setProperty("--udex-secondary-navigation-item-dropdown-desktop-max-height", `${maxHeight}px`);
402
+ this.style.setProperty(DROPDOWN_MAX_HEIGHT_VAR.desktop, `${maxHeight}px`);
398
403
  }
399
404
 
400
405
  setMobileDropdownMaxHeight(): void {
401
406
  if (!this._maxHeight || this._dropdownMaxHeightExceeds || !this.heightSatisfiesType) {
402
- const secondaryNavigationMobileTrigger = this.shadowRoot!.querySelector(".udex-secondary-navigation__item")!;
403
- const maxDropdownHeight = window.innerHeight - secondaryNavigationMobileTrigger.clientHeight;
404
- this.style.setProperty("--udex-secondary-navigation-item-dropdown-mobile-max-height", `${maxDropdownHeight}px`);
407
+ const { clientHeight } = this.shadowRoot!.querySelector(".udex-secondary-navigation__item")!;
408
+ const { top } = this.getBoundingClientRect();
409
+ const maxDropdownHeight = window.innerHeight - top - clientHeight;
410
+
411
+ this.style.setProperty(DROPDOWN_MAX_HEIGHT_VAR.mobile, `${maxDropdownHeight}px`);
405
412
  return;
406
413
  }
407
414
 
408
- this.style.setProperty("--udex-secondary-navigation-item-dropdown-mobile-max-height", `${this._maxHeight}`);
415
+ this.style.setProperty(DROPDOWN_MAX_HEIGHT_VAR.mobile, `${this._maxHeight}`);
409
416
  }
410
417
 
411
418
  get _dropdownMaxHeightExceeds(): boolean {
412
419
  const normalizedHeight = parseRelativeUnits(this._maxHeight, this.dropdown);
420
+ const { top } = this.getBoundingClientRect();
413
421
  const secondaryNavigationMobileTriggerHeight = this.shadowRoot!.querySelector(".udex-secondary-navigation__item")!.clientHeight;
414
- return normalizedHeight >= window.innerHeight - secondaryNavigationMobileTriggerHeight;
422
+ return normalizedHeight >= window.innerHeight - top - secondaryNavigationMobileTriggerHeight;
415
423
  }
416
424
 
417
425
  get heightSatisfiesType(): boolean {
@@ -41,7 +41,7 @@ export default function SecondaryNavigationTemplate(this: UDExSecondaryNavigatio
41
41
  subItems={item.items ?? []}
42
42
  onui5-sub-item-click={this.handleSubItemClick}
43
43
  onui5-nav-item-click={this.handleItemClick}
44
- {...{ "_nav-items-length": this.visibleItems.length }}>
44
+ _navItemsLength={this.visibleItems.length}>
45
45
  </UDExSecondaryNavigationItem>
46
46
  </li>
47
47
  ))}
@@ -53,7 +53,7 @@ export default function SecondaryNavigationTemplate(this: UDExSecondaryNavigatio
53
53
  onui5-nav-item-click={this.handleItemClick}
54
54
  label={this.moreButtonText}
55
55
  subItems={this._overflowItems}
56
- {...{ "_nav-items-length": this.visibleItems.length }}>
56
+ _navItemsLength={this.visibleItems.length}>
57
57
  </UDExSecondaryNavigationItem>
58
58
  </li>
59
59
  )}
@@ -75,10 +75,8 @@ export default function SecondaryNavigationTemplate(this: UDExSecondaryNavigatio
75
75
  onui5-sub-item-click={this.handleSubItemClick}
76
76
  onKeyDown={this.handleKeyDown}
77
77
  subItems={this.parsedItems}
78
- {...{
79
- "_is-mobile-menu-opener": "",
80
- "_max-height": this.maxDropdownHeight
81
- }}>
78
+ _maxHeight={this.maxDropdownHeight}
79
+ _is-mobile-menu-opener={true}>
82
80
  {this.hasMobileButtonsSlot && (
83
81
  <div className="udex-secondary-navigation__buttons" onClick={this.handleMobileButtonsClick}>
84
82
  <slot name="buttons"></slot>