@sapudex/web-components 2.32.1 → 2.33.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 (105) hide show
  1. package/cypress/fixtures/masthead-shell.ts +281 -0
  2. package/cypress/specs/Breadcrumbs.cy.tsx +196 -1
  3. package/cypress/specs/MastheadShell.cy.tsx +645 -0
  4. package/cypress/specs/SecondaryNavigationDesktop.cy.tsx +289 -95
  5. package/cypress/specs/SecondaryNavigationMobile.cy.tsx +42 -0
  6. package/cypress/specs/TabNavigation.cy.tsx +431 -10
  7. package/cypress/support/component-imports.instrumented.ts +14 -0
  8. package/cypress/support/component-imports.src.ts +10 -0
  9. package/dist/Breadcrumbs.d.ts +12 -0
  10. package/dist/Breadcrumbs.js +30 -6
  11. package/dist/Breadcrumbs.js.map +1 -1
  12. package/dist/BreadcrumbsPopoverTemplate.js +10 -1
  13. package/dist/BreadcrumbsPopoverTemplate.js.map +1 -1
  14. package/dist/BreadcrumbsTemplate.js +1 -1
  15. package/dist/BreadcrumbsTemplate.js.map +1 -1
  16. package/dist/SecondaryNavigation.d.ts +1 -6
  17. package/dist/SecondaryNavigation.js +6 -59
  18. package/dist/SecondaryNavigation.js.map +1 -1
  19. package/dist/SecondaryNavigationItem.d.ts +5 -12
  20. package/dist/SecondaryNavigationItem.js +34 -65
  21. package/dist/SecondaryNavigationItem.js.map +1 -1
  22. package/dist/SecondaryNavigationItemBase.d.ts +0 -1
  23. package/dist/SecondaryNavigationItemBase.js +0 -4
  24. package/dist/SecondaryNavigationItemBase.js.map +1 -1
  25. package/dist/Tab.d.ts +19 -0
  26. package/dist/Tab.js +22 -0
  27. package/dist/Tab.js.map +1 -1
  28. package/dist/TabNavigation.d.ts +9 -1
  29. package/dist/TabNavigation.js +25 -7
  30. package/dist/TabNavigation.js.map +1 -1
  31. package/dist/assets/{InputSuggestions-DeXhpK0F.js → InputSuggestions-B_Dl2L6w.js} +1 -1
  32. package/dist/assets/{ListItemStandardExpandableTextTemplate-jMEdrC07.js → ListItemStandardExpandableTextTemplate-9Z-aZmJx.js} +1 -1
  33. package/dist/assets/{bundle-S1uYREqT.css → bundle-DbTEs-Za.css} +1 -1
  34. package/dist/assets/{bundle.esm-CwJAt93x.js → bundle.esm-BlIxH9k1.js} +186 -186
  35. package/dist/css/themes/Breadcrumbs.css +1 -1
  36. package/dist/css/themes/BreadcrumbsPopover.css +1 -1
  37. package/dist/css/themes/ListItem.css +1 -1
  38. package/dist/css/themes/RatingIndicator.css +1 -1
  39. package/dist/css/themes/Slider.css +1 -1
  40. package/dist/css/themes/TabNavigation.css +1 -1
  41. package/dist/custom-elements-internal.json +211 -156
  42. package/dist/custom-elements.json +196 -141
  43. package/dist/generated/templates/ListItemTemplate.lit.js +4 -4
  44. package/dist/generated/templates/ListItemTemplate.lit.js.map +1 -1
  45. package/dist/generated/templates/SecondaryNavigationItemTemplate.lit.js +4 -4
  46. package/dist/generated/templates/SecondaryNavigationItemTemplate.lit.js.map +1 -1
  47. package/dist/generated/templates/SecondaryNavigationSubItemTemplate.lit.js +3 -3
  48. package/dist/generated/templates/SecondaryNavigationSubItemTemplate.lit.js.map +1 -1
  49. package/dist/generated/templates/SecondaryNavigationTemplate.lit.js +5 -5
  50. package/dist/generated/templates/SecondaryNavigationTemplate.lit.js.map +1 -1
  51. package/dist/generated/templates/TabHeaderTemplate.lit.js +40 -24
  52. package/dist/generated/templates/TabHeaderTemplate.lit.js.map +1 -1
  53. package/dist/generated/templates/TabNavigationTemplate.lit.js +1 -1
  54. package/dist/generated/templates/TabNavigationTemplate.lit.js.map +1 -1
  55. package/dist/generated/themes/Breadcrumbs.css.d.ts +1 -1
  56. package/dist/generated/themes/Breadcrumbs.css.js +1 -1
  57. package/dist/generated/themes/Breadcrumbs.css.js.map +1 -1
  58. package/dist/generated/themes/BreadcrumbsPopover.css.d.ts +1 -1
  59. package/dist/generated/themes/BreadcrumbsPopover.css.js +1 -1
  60. package/dist/generated/themes/BreadcrumbsPopover.css.js.map +1 -1
  61. package/dist/generated/themes/ListItem.css.d.ts +1 -1
  62. package/dist/generated/themes/ListItem.css.js +1 -1
  63. package/dist/generated/themes/ListItem.css.js.map +1 -1
  64. package/dist/generated/themes/RatingIndicator.css.d.ts +1 -1
  65. package/dist/generated/themes/RatingIndicator.css.js +1 -1
  66. package/dist/generated/themes/RatingIndicator.css.js.map +1 -1
  67. package/dist/generated/themes/Slider.css.d.ts +1 -1
  68. package/dist/generated/themes/Slider.css.js +1 -1
  69. package/dist/generated/themes/Slider.css.js.map +1 -1
  70. package/dist/generated/themes/TabNavigation.css.d.ts +1 -1
  71. package/dist/generated/themes/TabNavigation.css.js +1 -1
  72. package/dist/generated/themes/TabNavigation.css.js.map +1 -1
  73. package/dist/vscode.html-custom-data.json +16 -1
  74. package/dist/web-types.json +33 -3
  75. package/package.json +1 -1
  76. package/src/Breadcrumbs.ts +26 -7
  77. package/src/BreadcrumbsPopoverTemplate.tsx +53 -41
  78. package/src/BreadcrumbsTemplate.tsx +35 -21
  79. package/src/ListItem.hbs +16 -12
  80. package/src/SecondaryNavigation.hbs +6 -6
  81. package/src/SecondaryNavigation.ts +7 -66
  82. package/src/SecondaryNavigationItem.hbs +4 -6
  83. package/src/SecondaryNavigationItem.ts +40 -83
  84. package/src/SecondaryNavigationItemBase.ts +0 -3
  85. package/src/SecondaryNavigationSubItem.hbs +3 -7
  86. package/src/Tab.ts +32 -0
  87. package/src/TabHeader.hbs +40 -19
  88. package/src/TabNavigation.hbs +5 -9
  89. package/src/TabNavigation.ts +25 -8
  90. package/src/generated/templates/ListItemTemplate.lit.ts +4 -4
  91. package/src/generated/templates/SecondaryNavigationItemTemplate.lit.ts +4 -4
  92. package/src/generated/templates/SecondaryNavigationSubItemTemplate.lit.ts +3 -3
  93. package/src/generated/templates/SecondaryNavigationTemplate.lit.ts +5 -5
  94. package/src/generated/templates/TabHeaderTemplate.lit.ts +40 -24
  95. package/src/generated/templates/TabNavigationTemplate.lit.ts +1 -1
  96. package/src/generated/themes/Breadcrumbs.css.ts +1 -1
  97. package/src/generated/themes/BreadcrumbsPopover.css.ts +1 -1
  98. package/src/generated/themes/ListItem.css.ts +1 -1
  99. package/src/generated/themes/RatingIndicator.css.ts +1 -1
  100. package/src/generated/themes/Slider.css.ts +1 -1
  101. package/src/generated/themes/TabNavigation.css.ts +1 -1
  102. package/src/themes/Breadcrumbs.css +6 -0
  103. package/src/themes/BreadcrumbsPopover.css +12 -2
  104. package/src/themes/ListItem.css +6 -1
  105. package/src/themes/TabNavigation.css +58 -73
@@ -20,30 +20,44 @@ export default function BreadcrumbsTemplate(this: Breadcrumbs) {
20
20
  onClick={this._toggleDropdown}
21
21
  accessibleName={this._dropdownArrowAccessibleNameText}
22
22
  accessibleRole={UDExButtonAccessibleRole.Button}
23
- icon={slimArrowDown}
24
- aria-haspopup="true">
23
+ accessibilityAttributes={this._triggerAccessibilityAttributes}
24
+ icon={slimArrowDown}>
25
25
  </UDExLink>
26
26
  </li>
27
27
  {this._linksData.map(linkData =>
28
- <li
29
- class={`${this._rootClass}__link-wrapper ui5-breadcrumbs-link-wrapper`}
30
- id={`${linkData._id}-link-wrapper`}>
31
- {!linkData._isCurrentPageItem && (
32
- <>
33
- <span className={`${this._rootClass}__separator`} aria-hidden="true"></span>
34
- <UDExLink
35
- onClick={this._onLinkPress}
36
- id={`${linkData._id}-link`}
37
- class={`${rootClass}__item ${this._rootClass}__item--visible`}
38
- href={linkData.href}
39
- target={linkData.target}
40
- accessibleName={linkData._accessibleNameText}
41
- data-ui5-stable={linkData.stableDomRef}>
42
- {linkData.innerText}
43
- </UDExLink>
44
- </>
45
- )}
46
- </li>
28
+ (linkData._isCurrentPageItem && !this.showCurrentPage ? null : (
29
+ <li
30
+ role={linkData._isCurrentPageItem ? "presentation" : undefined}
31
+ class={`${this._rootClass}__link-wrapper ui5-breadcrumbs-link-wrapper`}
32
+ id={`${linkData._id}-link-wrapper`}>
33
+ {linkData._isCurrentPageItem ? (
34
+ <>
35
+ <span className={`${this._rootClass}__separator`} aria-hidden="true"></span>
36
+ <span
37
+ id={`${linkData._id}-link`}
38
+ class={`${rootClass}__item ${this._rootClass}__item--visible ${this._rootClass}__item--current-page`}
39
+ aria-current="page"
40
+ data-ui5-stable={linkData.stableDomRef}>
41
+ {linkData.textContent}
42
+ </span>
43
+ </>
44
+ ) : (
45
+ <>
46
+ <span className={`${this._rootClass}__separator`} aria-hidden="true"></span>
47
+ <UDExLink
48
+ onClick={this._onLinkPress}
49
+ id={`${linkData._id}-link`}
50
+ class={`${rootClass}__item ${this._rootClass}__item--visible`}
51
+ href={linkData.href}
52
+ target={linkData.target}
53
+ accessibleName={linkData._accessibleNameText}
54
+ data-ui5-stable={linkData.stableDomRef}>
55
+ {linkData.textContent}
56
+ </UDExLink>
57
+ </>
58
+ )}
59
+ </li>
60
+ ))
47
61
  )}
48
62
  </ol>
49
63
  </nav>
package/src/ListItem.hbs CHANGED
@@ -91,24 +91,28 @@
91
91
  <slot part="content"></slot>
92
92
  </div>
93
93
  {{#if additionalText}}<div class="udex-list__add-text" part="additional-text">{{additionalText}}</div>{{/if}}
94
- {{#if hasFirstIcon}}
95
- <slot name="firstIcon" @click={{_fireIconClickEvent}}></slot>
96
- {{/if}}
97
- {{#if hasSecondIcon}}
98
- <slot name="secondIcon" @click={{_fireIconClickEvent}}></slot>
99
- {{/if}}
94
+ <div class="udex-list__btn-wrap">
95
+ {{#if hasFirstIcon}}
96
+ <slot name="firstIcon" @click={{_fireIconClickEvent}}></slot>
97
+ {{/if}}
98
+ {{#if hasSecondIcon}}
99
+ <slot name="secondIcon" @click={{_fireIconClickEvent}}></slot>
100
+ {{/if}}
101
+ </div>
100
102
  {{else}}
101
103
  <div class="udex-list__text-holder">
102
104
  <slot part="content"></slot>
103
105
  {{#if supportingText}}<span class="udex-list__supporting-text" part="supporting">{{supportingText}}</span>{{/if}}
104
106
  </div>
105
107
  {{#if additionalText}}<div class="udex-list__add-text" part="additional-text">{{additionalText}}</div>{{/if}}
106
- {{#if hasFirstIcon}}
107
- <slot name="firstIcon" @click={{_fireIconClickEvent}}></slot>
108
- {{/if}}
109
- {{#if hasSecondIcon}}
110
- <slot name="secondIcon" @click={{_fireIconClickEvent}}></slot>
111
- {{/if}}
108
+ <div class="udex-list__btn-wrap">
109
+ {{#if hasFirstIcon}}
110
+ <slot name="firstIcon" @click={{_fireIconClickEvent}}></slot>
111
+ {{/if}}
112
+ {{#if hasSecondIcon}}
113
+ <slot name="secondIcon" @click={{_fireIconClickEvent}}></slot>
114
+ {{/if}}
115
+ </div>
112
116
  {{/if}}
113
117
  {{#if collapsible}}
114
118
  <div class="udex-list__group-heading__icon-wrapper">
@@ -10,6 +10,7 @@
10
10
  {{#if headingHref.length}}
11
11
  <a
12
12
  class="udex-secondary-navigation__title"
13
+ tabindex="0"
13
14
  @click="{{handleHeadingClick}}"
14
15
  href="{{headingHref}}">
15
16
  {{heading}}
@@ -19,14 +20,12 @@
19
20
  {{/if}}
20
21
  </div>
21
22
  {{/if}}
22
- <div class="udex-secondary-navigation__wrap">
23
+ <nav class="udex-secondary-navigation__wrap">
23
24
  <ul
24
- role="menubar"
25
25
  class="udex-secondary-navigation__list"
26
26
  @keydown="{{handleKeyDown}}">
27
27
  {{#each visibleItems}}
28
28
  <li
29
- role="none"
30
29
  class="udex-secondary-navigation__list-item">
31
30
  <udex-secondary-navigation-item
32
31
  index="{{@index}}"
@@ -44,7 +43,6 @@
44
43
  {{/each}}
45
44
  {{#if _showMoreButton}}
46
45
  <li
47
- role="none"
48
46
  class="udex-secondary-navigation__list-item">
49
47
  <udex-secondary-navigation-item
50
48
  _nav-items-length="{{visibleItems.length}}"
@@ -60,7 +58,7 @@
60
58
  {{#if hasDesktopButtonsSlot}}
61
59
  {{>buttons}}
62
60
  {{/if}}
63
- </div>
61
+ </nav>
64
62
  </div>
65
63
  <udex-secondary-navigation-item
66
64
  @keydown="{{handleKeyDown}}"
@@ -75,7 +73,9 @@
75
73
  _is-mobile-menu-opener
76
74
  .subItems="{{this.parsedItems}}">
77
75
  {{#if hasMobileButtonsSlot}}
78
- {{>buttons}}
76
+ <div class="udex-secondary-navigation__buttons" @click="{{handleMobileButtonsClick}}">
77
+ <slot name="buttons"></slot>
78
+ </div>
79
79
  {{/if}}
80
80
  </udex-secondary-navigation-item>
81
81
  </div>
@@ -6,9 +6,7 @@ import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";
6
6
  import slot from "@ui5/webcomponents-base/dist/decorators/slot.js";
7
7
  import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
8
8
  import { isDesktop } from "@ui5/webcomponents-base/dist/Device.js";
9
- import {
10
- isEscape, isLeft, isRight, isDown,
11
- } from "@ui5/webcomponents-base/dist/Keys.js";
9
+ import { isEscape } from "@ui5/webcomponents-base/dist/Keys.js";
12
10
  import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
13
11
  import type { UDExSecondaryNavigationItemClickEventDetail, UDExSecondaryNavigationItemSubItemClickEventDetail } from "./SecondaryNavigationItem.js";
14
12
  import UDExSecondaryNavigationItem from "./SecondaryNavigationItem.js";
@@ -200,7 +198,6 @@ class UDExSecondaryNavigation extends UI5Element {
200
198
 
201
199
  _navItems!: Array<NavItem>;
202
200
  _showMoreButton: boolean = true;
203
- _shouldFocusFirstItem: boolean = true;
204
201
  _rootHolder!: HTMLElement | null | undefined;
205
202
  _clickedNavItem!: UDExSecondaryNavigationItem;
206
203
  _boundReflowItems: () => void;
@@ -236,9 +233,6 @@ class UDExSecondaryNavigation extends UI5Element {
236
233
  if (!this._overflowItems.length) {
237
234
  this._showMoreButton = true;
238
235
  }
239
- if (this._shouldFocusFirstItem && this.isDesktopScreen) {
240
- this.domNavItems[0]._tabIndex = "0";
241
- }
242
236
  this.handleOutsideClick();
243
237
  }
244
238
 
@@ -248,9 +242,6 @@ class UDExSecondaryNavigation extends UI5Element {
248
242
 
249
243
  _handleResize() {
250
244
  this.reflowItems();
251
- if (this.isDesktopScreen) {
252
- this.resetTabIndex();
253
- }
254
245
  if (this._clickedNavItem && this.isDesktopScreen) {
255
246
  this._clickedNavItem.closeDropdown();
256
247
  }
@@ -288,45 +279,9 @@ class UDExSecondaryNavigation extends UI5Element {
288
279
  e.stopPropagation();
289
280
  const item = e.target as UDExSecondaryNavigationItem;
290
281
 
291
- if (isLeft(e)) {
292
- return this.focusPrevNavItem(e);
293
- }
294
- if (isRight(e)) {
295
- return this.focusNextNavItem(e);
296
- }
297
282
  if (isEscape(e) && item.hasNestedItems) {
298
283
  return item.closeDropdown();
299
284
  }
300
- if (isDown(e) && item.hasNestedItems) {
301
- item.openDropdown(e);
302
- }
303
- }
304
-
305
- focusPrevNavItem(e: KeyboardEvent): void {
306
- const item = e.target as UDExSecondaryNavigationItem;
307
- const currentSelectedIndex = this.getCurrentIndex(item);
308
- const previousSelectIndex = currentSelectedIndex - 1;
309
- const previousItem = this.domNavItems[previousSelectIndex];
310
- if (currentSelectedIndex > 0) {
311
- e.preventDefault();
312
- this.domNavItems[currentSelectedIndex]._tabIndex = "-1";
313
- previousItem._tabIndex = "0";
314
- previousItem?.focus();
315
- }
316
- }
317
-
318
- focusNextNavItem(e: KeyboardEvent): void {
319
- const item = e.target as UDExSecondaryNavigationItem;
320
- const currentSelectedIndex = this.getCurrentIndex(item);
321
- const lastItemIndex = this.domNavItems.length - 1;
322
- const nextSelectIndex = currentSelectedIndex + 1;
323
- const nextItem = this.domNavItems[nextSelectIndex];
324
- if (nextSelectIndex < lastItemIndex) {
325
- e.preventDefault();
326
- this.domNavItems[currentSelectedIndex]._tabIndex = "-1";
327
- nextItem._tabIndex = "0";
328
- nextItem.focus();
329
- }
330
285
  }
331
286
 
332
287
  getItemWidth(item: NavItem): number {
@@ -348,10 +303,6 @@ class UDExSecondaryNavigation extends UI5Element {
348
303
  return canvas.getContext("2d")!;
349
304
  }
350
305
 
351
- getCurrentIndex(item: UDExSecondaryNavigationItem): number {
352
- return this.domNavItems.indexOf(item);
353
- }
354
-
355
306
  handleItemClick(e: CustomEvent<UDExSecondaryNavigationItemClickEventDetail>): void {
356
307
  const { index, item, originalEvent: actualOriginalEvent } = e.detail;
357
308
  const clickedItem = item as UDExSecondaryNavigationItem;
@@ -374,8 +325,6 @@ class UDExSecondaryNavigation extends UI5Element {
374
325
  }
375
326
 
376
327
  this._clickedNavItem = clickedItem;
377
- this._shouldFocusFirstItem = false;
378
- this.setTabIndexById(_id);
379
328
  this.closePrevDropdown(_id);
380
329
 
381
330
  if (!subItems.length) {
@@ -499,11 +448,11 @@ class UDExSecondaryNavigation extends UI5Element {
499
448
  }
500
449
 
501
450
  handleOutsideClick(): void {
502
- document.addEventListener("mousedown", this.outsideClickListener);
451
+ document.addEventListener("click", this.outsideClickListener);
503
452
  }
504
453
 
505
454
  outsideClickListener = (e: MouseEvent): void => {
506
- if (this.isMobileScreen && e.target !== this) {
455
+ if (this.isMobileScreen && !e.composedPath().includes(this)) {
507
456
  this.closeMobileDropdown();
508
457
  return;
509
458
  }
@@ -513,6 +462,10 @@ class UDExSecondaryNavigation extends UI5Element {
513
462
  }
514
463
  };
515
464
 
465
+ handleMobileButtonsClick(): void {
466
+ this.closeMobileDropdown();
467
+ }
468
+
516
469
  closeMobileDropdown(): void {
517
470
  this.mobileNav?.closeDropdown();
518
471
  }
@@ -532,18 +485,6 @@ class UDExSecondaryNavigation extends UI5Element {
532
485
  });
533
486
  }
534
487
 
535
- resetTabIndex(): void {
536
- this.domNavItems.forEach((item, index) => {
537
- item._tabIndex = index === 0 ? "0" : "-1";
538
- });
539
- }
540
-
541
- setTabIndexById(id: string): void {
542
- this.domNavItems.forEach(item => {
543
- item._tabIndex = id === item._id ? "0" : "-1";
544
- });
545
- }
546
-
547
488
  get domNavItems(): Array<UDExSecondaryNavigationItem> {
548
489
  const items = this.shadowRoot?.querySelectorAll<UDExSecondaryNavigationItem>("[udex-secondary-navigation-item]");
549
490
  return items ? Array.from(items) : [];
@@ -1,11 +1,10 @@
1
1
  {{#if isLink}}
2
2
  <a
3
3
  class="udex-secondary-navigation__item"
4
- role="{{menuItemRole}}"
4
+ tabindex="0"
5
5
  ?active="{{isActive}}"
6
6
  href="{{path}}"
7
7
  target="{{target}}"
8
- tabindex="{{_tabIndex}}"
9
8
  aria-current="{{ariaCurrent}}"
10
9
  @keydown="{{handleItemLinkKeyDown}}"
11
10
  @click="{{fireNavItemClickEvent}}">
@@ -14,8 +13,7 @@
14
13
  {{else}}
15
14
  <button
16
15
  class="udex-secondary-navigation__item"
17
- role="{{itemRole}}"
18
- tabindex="{{menuOpenerTabIndex}}"
16
+ tabindex="0"
19
17
  ?active="{{isActive}}"
20
18
  aria-haspopup="{{hasNestedItems}}"
21
19
  aria-expanded="{{isOpen}}"
@@ -42,11 +40,11 @@
42
40
  {{#if isOpen}}
43
41
  <div
44
42
  class="udex-secondary-navigation__dropdown">
45
- <ul role="menu"
43
+ <ul
46
44
  class="udex-secondary-navigation__dropdown-list"
47
45
  @keydown="{{handleSubItemKeyDown}}">
48
46
  {{#each _processedItems}}
49
- <li role="none">
47
+ <li>
50
48
  <udex-secondary-navigation-sub-item
51
49
  index="{{@index}}"
52
50
  @ui5-sub-item-click="{{../handleSubItemClick}}"
@@ -5,7 +5,7 @@ import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";
5
5
  import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
6
6
  import UI5Icon from "@ui5/webcomponents/dist/Icon.js";
7
7
  import {
8
- isLeft, isRight, isUp, isDown, isEscape, isSpace, isEnter, isHome, isEnd, isTabNext, isTabPrevious,
8
+ isEscape, isEnter, isSpace, isLeft, isRight, isUp, isDown, isHome, isEnd, isTabNext, isTabPrevious,
9
9
  } from "@ui5/webcomponents-base/dist/Keys.js";
10
10
  import type { RelativeValue } from "./utils/parseRelativeUnits.js";
11
11
  import parseRelativeUnits from "./utils/parseRelativeUnits.js";
@@ -19,8 +19,6 @@ import SecondaryNavigationItemTemplate from "./generated/templates/SecondaryNavi
19
19
  // Styles
20
20
  import SecondaryNavigationItemCss from "./generated/themes/SecondaryNavigationItem.css.js";
21
21
 
22
- export const menuItemRole: string = "menuitem";
23
-
24
22
  type UDExSecondaryNavigationItemClickEventDetail = {
25
23
  item: HTMLElement,
26
24
  index: number,
@@ -30,7 +28,7 @@ type UDExSecondaryNavigationItemClickEventDetail = {
30
28
  type UDExSecondaryNavigationItemSubItemClickEventDetail = {
31
29
  item: NavItem,
32
30
  index: number,
33
- originalEvent: PointerEvent
31
+ originalEvent: PointerEvent | KeyboardEvent
34
32
  }
35
33
 
36
34
  /**
@@ -166,7 +164,6 @@ class UDExSecondaryNavigationItem extends UDExSecondaryNavigationItemBase {
166
164
  _dropdownHistory: Array<Array<NavItem>> = [];
167
165
  _shouldFocusFirstSubItem!: boolean;
168
166
  _subTitle!: string | undefined;
169
- _shouldSetTabIndex!: boolean;
170
167
 
171
168
  onAfterRendering(): void {
172
169
  if (this.isLastItem && this.isOpen && !this._isMobileView) {
@@ -181,11 +178,6 @@ class UDExSecondaryNavigationItem extends UDExSecondaryNavigationItemBase {
181
178
  if (this._isMobileView && this.isOpen) {
182
179
  this.setDropdownHeight();
183
180
  }
184
-
185
- if (this._shouldSetTabIndex) {
186
- this._tabIndex = "0";
187
- this._shouldSetTabIndex = false;
188
- }
189
181
  }
190
182
 
191
183
  onBeforeRendering() : void {
@@ -193,7 +185,7 @@ class UDExSecondaryNavigationItem extends UDExSecondaryNavigationItemBase {
193
185
  }
194
186
 
195
187
  handleSubItemClick(e: CustomEvent | KeyboardEvent): void {
196
- const { originalEvent } = e.detail;
188
+ const originalEvent: PointerEvent | KeyboardEvent = (e instanceof CustomEvent && e.detail?.originalEvent) ? e.detail.originalEvent : e as KeyboardEvent;
197
189
  const { index } = e.target as UDExSecondaryNavigationSubItem;
198
190
  const clickedItem = this._processedItems[index];
199
191
 
@@ -203,7 +195,7 @@ class UDExSecondaryNavigationItem extends UDExSecondaryNavigationItemBase {
203
195
  this.onShouldFocusFirstSubItem();
204
196
  }
205
197
 
206
- this.fireSubItemClickEvent(originalEvent as PointerEvent, clickedItem, index);
198
+ this.fireSubItemClickEvent(originalEvent, clickedItem, index);
207
199
  }
208
200
 
209
201
  onBackClick(): void {
@@ -222,7 +214,6 @@ class UDExSecondaryNavigationItem extends UDExSecondaryNavigationItemBase {
222
214
 
223
215
  closeDropdown(): void {
224
216
  this.isOpen = false;
225
- this._shouldSetTabIndex = true;
226
217
  }
227
218
 
228
219
  handleItemLinkKeyDown(e: KeyboardEvent): void {
@@ -268,10 +259,11 @@ class UDExSecondaryNavigationItem extends UDExSecondaryNavigationItemBase {
268
259
  e.preventDefault();
269
260
  this.handleEnterAndSpace(e);
270
261
  }
271
- if (isTabPrevious(e) && this._isMobileView) {
262
+ const { index } = e.target as UDExSecondaryNavigationSubItem;
263
+ if (isTabNext(e) && index === this.domNavItems.length - 1) {
272
264
  this.closeDropdown();
273
265
  }
274
- if ((isTabPrevious(e) || isTabNext(e)) && !this._isMobileView) {
266
+ if (isTabPrevious(e) && index === 0) {
275
267
  this.closeDropdown();
276
268
  }
277
269
  }
@@ -282,27 +274,40 @@ class UDExSecondaryNavigationItem extends UDExSecondaryNavigationItemBase {
282
274
  }
283
275
  }
284
276
 
277
+ handleEnterAndSpace(e: KeyboardEvent): void {
278
+ const { hasItems, isBack } = e.target as UDExSecondaryNavigationSubItem;
279
+ if (isBack) {
280
+ this.onBackClick();
281
+ this.onShouldFocusFirstSubItem();
282
+ return;
283
+ }
284
+
285
+ this.handleSubItemClick(e);
286
+
287
+ if (hasItems) {
288
+ this.onShouldFocusFirstSubItem();
289
+ } else {
290
+ this.closeDropdown();
291
+ this.focus();
292
+ }
293
+ }
294
+
295
+ handleEscapeKey(): void {
296
+ this.closeDropdown();
297
+ this.focus();
298
+ }
299
+
285
300
  handleUpArrow(e: KeyboardEvent): void {
286
301
  const { index } = e.target as UDExSecondaryNavigationSubItem;
287
302
  const lastIndex = this.domNavItems.length - 1;
288
- const previousSelectIndex = index - 1 < 0 ? lastIndex : index - 1;
289
- const previousItem = this.domNavItems[previousSelectIndex];
290
- const currentItem = this.domNavItems[index];
291
-
292
- this.unsetTabIndex(currentItem);
293
- this.setTabIndex(previousItem);
294
- previousItem.focus();
303
+ const previousIndex = index - 1 < 0 ? lastIndex : index - 1;
304
+ this.domNavItems[previousIndex].focus();
295
305
  }
296
306
 
297
307
  handleDownArrow(e: KeyboardEvent): void {
298
308
  const { index } = e.target as UDExSecondaryNavigationSubItem;
299
309
  const nextIndex = index + 1 > this.domNavItems.length - 1 ? 0 : index + 1;
300
- const nextItem = this.domNavItems[nextIndex];
301
- const currentItem = this.domNavItems[index];
302
-
303
- this.unsetTabIndex(currentItem);
304
- this.setTabIndex(nextItem);
305
- nextItem.focus();
310
+ this.domNavItems[nextIndex].focus();
306
311
  }
307
312
 
308
313
  handleLeftArrow(e: KeyboardEvent): void {
@@ -316,32 +321,15 @@ class UDExSecondaryNavigationItem extends UDExSecondaryNavigationItemBase {
316
321
  handleRightArrow(e: KeyboardEvent): void {
317
322
  const { hasItems, isBack, index } = e.target as UDExSecondaryNavigationSubItem;
318
323
  if (hasItems && !isBack) {
319
- this.handleSubItemClick(e);
320
- this.unsetTabIndex(this.domNavItems[index]);
321
- }
322
- }
323
-
324
- handleEnterAndSpace(e: KeyboardEvent): void {
325
- const { hasItems, isBack } = e.target as UDExSecondaryNavigationSubItem;
326
- if (isBack) {
327
- this.onBackClick();
328
- this.onShouldFocusFirstSubItem();
329
- return;
330
- }
331
-
332
- this.handleSubItemClick(e);
333
-
334
- if (hasItems) {
324
+ const clickedItem = this._processedItems[index];
325
+ this.setDropdownHistory();
326
+ this.setNestedItems(clickedItem);
335
327
  this.onShouldFocusFirstSubItem();
336
- } else {
337
- this.closeDropdown();
338
- this.focus();
339
328
  }
340
329
  }
341
330
 
342
- handleEscapeKey(): void {
343
- this.closeDropdown();
344
- this.focus();
331
+ onLastSubItemFocus(): void {
332
+ this.domNavItems[this.domNavItems.length - 1].focus();
345
333
  }
346
334
 
347
335
  fireNavItemClickEvent(e: PointerEvent | KeyboardEvent): void {
@@ -352,7 +340,7 @@ class UDExSecondaryNavigationItem extends UDExSecondaryNavigationItemBase {
352
340
  });
353
341
  }
354
342
 
355
- fireSubItemClickEvent(e: PointerEvent, clickedItem: NavItem, index: number): void {
343
+ fireSubItemClickEvent(e: PointerEvent | KeyboardEvent, clickedItem: NavItem, index: number): void {
356
344
  this.fireDecoratorEvent("sub-item-click", {
357
345
  item: clickedItem,
358
346
  index,
@@ -411,23 +399,8 @@ class UDExSecondaryNavigationItem extends UDExSecondaryNavigationItemBase {
411
399
  }
412
400
  }
413
401
 
414
- setTabIndex(item: UDExSecondaryNavigationSubItem): void {
415
- item._tabIndex = "0";
416
- }
417
-
418
- unsetTabIndex(item: UDExSecondaryNavigationSubItem): void {
419
- item._tabIndex = "-1";
420
- }
421
-
422
402
  onFirstSubItemFocus(): void {
423
- const firstSubItem = this.domNavItems[0];
424
-
425
- firstSubItem.focus();
426
- this.setTabIndex(firstSubItem);
427
- }
428
-
429
- onLastSubItemFocus(): void {
430
- this.domNavItems[this.domNavItems.length - 1].focus();
403
+ this.domNavItems[0]?.focus();
431
404
  }
432
405
 
433
406
  onShouldFocusFirstSubItem(): void {
@@ -438,14 +411,6 @@ class UDExSecondaryNavigationItem extends UDExSecondaryNavigationItemBase {
438
411
  return this.shadowRoot!.querySelector<HTMLElement>(".udex-secondary-navigation__dropdown")!;
439
412
  }
440
413
 
441
- get menuOpenerTabIndex(): string {
442
- if (this._isMobileMenuOpener) {
443
- return "0";
444
- }
445
-
446
- return this._tabIndex;
447
- }
448
-
449
414
  get isLastItem(): boolean {
450
415
  return this._navItemsLength === this.index;
451
416
  }
@@ -482,14 +447,6 @@ class UDExSecondaryNavigationItem extends UDExSecondaryNavigationItemBase {
482
447
  return !this.hasNestedItems && !!this.path;
483
448
  }
484
449
 
485
- get itemRole(): string {
486
- return this.role ? this.role : this.menuItemRole;
487
- }
488
-
489
- get menuItemRole(): string {
490
- return menuItemRole;
491
- }
492
-
493
450
  get title(): string {
494
451
  return this.label;
495
452
  }
@@ -93,9 +93,6 @@ class UDExSecondaryNavigationItemBase extends UI5Element {
93
93
  @property({ type: Boolean })
94
94
  _isMobileView!: boolean;
95
95
 
96
- @property({ type: String })
97
- _tabIndex: string = "-1";
98
-
99
96
  _handleResizeBound: ResizeObserverCallback;
100
97
 
101
98
  constructor() {
@@ -1,10 +1,8 @@
1
1
  {{#if isBack}}
2
2
  <button
3
- tabindex="{{_tabIndex}}"
4
3
  @click="{{onBackItemClick}}"
5
- role="menuitem"
6
4
  aria-label="{{backButtonAriaLabel}}"
7
- aria-haspopup="true"
5
+ tabindex="0"
8
6
  is-back
9
7
  class="udex-secondary-navigation__dropdown-item">
10
8
  <ui5-icon
@@ -17,13 +15,12 @@
17
15
  {{else}}
18
16
  {{#if isButton}}
19
17
  <button
20
- tabindex="{{_tabIndex}}"
21
18
  @click="{{onItemClick}}"
22
- role="menuitem"
23
19
  aria-haspopup="{{hasItems}}"
24
20
  ?sub-active="{{isSubItemActive}}"
25
21
  aria-label="{{label}}"
26
22
  ?active="{{active}}"
23
+ tabindex="0"
27
24
  aria-current="{{ariaCurrent}}"
28
25
  class="udex-secondary-navigation__dropdown-item">
29
26
  {{itemLabel}}
@@ -37,12 +34,11 @@
37
34
  </button>
38
35
  {{else}}
39
36
  <a
40
- tabindex="{{_tabIndex}}"
41
37
  @click="{{onItemClick}}"
42
- role="menuitem"
43
38
  href="{{path}}"
44
39
  target="{{target}}"
45
40
  ?active="{{active}}"
41
+ tabindex="0"
46
42
  aria-current="{{ariaCurrent}}"
47
43
  class="udex-secondary-navigation__dropdown-item">
48
44
  {{itemLabel}}