@sapudex/web-components 2.48.0 → 2.49.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 (307) hide show
  1. package/bundle.esm.js +2 -0
  2. package/cypress/specs/AccordionSpotlight.cy.tsx +402 -0
  3. package/cypress/specs/BusyIndicator.cy.tsx +15 -0
  4. package/cypress/specs/Carousel.cy.tsx +142 -0
  5. package/cypress/specs/FilterMenu.cy.tsx +968 -10
  6. package/cypress/specs/List.cy.tsx +106 -0
  7. package/cypress/specs/ListItem.cy.tsx +291 -1
  8. package/cypress/specs/MediaPlayer.cy.tsx +32 -0
  9. package/cypress/specs/SelectBox.cy.tsx +134 -3
  10. package/cypress/support/component-imports.instrumented.ts +6 -0
  11. package/cypress/support/component-imports.src.ts +6 -0
  12. package/dist/AccordionSpotlight.d.ts +149 -0
  13. package/dist/AccordionSpotlight.js +284 -0
  14. package/dist/AccordionSpotlight.js.map +1 -0
  15. package/dist/AccordionSpotlightItem.d.ts +76 -0
  16. package/dist/AccordionSpotlightItem.js +115 -0
  17. package/dist/AccordionSpotlightItem.js.map +1 -0
  18. package/dist/AccordionSpotlightItemTemplate.d.ts +2 -0
  19. package/dist/AccordionSpotlightItemTemplate.js +5 -0
  20. package/dist/AccordionSpotlightItemTemplate.js.map +1 -0
  21. package/dist/AccordionSpotlightTemplate.d.ts +2 -0
  22. package/dist/AccordionSpotlightTemplate.js +10 -0
  23. package/dist/AccordionSpotlightTemplate.js.map +1 -0
  24. package/dist/BusyIndicator.d.ts +9 -0
  25. package/dist/BusyIndicator.js +7 -1
  26. package/dist/BusyIndicator.js.map +1 -1
  27. package/dist/Carousel.d.ts +26 -15
  28. package/dist/Carousel.js +71 -55
  29. package/dist/Carousel.js.map +1 -1
  30. package/dist/FilterMenu.d.ts +12 -2
  31. package/dist/FilterMenu.js +24 -4
  32. package/dist/FilterMenu.js.map +1 -1
  33. package/dist/FilterMenuTemplate.js +1 -1
  34. package/dist/FilterMenuTemplate.js.map +1 -1
  35. package/dist/List.d.ts +1 -0
  36. package/dist/List.js +24 -11
  37. package/dist/List.js.map +1 -1
  38. package/dist/ListGroupHeader.js +5 -1
  39. package/dist/ListGroupHeader.js.map +1 -1
  40. package/dist/ListGroupHeaderBase.d.ts +22 -0
  41. package/dist/ListGroupHeaderBase.js +44 -0
  42. package/dist/ListGroupHeaderBase.js.map +1 -1
  43. package/dist/ListItem.d.ts +4 -0
  44. package/dist/ListItem.js +32 -0
  45. package/dist/ListItem.js.map +1 -1
  46. package/dist/MediaPlayer.d.ts +2 -0
  47. package/dist/MediaPlayer.js +12 -0
  48. package/dist/MediaPlayer.js.map +1 -1
  49. package/dist/PromoTile.js +1 -1
  50. package/dist/PromoTile.js.map +1 -1
  51. package/dist/SearchableListBase.d.ts +10 -1
  52. package/dist/SearchableListBase.js +23 -7
  53. package/dist/SearchableListBase.js.map +1 -1
  54. package/dist/SearchableListBaseTemplate.js +3 -2
  55. package/dist/SearchableListBaseTemplate.js.map +1 -1
  56. package/dist/SelectBase.d.ts +14 -0
  57. package/dist/SelectBase.js +56 -3
  58. package/dist/SelectBase.js.map +1 -1
  59. package/dist/SelectBoxTemplate.js +1 -1
  60. package/dist/SelectBoxTemplate.js.map +1 -1
  61. package/dist/TabNavigation.d.ts +6 -0
  62. package/dist/TabNavigation.js +5 -0
  63. package/dist/TabNavigation.js.map +1 -1
  64. package/dist/assets/{InputSuggestions-BcK6O4Bk.js → InputSuggestions-DaB1A6jW.js} +1 -1
  65. package/dist/assets/{ListItemStandardExpandableTextTemplate-u600dmHC.js → ListItemStandardExpandableTextTemplate-Co4KQuVw.js} +1 -1
  66. package/dist/assets/{bundle-JYo3bV8v.css → bundle-CkxyEA8c.css} +1 -1
  67. package/dist/assets/{bundle.esm-C6Ie2WeI.js → bundle.esm-al3NYhoB.js} +241 -238
  68. package/dist/assets/messagebundle_ar-BUZ_gTvQ.js +1 -0
  69. package/dist/assets/messagebundle_no-BZQfeWxT.js +1 -0
  70. package/dist/css/themes/Accordion.css +1 -1
  71. package/dist/css/themes/AccordionItem.css +1 -1
  72. package/dist/css/themes/AccordionSpotlight.css +1 -0
  73. package/dist/css/themes/AccordionSpotlightItem.css +1 -0
  74. package/dist/css/themes/Badge.css +1 -1
  75. package/dist/css/themes/BusyIndicator.css +1 -0
  76. package/dist/css/themes/Button.css +1 -1
  77. package/dist/css/themes/Divider.css +1 -1
  78. package/dist/css/themes/Dropdown.css +1 -1
  79. package/dist/css/themes/FilterMenu.css +1 -1
  80. package/dist/css/themes/Footer.css +1 -1
  81. package/dist/css/themes/ImageGridTableItem.css +1 -1
  82. package/dist/css/themes/MastheadShell.css +1 -1
  83. package/dist/css/themes/MediaPlayer.css +1 -1
  84. package/dist/css/themes/PhoneNumberField.css +1 -1
  85. package/dist/css/themes/ProgressBar.css +1 -1
  86. package/dist/css/themes/PromoTile.css +1 -1
  87. package/dist/css/themes/Review.css +1 -1
  88. package/dist/css/themes/ReviewItem.css +1 -1
  89. package/dist/css/themes/Search.css +1 -1
  90. package/dist/css/themes/SelectBase.css +1 -1
  91. package/dist/css/themes/SelectBox.css +1 -1
  92. package/dist/css/themes/SideNavigation.css +1 -1
  93. package/dist/css/themes/SideNavigationGroup.css +1 -1
  94. package/dist/css/themes/SocialMediaButton.css +1 -1
  95. package/dist/css/themes/StepInput.css +1 -1
  96. package/dist/css/themes/Switch.css +1 -1
  97. package/dist/css/themes/TabNavigation.css +1 -1
  98. package/dist/css/themes/Tag.css +1 -1
  99. package/dist/css/themes/TagGroup.css +1 -1
  100. package/dist/css/themes/TextArea.css +1 -1
  101. package/dist/css/themes/TextField.css +1 -1
  102. package/dist/css/themes/Toast.css +1 -1
  103. package/dist/custom-elements-internal.json +426 -35
  104. package/dist/custom-elements.json +384 -49
  105. package/dist/generated/assets/i18n/messagebundle_ar.json +1 -1
  106. package/dist/generated/assets/i18n/messagebundle_no.json +1 -1
  107. package/dist/generated/templates/ListGroupHeaderTemplate.lit.js +24 -21
  108. package/dist/generated/templates/ListGroupHeaderTemplate.lit.js.map +1 -1
  109. package/dist/generated/templates/ListItemTemplate.lit.js +2 -2
  110. package/dist/generated/templates/ListItemTemplate.lit.js.map +1 -1
  111. package/dist/generated/themes/Accordion.css.d.ts +1 -1
  112. package/dist/generated/themes/Accordion.css.js +1 -1
  113. package/dist/generated/themes/Accordion.css.js.map +1 -1
  114. package/dist/generated/themes/AccordionItem.css.d.ts +1 -1
  115. package/dist/generated/themes/AccordionItem.css.js +1 -1
  116. package/dist/generated/themes/AccordionItem.css.js.map +1 -1
  117. package/dist/generated/themes/AccordionSpotlight.css.d.ts +2 -0
  118. package/dist/generated/themes/AccordionSpotlight.css.js +8 -0
  119. package/dist/generated/themes/AccordionSpotlight.css.js.map +1 -0
  120. package/dist/generated/themes/AccordionSpotlightItem.css.d.ts +2 -0
  121. package/dist/generated/themes/AccordionSpotlightItem.css.js +8 -0
  122. package/dist/generated/themes/AccordionSpotlightItem.css.js.map +1 -0
  123. package/dist/generated/themes/Badge.css.d.ts +1 -1
  124. package/dist/generated/themes/Badge.css.js +1 -1
  125. package/dist/generated/themes/Badge.css.js.map +1 -1
  126. package/dist/generated/themes/BusyIndicator.css.d.ts +2 -0
  127. package/dist/generated/themes/BusyIndicator.css.js +8 -0
  128. package/dist/generated/themes/BusyIndicator.css.js.map +1 -0
  129. package/dist/generated/themes/Button.css.d.ts +1 -1
  130. package/dist/generated/themes/Button.css.js +1 -1
  131. package/dist/generated/themes/Button.css.js.map +1 -1
  132. package/dist/generated/themes/Divider.css.d.ts +1 -1
  133. package/dist/generated/themes/Divider.css.js +1 -1
  134. package/dist/generated/themes/Divider.css.js.map +1 -1
  135. package/dist/generated/themes/Dropdown.css.d.ts +1 -1
  136. package/dist/generated/themes/Dropdown.css.js +1 -1
  137. package/dist/generated/themes/Dropdown.css.js.map +1 -1
  138. package/dist/generated/themes/FilterMenu.css.d.ts +1 -1
  139. package/dist/generated/themes/FilterMenu.css.js +1 -1
  140. package/dist/generated/themes/FilterMenu.css.js.map +1 -1
  141. package/dist/generated/themes/Footer.css.d.ts +1 -1
  142. package/dist/generated/themes/Footer.css.js +1 -1
  143. package/dist/generated/themes/Footer.css.js.map +1 -1
  144. package/dist/generated/themes/ImageGridTableItem.css.d.ts +1 -1
  145. package/dist/generated/themes/ImageGridTableItem.css.js +1 -1
  146. package/dist/generated/themes/ImageGridTableItem.css.js.map +1 -1
  147. package/dist/generated/themes/MastheadShell.css.d.ts +1 -1
  148. package/dist/generated/themes/MastheadShell.css.js +1 -1
  149. package/dist/generated/themes/MastheadShell.css.js.map +1 -1
  150. package/dist/generated/themes/MediaPlayer.css.d.ts +1 -1
  151. package/dist/generated/themes/MediaPlayer.css.js +1 -1
  152. package/dist/generated/themes/MediaPlayer.css.js.map +1 -1
  153. package/dist/generated/themes/PhoneNumberField.css.d.ts +1 -1
  154. package/dist/generated/themes/PhoneNumberField.css.js +1 -1
  155. package/dist/generated/themes/PhoneNumberField.css.js.map +1 -1
  156. package/dist/generated/themes/ProgressBar.css.d.ts +1 -1
  157. package/dist/generated/themes/ProgressBar.css.js +1 -1
  158. package/dist/generated/themes/ProgressBar.css.js.map +1 -1
  159. package/dist/generated/themes/PromoTile.css.d.ts +1 -1
  160. package/dist/generated/themes/PromoTile.css.js +1 -1
  161. package/dist/generated/themes/PromoTile.css.js.map +1 -1
  162. package/dist/generated/themes/Review.css.d.ts +1 -1
  163. package/dist/generated/themes/Review.css.js +1 -1
  164. package/dist/generated/themes/Review.css.js.map +1 -1
  165. package/dist/generated/themes/ReviewItem.css.d.ts +1 -1
  166. package/dist/generated/themes/ReviewItem.css.js +1 -1
  167. package/dist/generated/themes/ReviewItem.css.js.map +1 -1
  168. package/dist/generated/themes/Search.css.d.ts +1 -1
  169. package/dist/generated/themes/Search.css.js +1 -1
  170. package/dist/generated/themes/Search.css.js.map +1 -1
  171. package/dist/generated/themes/SelectBase.css.d.ts +1 -1
  172. package/dist/generated/themes/SelectBase.css.js +1 -1
  173. package/dist/generated/themes/SelectBase.css.js.map +1 -1
  174. package/dist/generated/themes/SelectBox.css.d.ts +1 -1
  175. package/dist/generated/themes/SelectBox.css.js +1 -1
  176. package/dist/generated/themes/SelectBox.css.js.map +1 -1
  177. package/dist/generated/themes/SideNavigation.css.d.ts +1 -1
  178. package/dist/generated/themes/SideNavigation.css.js +1 -1
  179. package/dist/generated/themes/SideNavigation.css.js.map +1 -1
  180. package/dist/generated/themes/SideNavigationGroup.css.d.ts +1 -1
  181. package/dist/generated/themes/SideNavigationGroup.css.js +1 -1
  182. package/dist/generated/themes/SideNavigationGroup.css.js.map +1 -1
  183. package/dist/generated/themes/SocialMediaButton.css.d.ts +1 -1
  184. package/dist/generated/themes/SocialMediaButton.css.js +1 -1
  185. package/dist/generated/themes/SocialMediaButton.css.js.map +1 -1
  186. package/dist/generated/themes/StepInput.css.d.ts +1 -1
  187. package/dist/generated/themes/StepInput.css.js +1 -1
  188. package/dist/generated/themes/StepInput.css.js.map +1 -1
  189. package/dist/generated/themes/Switch.css.d.ts +1 -1
  190. package/dist/generated/themes/Switch.css.js +1 -1
  191. package/dist/generated/themes/Switch.css.js.map +1 -1
  192. package/dist/generated/themes/TabNavigation.css.d.ts +1 -1
  193. package/dist/generated/themes/TabNavigation.css.js +1 -1
  194. package/dist/generated/themes/TabNavigation.css.js.map +1 -1
  195. package/dist/generated/themes/Tag.css.d.ts +1 -1
  196. package/dist/generated/themes/Tag.css.js +1 -1
  197. package/dist/generated/themes/Tag.css.js.map +1 -1
  198. package/dist/generated/themes/TagGroup.css.d.ts +1 -1
  199. package/dist/generated/themes/TagGroup.css.js +1 -1
  200. package/dist/generated/themes/TagGroup.css.js.map +1 -1
  201. package/dist/generated/themes/TextArea.css.d.ts +1 -1
  202. package/dist/generated/themes/TextArea.css.js +1 -1
  203. package/dist/generated/themes/TextArea.css.js.map +1 -1
  204. package/dist/generated/themes/TextField.css.d.ts +1 -1
  205. package/dist/generated/themes/TextField.css.js +1 -1
  206. package/dist/generated/themes/TextField.css.js.map +1 -1
  207. package/dist/generated/themes/Toast.css.d.ts +1 -1
  208. package/dist/generated/themes/Toast.css.js +1 -1
  209. package/dist/generated/themes/Toast.css.js.map +1 -1
  210. package/dist/messagebundle_ar.properties +99 -0
  211. package/dist/messagebundle_no.properties +126 -1
  212. package/dist/vscode.html-custom-data.json +76 -11
  213. package/dist/web-types.json +194 -26
  214. package/package.json +1 -1
  215. package/src/AccordionSpotlight.ts +321 -0
  216. package/src/AccordionSpotlightItem.ts +117 -0
  217. package/src/AccordionSpotlightItemTemplate.tsx +7 -0
  218. package/src/AccordionSpotlightTemplate.tsx +107 -0
  219. package/src/BusyIndicator.ts +17 -2
  220. package/src/Carousel.ts +118 -80
  221. package/src/FilterMenu.ts +25 -4
  222. package/src/FilterMenuTemplate.tsx +1 -1
  223. package/src/List.ts +23 -11
  224. package/src/ListGroupHeader.hbs +11 -10
  225. package/src/ListGroupHeader.ts +5 -1
  226. package/src/ListGroupHeaderBase.ts +48 -0
  227. package/src/ListItem.hbs +5 -1
  228. package/src/ListItem.ts +36 -0
  229. package/src/MediaPlayer.ts +11 -0
  230. package/src/PromoTile.ts +1 -1
  231. package/src/SearchableListBase.ts +24 -7
  232. package/src/SearchableListBaseTemplate.tsx +5 -2
  233. package/src/SelectBase.ts +58 -3
  234. package/src/SelectBoxTemplate.tsx +1 -0
  235. package/src/TabNavigation.ts +6 -0
  236. package/src/generated/templates/ListGroupHeaderTemplate.lit.ts +24 -21
  237. package/src/generated/templates/ListItemTemplate.lit.ts +2 -2
  238. package/src/generated/themes/Accordion.css.ts +1 -1
  239. package/src/generated/themes/AccordionItem.css.ts +1 -1
  240. package/src/generated/themes/AccordionSpotlight.css.ts +9 -0
  241. package/src/generated/themes/AccordionSpotlightItem.css.ts +9 -0
  242. package/src/generated/themes/Badge.css.ts +1 -1
  243. package/src/generated/themes/BusyIndicator.css.ts +9 -0
  244. package/src/generated/themes/Button.css.ts +1 -1
  245. package/src/generated/themes/Divider.css.ts +1 -1
  246. package/src/generated/themes/Dropdown.css.ts +1 -1
  247. package/src/generated/themes/FilterMenu.css.ts +1 -1
  248. package/src/generated/themes/Footer.css.ts +1 -1
  249. package/src/generated/themes/ImageGridTableItem.css.ts +1 -1
  250. package/src/generated/themes/MastheadShell.css.ts +1 -1
  251. package/src/generated/themes/MediaPlayer.css.ts +1 -1
  252. package/src/generated/themes/PhoneNumberField.css.ts +1 -1
  253. package/src/generated/themes/ProgressBar.css.ts +1 -1
  254. package/src/generated/themes/PromoTile.css.ts +1 -1
  255. package/src/generated/themes/Review.css.ts +1 -1
  256. package/src/generated/themes/ReviewItem.css.ts +1 -1
  257. package/src/generated/themes/Search.css.ts +1 -1
  258. package/src/generated/themes/SelectBase.css.ts +1 -1
  259. package/src/generated/themes/SelectBox.css.ts +1 -1
  260. package/src/generated/themes/SideNavigation.css.ts +1 -1
  261. package/src/generated/themes/SideNavigationGroup.css.ts +1 -1
  262. package/src/generated/themes/SocialMediaButton.css.ts +1 -1
  263. package/src/generated/themes/StepInput.css.ts +1 -1
  264. package/src/generated/themes/Switch.css.ts +1 -1
  265. package/src/generated/themes/TabNavigation.css.ts +1 -1
  266. package/src/generated/themes/Tag.css.ts +1 -1
  267. package/src/generated/themes/TagGroup.css.ts +1 -1
  268. package/src/generated/themes/TextArea.css.ts +1 -1
  269. package/src/generated/themes/TextField.css.ts +1 -1
  270. package/src/generated/themes/Toast.css.ts +1 -1
  271. package/src/i18n/messagebundle_ar.properties +99 -0
  272. package/src/i18n/messagebundle_no.properties +126 -1
  273. package/src/themes/Accordion.css +1 -1
  274. package/src/themes/AccordionItem.css +4 -4
  275. package/src/themes/AccordionSpotlight.css +264 -0
  276. package/src/themes/AccordionSpotlightItem.css +3 -0
  277. package/src/themes/Badge.css +7 -7
  278. package/src/themes/BusyIndicator.css +24 -0
  279. package/src/themes/Button.css +57 -57
  280. package/src/themes/Divider.css +1 -1
  281. package/src/themes/Dropdown.css +1 -1
  282. package/src/themes/FilterMenu.css +2 -2
  283. package/src/themes/Footer.css +1 -1
  284. package/src/themes/ImageGridTableItem.css +1 -1
  285. package/src/themes/MastheadShell.css +2 -2
  286. package/src/themes/MediaPlayer.css +5 -34
  287. package/src/themes/PhoneNumberField.css +6 -6
  288. package/src/themes/ProgressBar.css +4 -0
  289. package/src/themes/PromoTile.css +4 -4
  290. package/src/themes/Review.css +2 -2
  291. package/src/themes/ReviewItem.css +2 -2
  292. package/src/themes/Search.css +5 -5
  293. package/src/themes/SelectBase.css +14 -14
  294. package/src/themes/SelectBox.css +1 -1
  295. package/src/themes/SideNavigation.css +1 -1
  296. package/src/themes/SideNavigationGroup.css +1 -1
  297. package/src/themes/SocialMediaButton.css +2 -2
  298. package/src/themes/StepInput.css +8 -8
  299. package/src/themes/Switch.css +9 -9
  300. package/src/themes/TabNavigation.css +1 -1
  301. package/src/themes/Tag.css +4 -4
  302. package/src/themes/TagGroup.css +1 -0
  303. package/src/themes/TextArea.css +4 -4
  304. package/src/themes/TextField.css +13 -13
  305. package/src/themes/Toast.css +1 -1
  306. package/dist/assets/messagebundle_ar-BNhVFt1-.js +0 -1
  307. package/dist/assets/messagebundle_no-BIUfmTWJ.js +0 -1
@@ -0,0 +1,321 @@
1
+ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
2
+ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
3
+ import property from "@ui5/webcomponents-base/dist/decorators/property.js";
4
+ import type { DefaultSlot, Slot } from "@ui5/webcomponents-base/dist/UI5Element.js";
5
+ import slot from "@ui5/webcomponents-base/dist/decorators/slot-strict.js";
6
+ import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";
7
+ import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js";
8
+ import { isDesktop } from "@ui5/webcomponents-base/dist/Device.js";
9
+ import AccordionSpotlightTemplate from "./AccordionSpotlightTemplate.js";
10
+ import AccordionSpotlightItem from "./AccordionSpotlightItem.js";
11
+ import UDExButton from "./Button.js";
12
+ import "@ui5/webcomponents-icons/dist/play.js";
13
+ import "@ui5/webcomponents-icons/dist/pause.js";
14
+ import type { ResizeObserverCallback } from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
15
+ import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
16
+ import { BreakpointUtils } from "./utils/Breakpoints.js";
17
+
18
+ // Styles
19
+ import AccordionSpotlightCss from "./generated/themes/AccordionSpotlight.css.js";
20
+
21
+ export enum UDExAccordionSpotlightVerticalAlignment {
22
+ Top = "Top",
23
+ Center = "Center",
24
+ }
25
+
26
+ export enum UDExAccordionSpotlightPlacement {
27
+ Start = "Start",
28
+ End = "End",
29
+ }
30
+
31
+ export enum UDExAccordionSpotlightMediaMode {
32
+ Dynamic = "Dynamic",
33
+ Static = "Static",
34
+ }
35
+
36
+ /**
37
+ * @class
38
+ *
39
+ * <h3 class="comment-api-title">Overview</h3>
40
+ *
41
+ * Vertical accordion navigation with spotlight layout. Items are listed on the
42
+ * left; the expanded panel is displayed on the right (desktop) or inline below
43
+ * the heading (mobile). Follows the WAI-ARIA APG Accordion pattern.
44
+ *
45
+ * <h3>Usage</h3>
46
+ *
47
+ * For the <code>udex-accordion-spotlight</code>
48
+ * <h3>ES6 Module Import</h3>
49
+ *
50
+ * <code>import "@sapudex/web-components/dist/AccordionSpotlight.js";</code>
51
+ *
52
+ * @constructor
53
+ * @extends UI5Element
54
+ * @public
55
+ */
56
+ @customElement({
57
+ tag: "udex-accordion-spotlight",
58
+ renderer: jsxRenderer,
59
+ styles: AccordionSpotlightCss,
60
+ template: AccordionSpotlightTemplate,
61
+ dependencies: [AccordionSpotlightItem, UDExButton],
62
+ })
63
+
64
+ /**
65
+ * Fired when the expanded item clicked.
66
+ *
67
+ * @public
68
+ * @param {AccordionSpotlightItem} [item] The accordion spotlight item that was clicked
69
+ */
70
+ @event("item-click", { bubbles: true })
71
+
72
+ class UDExAccordionSpotlight extends UI5Element {
73
+ eventDetails!: {
74
+ "item-click": { item: AccordionSpotlightItem },
75
+ };
76
+
77
+ /**
78
+ * The index of the currently expanded item (0-based).
79
+ * Derived from items' <code>selected</code> attribute; kept in sync by the parent.
80
+ *
81
+ * @private
82
+ */
83
+ @property({ type: Number, noAttribute: true })
84
+ _selectedIndex: number = 0;
85
+
86
+ /**
87
+ * Vertical alignment of the navigation sidebar relative to the content panel.
88
+ *
89
+ * @default "Top"
90
+ * @public
91
+ */
92
+ @property()
93
+ verticalAlignment: `${UDExAccordionSpotlightVerticalAlignment}` = UDExAccordionSpotlightVerticalAlignment.Top;
94
+
95
+ /**
96
+ * Placement of the navigation sidebar — "Start" (left) or "End" (right).
97
+ *
98
+ * @default "Start"
99
+ * @public
100
+ */
101
+ @property()
102
+ placement: `${UDExAccordionSpotlightPlacement}` = UDExAccordionSpotlightPlacement.Start;
103
+
104
+ /**
105
+ * Enables automatic cycling through items on an interval.
106
+ *
107
+ * @default false
108
+ * @public
109
+ */
110
+ @property({ type: Boolean })
111
+ autoPlay: boolean = false;
112
+
113
+ /**
114
+ * Interval in milliseconds between automatic item advances. Applies only when autoPlay is enabled.
115
+ *
116
+ * @default 5000
117
+ * @public
118
+ */
119
+ @property({ type: Number })
120
+ autoPlayInterval: number = 5000;
121
+
122
+ /**
123
+ * Defines the width of the navigation panel.
124
+ *
125
+ * @default "auto"
126
+ * @public
127
+ */
128
+ @property({ type: String })
129
+ tabWidth: string = "auto";
130
+
131
+ /**
132
+ * Controls how the media area behaves. In <code>Static</code> mode a single
133
+ * persistent media element (image or video) is displayed alongside the nav
134
+ * list and never changes when items are expanded. In <code>Dynamic</code>
135
+ * mode (default) each item provides its own content panel.
136
+ *
137
+ * @default "Dynamic"
138
+ * @public
139
+ */
140
+ @property()
141
+ mediaMode: `${UDExAccordionSpotlightMediaMode}` = UDExAccordionSpotlightMediaMode.Dynamic;
142
+
143
+ /**
144
+ * @private
145
+ */
146
+ @property({ type: Boolean, noAttribute: true })
147
+ _isMobile: boolean = false;
148
+
149
+ /**
150
+ * @private
151
+ */
152
+ @property({ type: Boolean, noAttribute: true })
153
+ _isPaused: boolean = false;
154
+
155
+ /**
156
+ * The slotted AccordionSpotlightItem elements.
157
+ *
158
+ * @public
159
+ */
160
+ @slot({ type: HTMLElement, "default": true, individualSlots: true })
161
+ items!: DefaultSlot<AccordionSpotlightItem>;
162
+
163
+ /**
164
+ * Defines optional content rendered below the navigation items.
165
+ * Use to place a button or any action element beneath the items.
166
+ *
167
+ * @slot footer
168
+ * @public
169
+ */
170
+ @slot({ type: HTMLElement })
171
+ footer!: Slot<HTMLElement>;
172
+
173
+ /**
174
+ * Persistent media area shown in <code>Static</code> media mode.
175
+ * Place an <code>&lt;img&gt;</code> or <code>&lt;video&gt;</code> element here;
176
+ * it remains visible regardless of which item is currently expanded.
177
+ *
178
+ * @slot media
179
+ * @public
180
+ */
181
+ @slot({ type: HTMLElement })
182
+ media!: Slot<HTMLElement>;
183
+
184
+ _handleResizeBound: ResizeObserverCallback;
185
+ _autoPlayTimer?: number;
186
+
187
+ constructor() {
188
+ super();
189
+ this._handleResizeBound = this._handleResize.bind(this);
190
+ }
191
+
192
+ onBeforeRendering() {
193
+ this._syncItemStates();
194
+ }
195
+
196
+ onAfterRendering() {
197
+ this._checkMobile();
198
+ }
199
+
200
+ onEnterDOM() {
201
+ ResizeHandler.register(this, this._handleResizeBound);
202
+
203
+ if (isDesktop()) {
204
+ this.setAttribute("desktop", "");
205
+ }
206
+
207
+ if (this.autoPlay) {
208
+ const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
209
+ if (prefersReducedMotion) {
210
+ this._isPaused = true;
211
+ } else {
212
+ this._startAutoPlay();
213
+ }
214
+ }
215
+ }
216
+
217
+ onExitDOM() {
218
+ ResizeHandler.deregister(this, this._handleResizeBound);
219
+ this._stopAutoPlay();
220
+ }
221
+
222
+ _handleResize(): void {
223
+ this._checkMobile();
224
+ }
225
+
226
+ _checkMobile() {
227
+ const isMobile = BreakpointUtils.isAtMost("S");
228
+ if (isMobile !== this._isMobile) {
229
+ this._isMobile = isMobile;
230
+ }
231
+ }
232
+
233
+ _syncItemStates() {
234
+ if (this.items.length === 0) {
235
+ return;
236
+ }
237
+
238
+ const foundIndex = this.items.findIndex(item => item.selected);
239
+ const activeIndex = foundIndex === -1 ? 0 : foundIndex;
240
+ this._selectedIndex = activeIndex;
241
+
242
+ this.items.forEach((item, index) => {
243
+ item.selected = index === activeIndex;
244
+ item._isMobile = this._isMobile;
245
+ });
246
+ }
247
+
248
+ _startAutoPlay(): void {
249
+ this._stopAutoPlay();
250
+ this._isPaused = false;
251
+ this._autoPlayTimer = window.setInterval(() => {
252
+ this._advanceItem();
253
+ }, this.autoPlayInterval);
254
+ }
255
+
256
+ _stopAutoPlay(): void {
257
+ if (this._autoPlayTimer !== undefined) {
258
+ window.clearInterval(this._autoPlayTimer);
259
+ this._autoPlayTimer = undefined;
260
+ }
261
+ }
262
+
263
+ _advanceItem(): void {
264
+ const count = this.items.length;
265
+ if (count === 0) {
266
+ return;
267
+ }
268
+
269
+ const next = (this._selectedIndex + 1) % count;
270
+ this._selectItem(next);
271
+ }
272
+
273
+ onPlayButtonClick(): void {
274
+ if (this._isPaused) {
275
+ this._startAutoPlay();
276
+ } else {
277
+ this._stopAutoPlay();
278
+ this._isPaused = true;
279
+ }
280
+ }
281
+
282
+ handleNavItemClick(e: MouseEvent) {
283
+ const btn = (e.target as HTMLElement).closest<HTMLElement>("[data-index]");
284
+ if (!btn) {
285
+ return;
286
+ }
287
+ const index = Number.parseInt(btn.dataset.index!);
288
+ this._selectItem(index);
289
+ }
290
+
291
+ private _selectItem(index: number) {
292
+ if (index === this._selectedIndex) {
293
+ return;
294
+ }
295
+
296
+ this._selectedIndex = index;
297
+ this.items.forEach((item, i) => { item.selected = i === index; });
298
+ const item = this.items[index];
299
+ this.fireDecoratorEvent("item-click", { item });
300
+ }
301
+
302
+ get playBtnIcon(): string {
303
+ return this._isPaused ? "play" : "pause";
304
+ }
305
+
306
+ get showFooterSlot(): boolean {
307
+ return this.footer?.length > 0;
308
+ }
309
+
310
+ get isStaticMedia(): boolean {
311
+ return this.mediaMode === UDExAccordionSpotlightMediaMode.Static;
312
+ }
313
+
314
+ get showMediaSlot(): boolean {
315
+ return this.isStaticMedia && this.media?.length > 0;
316
+ }
317
+ }
318
+
319
+ UDExAccordionSpotlight.define();
320
+
321
+ export default UDExAccordionSpotlight;
@@ -0,0 +1,117 @@
1
+ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
2
+ import type { DefaultSlot, Slot } from "@ui5/webcomponents-base/dist/UI5Element.js";
3
+ import slot from "@ui5/webcomponents-base/dist/decorators/slot-strict.js";
4
+ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
5
+ import property from "@ui5/webcomponents-base/dist/decorators/property.js";
6
+ import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js";
7
+
8
+ import AccordionSpotlightItemTemplate from "./AccordionSpotlightItemTemplate.js";
9
+
10
+ // Styles
11
+ import AccordionSpotlightItemCss from "./generated/themes/AccordionSpotlightItem.css.js";
12
+
13
+ /**
14
+ * @class
15
+ *
16
+ * <h3 class="comment-api-title">Overview</h3>
17
+ *
18
+ * A single item within the <code>udex-accordion-spotlight</code> component.
19
+ * Provides a heading button (<code>aria-expanded</code>) and an associated
20
+ * content region (<code>role="region"</code>).
21
+ *
22
+ * <h3>Usage</h3>
23
+ *
24
+ * For the <code>udex-accordion-spotlight-item</code>
25
+ * <h3>ES6 Module Import</h3>
26
+ *
27
+ * <code>import "@sapudex/web-components/dist/AccordionSpotlightItem.js";</code>
28
+ *
29
+ * @constructor
30
+ * @extends UI5Element
31
+ * @public
32
+ */
33
+ @customElement({
34
+ tag: "udex-accordion-spotlight-item",
35
+ renderer: jsxRenderer,
36
+ styles: AccordionSpotlightItemCss,
37
+ template: AccordionSpotlightItemTemplate,
38
+ })
39
+ class UDExAccordionSpotlightItem extends UI5Element {
40
+ /**
41
+ * The label text shown in the heading button.
42
+ *
43
+ * @default ""
44
+ * @public
45
+ */
46
+ @property()
47
+ heading: string = "";
48
+
49
+ /**
50
+ * Optional descriptive subtext visible when the item is expanded.
51
+ *
52
+ * @default ""
53
+ * @public
54
+ */
55
+ @property()
56
+ subheading: string = "";
57
+
58
+ /**
59
+ * Whether this item is currently expanded.
60
+ * Set on the element directly to control the initial selection.
61
+ *
62
+ * @default false
63
+ * @public
64
+ */
65
+ @property({ type: Boolean })
66
+ selected: boolean = false;
67
+
68
+ /**
69
+ * Whether the parent is in mobile layout mode (managed by the parent component).
70
+ *
71
+ * @default false
72
+ * @private
73
+ */
74
+ @property({ type: Boolean, noAttribute: true })
75
+ _isMobile: boolean = false;
76
+
77
+ /**
78
+ * Zero-based index within the parent (managed by the parent component).
79
+ *
80
+ * @private
81
+ */
82
+ @property({ type: Number, noAttribute: true })
83
+ _index: number = 0;
84
+
85
+ /**
86
+ * The slotted content for this item's panel.
87
+ *
88
+ * @public
89
+ */
90
+ @slot({ type: Node, "default": true })
91
+ content!: DefaultSlot<Node>;
92
+
93
+ /**
94
+ * Defines the link(s) to be displayed in the tab header (vertical orientation only).
95
+ * Use this slot to add one or more udex-link elements to the tab button.
96
+ *
97
+ * @slot link
98
+ * @public
99
+ */
100
+ @slot({ type: HTMLElement })
101
+ link!: Slot<HTMLElement>;
102
+
103
+ get hasLinkSlot(): boolean {
104
+ return this.link && this.link.length > 0;
105
+ }
106
+
107
+ get linkSlotHtml(): string {
108
+ if (!this.link || this.link.length === 0) {
109
+ return "";
110
+ }
111
+ return this.link.map(l => l.outerHTML).join("");
112
+ }
113
+ }
114
+
115
+ UDExAccordionSpotlightItem.define();
116
+
117
+ export default UDExAccordionSpotlightItem;
@@ -0,0 +1,7 @@
1
+ import type AccordionSpotlightItem from "./AccordionSpotlightItem.js";
2
+
3
+ export default function AccordionSpotlightItemTemplate(this: AccordionSpotlightItem) {
4
+ return (
5
+ <slot></slot>
6
+ );
7
+ }
@@ -0,0 +1,107 @@
1
+ import type AccordionSpotlight from "./AccordionSpotlight.js";
2
+ import UDExButton from "./Button.js";
3
+ import UDExButtonSize from "./types/ButtonSize.js";
4
+ import UDExButtonDesign from "./types/ButtonDesign.js";
5
+
6
+ export default function AccordionSpotlightTemplate(this: AccordionSpotlight) {
7
+ const rootClass = "udex-accordion-spotlight";
8
+
9
+ return (
10
+ <div class={`${rootClass}`}>
11
+ <div
12
+ class={`${rootClass}__nav`}>
13
+ {this.autoPlay && (
14
+ <UDExButton
15
+ class={`${rootClass}__play-button`}
16
+ design={UDExButtonDesign.Tertiary}
17
+ size={UDExButtonSize.Large}
18
+ icon={this.playBtnIcon}
19
+ onClick={this.onPlayButtonClick.bind(this)}
20
+ />
21
+ )}
22
+
23
+ <div class={`${rootClass}__nav-holder`}>
24
+ {this.items.map((item, index) => (
25
+ <>
26
+ <div class={`${rootClass}__nav-item`}>
27
+ <button
28
+ id={item._id}
29
+ class={`${rootClass}-item__button ${item.selected ? ` ${rootClass}-item__button--active` : ""}`}
30
+ type="button"
31
+ aria-expanded={item.selected}
32
+ aria-controls={`${item._id}-controls`}
33
+ data-index={String(index)}
34
+ onClick={this.handleNavItemClick.bind(this)}>
35
+ {item.heading}
36
+ </button>
37
+
38
+ {(!!item.subheading || item.hasLinkSlot) && (
39
+ <div
40
+ class={`${rootClass}-item__expand${item.selected ? ` ${rootClass}-item__expand--open` : ""}`}
41
+ aria-hidden={item.selected ? undefined : "true"}
42
+ inert={!item.selected}>
43
+ <div class={`${rootClass}-item__expand-inner`}>
44
+ {!!item.subheading && (
45
+ <span class={`${rootClass}-item__subheading`}>
46
+ {item.subheading}
47
+ </span>
48
+ )}
49
+ {item.hasLinkSlot &&
50
+ <div
51
+ class={`${rootClass}-item__links`}
52
+ dangerouslySetInnerHTML={{ __html: item.linkSlotHtml }}>
53
+ </div>
54
+ }
55
+ </div>
56
+ </div>
57
+ )}
58
+ </div>
59
+
60
+ {this._isMobile && !this.isStaticMedia && (
61
+ <div
62
+ id={`${item._id}-controls`}
63
+ class={`${rootClass}__panel${item.selected ? ` ${rootClass}__panel--open` : ""}`}
64
+ role="region"
65
+ aria-labelledby={item._id}
66
+ aria-hidden={item.selected ? undefined : "true"}
67
+ inert={!item.selected}>
68
+ <div class={`${rootClass}__panel-inner`}>
69
+ <slot name={item._individualSlot}></slot>
70
+ </div>
71
+ </div>
72
+ )}
73
+ </>
74
+ ))}
75
+ </div>
76
+ {this.showFooterSlot && (
77
+ <div class={`${rootClass}__footer`}><slot name="footer"></slot></div>
78
+ )}
79
+ </div>
80
+
81
+ {this.showMediaSlot && (
82
+ <div class={`${rootClass}__media`}>
83
+ <slot name="media"></slot>
84
+ </div>
85
+ )}
86
+
87
+ {!this._isMobile && !this.isStaticMedia && (
88
+ <div class={`${rootClass}__content`}>
89
+ {this.items.map(item => (
90
+ <div
91
+ key={item.__id}
92
+ id={`${item._id}-controls`}
93
+ class={`${rootClass}__panel${item.selected ? ` ${rootClass}__panel--open` : ""}`}
94
+ role="region"
95
+ aria-labelledby={item._id}
96
+ aria-hidden={item.selected ? undefined : "true"}
97
+ inert={!item.selected}>
98
+ <div class={`${rootClass}__panel-inner`}>
99
+ <slot name={item._individualSlot}></slot>
100
+ </div>
101
+ </div>
102
+ ))}
103
+ </div>
104
+ )}
105
+ </div>
106
+ );
107
+ }
@@ -1,7 +1,11 @@
1
1
  import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
2
+ import property from "@ui5/webcomponents-base/dist/decorators/property.js";
2
3
  import BusyIndicator from "@ui5/webcomponents/dist/BusyIndicator.js";
3
4
  import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js";
4
5
 
6
+ // Styles
7
+ import BusyIndicatorCss from "./generated/themes/BusyIndicator.css.js";
8
+
5
9
  /**
6
10
  * @class
7
11
  *
@@ -23,10 +27,21 @@ import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js";
23
27
  @customElement({
24
28
  tag: "udex-busy-indicator",
25
29
  renderer: jsxRenderer,
26
- styles: [BusyIndicator.styles],
30
+ styles: [BusyIndicator.styles, BusyIndicatorCss],
27
31
  })
28
32
 
29
- class UDExBusyIndicator extends BusyIndicator {}
33
+ class UDExBusyIndicator extends BusyIndicator {
34
+ /**
35
+ * Renders the busy indicator inside a surface container — a semi-transparent backdrop
36
+ * with a white rounded card holding the indicator dots. Use this when the indicator
37
+ * overlays content where the dots alone would not meet accessibility contrast requirements.
38
+ *
39
+ * @default false
40
+ * @public
41
+ */
42
+ @property({ type: Boolean })
43
+ surfaceContainer!: boolean;
44
+ }
30
45
 
31
46
  UDExBusyIndicator.define();
32
47