@sapudex/web-components 2.4.1 → 2.5.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 (247) hide show
  1. package/dist/MastheadCountrySelector.d.ts +3 -0
  2. package/dist/MastheadCountrySelector.js +8 -1
  3. package/dist/MastheadCountrySelector.js.map +1 -1
  4. package/dist/MastheadItem.d.ts +12 -1
  5. package/dist/MastheadItem.js +51 -7
  6. package/dist/MastheadItem.js.map +1 -1
  7. package/dist/MastheadMenu.d.ts +2 -1
  8. package/dist/MastheadMenu.js +16 -11
  9. package/dist/MastheadMenu.js.map +1 -1
  10. package/dist/MastheadMobileMenu.d.ts +4 -0
  11. package/dist/MastheadMobileMenu.js +44 -6
  12. package/dist/MastheadMobileMenu.js.map +1 -1
  13. package/dist/MastheadShell.d.ts +61 -16
  14. package/dist/MastheadShell.js +48 -68
  15. package/dist/MastheadShell.js.map +1 -1
  16. package/dist/MediaPlayer.d.ts +0 -1
  17. package/dist/MediaPlayer.js +0 -1
  18. package/dist/MediaPlayer.js.map +1 -1
  19. package/dist/SearchableListBase.js +4 -0
  20. package/dist/SearchableListBase.js.map +1 -1
  21. package/dist/SecondaryNavigation.d.ts +11 -0
  22. package/dist/SecondaryNavigation.js +11 -0
  23. package/dist/SecondaryNavigation.js.map +1 -1
  24. package/dist/TagGroup.js +3 -2
  25. package/dist/TagGroup.js.map +1 -1
  26. package/dist/assets/{InputSuggestions-B7dpC1q9.js → InputSuggestions-RQHqFxZ9.js} +1 -1
  27. package/dist/assets/{ListItemStandardExpandableTextTemplate-BF6mHEec.js → ListItemStandardExpandableTextTemplate-ClcY2jB2.js} +1 -1
  28. package/dist/assets/{bundle.esm-BFePNrxi.js → bundle.esm-DGH8Pvav.js} +179 -179
  29. package/dist/assets/messagebundle_ar-C39XMRa3.js +1 -0
  30. package/dist/assets/messagebundle_bg-CFuqxDUo.js +1 -0
  31. package/dist/assets/messagebundle_cs-HZFdxP5k.js +1 -0
  32. package/dist/assets/messagebundle_da-Cb19y_UU.js +1 -0
  33. package/dist/assets/messagebundle_de-BPtfcnG8.js +1 -0
  34. package/dist/assets/messagebundle_el-BfR2BVvB.js +1 -0
  35. package/dist/assets/messagebundle_es-DEz3xznF.js +1 -0
  36. package/dist/assets/messagebundle_et-BHSda64J.js +1 -0
  37. package/dist/assets/messagebundle_fi-DTkxmWJb.js +1 -0
  38. package/dist/assets/messagebundle_fr-BEq1Nxlj.js +1 -0
  39. package/dist/assets/messagebundle_hr-BzWPMYA7.js +1 -0
  40. package/dist/assets/messagebundle_hu-DQvndOA8.js +1 -0
  41. package/dist/assets/messagebundle_it-Bx7wA4HY.js +1 -0
  42. package/dist/assets/messagebundle_iw-L2hZONxh.js +1 -0
  43. package/dist/assets/messagebundle_ko-D4ckbm7i.js +1 -0
  44. package/dist/assets/messagebundle_lt-BriAnQM8.js +1 -0
  45. package/dist/assets/messagebundle_lv-Di1Ng3Tk.js +1 -0
  46. package/dist/assets/messagebundle_nl-Bhq20VT1.js +1 -0
  47. package/dist/assets/messagebundle_no-bTeyeWYl.js +1 -0
  48. package/dist/assets/messagebundle_pl-BnBUJpAL.js +1 -0
  49. package/dist/assets/messagebundle_pt-Cd_ey78V.js +1 -0
  50. package/dist/assets/messagebundle_ro-Cy-zHe5i.js +1 -0
  51. package/dist/assets/messagebundle_ru-CiDd56L1.js +1 -0
  52. package/dist/assets/messagebundle_sk-DJS6mahY.js +1 -0
  53. package/dist/assets/messagebundle_sl-BUi3OLzP.js +1 -0
  54. package/dist/assets/messagebundle_sr-BtodsTa0.js +1 -0
  55. package/dist/assets/messagebundle_sv-CVVuFZcm.js +1 -0
  56. package/dist/assets/messagebundle_tr-CqVlQ8yY.js +1 -0
  57. package/dist/assets/messagebundle_uk-aDyDoabO.js +1 -0
  58. package/dist/assets/messagebundle_zh_CN-CTb6-Dhs.js +1 -0
  59. package/dist/assets/messagebundle_zh_TW-DtT5REQh.js +1 -0
  60. package/dist/css/themes/MastheadItem.css +1 -1
  61. package/dist/css/themes/MastheadShell.css +1 -1
  62. package/dist/css/themes/Modal.css +1 -1
  63. package/dist/css/themes/RatingIndicator.css +1 -1
  64. package/dist/css/themes/Slider.css +1 -1
  65. package/dist/custom-elements-internal.json +157 -32
  66. package/dist/custom-elements.json +153 -32
  67. package/dist/generated/assets/i18n/messagebundle_ar.json +1 -1
  68. package/dist/generated/assets/i18n/messagebundle_bg.json +1 -1
  69. package/dist/generated/assets/i18n/messagebundle_cs.json +1 -1
  70. package/dist/generated/assets/i18n/messagebundle_da.json +1 -1
  71. package/dist/generated/assets/i18n/messagebundle_de.json +1 -1
  72. package/dist/generated/assets/i18n/messagebundle_el.json +1 -1
  73. package/dist/generated/assets/i18n/messagebundle_es.json +1 -1
  74. package/dist/generated/assets/i18n/messagebundle_et.json +1 -1
  75. package/dist/generated/assets/i18n/messagebundle_fi.json +1 -1
  76. package/dist/generated/assets/i18n/messagebundle_fr.json +1 -1
  77. package/dist/generated/assets/i18n/messagebundle_hr.json +1 -1
  78. package/dist/generated/assets/i18n/messagebundle_hu.json +1 -1
  79. package/dist/generated/assets/i18n/messagebundle_it.json +1 -1
  80. package/dist/generated/assets/i18n/messagebundle_iw.json +1 -1
  81. package/dist/generated/assets/i18n/messagebundle_ko.json +1 -1
  82. package/dist/generated/assets/i18n/messagebundle_lt.json +1 -1
  83. package/dist/generated/assets/i18n/messagebundle_lv.json +1 -1
  84. package/dist/generated/assets/i18n/messagebundle_nl.json +1 -1
  85. package/dist/generated/assets/i18n/messagebundle_no.json +1 -1
  86. package/dist/generated/assets/i18n/messagebundle_pl.json +1 -1
  87. package/dist/generated/assets/i18n/messagebundle_pt.json +1 -1
  88. package/dist/generated/assets/i18n/messagebundle_ro.json +1 -1
  89. package/dist/generated/assets/i18n/messagebundle_ru.json +1 -1
  90. package/dist/generated/assets/i18n/messagebundle_sk.json +1 -1
  91. package/dist/generated/assets/i18n/messagebundle_sl.json +1 -1
  92. package/dist/generated/assets/i18n/messagebundle_sr.json +1 -1
  93. package/dist/generated/assets/i18n/messagebundle_sv.json +1 -1
  94. package/dist/generated/assets/i18n/messagebundle_tr.json +1 -1
  95. package/dist/generated/assets/i18n/messagebundle_uk.json +1 -1
  96. package/dist/generated/assets/i18n/messagebundle_zh_CN.json +1 -1
  97. package/dist/generated/assets/i18n/messagebundle_zh_TW.json +1 -1
  98. package/dist/generated/templates/MastheadItemTemplate.lit.js +6 -6
  99. package/dist/generated/templates/MastheadItemTemplate.lit.js.map +1 -1
  100. package/dist/generated/templates/MastheadMobileMenuTemplate.lit.js +11 -11
  101. package/dist/generated/templates/MastheadMobileMenuTemplate.lit.js.map +1 -1
  102. package/dist/generated/templates/MastheadShellTemplate.lit.js +17 -14
  103. package/dist/generated/templates/MastheadShellTemplate.lit.js.map +1 -1
  104. package/dist/generated/templates/SecondaryNavigationTemplate.lit.js +1 -1
  105. package/dist/generated/templates/SecondaryNavigationTemplate.lit.js.map +1 -1
  106. package/dist/generated/themes/MastheadItem.css.d.ts +1 -1
  107. package/dist/generated/themes/MastheadItem.css.js +1 -1
  108. package/dist/generated/themes/MastheadItem.css.js.map +1 -1
  109. package/dist/generated/themes/MastheadShell.css.d.ts +1 -1
  110. package/dist/generated/themes/MastheadShell.css.js +1 -1
  111. package/dist/generated/themes/MastheadShell.css.js.map +1 -1
  112. package/dist/generated/themes/Modal.css.d.ts +1 -1
  113. package/dist/generated/themes/Modal.css.js +1 -1
  114. package/dist/generated/themes/Modal.css.js.map +1 -1
  115. package/dist/generated/themes/RatingIndicator.css.d.ts +1 -1
  116. package/dist/generated/themes/RatingIndicator.css.js +1 -1
  117. package/dist/generated/themes/RatingIndicator.css.js.map +1 -1
  118. package/dist/generated/themes/Slider.css.d.ts +1 -1
  119. package/dist/generated/themes/Slider.css.js +1 -1
  120. package/dist/generated/themes/Slider.css.js.map +1 -1
  121. package/dist/messagebundle_ar.properties +3 -0
  122. package/dist/messagebundle_bg.properties +3 -0
  123. package/dist/messagebundle_cs.properties +3 -0
  124. package/dist/messagebundle_da.properties +3 -0
  125. package/dist/messagebundle_de.properties +3 -0
  126. package/dist/messagebundle_el.properties +3 -0
  127. package/dist/messagebundle_es.properties +3 -0
  128. package/dist/messagebundle_et.properties +3 -0
  129. package/dist/messagebundle_fi.properties +3 -0
  130. package/dist/messagebundle_fr.properties +3 -0
  131. package/dist/messagebundle_hr.properties +3 -0
  132. package/dist/messagebundle_hu.properties +3 -0
  133. package/dist/messagebundle_it.properties +3 -0
  134. package/dist/messagebundle_iw.properties +3 -1
  135. package/dist/messagebundle_ko.properties +3 -0
  136. package/dist/messagebundle_lt.properties +3 -0
  137. package/dist/messagebundle_lv.properties +3 -0
  138. package/dist/messagebundle_nl.properties +3 -0
  139. package/dist/messagebundle_no.properties +3 -0
  140. package/dist/messagebundle_pl.properties +3 -0
  141. package/dist/messagebundle_pt.properties +3 -0
  142. package/dist/messagebundle_pt_BR.properties +3 -0
  143. package/dist/messagebundle_ro.properties +3 -0
  144. package/dist/messagebundle_ru.properties +3 -0
  145. package/dist/messagebundle_sk.properties +3 -0
  146. package/dist/messagebundle_sl.properties +3 -0
  147. package/dist/messagebundle_sr.properties +3 -1
  148. package/dist/messagebundle_sv.properties +3 -0
  149. package/dist/messagebundle_tr.properties +3 -0
  150. package/dist/messagebundle_uk.properties +3 -0
  151. package/dist/messagebundle_zh_CN.properties +3 -1
  152. package/dist/messagebundle_zh_TW.properties +3 -0
  153. package/dist/types/AnalyticsName.d.ts +2 -2
  154. package/dist/types/AnalyticsName.js +1 -1
  155. package/dist/types/AnalyticsName.js.map +1 -1
  156. package/dist/vscode.html-custom-data.json +31 -1
  157. package/dist/web-types.json +86 -18
  158. package/package.json +1 -1
  159. package/src/MastheadCountrySelector.ts +11 -1
  160. package/src/MastheadItem.hbs +22 -14
  161. package/src/MastheadItem.ts +64 -9
  162. package/src/MastheadMenu.ts +22 -12
  163. package/src/MastheadMobileMenu.hbs +12 -0
  164. package/src/MastheadMobileMenu.ts +50 -7
  165. package/src/MastheadShell.hbs +35 -1
  166. package/src/MastheadShell.ts +105 -29
  167. package/src/MediaPlayer.ts +0 -1
  168. package/src/SearchableListBase.ts +4 -0
  169. package/src/SecondaryNavigation.hbs +6 -1
  170. package/src/SecondaryNavigation.ts +22 -0
  171. package/src/TagGroup.ts +3 -2
  172. package/src/generated/templates/MastheadItemTemplate.lit.ts +6 -6
  173. package/src/generated/templates/MastheadMobileMenuTemplate.lit.ts +11 -11
  174. package/src/generated/templates/MastheadShellTemplate.lit.ts +17 -14
  175. package/src/generated/templates/SecondaryNavigationTemplate.lit.ts +1 -1
  176. package/src/generated/themes/MastheadItem.css.ts +1 -1
  177. package/src/generated/themes/MastheadShell.css.ts +1 -1
  178. package/src/generated/themes/Modal.css.ts +1 -1
  179. package/src/generated/themes/RatingIndicator.css.ts +1 -1
  180. package/src/generated/themes/Slider.css.ts +1 -1
  181. package/src/i18n/messagebundle_ar.properties +3 -0
  182. package/src/i18n/messagebundle_bg.properties +3 -0
  183. package/src/i18n/messagebundle_cs.properties +3 -0
  184. package/src/i18n/messagebundle_da.properties +3 -0
  185. package/src/i18n/messagebundle_de.properties +3 -0
  186. package/src/i18n/messagebundle_el.properties +3 -0
  187. package/src/i18n/messagebundle_es.properties +3 -0
  188. package/src/i18n/messagebundle_et.properties +3 -0
  189. package/src/i18n/messagebundle_fi.properties +3 -0
  190. package/src/i18n/messagebundle_fr.properties +3 -0
  191. package/src/i18n/messagebundle_hr.properties +3 -0
  192. package/src/i18n/messagebundle_hu.properties +3 -0
  193. package/src/i18n/messagebundle_it.properties +3 -0
  194. package/src/i18n/messagebundle_iw.properties +3 -1
  195. package/src/i18n/messagebundle_ko.properties +3 -0
  196. package/src/i18n/messagebundle_lt.properties +3 -0
  197. package/src/i18n/messagebundle_lv.properties +3 -0
  198. package/src/i18n/messagebundle_nl.properties +3 -0
  199. package/src/i18n/messagebundle_no.properties +3 -0
  200. package/src/i18n/messagebundle_pl.properties +3 -0
  201. package/src/i18n/messagebundle_pt.properties +3 -0
  202. package/src/i18n/messagebundle_pt_BR.properties +3 -0
  203. package/src/i18n/messagebundle_ro.properties +3 -0
  204. package/src/i18n/messagebundle_ru.properties +3 -0
  205. package/src/i18n/messagebundle_sk.properties +3 -0
  206. package/src/i18n/messagebundle_sl.properties +3 -0
  207. package/src/i18n/messagebundle_sr.properties +3 -1
  208. package/src/i18n/messagebundle_sv.properties +3 -0
  209. package/src/i18n/messagebundle_tr.properties +3 -0
  210. package/src/i18n/messagebundle_uk.properties +3 -0
  211. package/src/i18n/messagebundle_zh_CN.properties +3 -1
  212. package/src/i18n/messagebundle_zh_TW.properties +3 -0
  213. package/src/themes/MastheadItem.css +16 -0
  214. package/src/themes/MastheadShell.css +38 -4
  215. package/src/themes/Modal.css +2 -2
  216. package/src/types/AnalyticsName.ts +2 -2
  217. package/dist/assets/messagebundle_ar-9zPDAqTU.js +0 -1
  218. package/dist/assets/messagebundle_bg-DWxB0fCn.js +0 -1
  219. package/dist/assets/messagebundle_cs-C_ZNAcZs.js +0 -1
  220. package/dist/assets/messagebundle_da-CRRThnbQ.js +0 -1
  221. package/dist/assets/messagebundle_de-CEztl_Bk.js +0 -1
  222. package/dist/assets/messagebundle_el-dli9W3Ld.js +0 -1
  223. package/dist/assets/messagebundle_es-BKJxfGUS.js +0 -1
  224. package/dist/assets/messagebundle_et-CEgPnb-F.js +0 -1
  225. package/dist/assets/messagebundle_fi-CB9L6Ted.js +0 -1
  226. package/dist/assets/messagebundle_fr-DV0xFXy7.js +0 -1
  227. package/dist/assets/messagebundle_hr-CxG6YfU9.js +0 -1
  228. package/dist/assets/messagebundle_hu-BD5GvMh2.js +0 -1
  229. package/dist/assets/messagebundle_it-CcnIcv1Q.js +0 -1
  230. package/dist/assets/messagebundle_iw-njoSdOP-.js +0 -1
  231. package/dist/assets/messagebundle_ko-BsIdyV2m.js +0 -1
  232. package/dist/assets/messagebundle_lt-Cx5dKaVi.js +0 -1
  233. package/dist/assets/messagebundle_lv-CjYkt6X6.js +0 -1
  234. package/dist/assets/messagebundle_nl-BxcksDMG.js +0 -1
  235. package/dist/assets/messagebundle_no-6rWbHkD4.js +0 -1
  236. package/dist/assets/messagebundle_pl-CdoiDA_-.js +0 -1
  237. package/dist/assets/messagebundle_pt-DtbX15Ym.js +0 -1
  238. package/dist/assets/messagebundle_ro-C5ojQbzO.js +0 -1
  239. package/dist/assets/messagebundle_ru-BcLhFIo9.js +0 -1
  240. package/dist/assets/messagebundle_sk-B4D9Y2b-.js +0 -1
  241. package/dist/assets/messagebundle_sl-D43o0FSO.js +0 -1
  242. package/dist/assets/messagebundle_sr-Co2xNpod.js +0 -1
  243. package/dist/assets/messagebundle_sv-4hT4lgLu.js +0 -1
  244. package/dist/assets/messagebundle_tr-DxFj6Icf.js +0 -1
  245. package/dist/assets/messagebundle_uk-Sdu5cmOP.js +0 -1
  246. package/dist/assets/messagebundle_zh_CN-CuN02AOJ.js +0 -1
  247. package/dist/assets/messagebundle_zh_TW-CRXaxYip.js +0 -1
@@ -10,6 +10,7 @@ import "@ui5/webcomponents-icons/dist/search.js";
10
10
  import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
11
11
  import { isEscape } from "@ui5/webcomponents-base/dist/Keys.js";
12
12
  import { isDesktop } from "@ui5/webcomponents-base/dist/Device.js";
13
+ import { getFirstFocusableElement } from "@ui5/webcomponents-base/dist/util/FocusableElements.js";
13
14
  import {
14
15
  OPENS_IN_A_NEW_WINDOW, PROFILE, CART, COUNTRY_SELECTOR, SUPPORT, SEARCH,
15
16
  } from "./generated/i18n/i18n-defaults.js";
@@ -22,7 +23,6 @@ import { UDExTarget } from "./types/common.js";
22
23
  import { BreakpointUtils } from "./utils/Breakpoints.js";
23
24
  import parseArrayFromString from "./utils/parseArrayFromString.js";
24
25
  import AnalyticsName from "./types/AnalyticsName.js";
25
-
26
26
  // Styles
27
27
  import MastheadItemCss from "./generated/themes/MastheadItem.css.js";
28
28
 
@@ -285,12 +285,14 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
285
285
  @slot({ type: HTMLElement, "default": true })
286
286
  content?: Array<HTMLElement>;
287
287
 
288
+ @property({ type: Boolean })
289
+ _preventFocusOut!: boolean;
290
+
288
291
  @i18n("@sapudex/web-components")
289
292
  static i18nBundle: I18nBundle;
290
293
 
291
294
  _profileAvatar!: UDExAvatar;
292
295
  _mastheadShell!: UDExMastheadShell;
293
- _isEscPress!: boolean;
294
296
 
295
297
  onEnterDOM(): void {
296
298
  if (isDesktop()) {
@@ -310,15 +312,18 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
310
312
  this.setDropdownInsetStart();
311
313
  }
312
314
 
315
+ if (this.shouldFocusFirstElement) {
316
+ this.applyFocusToFirstElement();
317
+ }
318
+
313
319
  this.handleOutsideClick();
314
- this._isEscPress = false;
315
320
  }
316
321
 
317
322
  handleOutsideClick(): void {
318
323
  document.addEventListener("click", (e: Event) => {
319
324
  const target = e.target as HTMLElement;
320
325
  const item = target.closest("[udex-masthead-item]");
321
- if (item !== this && !this.isMobile) {
326
+ if (item !== this && !this.isMobile && this.selected) {
322
327
  if (this.isDropdownOpened) {
323
328
  this.fireDropdownCloseEvent(this.eventItemTitle, UDExMastheadDropdownItemAction.ClickOutside);
324
329
  }
@@ -328,13 +333,27 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
328
333
  });
329
334
  }
330
335
 
336
+ handleMouseDown(): void {
337
+ this._preventFocusOut = true;
338
+ }
339
+
340
+ handleMouseUp(): void {
341
+ this._preventFocusOut = false;
342
+ }
343
+
331
344
  handleFocusout(e: FocusEvent): void {
332
- if (e.relatedTarget === null || this._isEscPress) {
345
+ if (this.isFocusOutPrevented(e)) {
333
346
  return;
334
347
  }
335
348
 
336
- const eTarget = e.target as HTMLElement;
337
- if (!this.isMobile && eTarget.getAttribute("slot") === "dropdown") {
349
+ this.handleFocusOutForDropdowns(e);
350
+ }
351
+
352
+ handleFocusOutForDropdowns(e: FocusEvent): void {
353
+ const relatedTarget = e.relatedTarget as HTMLElement;
354
+ const target = e.target as HTMLElement;
355
+
356
+ if (this.shouldCloseDropdown(relatedTarget, target)) {
338
357
  this.closeDropdown();
339
358
  }
340
359
  }
@@ -350,7 +369,6 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
350
369
  }
351
370
 
352
371
  handleKeyEscape(): void {
353
- this._isEscPress = true;
354
372
  this.closeDropdown();
355
373
  if (this.isProfileBtn) {
356
374
  this._profileAvatar.focus();
@@ -405,7 +423,7 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
405
423
  }
406
424
 
407
425
  setDropdownInsetStart(): void {
408
- const dropdown = this.getDomElement(".udex-masthead-item__dropdown");
426
+ const dropdown = this.dropdownHolder;
409
427
  if (dropdown) {
410
428
  const rect = dropdown.getBoundingClientRect();
411
429
  const marginInlineStart = this.calculateMarginInlineStart(rect);
@@ -454,6 +472,13 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
454
472
  this.fireDropdownCloseEvent(this.accessibleName || this.eventItemTitle, UDExMastheadDropdownItemAction.Close);
455
473
  }
456
474
 
475
+ async applyFocusToFirstElement(): Promise<void> {
476
+ const focusedElement = await getFirstFocusableElement(this.dropdownHolder);
477
+ if (focusedElement) {
478
+ focusedElement.focus();
479
+ }
480
+ }
481
+
457
482
  getDomElement(selector: string): HTMLElement | undefined | null {
458
483
  return this.shadowRoot?.querySelector(`${selector}`);
459
484
  }
@@ -462,6 +487,32 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
462
487
  return parseArrayFromString(this.subItems);
463
488
  }
464
489
 
490
+ private isFocusOutPrevented(e: FocusEvent): boolean {
491
+ return this.isMobile || e.relatedTarget === null || this._preventFocusOut;
492
+ }
493
+
494
+ private isProfileButtonTarget(relatedTarget: HTMLElement | null): boolean {
495
+ return (relatedTarget?.tagName === "UDEX-AVATAR" || relatedTarget?.tagName === "UDEX-MASTHEAD-ITEM") && this.isProfileBtn;
496
+ }
497
+
498
+ private isNavItemTarget(target: HTMLElement): boolean {
499
+ return target.getAttribute("slot") === "dropdown" && !this.isProfileBtn;
500
+ }
501
+
502
+ private isRelatedTargetOutside(relatedTarget: HTMLElement | null): boolean {
503
+ return relatedTarget?.closest("[udex-masthead-item]") === null;
504
+ }
505
+
506
+ private shouldCloseDropdown(relatedTarget: HTMLElement, target:HTMLElement): boolean {
507
+ return this.isRelatedTargetOutside(relatedTarget)
508
+ || this.isProfileButtonTarget(relatedTarget)
509
+ || this.isNavItemTarget(target);
510
+ }
511
+
512
+ get dropdownHolder(): HTMLElement {
513
+ return this.getDomElement(".udex-masthead-item__dropdown")!;
514
+ }
515
+
465
516
  get mastheadShell(): UDExMastheadShell {
466
517
  return document.querySelector<UDExMastheadShell>("[udex-masthead-shell]")!;
467
518
  }
@@ -513,6 +564,10 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
513
564
  return labels.length ? labels.join(" ").trim() : undefined;
514
565
  }
515
566
 
567
+ get shouldFocusFirstElement(): boolean {
568
+ return this.isDropdownOpened && !this._preventFocusOut;
569
+ }
570
+
516
571
  get isDropdownOpened(): boolean {
517
572
  return this.hasDropdownSlot && this.selected;
518
573
  }
@@ -9,6 +9,7 @@ import "@ui5/webcomponents-icons/dist/action.js";
9
9
  import { isUp, isDown } from "@ui5/webcomponents-base/dist/Keys.js";
10
10
  import UDExBadge from "./Badge.js";
11
11
  import UDExMastheadMenuItem, { UDExItemType } from "./MastheadMenuItem.js";
12
+ import type UDExMastheadItem from "./MastheadItem.js";
12
13
  import UDExDivider from "./Divider.js";
13
14
  import MastheadMenuTemplate from "./generated/templates/MastheadMenuTemplate.lit.js";
14
15
  import parseArrayFromString from "./utils/parseArrayFromString.js";
@@ -38,9 +39,10 @@ export type MenuItem = {
38
39
 
39
40
  type UDExMastheadMenuMenuItemClickEventDetail = {
40
41
  category?: string,
42
+ analyticsPath: Array<string>,
43
+ analyticsName: AnalyticsName,
41
44
  originalEvent: PointerEvent,
42
45
  item: UDExMastheadMenuItem,
43
- analyticsName: AnalyticsName,
44
46
  sourceNode: HTMLElement,
45
47
  }
46
48
 
@@ -129,18 +131,26 @@ class UDExMastheadMenu extends UI5Element {
129
131
  }
130
132
 
131
133
  handleMenuItemClick(e: PointerEvent): void {
132
- const item = e.target as UDExMastheadMenuItem;
133
- const { url, type } = item;
134
- if (url?.length) {
135
- const list = item.closest(".udex-masthead-menu__list") as HTMLElement;
136
- this.fireDecoratorEvent("menu-item-click", {
137
- sourceNode: item.shadowRoot?.querySelector(".udex-masthead-menu-item") as HTMLElement,
138
- analyticsName: AnalyticsName.Header,
139
- item,
140
- originalEvent: e,
141
- ...(type !== UDExItemType.Heading && { category: list?.getAttribute("category") || "" }),
142
- });
134
+ const menuItem = e.target as UDExMastheadMenuItem;
135
+ if (!menuItem.url?.length) {
136
+ return;
143
137
  }
138
+
139
+ const mainItem = this.closest("[udex-masthead-item]") as UDExMastheadItem;
140
+ const menuList = menuItem.closest(".udex-masthead-menu__list") as HTMLElement;
141
+ const sourceNode = menuItem.shadowRoot?.querySelector(".udex-masthead-menu-item") as HTMLElement;
142
+ const category = menuList?.getAttribute("category") || "";
143
+
144
+ const eventDetail: UDExMastheadMenuMenuItemClickEventDetail = {
145
+ analyticsPath: [mainItem?.label, category, menuItem.label].filter(Boolean),
146
+ analyticsName: AnalyticsName.Header,
147
+ originalEvent: e,
148
+ item: menuItem,
149
+ sourceNode,
150
+ ...(menuItem.type !== UDExItemType.Heading && { category }),
151
+ };
152
+
153
+ this.fireDecoratorEvent("menu-item-click", eventDetail);
144
154
  }
145
155
 
146
156
  focusPreviousItem(item: UDExMastheadMenuItem): void {
@@ -18,6 +18,7 @@
18
18
  @click="{{handleExploreBackToMenuItems}}"
19
19
  label="{{_clickedItem.innerText}}"
20
20
  type="Button"
21
+ is-back
21
22
  has-border
22
23
  icon-start
23
24
  is-explore-back>
@@ -39,6 +40,7 @@
39
40
  label="{{_clickedItem.innerText}}"
40
41
  aria-has-popup="true"
41
42
  type="Button"
43
+ is-back
42
44
  has-border
43
45
  icon-start
44
46
  is-back-to-nav>
@@ -59,6 +61,7 @@
59
61
  aria-has-popup="true"
60
62
  has-border
61
63
  icon-start
64
+ is-back
62
65
  is-back-to-categories>
63
66
  </udex-masthead-menu-item>
64
67
  </li>
@@ -76,6 +79,7 @@
76
79
  accessible-role-text="button"
77
80
  aria-has-popup="true"
78
81
  type="Button"
82
+ first-level-btn
79
83
  first-level
80
84
  icon-end
81
85
  is-explore
@@ -95,6 +99,8 @@
95
99
  aria-has-popup="true"
96
100
  id="{{this._id}}"
97
101
  type="Button"
102
+ first-level-btn
103
+ first-level
98
104
  has-border
99
105
  icon-end
100
106
  first-level>
@@ -106,6 +112,7 @@
106
112
  url="{{this.href}}"
107
113
  label="{{this.innerText}}"
108
114
  target="{{this.target}}"
115
+ first-level
109
116
  has-border>
110
117
  </udex-masthead-menu-item>
111
118
  {{/if}}
@@ -121,6 +128,7 @@
121
128
  url="{{_clickedItem.href}}"
122
129
  label="{{overviewLinkText}}"
123
130
  @click="{{handleMobileItemEvent}}"
131
+ second-level
124
132
  has-border>
125
133
  </udex-masthead-menu-item>
126
134
  </li>
@@ -136,6 +144,7 @@
136
144
  label="{{this.category}}"
137
145
  aria-has-popup="true"
138
146
  type="Button"
147
+ second-level-btn
139
148
  second-level
140
149
  has-border
141
150
  icon-end>
@@ -149,6 +158,7 @@
149
158
  @click="{{../handleMobileItemEvent}}"
150
159
  url="{{this.url}}"
151
160
  label="{{this.title}}"
161
+ second-level
152
162
  has-border>
153
163
  </udex-masthead-menu-item>
154
164
  </li>
@@ -165,6 +175,7 @@
165
175
  @click="{{../handleMobileCategoryItemEvent}}"
166
176
  url="{{this._category.url}}"
167
177
  label="{{overviewLinkText}}"
178
+ third-level
168
179
  has-border>
169
180
  </udex-masthead-menu-item>
170
181
  </li>
@@ -177,6 +188,7 @@
177
188
  @click="{{../handleMobileCategoryItemEvent}}"
178
189
  label="{{this.title}}"
179
190
  url="{{this.url}}"
191
+ third-level
180
192
  has-border>
181
193
  </udex-masthead-menu-item>
182
194
  </li>
@@ -24,7 +24,9 @@ type UDExMastheadMobileMenuItemClickEventDetail = {
24
24
  item: UDExMastheadMenuItem,
25
25
  category?: string,
26
26
  isMobile: boolean,
27
+ isBack: boolean,
27
28
  analyticsName: AnalyticsName,
29
+ analyticsPath: Array<string>,
28
30
  sourceNode: HTMLElement,
29
31
  }
30
32
 
@@ -127,6 +129,7 @@ class UDExMastheadMobileMenu extends UI5Element {
127
129
  _shouldFocusItemByIndex!: boolean;
128
130
  _shouldFocusExploreBtn!: boolean;
129
131
  _focusedItemIndex!: number;
132
+ _navItem?: UDExMastheadMenuItem;
130
133
 
131
134
  onAfterRendering() {
132
135
  this.handleMenuMode();
@@ -299,12 +302,12 @@ class UDExMastheadMobileMenu extends UI5Element {
299
302
  this.fireMobileItemEvent(e);
300
303
  }
301
304
 
302
- if (target.hasAttribute("first-level")) {
305
+ if (target.hasAttribute("first-level-btn")) {
303
306
  this.openCategories(item);
304
307
  this.fireMobileItemEvent(e);
305
308
  }
306
309
 
307
- if (target.hasAttribute("second-level")) {
310
+ if (target.hasAttribute("second-level-btn")) {
308
311
  this.openCategoryItems(e);
309
312
  this.fireMobileItemEvent(e);
310
313
  }
@@ -416,15 +419,19 @@ class UDExMastheadMobileMenu extends UI5Element {
416
419
 
417
420
  fireMobileItemEvent(e: PointerEvent | KeyboardEvent, category?: string) {
418
421
  const item = e.target as UDExMastheadMenuItem;
419
-
420
- this.fireDecoratorEvent("item-click", {
421
- isMobile: true,
422
+ const isBack = item.hasAttribute("is-back");
423
+ const eventDetail: UDExMastheadMobileMenuItemClickEventDetail = {
424
+ ...(category && { category }),
422
425
  item,
426
+ isMobile: true,
427
+ isBack,
428
+ analyticsPath: this.buildAnalyticsPath(item),
423
429
  originalEvent: e,
424
430
  analyticsName: AnalyticsName.Header,
425
431
  sourceNode: item.shadowRoot?.querySelector(".udex-masthead-menu-item") as HTMLElement,
426
- ...(category && { category }),
427
- });
432
+ };
433
+
434
+ this.fireDecoratorEvent("item-click", eventDetail);
428
435
  }
429
436
 
430
437
  fireExploreSapMobileButton(e: PointerEvent | KeyboardEvent) {
@@ -483,6 +490,42 @@ class UDExMastheadMobileMenu extends UI5Element {
483
490
  });
484
491
  }
485
492
 
493
+ buildAnalyticsPath(item: UDExMastheadMenuItem): Array<string> {
494
+ const category = this.getListItemByIndex(0).label.trim();
495
+ const isFirstLevel = item.hasAttribute("first-level");
496
+ const isSecondLevel = item.hasAttribute("second-level");
497
+ const isThirdLevel = item.hasAttribute("third-level");
498
+ const isBackToCategories = item.hasAttribute("is-back-to-categories");
499
+ const shouldResetPath = item.hasAttribute("is-back-to-nav") || this._hideExploreSapBtn;
500
+ const isExploreMode = !this.showExploreBtn && !!this.items.length;
501
+ const clickedLabel = item.label.trim();
502
+ const analyticsPath: Array<string> = [];
503
+
504
+ if (shouldResetPath) {
505
+ this._navItem = undefined;
506
+ analyticsPath.length = 0;
507
+ }
508
+
509
+ if (isFirstLevel) {
510
+ this._navItem = item;
511
+ analyticsPath.push(clickedLabel);
512
+ } else if (isSecondLevel) {
513
+ analyticsPath.push(...(this._navItem ? [category, clickedLabel] : [clickedLabel]));
514
+ } else if (isThirdLevel) {
515
+ analyticsPath.push(...(this._navItem ? [this._navItem.label.trim(), category, clickedLabel] : [category, clickedLabel]));
516
+ } else if (isBackToCategories) {
517
+ if (this._navItem) {
518
+ analyticsPath.push(this._navItem.label.trim());
519
+ }
520
+ }
521
+
522
+ if (isExploreMode) {
523
+ analyticsPath.unshift(this.exploreItem.label);
524
+ }
525
+
526
+ return analyticsPath;
527
+ }
528
+
486
529
  get exploreBtnMenu(): UDExMastheadMenuItem {
487
530
  return this.shadowRoot!.querySelector<UDExMastheadMenuItem>(".udex-masthead-mobile-menu__explore-btn")!;
488
531
  }
@@ -1,5 +1,5 @@
1
1
  <header
2
- class="udex-masthead-shell"
2
+ class="{{mainClass}}"
3
3
  @keydown="{{handleKeyDown}}">
4
4
  <div class="udex-masthead-shell__main-content">
5
5
  <div class="udex-masthead-shell__landing-wrap">
@@ -10,6 +10,10 @@
10
10
  {{#if siteLabel}}
11
11
  {{>siteLabel}}
12
12
  {{/if}}
13
+
14
+ {{#if coBrandImage}}
15
+ {{>coBrand}}
16
+ {{/if}}
13
17
  </div>
14
18
 
15
19
  {{#if isMainMenuVisible}}
@@ -166,6 +170,7 @@
166
170
  @click="{{handleSiteLabelClick}}"
167
171
  role="link"
168
172
  href="{{siteLabelUrl}}"
173
+ title="{{siteLabelTitle}}"
169
174
  target="_self"
170
175
  aria-label="{{siteLabelAriaLabel}}"
171
176
  class="udex-masthead-shell__site-label udex-masthead-shell__site-label--link">
@@ -175,3 +180,32 @@
175
180
  <div class="udex-masthead-shell__site-label">{{siteLabel}}</div>
176
181
  {{/if}}
177
182
  {{/inline}}
183
+
184
+ {{#*inline "coBrand"}}
185
+ {{#if coBrandUrl}}
186
+ <div class="udex-masthead-shell__co-brand">
187
+ <a
188
+ class="udex-masthead-shell__co-brand-link"
189
+ @click="{{handleCoBrandClick}}"
190
+ href="{{coBrandUrl}}"
191
+ title="{{coBrandTitle}}"
192
+ aria-label="{{coBrandAriaLabel}}"
193
+ target="_self"
194
+ role="link">
195
+ <img
196
+ class="udex-masthead-shell__co-brand-image"
197
+ src="{{coBrandImage}}"
198
+ alt="{{coBrandAlt}}"
199
+ />
200
+ </a>
201
+ </div>
202
+ {{else}}
203
+ <div class="udex-masthead-shell__co-brand">
204
+ <img
205
+ class="udex-masthead-shell__co-brand-image"
206
+ src="{{coBrandImage}}"
207
+ alt="{{coBrandAlt}}"
208
+ />
209
+ </div>
210
+ {{/if}}
211
+ {{/inline}}