@sapudex/web-components 2.30.0 → 2.31.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 (175) hide show
  1. package/cypress/specs/ListItem.cy.tsx +22 -26
  2. package/cypress/specs/PromoTile.cy.tsx +10 -0
  3. package/cypress/specs/SecondaryNavigationDesktop.cy.tsx +12 -12
  4. package/cypress/specs/SelectBox.cy.tsx +76 -0
  5. package/dist/Breadcrumbs.d.ts +0 -4
  6. package/dist/Breadcrumbs.js +7 -16
  7. package/dist/Breadcrumbs.js.map +1 -1
  8. package/dist/BreadcrumbsTemplate.js +1 -1
  9. package/dist/BreadcrumbsTemplate.js.map +1 -1
  10. package/dist/List.js +3 -3
  11. package/dist/List.js.map +1 -1
  12. package/dist/ListItemBase.d.ts +0 -2
  13. package/dist/ListItemBase.js +0 -6
  14. package/dist/ListItemBase.js.map +1 -1
  15. package/dist/MastheadCountrySelector.d.ts +3 -15
  16. package/dist/MastheadCountrySelector.js +28 -72
  17. package/dist/MastheadCountrySelector.js.map +1 -1
  18. package/dist/MastheadItem.d.ts +1 -0
  19. package/dist/MastheadItem.js +7 -0
  20. package/dist/MastheadItem.js.map +1 -1
  21. package/dist/MastheadMenuItem.d.ts +7 -0
  22. package/dist/MastheadMenuItem.js +3 -0
  23. package/dist/MastheadMenuItem.js.map +1 -1
  24. package/dist/MastheadMobileMenu.d.ts +2 -12
  25. package/dist/MastheadMobileMenu.js +31 -116
  26. package/dist/MastheadMobileMenu.js.map +1 -1
  27. package/dist/MastheadProfileMenu.js +1 -1
  28. package/dist/MastheadProfileMenu.js.map +1 -1
  29. package/dist/MastheadShell.d.ts +1 -6
  30. package/dist/MastheadShell.js +7 -44
  31. package/dist/MastheadShell.js.map +1 -1
  32. package/dist/Pagination.d.ts +14 -1
  33. package/dist/Pagination.js +39 -6
  34. package/dist/Pagination.js.map +1 -1
  35. package/dist/PromoTile.d.ts +8 -0
  36. package/dist/PromoTile.js +4 -0
  37. package/dist/PromoTile.js.map +1 -1
  38. package/dist/PromoTileTemplate.js +3 -1
  39. package/dist/PromoTileTemplate.js.map +1 -1
  40. package/dist/SecondaryNavigationItem.js +7 -1
  41. package/dist/SecondaryNavigationItem.js.map +1 -1
  42. package/dist/SelectBase.js +28 -7
  43. package/dist/SelectBase.js.map +1 -1
  44. package/dist/assets/{InputSuggestions-CaAXs3ok.js → InputSuggestions-i2kFpCfC.js} +1 -1
  45. package/dist/assets/{ListItemStandardExpandableTextTemplate-CPqUBd--.js → ListItemStandardExpandableTextTemplate-C1ceDaxu.js} +1 -1
  46. package/dist/assets/{bundle.esm-L-7H6J4f.js → bundle.esm-DQ3cxywT.js} +209 -209
  47. package/dist/assets/messagebundle_en-DWAgV5VH.js +1 -0
  48. package/dist/css/themes/BreadcrumbsPopover.css +1 -1
  49. package/dist/css/themes/Dropdown.css +1 -1
  50. package/dist/css/themes/Link.css +1 -1
  51. package/dist/css/themes/ListGroupHeader.css +1 -1
  52. package/dist/css/themes/MastheadCountrySelector.css +1 -1
  53. package/dist/css/themes/MastheadItem.css +1 -1
  54. package/dist/css/themes/MastheadShell.css +1 -1
  55. package/dist/css/themes/RatingIndicator.css +1 -1
  56. package/dist/css/themes/SecondaryNavigation.css +1 -1
  57. package/dist/css/themes/SecondaryNavigationItem.css +1 -1
  58. package/dist/css/themes/SecondaryNavigationSubItem.css +1 -1
  59. package/dist/css/themes/Slider.css +1 -1
  60. package/dist/custom-elements-internal.json +32 -13
  61. package/dist/custom-elements.json +32 -13
  62. package/dist/generated/assets/i18n/messagebundle_en.json +1 -1
  63. package/dist/generated/i18n/i18n-defaults.d.ts +2 -1
  64. package/dist/generated/i18n/i18n-defaults.js +2 -1
  65. package/dist/generated/i18n/i18n-defaults.js.map +1 -1
  66. package/dist/generated/templates/ListGroupHeaderTemplate.lit.js +12 -16
  67. package/dist/generated/templates/ListGroupHeaderTemplate.lit.js.map +1 -1
  68. package/dist/generated/templates/ListItemTemplate.lit.js +32 -36
  69. package/dist/generated/templates/ListItemTemplate.lit.js.map +1 -1
  70. package/dist/generated/templates/MastheadCountrySelectorTemplate.lit.js +3 -3
  71. package/dist/generated/templates/MastheadCountrySelectorTemplate.lit.js.map +1 -1
  72. package/dist/generated/templates/MastheadMenuItemTemplate.lit.js +1 -1
  73. package/dist/generated/templates/MastheadMenuItemTemplate.lit.js.map +1 -1
  74. package/dist/generated/templates/MastheadMobileMenuTemplate.lit.js +1 -1
  75. package/dist/generated/templates/MastheadMobileMenuTemplate.lit.js.map +1 -1
  76. package/dist/generated/templates/MastheadShellTemplate.lit.js +9 -10
  77. package/dist/generated/templates/MastheadShellTemplate.lit.js.map +1 -1
  78. package/dist/generated/themes/BreadcrumbsPopover.css.d.ts +1 -1
  79. package/dist/generated/themes/BreadcrumbsPopover.css.js +1 -1
  80. package/dist/generated/themes/BreadcrumbsPopover.css.js.map +1 -1
  81. package/dist/generated/themes/Dropdown.css.d.ts +1 -1
  82. package/dist/generated/themes/Dropdown.css.js +1 -1
  83. package/dist/generated/themes/Dropdown.css.js.map +1 -1
  84. package/dist/generated/themes/Link.css.d.ts +1 -1
  85. package/dist/generated/themes/Link.css.js +1 -1
  86. package/dist/generated/themes/Link.css.js.map +1 -1
  87. package/dist/generated/themes/ListGroupHeader.css.d.ts +1 -1
  88. package/dist/generated/themes/ListGroupHeader.css.js +1 -1
  89. package/dist/generated/themes/ListGroupHeader.css.js.map +1 -1
  90. package/dist/generated/themes/MastheadCountrySelector.css.d.ts +1 -1
  91. package/dist/generated/themes/MastheadCountrySelector.css.js +1 -1
  92. package/dist/generated/themes/MastheadCountrySelector.css.js.map +1 -1
  93. package/dist/generated/themes/MastheadItem.css.d.ts +1 -1
  94. package/dist/generated/themes/MastheadItem.css.js +1 -1
  95. package/dist/generated/themes/MastheadItem.css.js.map +1 -1
  96. package/dist/generated/themes/MastheadShell.css.d.ts +1 -1
  97. package/dist/generated/themes/MastheadShell.css.js +1 -1
  98. package/dist/generated/themes/MastheadShell.css.js.map +1 -1
  99. package/dist/generated/themes/RatingIndicator.css.d.ts +1 -1
  100. package/dist/generated/themes/RatingIndicator.css.js +1 -1
  101. package/dist/generated/themes/RatingIndicator.css.js.map +1 -1
  102. package/dist/generated/themes/SecondaryNavigation.css.d.ts +1 -1
  103. package/dist/generated/themes/SecondaryNavigation.css.js +1 -1
  104. package/dist/generated/themes/SecondaryNavigation.css.js.map +1 -1
  105. package/dist/generated/themes/SecondaryNavigationItem.css.d.ts +1 -1
  106. package/dist/generated/themes/SecondaryNavigationItem.css.js +1 -1
  107. package/dist/generated/themes/SecondaryNavigationItem.css.js.map +1 -1
  108. package/dist/generated/themes/SecondaryNavigationSubItem.css.d.ts +1 -1
  109. package/dist/generated/themes/SecondaryNavigationSubItem.css.js +1 -1
  110. package/dist/generated/themes/SecondaryNavigationSubItem.css.js.map +1 -1
  111. package/dist/generated/themes/Slider.css.d.ts +1 -1
  112. package/dist/generated/themes/Slider.css.js +1 -1
  113. package/dist/generated/themes/Slider.css.js.map +1 -1
  114. package/dist/messagebundle.properties +3 -0
  115. package/dist/messagebundle_en.properties +1 -0
  116. package/dist/types/List.d.ts +0 -2
  117. package/dist/types/List.js +0 -2
  118. package/dist/types/List.js.map +1 -1
  119. package/dist/vscode.html-custom-data.json +22 -73
  120. package/dist/web-types.json +33 -73
  121. package/package.json +2 -1
  122. package/src/Breadcrumbs.ts +8 -20
  123. package/src/BreadcrumbsTemplate.tsx +1 -1
  124. package/src/List.ts +3 -3
  125. package/src/ListGroupHeader.hbs +7 -11
  126. package/src/ListItem.hbs +0 -2
  127. package/src/ListItemBase.ts +0 -8
  128. package/src/MastheadCountrySelector.hbs +5 -2
  129. package/src/MastheadCountrySelector.ts +31 -85
  130. package/src/MastheadItem.ts +8 -0
  131. package/src/MastheadMenuItem.hbs +1 -0
  132. package/src/MastheadMenuItem.ts +9 -0
  133. package/src/MastheadMobileMenu.hbs +0 -1
  134. package/src/MastheadMobileMenu.ts +34 -130
  135. package/src/MastheadProfileMenu.ts +1 -1
  136. package/src/MastheadShell.hbs +9 -11
  137. package/src/MastheadShell.ts +8 -50
  138. package/src/Pagination.ts +51 -7
  139. package/src/PromoTile.ts +10 -0
  140. package/src/PromoTileTemplate.tsx +4 -1
  141. package/src/SecondaryNavigationItem.ts +1 -2
  142. package/src/SelectBase.ts +33 -7
  143. package/src/generated/i18n/i18n-defaults.ts +2 -2
  144. package/src/generated/templates/ListGroupHeaderTemplate.lit.ts +12 -16
  145. package/src/generated/templates/ListItemTemplate.lit.ts +32 -36
  146. package/src/generated/templates/MastheadCountrySelectorTemplate.lit.ts +3 -3
  147. package/src/generated/templates/MastheadMenuItemTemplate.lit.ts +1 -1
  148. package/src/generated/templates/MastheadMobileMenuTemplate.lit.ts +1 -1
  149. package/src/generated/templates/MastheadShellTemplate.lit.ts +9 -10
  150. package/src/generated/themes/BreadcrumbsPopover.css.ts +1 -1
  151. package/src/generated/themes/Dropdown.css.ts +1 -1
  152. package/src/generated/themes/Link.css.ts +1 -1
  153. package/src/generated/themes/ListGroupHeader.css.ts +1 -1
  154. package/src/generated/themes/MastheadCountrySelector.css.ts +1 -1
  155. package/src/generated/themes/MastheadItem.css.ts +1 -1
  156. package/src/generated/themes/MastheadShell.css.ts +1 -1
  157. package/src/generated/themes/RatingIndicator.css.ts +1 -1
  158. package/src/generated/themes/SecondaryNavigation.css.ts +1 -1
  159. package/src/generated/themes/SecondaryNavigationItem.css.ts +1 -1
  160. package/src/generated/themes/SecondaryNavigationSubItem.css.ts +1 -1
  161. package/src/generated/themes/Slider.css.ts +1 -1
  162. package/src/i18n/messagebundle.properties +3 -0
  163. package/src/i18n/messagebundle_en.properties +1 -0
  164. package/src/themes/BreadcrumbsPopover.css +2 -0
  165. package/src/themes/Dropdown.css +5 -1
  166. package/src/themes/Link.css +2 -3
  167. package/src/themes/ListGroupHeader.css +3 -11
  168. package/src/themes/MastheadCountrySelector.css +2 -2
  169. package/src/themes/MastheadItem.css +57 -0
  170. package/src/themes/MastheadShell.css +0 -2
  171. package/src/themes/SecondaryNavigation.css +6 -3
  172. package/src/themes/SecondaryNavigationItem.css +11 -10
  173. package/src/themes/SecondaryNavigationSubItem.css +3 -2
  174. package/src/types/List.ts +0 -2
  175. package/dist/assets/messagebundle_en-J-MHTtdL.js +0 -1
@@ -12,7 +12,7 @@ export default function BreadcrumbsTemplate(this: Breadcrumbs) {
12
12
  <nav
13
13
  class={`${this._rootClass} ui5-breadcrumbs-root`}
14
14
  aria-label={this._breadcrumbsAccessibleNameText}>
15
- <ol onFocusIn={this._onfocusin}>
15
+ <ol>
16
16
  <li class={`${this._rootClass}__arrow-wrapper ui5-breadcrumbs-dropdown-arrow-link-wrapper`}>
17
17
  <UDExLink
18
18
  id={`udex-${this._id}-breadcrumbs__opener`}
package/src/List.ts CHANGED
@@ -241,7 +241,7 @@ class UDExList extends UI5Element {
241
241
  const lastItemIndex = items.length - 1;
242
242
  const previousSelectIndex = currentSelectedIndex - 1 < 0 ? lastItemIndex : currentSelectedIndex - 1;
243
243
  const isHeaderItem = items[previousSelectIndex].isGroup;
244
- const nonInteractiveHeader = items[previousSelectIndex].nonInteractive;
244
+ const nonInteractiveHeader = items[previousSelectIndex].nonInteractive && !items[previousSelectIndex].collapsible;
245
245
 
246
246
  if (nonInteractiveHeader && previousSelectIndex === 0) {
247
247
  this.unsetTabIndexByIndex(items, currentSelectedIndex);
@@ -294,7 +294,7 @@ class UDExList extends UI5Element {
294
294
  const currentSelectedIndex = this.getCurrentIndex(items, e.target as UDExListItemBase);
295
295
  const nextSelectIndex = currentSelectedIndex + 1 > items.length - 1 ? 0 : currentSelectedIndex + 1;
296
296
  const isHeaderItem = items[nextSelectIndex].isGroup;
297
- const nonInteractiveHeader = items[nextSelectIndex].nonInteractive;
297
+ const nonInteractiveHeader = items[nextSelectIndex].nonInteractive && !items[nextSelectIndex].collapsible;
298
298
 
299
299
  if (nonInteractiveHeader) {
300
300
  this.unsetTabIndexByIndex(items, currentSelectedIndex);
@@ -337,7 +337,7 @@ class UDExList extends UI5Element {
337
337
  const currentSelectedIndex = this.getCurrentIndex(items, e.target as UDExListItemBase);
338
338
  const firstItem = items[0];
339
339
  const isHeaderItem = firstItem.isGroup;
340
- const nonInteractiveItem = firstItem.nonInteractive;
340
+ const nonInteractiveItem = firstItem.nonInteractive && !firstItem.collapsible;
341
341
 
342
342
  if (nonInteractiveItem) {
343
343
  this.unsetTabIndexByIndex(items, currentSelectedIndex);
@@ -125,8 +125,6 @@
125
125
 
126
126
  {{#*inline "single-group-header"}}
127
127
  <div class="udex-list__group-content udex-list__group-header-wrap {{sizeClass}}" part="group-item">
128
- {{#if typeNumber}}<span class="udex-list__number">{{numberOfItem}}.</span>{{/if}}
129
- {{#if typeCircle}}<span class="udex-list__circle">&#x2022;</span>{{/if}}
130
128
  {{#if typeIcon}}
131
129
  <ui5-icon
132
130
  class="udex-list__icon"
@@ -147,15 +145,13 @@
147
145
 
148
146
  {{#*inline "single-group-header-collapsible"}}
149
147
  <div class="udex-list__group-content udex-list__group-header-wrap {{sizeClass}}" part="group-item"
150
- id="{{this._id}}_group-content__focusable"
151
- role="button"
152
- tabindex="0"
153
- @keydown="{{handleKeyDown}}"
154
- _tab-index="{{_effectiveTabIndex}}"
155
- aria-expanded="{{expanded}}"
156
- aria-controls="{{ariaControlsId}}">
157
- {{#if typeNumber}}<span class="udex-list__number">{{numberOfItem}}.</span>{{/if}}
158
- {{#if typeCircle}}<span class="udex-list__circle">&#x2022;</span>{{/if}}
148
+ id="{{this._id}}_group-content__focusable"
149
+ role="button"
150
+ tabindex="0"
151
+ @keydown="{{handleKeyDown}}"
152
+ _tab-index="{{_effectiveTabIndex}}"
153
+ aria-expanded="{{expanded}}"
154
+ aria-controls="{{ariaControlsId}}">
159
155
  {{#if typeIcon}}
160
156
  <ui5-icon
161
157
  class="udex-list__icon"
package/src/ListItem.hbs CHANGED
@@ -56,8 +56,6 @@
56
56
  <span class="udex-list__flag" style="background-position: {{flagPosition}}"></span>
57
57
  </div>
58
58
  {{/if}}
59
- {{#if typeNumber}}<span class="udex-list__number">{{numberOfItem}}.</span>{{/if}}
60
- {{#if typeCircle}}<span class="udex-list__circle">&#x2022;</span>{{/if}}
61
59
  {{#if typeIcon}}
62
60
  <ui5-icon
63
61
  class="udex-list__icon"
@@ -298,14 +298,6 @@ class UDExListItemBase extends UI5Element {
298
298
  return this.modeMultiSelect || this.modeRadioGroup;
299
299
  }
300
300
 
301
- get typeNumber(): boolean {
302
- return this.type === UDExListStyleType.Number;
303
- }
304
-
305
- get typeCircle(): boolean {
306
- return this.type === UDExListStyleType.Circle;
307
- }
308
-
309
301
  get typeIcon(): boolean {
310
302
  return this.type === UDExListStyleType.Icon;
311
303
  }
@@ -4,6 +4,8 @@
4
4
  {{#unless this.isSingleMode}}
5
5
  <udex-masthead-menu-item
6
6
  class="udex-masthead-country-selector__region-back-item"
7
+ accessible-role="button"
8
+ _accessible-Name="{{backToRegionListAccessibleName}}"
7
9
  @click="{{backToRegions}}"
8
10
  label="{{_activeRegion?.title}}"
9
11
  type="Button"
@@ -48,13 +50,14 @@
48
50
  </div>
49
51
  {{else}}
50
52
  <span class="udex-masthead-country-selector__title">{{regionTitle}}</span>
51
- <ul class="udex-masthead-country-selector__list" role="menu">
53
+ <ul class="udex-masthead-country-selector__list">
52
54
  {{#each regionsData}}
53
- <li role="none">
55
+ <li>
54
56
  <udex-masthead-menu-item
55
57
  id="{{this._id}}"
56
58
  @click="{{../handleRegionClick}}"
57
59
  index="{{@index}}"
60
+ accessible-role="button"
58
61
  class="udex-masthead-country-selector__item udex-masthead-country-selector__item_region"
59
62
  aria-haspopup="true"
60
63
  type="Button"
@@ -9,7 +9,7 @@ import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js";
9
9
  import { isDesktop } from "@ui5/webcomponents-base/dist/Device.js";
10
10
  import "@ui5/webcomponents-icons/dist/slim-arrow-right.js";
11
11
  import {
12
- isUp, isDown, isRight, isLeft, isEnd, isHome,
12
+ isEnd, isHome, isTabNext, isTabPrevious,
13
13
  } from "@ui5/webcomponents-base/dist/Keys.js";
14
14
  import UDExMastheadMenuItem from "./MastheadMenuItem.js";
15
15
  import UDExSearch, { Mode as UDExSearchMode } from "./Search.js";
@@ -17,7 +17,7 @@ import MastheadCountrySelectorTemplate from "./generated/templates/MastheadCount
17
17
  import AnalyticsName from "./types/AnalyticsName.js";
18
18
  import { BreakpointUtils } from "./utils/Breakpoints.js";
19
19
  import type UDExMastheadShell from "./MastheadShell.js";
20
- import { NO_MATCHES_FOUND, RESULT_RETURNED } from "./generated/i18n/i18n-defaults.js";
20
+ import { NO_MATCHES_FOUND, RESULT_RETURNED, BACK_TO_REGION_LIST } from "./generated/i18n/i18n-defaults.js";
21
21
  import translate from "./utils/translate.js";
22
22
 
23
23
  // Styles
@@ -217,14 +217,6 @@ class UDExMastheadCountrySelector extends UI5Element {
217
217
  @property({ type: Boolean })
218
218
  _isMobileMode!: boolean;
219
219
 
220
- /**
221
- * Defines direction of the component.
222
- *
223
- * @private
224
- */
225
- @property({ type: String })
226
- _direction!: string;
227
-
228
220
  @property({ type: Boolean, noAttribute: true })
229
221
  _requestRender = false;
230
222
 
@@ -250,7 +242,6 @@ class UDExMastheadCountrySelector extends UI5Element {
250
242
  this._mastheadShell = this.mastheadShell;
251
243
  this.handleFocusItem();
252
244
  this.setTabIndexForItems();
253
- this.handleDirection();
254
245
  this.handleOutsideClick();
255
246
 
256
247
  if (this.isSingleMode) {
@@ -283,55 +274,23 @@ class UDExMastheadCountrySelector extends UI5Element {
283
274
  handleKeyDown(e: KeyboardEvent): void {
284
275
  const item = e.target as UDExMastheadMenuItem;
285
276
 
286
- if (item.hasAttribute("is-back")) {
287
- this.handleBackKeyboard(e);
288
- return;
289
- }
290
-
291
277
  if (item.hasAttribute("is-nav-item")) {
292
- this.handleUpArrow(e);
293
- this.handleDownArrow(e);
294
- this.handleRightArrow(e);
295
- this.handleLeftArrow(e);
278
+ const isFirstItem = item === this.items[0];
279
+ const isLastItem = item === this.items[this.items.length - 1];
280
+
281
+ if (isTabNext(e) && !isLastItem) {
282
+ e.preventDefault();
283
+ this.focusNextItem(item);
284
+ }
285
+ if (isTabPrevious(e) && !isFirstItem) {
286
+ e.preventDefault();
287
+ this.focusPreviousItem(item);
288
+ }
296
289
  this.handleHomeKey(e);
297
290
  this.handleEndKey(e);
298
291
  }
299
292
  }
300
293
 
301
- handleBackKeyboard(e: KeyboardEvent): void {
302
- if ((isLeft(e) && !this.isRtlDirection) || (isRight(e) && this.isRtlDirection)) {
303
- this.backToRegions();
304
- }
305
- }
306
-
307
- handleRightArrow(e: KeyboardEvent): void {
308
- if (isRight(e) && !this.isRtlDirection) {
309
- this.openCountriesByRegion(e);
310
- this.fireEventRegionItemClick(e);
311
- }
312
- }
313
-
314
- handleLeftArrow(e: KeyboardEvent): void {
315
- if (isLeft(e) && this.isRtlDirection) {
316
- this.openCountriesByRegion(e);
317
- this.fireEventRegionItemClick(e);
318
- }
319
- }
320
-
321
- handleUpArrow(e: KeyboardEvent): void {
322
- if (isUp(e)) {
323
- e.preventDefault();
324
- this.focusPreviousItem(e);
325
- }
326
- }
327
-
328
- handleDownArrow(e: KeyboardEvent): void {
329
- if (isDown(e)) {
330
- e.preventDefault();
331
- this.focusNextItem(e);
332
- }
333
- }
334
-
335
294
  handleSearch(e: CustomEvent): void {
336
295
  const searchTerm = e.detail.value.toLowerCase().trim() as string;
337
296
 
@@ -377,17 +336,6 @@ class UDExMastheadCountrySelector extends UI5Element {
377
336
  this._requestRender = !this._requestRender;
378
337
  }
379
338
 
380
- handleDirection() {
381
- const directionStyles: string = window
382
- .getComputedStyle(this)
383
- .getPropertyValue("direction");
384
- if (!directionStyles) {
385
- this._direction = "ltr";
386
- } else {
387
- this._direction = directionStyles;
388
- }
389
- }
390
-
391
339
  handleOutsideClick(): void {
392
340
  document.addEventListener("mousedown", (e: Event): void => {
393
341
  if (e.target !== this && !this.isMobile) {
@@ -415,21 +363,9 @@ class UDExMastheadCountrySelector extends UI5Element {
415
363
  this._shouldFocusRegionByIndex = true;
416
364
  }
417
365
 
418
- focusPreviousItem(e: KeyboardEvent): void {
419
- const currentIndex = (e.target as UDExMastheadMenuItem).index;
420
- const lastItemIndex = this.items.length - 1;
421
- const prevIndex = currentIndex - 1 < 0 ? lastItemIndex : currentIndex - 1;
422
- const prevItem = this.items[prevIndex];
423
- this.items[currentIndex]._tabIndex = "-1";
424
- prevItem._tabIndex = "0";
425
- prevItem.scrollIntoView({ block: "center" });
426
- prevItem.focus({ preventScroll: true });
427
- }
428
-
429
- focusNextItem(e: KeyboardEvent): void {
430
- const currentIndex = (e.target as UDExMastheadMenuItem).index;
431
- const lastItemIndex = this.items.length - 1;
432
- const nextIndex = currentIndex + 1 > lastItemIndex ? 0 : currentIndex + 1;
366
+ focusNextItem(currentItem: UDExMastheadMenuItem): void {
367
+ const currentIndex = currentItem.index;
368
+ const nextIndex = currentIndex + 1;
433
369
  const nextItem = this.items[nextIndex];
434
370
  this.items[currentIndex]._tabIndex = "-1";
435
371
  nextItem._tabIndex = "0";
@@ -437,6 +373,16 @@ class UDExMastheadCountrySelector extends UI5Element {
437
373
  nextItem.focus({ preventScroll: true });
438
374
  }
439
375
 
376
+ focusPreviousItem(currentItem: UDExMastheadMenuItem): void {
377
+ const currentIndex = currentItem.index;
378
+ const prevIndex = currentIndex - 1;
379
+ const prevItem = this.items[prevIndex];
380
+ this.items[currentIndex]._tabIndex = "-1";
381
+ prevItem._tabIndex = "0";
382
+ prevItem.scrollIntoView({ block: "center" });
383
+ prevItem.focus({ preventScroll: true });
384
+ }
385
+
440
386
  focusLastItem(e: KeyboardEvent): void {
441
387
  const currentIndex = (e.target as UDExMastheadMenuItem).index;
442
388
  const lastItemIndex = this.items.length - 1;
@@ -564,7 +510,7 @@ class UDExMastheadCountrySelector extends UI5Element {
564
510
  }
565
511
 
566
512
  handleCountryListShadowVisible(): void {
567
- if (this.scrollBottomCountriesList === 0) {
513
+ if (this.scrollBottomCountriesList <= 1) {
568
514
  this.removeScrollableClassInCountryList();
569
515
  } else {
570
516
  this.addScrollableClassToCountryList();
@@ -623,10 +569,6 @@ class UDExMastheadCountrySelector extends UI5Element {
623
569
  }));
624
570
  }
625
571
 
626
- get isRtlDirection(): boolean {
627
- return this._direction === "rtl";
628
- }
629
-
630
572
  get homeSearchMode(): UDExSearchMode {
631
573
  return UDExSearchMode.HomeSearch;
632
574
  }
@@ -642,6 +584,10 @@ class UDExMastheadCountrySelector extends UI5Element {
642
584
  get mastheadShell(): UDExMastheadShell {
643
585
  return document.querySelector<UDExMastheadShell>("[udex-masthead-shell]")!;
644
586
  }
587
+
588
+ get backToRegionListAccessibleName(): string {
589
+ return `${this._activeRegion?.title} ${translate(UDExMastheadCountrySelector, BACK_TO_REGION_LIST)}`;
590
+ }
645
591
  }
646
592
 
647
593
  UDExMastheadCountrySelector.define();
@@ -481,6 +481,14 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
481
481
  }
482
482
  }
483
483
 
484
+ recalculateDropdownPosition(): void {
485
+ const dropdown = this.dropdownHolder;
486
+ if (dropdown) {
487
+ dropdown.style.marginInlineStart = "";
488
+ this.setDropdownInsetStart();
489
+ }
490
+ }
491
+
484
492
  calculateMarginInlineStart(rect: DOMRect): number | null {
485
493
  const { left, right } = rect;
486
494
 
@@ -38,6 +38,7 @@
38
38
  {{#if isButtonType}}
39
39
  <button
40
40
  _id="{{id}}"
41
+ aria-label="{{_accessibleName}}"
41
42
  class="udex-masthead-menu-item {{rootClass}}"
42
43
  part="menu-item-button"
43
44
  aria-haspopup="{{ariaHasPopup}}"
@@ -162,6 +162,15 @@ class UDExMastheadMenuItem extends UI5Element {
162
162
  @property()
163
163
  target: `${UDExTarget}` = UDExTarget._self;
164
164
 
165
+ /**
166
+ * Defines the accessible name of the item.
167
+ *
168
+ * @default undefined
169
+ * @private
170
+ */
171
+ @property()
172
+ _accessibleName?: string;
173
+
165
174
  /**
166
175
  * Defines the tabindex attribute for the item.
167
176
  *
@@ -75,7 +75,6 @@
75
75
  class="udex-masthead-mobile-menu__explore-btn"
76
76
  id="{{exploreItem._id}}"
77
77
  @click="{{handleExploreSapClick}}"
78
- @keydown="{{handleLeftRightKeys}}"
79
78
  accessible-role-text="button"
80
79
  aria-haspopup="true"
81
80
  type="Button"
@@ -7,7 +7,7 @@ import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";
7
7
  import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js";
8
8
  import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js";
9
9
  import {
10
- isUp, isDown, isRight, isLeft, isHome, isEnd,
10
+ isHome, isEnd, isTabNext, isTabPrevious,
11
11
  } from "@ui5/webcomponents-base/dist/Keys.js";
12
12
  import type { MenuItem, SubMenuLinkItem } from "./MastheadItem.js";
13
13
  import type UDExMastheadItem from "./MastheadItem.js";
@@ -134,9 +134,6 @@ class UDExMastheadMobileMenu extends UI5Element {
134
134
  @property({ type: Boolean })
135
135
  _showCategoryItems!: boolean;
136
136
 
137
- @property({ type: String })
138
- _direction?: string;
139
-
140
137
  @i18n("@sapudex/web-components")
141
138
  static i18nBundle: I18nBundle;
142
139
 
@@ -202,63 +199,51 @@ class UDExMastheadMobileMenu extends UI5Element {
202
199
  }
203
200
 
204
201
  handlePressKey(e: KeyboardEvent) {
205
- this.handleUpArrow(e);
206
- this.handleDownArrow(e);
207
- this.handleLeftRightKeys(e);
208
- this.handleHomeKey(e);
209
- this.handleEndKey(e);
210
- }
202
+ const currentItem = e.target as UDExMastheadMenuItem;
203
+ const items = this.navigationItems;
204
+ const isFirstItem = currentItem === items[0];
205
+ const isLastItem = currentItem === items[items.length - 1];
211
206
 
212
- handleLeftRightKeys(e: KeyboardEvent) {
213
- this.handleRightArrow(e);
214
- this.handleLeftArrow(e);
215
- }
216
-
217
- handleRightArrow(e: KeyboardEvent) {
218
- if (isRight(e)) {
207
+ if (isTabNext(e) && !isLastItem) {
219
208
  e.preventDefault();
220
- this.handleDirection();
221
- if (this.isRtlDirection) {
222
- this.moveToBackWithKeyboard(e);
223
- } else {
224
- this.moveToNextLevelWithKeyboard(e);
225
- }
209
+ this.focusNextItem(currentItem);
226
210
  }
227
- }
228
-
229
- handleLeftArrow(e: KeyboardEvent) {
230
- if (isLeft(e)) {
211
+ if (isTabPrevious(e) && !isFirstItem) {
231
212
  e.preventDefault();
232
- this.handleDirection();
233
- if (this.isRtlDirection) {
234
- this.moveToNextLevelWithKeyboard(e);
235
- } else {
236
- this.moveToBackWithKeyboard(e);
237
- }
213
+ this.focusPreviousItem(currentItem);
238
214
  }
215
+ this.handleHomeKey(e);
216
+ this.handleEndKey(e);
239
217
  }
240
218
 
241
- handleUpArrow(e: KeyboardEvent) {
242
- if (isUp(e)) {
243
- e.preventDefault();
244
- this.focusPreviousItem(e);
245
- }
246
- }
219
+ focusNextItem(currentItem: UDExMastheadMenuItem): void {
220
+ const currentIndex = this.getCurrentIndex(currentItem);
221
+ const nextIndex = currentIndex + 1;
222
+ const currentListItem = this.getListItemByIndex(currentIndex);
223
+ let nextItem = this.getListItemByIndex(nextIndex);
247
224
 
248
- handleDownArrow(e: KeyboardEvent) {
249
- if (isDown(e)) {
250
- e.preventDefault();
251
- this.focusNextItem(e);
225
+ if (nextItem.type === UDExItemType.Heading) {
226
+ nextItem = this.getListItemByIndex(nextIndex + 1);
252
227
  }
228
+
229
+ currentListItem._tabIndex = "-1";
230
+ nextItem._tabIndex = "0";
231
+ nextItem.focus();
253
232
  }
254
233
 
255
- handleDirection() {
256
- const directionStyles: string = window.getComputedStyle(this).getPropertyValue("direction");
257
- if (!directionStyles) {
258
- this._direction = "ltr";
259
- } else {
260
- this._direction = directionStyles;
234
+ focusPreviousItem(currentItem: UDExMastheadMenuItem): void {
235
+ const currentIndex = this.getCurrentIndex(currentItem);
236
+ const previousIndex = currentIndex - 1;
237
+ const currentListItem = this.getListItemByIndex(currentIndex);
238
+ let prevItem = this.getListItemByIndex(previousIndex);
239
+
240
+ if (prevItem.type === UDExItemType.Heading) {
241
+ prevItem = this.getListItemByIndex(this.navigationItems.length - 1);
261
242
  }
243
+
244
+ currentListItem._tabIndex = "-1";
245
+ prevItem._tabIndex = "0";
246
+ prevItem.focus();
262
247
  }
263
248
 
264
249
  handleMobileItemEvent(e: PointerEvent) {
@@ -291,51 +276,6 @@ class UDExMastheadMobileMenu extends UI5Element {
291
276
  }
292
277
  }
293
278
 
294
- moveToBackWithKeyboard(e: KeyboardEvent) {
295
- const target = e.target as UDExMastheadMenuItem;
296
- if (target.hasAttribute("is-back-to-nav")) {
297
- this.showFirstLevelMenu();
298
- this.setFocusItemByIndex(this.items.indexOf(this._clickedItem));
299
- this.fireMobileItemEvent(e);
300
- }
301
-
302
- if (target.hasAttribute("is-back-to-categories")) {
303
- this.showCategories();
304
- this.setFocusItemByIndex(this._category.index);
305
- this.fireMobileItemEvent(e);
306
- }
307
-
308
- if (target.hasAttribute("is-explore-back")) {
309
- this.showFirstLevelMenu();
310
- this.setFocusExploreBtn();
311
- this._focusedItemIndex = 0;
312
- this.fireMobileItemEvent(e);
313
- }
314
- }
315
-
316
- moveToNextLevelWithKeyboard(e: KeyboardEvent) {
317
- const target = e.target as UDExMastheadItem;
318
- const item = this.getClickedItem(e.target as UDExMastheadItem);
319
-
320
- if (target.hasAttribute("is-explore")) {
321
- this._hideExploreSapBtn = true;
322
- this._showCategoryItems = false;
323
- this.fireMobileItemEvent(e);
324
- }
325
-
326
- if (target.hasAttribute("first-level-btn")) {
327
- this.openCategories(item);
328
- this.fireMobileItemEvent(e);
329
- }
330
-
331
- if (target.hasAttribute("second-level-btn")) {
332
- this.openCategoryItems(e);
333
- this.fireMobileItemEvent(e);
334
- }
335
-
336
- this.setFocusItemByIndex(0);
337
- }
338
-
339
279
  focusItemByIndex(index: number): void {
340
280
  this.getListItemByIndex(index)?.focus();
341
281
  this._shouldFocusItemByIndex = false;
@@ -346,38 +286,6 @@ class UDExMastheadMobileMenu extends UI5Element {
346
286
  this._shouldFocusExploreBtn = false;
347
287
  }
348
288
 
349
- focusPreviousItem(e: KeyboardEvent): void {
350
- const currentIndex = this.getCurrentIndex(e.target as UDExMastheadMenuItem);
351
- const lastIndex = this.navigationItems.length - 1;
352
- const previousIndex = currentIndex - 1 < 0 ? lastIndex : currentIndex - 1;
353
- const currentItem = this.getListItemByIndex(currentIndex);
354
- let prevItem = this.getListItemByIndex(previousIndex);
355
-
356
- if (prevItem.type === UDExItemType.Heading) {
357
- prevItem = this.getListItemByIndex(lastIndex);
358
- }
359
-
360
- currentItem._tabIndex = "-1";
361
- prevItem._tabIndex = "0";
362
- prevItem.focus();
363
- }
364
-
365
- focusNextItem(e: KeyboardEvent): void {
366
- const currentIndex = this.getCurrentIndex(e.target as UDExMastheadMenuItem);
367
- const navLength = this.navigationItems.length;
368
- const nextIndex = currentIndex + 1 > navLength - 1 ? 0 : currentIndex + 1;
369
- const currentItem = this.getListItemByIndex(currentIndex);
370
- let nextItem = this.getListItemByIndex(nextIndex);
371
-
372
- if (nextItem.type === UDExItemType.Heading) {
373
- nextItem = this.getListItemByIndex(nextIndex + 1);
374
- }
375
-
376
- currentItem._tabIndex = "-1";
377
- nextItem._tabIndex = "0";
378
- nextItem.focus();
379
- }
380
-
381
289
  handleEndKey(e: KeyboardEvent): void {
382
290
  if (isEnd(e)) {
383
291
  e.preventDefault();
@@ -572,10 +480,6 @@ class UDExMastheadMobileMenu extends UI5Element {
572
480
  return this.shadowRoot!.querySelector<UDExMastheadMenuItem>(".udex-masthead-mobile-menu__explore-btn")!;
573
481
  }
574
482
 
575
- get isRtlDirection(): boolean {
576
- return this._direction === "rtl";
577
- }
578
-
579
483
  get navigationItems(): Array<UDExMastheadMenuItem> {
580
484
  return Array.from(this.shadowRoot!.querySelectorAll<UDExMastheadMenuItem>("ul [udex-masthead-menu-item]"));
581
485
  }
@@ -418,7 +418,7 @@ class UDExMastheadProfileMenu extends UI5Element {
418
418
  }
419
419
 
420
420
  toggleScrollableClass(el: HTMLElement, className: string, scrollBottom: number): void {
421
- if (scrollBottom === 0) {
421
+ if (scrollBottom <= 1) {
422
422
  el.classList.remove(`${className}_scrollable`);
423
423
  } else {
424
424
  el.classList.add(`${className}_scrollable`);
@@ -53,17 +53,6 @@
53
53
  {{/if}}
54
54
 
55
55
  <div class="{{rightMenuClass}}">
56
- {{#if hasMobileMenuButtons}}
57
- <udex-masthead-item
58
- @ui5-item-click="{{handleOpenMobileMenu}}"
59
- class="udex-masthead-shell__menu-btn"
60
- accessible-role="button"
61
- icon="menu2"
62
- part="menu-open-btn"
63
- accessible-name="menu">
64
- <slot slot="dropdown" name="mobileMenu"></slot>
65
- </udex-masthead-item>
66
- {{/if}}
67
56
  {{#if hasExploreSAP}}
68
57
  <div
69
58
  class="udex-masthead-shell__explore"
@@ -124,6 +113,15 @@
124
113
  </div>
125
114
  {{/if}}
126
115
  {{#if hasMobileMenuButtons}}
116
+ <udex-masthead-item
117
+ @ui5-item-click="{{handleOpenMobileMenu}}"
118
+ class="udex-masthead-shell__menu-btn"
119
+ accessible-role="button"
120
+ icon="menu2"
121
+ part="menu-open-btn"
122
+ accessible-name="menu">
123
+ <slot slot="dropdown" name="mobileMenu"></slot>
124
+ </udex-masthead-item>
127
125
  <udex-masthead-item
128
126
  @keydown="{{handleEnterAndSpaceOnCloseBtn}}"
129
127
  @ui5-item-click="{{closeMobileMenu}}"