@sapudex/web-components 2.25.1 → 2.26.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.
- package/cypress/fixtures/profile-menu.ts +2 -1
- package/cypress/specs/MastheadProfileMenu.cy.tsx +21 -6
- package/dist/List.d.ts +9 -0
- package/dist/List.js +33 -2
- package/dist/List.js.map +1 -1
- package/dist/MastheadCountrySelector.d.ts +11 -0
- package/dist/MastheadCountrySelector.js +71 -14
- package/dist/MastheadCountrySelector.js.map +1 -1
- package/dist/MastheadItem.d.ts +1 -0
- package/dist/MastheadItem.js +9 -1
- package/dist/MastheadItem.js.map +1 -1
- package/dist/MastheadMenu.d.ts +11 -0
- package/dist/MastheadMenu.js +43 -13
- package/dist/MastheadMenu.js.map +1 -1
- package/dist/MastheadProfileMenu.d.ts +33 -3
- package/dist/MastheadProfileMenu.js +93 -5
- package/dist/MastheadProfileMenu.js.map +1 -1
- package/dist/Pagination.d.ts +2 -0
- package/dist/Pagination.js +31 -6
- package/dist/Pagination.js.map +1 -1
- package/dist/PaginationTemplate.js +6 -5
- package/dist/PaginationTemplate.js.map +1 -1
- package/dist/Tooltip.js +3 -5
- package/dist/Tooltip.js.map +1 -1
- package/dist/TooltipTemplate.d.ts +2 -0
- package/dist/TooltipTemplate.js +7 -0
- package/dist/TooltipTemplate.js.map +1 -0
- package/dist/assets/{InputSuggestions-CTFZ6hH-.js → InputSuggestions-CG5owMFQ.js} +1 -1
- package/dist/assets/{ListItemStandardExpandableTextTemplate-wXdCijez.js → ListItemStandardExpandableTextTemplate-DpVr7qdn.js} +1 -1
- package/dist/assets/{bundle.esm-BXCZ9BP3.js → bundle.esm-CTkLMr6f.js} +185 -185
- package/dist/css/themes/MastheadCountrySelector.css +1 -1
- package/dist/css/themes/MastheadItem.css +1 -1
- package/dist/css/themes/MastheadMenu.css +1 -1
- package/dist/css/themes/MastheadMenuItem.css +1 -1
- package/dist/css/themes/MastheadProfileMenu.css +1 -1
- package/dist/css/themes/Quote.css +1 -1
- package/dist/css/themes/RatingIndicator.css +1 -1
- package/dist/css/themes/Slider.css +1 -1
- package/dist/custom-elements-internal.json +163 -155
- package/dist/custom-elements.json +144 -140
- package/dist/generated/templates/MastheadCountrySelectorTemplate.lit.js +1 -1
- package/dist/generated/templates/MastheadCountrySelectorTemplate.lit.js.map +1 -1
- package/dist/generated/templates/MastheadProfileMenuTemplate.lit.js +7 -5
- package/dist/generated/templates/MastheadProfileMenuTemplate.lit.js.map +1 -1
- package/dist/generated/themes/MastheadCountrySelector.css.d.ts +1 -1
- package/dist/generated/themes/MastheadCountrySelector.css.js +1 -1
- package/dist/generated/themes/MastheadCountrySelector.css.js.map +1 -1
- package/dist/generated/themes/MastheadItem.css.d.ts +1 -1
- package/dist/generated/themes/MastheadItem.css.js +1 -1
- package/dist/generated/themes/MastheadItem.css.js.map +1 -1
- package/dist/generated/themes/MastheadMenu.css.d.ts +1 -1
- package/dist/generated/themes/MastheadMenu.css.js +1 -1
- package/dist/generated/themes/MastheadMenu.css.js.map +1 -1
- package/dist/generated/themes/MastheadMenuItem.css.d.ts +1 -1
- package/dist/generated/themes/MastheadMenuItem.css.js +1 -1
- package/dist/generated/themes/MastheadMenuItem.css.js.map +1 -1
- package/dist/generated/themes/MastheadProfileMenu.css.d.ts +1 -1
- package/dist/generated/themes/MastheadProfileMenu.css.js +1 -1
- package/dist/generated/themes/MastheadProfileMenu.css.js.map +1 -1
- package/dist/generated/themes/Quote.css.d.ts +1 -1
- package/dist/generated/themes/Quote.css.js +1 -1
- package/dist/generated/themes/Quote.css.js.map +1 -1
- package/dist/generated/themes/RatingIndicator.css.d.ts +1 -1
- package/dist/generated/themes/RatingIndicator.css.js +1 -1
- package/dist/generated/themes/RatingIndicator.css.js.map +1 -1
- package/dist/generated/themes/Slider.css.d.ts +1 -1
- package/dist/generated/themes/Slider.css.js +1 -1
- package/dist/generated/themes/Slider.css.js.map +1 -1
- package/dist/types/List.d.ts +6 -0
- package/dist/types/List.js +7 -0
- package/dist/types/List.js.map +1 -1
- package/dist/vscode.html-custom-data.json +1 -1
- package/dist/web-types.json +4 -6
- package/package.json +1 -1
- package/src/List.ts +41 -2
- package/src/MastheadCountrySelector.hbs +20 -16
- package/src/MastheadCountrySelector.ts +83 -16
- package/src/MastheadItem.ts +10 -1
- package/src/MastheadMenu.ts +56 -13
- package/src/MastheadProfileMenu.hbs +43 -26
- package/src/MastheadProfileMenu.ts +124 -7
- package/src/Pagination.ts +32 -6
- package/src/PaginationTemplate.tsx +19 -16
- package/src/Tooltip.ts +7 -6
- package/src/TooltipTemplate.tsx +29 -0
- package/src/generated/templates/MastheadCountrySelectorTemplate.lit.ts +1 -1
- package/src/generated/templates/MastheadProfileMenuTemplate.lit.ts +7 -5
- package/src/generated/themes/MastheadCountrySelector.css.ts +1 -1
- package/src/generated/themes/MastheadItem.css.ts +1 -1
- package/src/generated/themes/MastheadMenu.css.ts +1 -1
- package/src/generated/themes/MastheadMenuItem.css.ts +1 -1
- package/src/generated/themes/MastheadProfileMenu.css.ts +1 -1
- package/src/generated/themes/Quote.css.ts +1 -1
- package/src/generated/themes/RatingIndicator.css.ts +1 -1
- package/src/generated/themes/Slider.css.ts +1 -1
- package/src/themes/MastheadCountrySelector.css +70 -10
- package/src/themes/MastheadItem.css +0 -1
- package/src/themes/MastheadMenu.css +1 -2
- package/src/themes/MastheadMenuItem.css +1 -0
- package/src/themes/MastheadProfileMenu.css +113 -17
- package/src/themes/Quote.css +1 -1
- package/src/types/List.ts +7 -0
- package/cypress/downloads/downloads.html +0 -0
- package/dist/generated/templates/TooltipTemplate.lit.d.ts +0 -3
- package/dist/generated/templates/TooltipTemplate.lit.js +0 -8
- package/dist/generated/templates/TooltipTemplate.lit.js.map +0 -1
- package/src/Tooltip.hbs +0 -22
- package/src/generated/templates/TooltipTemplate.lit.ts +0 -12
package/src/List.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
isUp, isDown, isHome, isEnd,
|
|
9
9
|
} from "@ui5/webcomponents-base/dist/Keys.js";
|
|
10
10
|
import type UDExListItem from "./ListItem.js";
|
|
11
|
+
import type { UDExScrollIntoViewOptions } from "./types/List.js";
|
|
11
12
|
import { UDExListStyleType, UDExListMode } from "./types/List.js";
|
|
12
13
|
import type UDExListGroupHeader from "./ListGroupHeader.js";
|
|
13
14
|
import type UDExListGroupHeaderBase from "./ListGroupHeaderBase.js";
|
|
@@ -162,6 +163,15 @@ class UDExList extends UI5Element {
|
|
|
162
163
|
@slot({ type: HTMLElement, "default": true })
|
|
163
164
|
items!: Array<UDExListItemBase>;
|
|
164
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Defines the scroll behavior for the items of the component.
|
|
168
|
+
*
|
|
169
|
+
* @default undefined
|
|
170
|
+
* @private
|
|
171
|
+
*/
|
|
172
|
+
@property()
|
|
173
|
+
_scrollIntoView?: `${UDExScrollIntoViewOptions}`;
|
|
174
|
+
|
|
165
175
|
_focusHandler: UDExListWithFirstLetterFocus = new UDExFirstLetterFocusHandler();
|
|
166
176
|
|
|
167
177
|
@i18n("@sapudex/web-components")
|
|
@@ -211,6 +221,9 @@ class UDExList extends UI5Element {
|
|
|
211
221
|
if (nonInteractiveHeader && previousSelectIndex === 0) {
|
|
212
222
|
this.unsetTabIndexByIndex(items, currentSelectedIndex);
|
|
213
223
|
this.setTabIndexByIndex(items, lastItemIndex);
|
|
224
|
+
if (this._scrollIntoView) {
|
|
225
|
+
this.scrollToItem(items[lastItemIndex]);
|
|
226
|
+
}
|
|
214
227
|
items[lastItemIndex].focus();
|
|
215
228
|
return;
|
|
216
229
|
}
|
|
@@ -218,6 +231,9 @@ class UDExList extends UI5Element {
|
|
|
218
231
|
if (nonInteractiveHeader) {
|
|
219
232
|
this.unsetTabIndexByIndex(items, currentSelectedIndex);
|
|
220
233
|
this.setTabIndexByIndex(items, previousSelectIndex - 1);
|
|
234
|
+
if (this._scrollIntoView) {
|
|
235
|
+
this.scrollToItem(items[previousSelectIndex - 1]);
|
|
236
|
+
}
|
|
221
237
|
items[previousSelectIndex - 1].focus();
|
|
222
238
|
return;
|
|
223
239
|
}
|
|
@@ -225,6 +241,9 @@ class UDExList extends UI5Element {
|
|
|
225
241
|
if (isHeaderItem) {
|
|
226
242
|
this.unsetTabIndexByIndex(items, currentSelectedIndex);
|
|
227
243
|
this.setTabIndexByIndex(items, previousSelectIndex);
|
|
244
|
+
if (this._scrollIntoView) {
|
|
245
|
+
this.scrollToItem(items[previousSelectIndex]);
|
|
246
|
+
}
|
|
228
247
|
this.focusHeader(items[previousSelectIndex]);
|
|
229
248
|
return;
|
|
230
249
|
}
|
|
@@ -236,7 +255,12 @@ class UDExList extends UI5Element {
|
|
|
236
255
|
|
|
237
256
|
this.unsetTabIndexByIndex(items, currentSelectedIndex);
|
|
238
257
|
this.setTabIndexByIndex(items, previousSelectIndex);
|
|
239
|
-
setTimeout(() => {
|
|
258
|
+
setTimeout(() => {
|
|
259
|
+
if (this._scrollIntoView) {
|
|
260
|
+
this.scrollToItem(items[previousSelectIndex]);
|
|
261
|
+
}
|
|
262
|
+
items[previousSelectIndex].focus();
|
|
263
|
+
}, 0);
|
|
240
264
|
}
|
|
241
265
|
|
|
242
266
|
handleDownArrow(e: KeyboardEvent): void {
|
|
@@ -250,6 +274,9 @@ class UDExList extends UI5Element {
|
|
|
250
274
|
if (nonInteractiveHeader) {
|
|
251
275
|
this.unsetTabIndexByIndex(items, currentSelectedIndex);
|
|
252
276
|
this.setTabIndexByIndex(items, nextSelectIndex + 1);
|
|
277
|
+
if (this._scrollIntoView) {
|
|
278
|
+
this.scrollToItem(items[nextSelectIndex + 1]);
|
|
279
|
+
}
|
|
253
280
|
items[nextSelectIndex + 1].focus();
|
|
254
281
|
return;
|
|
255
282
|
}
|
|
@@ -257,6 +284,9 @@ class UDExList extends UI5Element {
|
|
|
257
284
|
if (isHeaderItem) {
|
|
258
285
|
this.unsetTabIndexByIndex(items, currentSelectedIndex);
|
|
259
286
|
this.setTabIndexByIndex(items, nextSelectIndex);
|
|
287
|
+
if (this._scrollIntoView) {
|
|
288
|
+
this.scrollToItem(items[nextSelectIndex]);
|
|
289
|
+
}
|
|
260
290
|
this.focusHeader(items[nextSelectIndex]);
|
|
261
291
|
return;
|
|
262
292
|
}
|
|
@@ -268,7 +298,12 @@ class UDExList extends UI5Element {
|
|
|
268
298
|
|
|
269
299
|
this.unsetTabIndexByIndex(items, currentSelectedIndex);
|
|
270
300
|
this.setTabIndexByIndex(items, nextSelectIndex);
|
|
271
|
-
setTimeout(() => {
|
|
301
|
+
setTimeout(() => {
|
|
302
|
+
if (this._scrollIntoView) {
|
|
303
|
+
this.scrollToItem(items[nextSelectIndex]);
|
|
304
|
+
}
|
|
305
|
+
items[nextSelectIndex].focus();
|
|
306
|
+
}, 0);
|
|
272
307
|
}
|
|
273
308
|
|
|
274
309
|
handleHomeKey(e: KeyboardEvent): void {
|
|
@@ -370,6 +405,10 @@ class UDExList extends UI5Element {
|
|
|
370
405
|
header.focus();
|
|
371
406
|
}
|
|
372
407
|
|
|
408
|
+
scrollToItem(item: UDExListItemBase): void {
|
|
409
|
+
item.scrollIntoView({ block: this._scrollIntoView?.toLowerCase() as ScrollLogicalPosition });
|
|
410
|
+
}
|
|
411
|
+
|
|
373
412
|
unsetTabIndexByIndex(items: UDExListItemBase[], index: number): void {
|
|
374
413
|
items[index]._tabIndex = "-1";
|
|
375
414
|
}
|
|
@@ -25,22 +25,26 @@
|
|
|
25
25
|
show-submit-button>
|
|
26
26
|
</udex-search>
|
|
27
27
|
<span aria-live="polite" aria-atomic="true" class="hidden">{{_accSearchResultInfo}}</span>
|
|
28
|
-
<
|
|
29
|
-
{{
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
28
|
+
<div class="udex-masthead-country-selector__list-container">
|
|
29
|
+
<div class="udex-masthead-country-selector__list-wrap" @scroll={{this.handleCountryListShadowVisible}}>
|
|
30
|
+
<ul class="udex-masthead-country-selector__list udex-masthead-country-selector__list_countries" role="menu">
|
|
31
|
+
{{#each _activeCountries}}
|
|
32
|
+
<li role="none">
|
|
33
|
+
<udex-masthead-menu-item
|
|
34
|
+
class="udex-masthead-country-selector__item udex-masthead-country-selector__item_countries"
|
|
35
|
+
@click="{{../handleCountryClick}}"
|
|
36
|
+
_country-code="{{this.countryCode}}"
|
|
37
|
+
url="{{this.url}}"
|
|
38
|
+
label="{{this.displayTitle}}"
|
|
39
|
+
index="{{@index}}"
|
|
40
|
+
part="menu-item"
|
|
41
|
+
is-nav-item>
|
|
42
|
+
</udex-masthead-menu-item>
|
|
43
|
+
</li>
|
|
44
|
+
{{/each}}
|
|
45
|
+
</ul>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
44
48
|
{{else}}
|
|
45
49
|
<span class="udex-masthead-country-selector__title">{{regionTitle}}</span>
|
|
46
50
|
<ul class="udex-masthead-country-selector__list" role="menu">
|
|
@@ -215,6 +215,8 @@ class UDExMastheadCountrySelector extends UI5Element {
|
|
|
215
215
|
_accSearchResultInfo?: string;
|
|
216
216
|
_activeRegionIndex!: number;
|
|
217
217
|
_mastheadShell!: UDExMastheadShell;
|
|
218
|
+
_countriesListHolderClassName = "udex-masthead-country-selector__list-wrap";
|
|
219
|
+
_itemClassName = "udex-masthead-country-selector__item";
|
|
218
220
|
|
|
219
221
|
@i18n("@sapudex/web-components")
|
|
220
222
|
static i18nBundle: I18nBundle;
|
|
@@ -234,6 +236,10 @@ class UDExMastheadCountrySelector extends UI5Element {
|
|
|
234
236
|
if (this.isSingleMode) {
|
|
235
237
|
this.handleSingleRegionMode();
|
|
236
238
|
}
|
|
239
|
+
|
|
240
|
+
if (this._activeCountries) {
|
|
241
|
+
this.checkScrollableCountriesList();
|
|
242
|
+
}
|
|
237
243
|
}
|
|
238
244
|
|
|
239
245
|
onEnterDOM(): void {
|
|
@@ -397,10 +403,10 @@ class UDExMastheadCountrySelector extends UI5Element {
|
|
|
397
403
|
const lastItemIndex = this.items.length - 1;
|
|
398
404
|
const prevIndex = currentIndex - 1 < 0 ? lastItemIndex : currentIndex - 1;
|
|
399
405
|
const prevItem = this.items[prevIndex];
|
|
400
|
-
|
|
401
406
|
this.items[currentIndex]._tabIndex = "-1";
|
|
402
407
|
prevItem._tabIndex = "0";
|
|
403
|
-
prevItem.
|
|
408
|
+
prevItem.scrollIntoView({ block: "center" });
|
|
409
|
+
prevItem.focus({ preventScroll: true });
|
|
404
410
|
}
|
|
405
411
|
|
|
406
412
|
focusNextItem(e: KeyboardEvent): void {
|
|
@@ -408,34 +414,53 @@ class UDExMastheadCountrySelector extends UI5Element {
|
|
|
408
414
|
const lastItemIndex = this.items.length - 1;
|
|
409
415
|
const nextIndex = currentIndex + 1 > lastItemIndex ? 0 : currentIndex + 1;
|
|
410
416
|
const nextItem = this.items[nextIndex];
|
|
411
|
-
|
|
412
417
|
this.items[currentIndex]._tabIndex = "-1";
|
|
413
418
|
nextItem._tabIndex = "0";
|
|
414
|
-
nextItem.
|
|
419
|
+
nextItem.scrollIntoView({ block: "center" });
|
|
420
|
+
nextItem.focus({ preventScroll: true });
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
focusLastItem(e: KeyboardEvent): void {
|
|
424
|
+
const currentIndex = (e.target as UDExMastheadMenuItem).index;
|
|
425
|
+
const lastItemIndex = this.items.length - 1;
|
|
426
|
+
const lastItem = this.items[lastItemIndex];
|
|
427
|
+
|
|
428
|
+
this.items[currentIndex]._tabIndex = "-1";
|
|
429
|
+
lastItem._tabIndex = "0";
|
|
430
|
+
lastItem.scrollIntoView({ block: "end" });
|
|
431
|
+
lastItem.focus({ preventScroll: true });
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
focusFirstItem(e: KeyboardEvent): void {
|
|
435
|
+
const currentIndex = (e.target as UDExMastheadMenuItem).index;
|
|
436
|
+
const firstItem = this.items[0];
|
|
437
|
+
|
|
438
|
+
this.items[currentIndex]._tabIndex = "-1";
|
|
439
|
+
firstItem._tabIndex = "0";
|
|
440
|
+
firstItem.focus();
|
|
415
441
|
}
|
|
416
442
|
|
|
417
443
|
handleEndKey(e: KeyboardEvent): void {
|
|
418
444
|
if (isEnd(e)) {
|
|
419
445
|
e.preventDefault();
|
|
420
|
-
const currentIndex = (e.target as UDExMastheadMenuItem).index;
|
|
421
|
-
const lastItemIndex = this.items.length - 1;
|
|
422
|
-
const lastItem = this.items[lastItemIndex];
|
|
423
446
|
|
|
424
|
-
this.
|
|
425
|
-
|
|
426
|
-
|
|
447
|
+
if (this.isScrollableCountriesList) {
|
|
448
|
+
this.removeScrollableClassInCountryList();
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
this.focusLastItem(e);
|
|
427
452
|
}
|
|
428
453
|
}
|
|
429
454
|
|
|
430
455
|
handleHomeKey(e: KeyboardEvent): void {
|
|
431
456
|
if (isHome(e)) {
|
|
432
457
|
e.preventDefault();
|
|
433
|
-
const currentIndex = (e.target as UDExMastheadMenuItem).index;
|
|
434
|
-
const firstItem = this.items[0];
|
|
435
458
|
|
|
436
|
-
this.
|
|
437
|
-
|
|
438
|
-
|
|
459
|
+
if (this.isScrollableCountriesList) {
|
|
460
|
+
this.addScrollableClassToCountryList();
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
this.focusFirstItem(e);
|
|
439
464
|
}
|
|
440
465
|
}
|
|
441
466
|
|
|
@@ -509,6 +534,48 @@ class UDExMastheadCountrySelector extends UI5Element {
|
|
|
509
534
|
this._mastheadShell.mobileBtn?.focus();
|
|
510
535
|
}
|
|
511
536
|
|
|
537
|
+
checkScrollableCountriesList(): void {
|
|
538
|
+
if (this.countryListHolder) {
|
|
539
|
+
requestAnimationFrame(() => {
|
|
540
|
+
if (this.isScrollableCountriesList) {
|
|
541
|
+
this.addScrollableClassToCountryList();
|
|
542
|
+
} else {
|
|
543
|
+
this.removeScrollableClassInCountryList();
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
handleCountryListShadowVisible(): void {
|
|
550
|
+
if (this.scrollBottomCountriesList === 0) {
|
|
551
|
+
this.removeScrollableClassInCountryList();
|
|
552
|
+
} else {
|
|
553
|
+
this.addScrollableClassToCountryList();
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
addScrollableClassToCountryList(): void {
|
|
558
|
+
this.countryListHolder.classList.add(`${this._countriesListHolderClassName}_scrollable`);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
removeScrollableClassInCountryList(): void {
|
|
562
|
+
this.countryListHolder.classList.remove(`${this._countriesListHolderClassName}_scrollable`);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
get scrollBottomCountriesList(): number {
|
|
566
|
+
const countriesList = this.countryListHolder;
|
|
567
|
+
return countriesList.scrollHeight - countriesList.scrollTop - countriesList.clientHeight;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
get isScrollableCountriesList(): boolean {
|
|
571
|
+
const countriesList = this.countryListHolder;
|
|
572
|
+
return countriesList ? countriesList.scrollHeight > countriesList.clientHeight : false;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
get countryListHolder(): HTMLElement {
|
|
576
|
+
return this.shadowRoot?.querySelector<HTMLElement>(`.${this._countriesListHolderClassName}`) as HTMLElement;
|
|
577
|
+
}
|
|
578
|
+
|
|
512
579
|
get noMatchesFoundText(): string {
|
|
513
580
|
return translate(UDExMastheadCountrySelector, NO_MATCHES_FOUND);
|
|
514
581
|
}
|
|
@@ -518,7 +585,7 @@ class UDExMastheadCountrySelector extends UI5Element {
|
|
|
518
585
|
}
|
|
519
586
|
|
|
520
587
|
get items(): Array<UDExMastheadMenuItem> {
|
|
521
|
-
const items = this.shadowRoot?.querySelectorAll<UDExMastheadMenuItem>(
|
|
588
|
+
const items = this.shadowRoot?.querySelectorAll<UDExMastheadMenuItem>(`.${this._itemClassName}`);
|
|
522
589
|
return items ? Array.from(items) : [];
|
|
523
590
|
}
|
|
524
591
|
|
package/src/MastheadItem.ts
CHANGED
|
@@ -412,7 +412,7 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
|
|
|
412
412
|
|
|
413
413
|
handleItemClick(e: PointerEvent): void {
|
|
414
414
|
if (this.isProfileBtn) {
|
|
415
|
-
this.
|
|
415
|
+
this.handleProfileButtonClick();
|
|
416
416
|
}
|
|
417
417
|
this.handleSelectedChange();
|
|
418
418
|
this.fireItemClickEvent(e);
|
|
@@ -423,6 +423,15 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
|
|
|
423
423
|
this.selected = this.isMobile ? true : !this.selected;
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
+
handleProfileButtonClick(): void {
|
|
427
|
+
const profile = this.profileSlot;
|
|
428
|
+
if (profile) {
|
|
429
|
+
profile.closeIdentitiesPanel();
|
|
430
|
+
profile.scrollToTopProfileMenu();
|
|
431
|
+
profile._requestRender = true;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
426
435
|
fireDropdownEvents(): void {
|
|
427
436
|
if (this.hasDropdownSlot) {
|
|
428
437
|
const { Open, Close } = UDExMastheadDropdownItemAction;
|
package/src/MastheadMenu.ts
CHANGED
|
@@ -8,7 +8,9 @@ import Icon from "@ui5/webcomponents/dist/Icon.js";
|
|
|
8
8
|
import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";
|
|
9
9
|
import "@ui5/webcomponents-icons/dist/slim-arrow-right.js";
|
|
10
10
|
import "@ui5/webcomponents-icons/dist/action.js";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
isUp, isDown, isTabNext, isTabPrevious, isHome, isEnd,
|
|
13
|
+
} from "@ui5/webcomponents-base/dist/Keys.js";
|
|
12
14
|
import UDExBadge from "./Badge.js";
|
|
13
15
|
import UDExMastheadMenuItem, { UDExItemType } from "./MastheadMenuItem.js";
|
|
14
16
|
import type UDExMastheadItem from "./MastheadItem.js";
|
|
@@ -17,6 +19,7 @@ import MastheadMenuTemplate from "./generated/templates/MastheadMenuTemplate.lit
|
|
|
17
19
|
import parseArrayFromString from "./utils/parseArrayFromString.js";
|
|
18
20
|
import AnalyticsName from "./types/AnalyticsName.js";
|
|
19
21
|
import { OVERVIEW } from "./generated/i18n/i18n-defaults.js";
|
|
22
|
+
import type { UDExScrollIntoViewOptions } from "./types/List.js";
|
|
20
23
|
import translate from "./utils/translate.js";
|
|
21
24
|
|
|
22
25
|
// Styles
|
|
@@ -120,28 +123,58 @@ class UDExMastheadMenu extends UI5Element {
|
|
|
120
123
|
@property({ type: Boolean })
|
|
121
124
|
_isMobileMode!: boolean;
|
|
122
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Defines the scroll behavior for the items of the component.
|
|
128
|
+
*
|
|
129
|
+
* @default undefined
|
|
130
|
+
* @private
|
|
131
|
+
*/
|
|
132
|
+
@property()
|
|
133
|
+
_scrollIntoView?: `${UDExScrollIntoViewOptions}`;
|
|
134
|
+
|
|
123
135
|
@i18n("@sapudex/web-components")
|
|
124
136
|
static i18nBundle: I18nBundle;
|
|
125
137
|
|
|
126
138
|
handleKeyDown(e: KeyboardEvent): void {
|
|
127
|
-
this.
|
|
128
|
-
this.
|
|
139
|
+
const isFirstItem = e.target === this.links[0];
|
|
140
|
+
const isLastItem = e.target === this.links[this.links.length - 1];
|
|
141
|
+
|
|
142
|
+
if (isUp(e) || (isTabPrevious(e) && !isFirstItem)) {
|
|
143
|
+
this.handleUpArrow(e);
|
|
144
|
+
}
|
|
145
|
+
if (isDown(e) || (isTabNext(e) && !isLastItem)) {
|
|
146
|
+
this.handleDownArrow(e);
|
|
147
|
+
}
|
|
148
|
+
if (isHome(e)) {
|
|
149
|
+
this.handleHomeKey(e);
|
|
150
|
+
}
|
|
151
|
+
if (isEnd(e)) {
|
|
152
|
+
this.handleEndKey(e);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
handleHomeKey(e: KeyboardEvent): void {
|
|
157
|
+
e.preventDefault();
|
|
158
|
+
const firstItem = this.links[0];
|
|
159
|
+
firstItem.focus();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
handleEndKey(e: KeyboardEvent): void {
|
|
163
|
+
e.preventDefault();
|
|
164
|
+
const lastItem = this.links[this.links.length - 1];
|
|
165
|
+
lastItem.focus();
|
|
129
166
|
}
|
|
130
167
|
|
|
131
168
|
handleUpArrow(e: KeyboardEvent): void {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
this.focusPreviousItem(currentItem);
|
|
136
|
-
}
|
|
169
|
+
e.preventDefault();
|
|
170
|
+
const currentItem = e.target as UDExMastheadMenuItem;
|
|
171
|
+
this.focusPreviousItem(currentItem);
|
|
137
172
|
}
|
|
138
173
|
|
|
139
174
|
handleDownArrow(e: KeyboardEvent): void {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
this.focusNextItem(currentItem);
|
|
144
|
-
}
|
|
175
|
+
e.preventDefault();
|
|
176
|
+
const currentItem = e.target as UDExMastheadMenuItem;
|
|
177
|
+
this.focusNextItem(currentItem);
|
|
145
178
|
}
|
|
146
179
|
|
|
147
180
|
handleMenuItemClick(e: PointerEvent): void {
|
|
@@ -171,12 +204,18 @@ class UDExMastheadMenu extends UI5Element {
|
|
|
171
204
|
const currentSelectedIndex = this.getCurrentIndex(item);
|
|
172
205
|
const lastItemIndex = this.links.length - 1;
|
|
173
206
|
const previousSelectIndex = currentSelectedIndex - 1 < 0 ? lastItemIndex : currentSelectedIndex - 1;
|
|
207
|
+
if (this._scrollIntoView) {
|
|
208
|
+
this.scrollToItem(this.links[previousSelectIndex]);
|
|
209
|
+
}
|
|
174
210
|
this.links[previousSelectIndex].focus();
|
|
175
211
|
}
|
|
176
212
|
|
|
177
213
|
focusNextItem(item: UDExMastheadMenuItem): void {
|
|
178
214
|
const currentSelectedIndex = this.getCurrentIndex(item);
|
|
179
215
|
const nextSelectIndex = currentSelectedIndex + 1 > this.links.length - 1 ? 0 : currentSelectedIndex + 1;
|
|
216
|
+
if (this._scrollIntoView) {
|
|
217
|
+
this.scrollToItem(this.links[nextSelectIndex]);
|
|
218
|
+
}
|
|
180
219
|
this.links[nextSelectIndex].focus();
|
|
181
220
|
}
|
|
182
221
|
|
|
@@ -184,6 +223,10 @@ class UDExMastheadMenu extends UI5Element {
|
|
|
184
223
|
return this.links.indexOf(item);
|
|
185
224
|
}
|
|
186
225
|
|
|
226
|
+
scrollToItem(item: UDExMastheadMenuItem): void {
|
|
227
|
+
item.scrollIntoView({ block: this._scrollIntoView?.toLowerCase() as ScrollLogicalPosition });
|
|
228
|
+
}
|
|
229
|
+
|
|
187
230
|
get links(): Array<UDExMastheadMenuItem> {
|
|
188
231
|
const menuItems: Array<UDExMastheadMenuItem> = Array.from(this.shadowRoot!.querySelectorAll("[udex-masthead-menu-item]"));
|
|
189
232
|
return menuItems.filter(({ url }) => url && url.length > 0);
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
<udex-avatar
|
|
15
15
|
aria-hidden="true"
|
|
16
16
|
size="L"
|
|
17
|
-
initials="{{userData.avatarInitials}}"
|
|
17
|
+
initials="{{userData.avatarInitials}}"
|
|
18
|
+
fallback-icon="{{userData.fallbackIcon}}">
|
|
18
19
|
{{#if userData.avatarUrl}}
|
|
19
20
|
<img src="{{userData.avatarUrl}}" alt="avatar"/>
|
|
20
21
|
{{/if}}
|
|
@@ -40,25 +41,39 @@
|
|
|
40
41
|
<slot name="message"></slot>
|
|
41
42
|
</div>
|
|
42
43
|
{{/if}}
|
|
43
|
-
<div class="udex-masthead-profile-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
label="{{logoutText}}"
|
|
55
|
-
url="{{logoutUrl}}">
|
|
56
|
-
</udex-masthead-menu-item>
|
|
44
|
+
<div class="udex-masthead-profile-menu__content">
|
|
45
|
+
<div
|
|
46
|
+
class="udex-masthead-profile-menu__links"
|
|
47
|
+
@scroll="{{handleProfileMenuShadowVisible}}">
|
|
48
|
+
<udex-masthead-menu
|
|
49
|
+
exportparts="badge, menu-item"
|
|
50
|
+
part="menu"
|
|
51
|
+
sub-items='{{linksList}}'
|
|
52
|
+
@ui5-menu-item-click="{{handleProfileMenuItemClick}}"
|
|
53
|
+
_scroll-into-view="Center">
|
|
54
|
+
</udex-masthead-menu>
|
|
57
55
|
</div>
|
|
58
|
-
{{/if}}
|
|
59
56
|
</div>
|
|
57
|
+
{{#if hasActionButton}}
|
|
58
|
+
<div class="udex-masthead-profile-menu__actions">
|
|
59
|
+
{{#if hasLogoutButton}}
|
|
60
|
+
<div class="udex-masthead-profile-menu__btn">
|
|
61
|
+
<slot name="logoutButton"></slot>
|
|
62
|
+
</div>
|
|
63
|
+
{{else}}
|
|
64
|
+
<udex-link
|
|
65
|
+
@click="{{handleUserLogoutClick}}"
|
|
66
|
+
end-icon="action"
|
|
67
|
+
design="Default"
|
|
68
|
+
accessible-role="Link"
|
|
69
|
+
href="{{logoutUrl}}">
|
|
70
|
+
{{logoutText}}
|
|
71
|
+
</udex-link>
|
|
72
|
+
{{/if}}
|
|
73
|
+
</div>
|
|
74
|
+
{{/if}}
|
|
60
75
|
{{/inline}}
|
|
61
|
-
|
|
76
|
+
|
|
62
77
|
{{#*inline "account-indetities"}}
|
|
63
78
|
<div class="udex-masthead-profile-menu__header-wrap back-btn">
|
|
64
79
|
<udex-masthead-menu-item
|
|
@@ -70,13 +85,15 @@
|
|
|
70
85
|
</udex-masthead-menu-item>
|
|
71
86
|
<span class="udex-masthead-profile-menu__switcher-title">{{switcherAccountText}}</span>
|
|
72
87
|
</div>
|
|
88
|
+
<span class="udex-masthead-profile-menu__identities-list-title">{{listTitleText}}</span>
|
|
73
89
|
<div class="udex-masthead-profile-menu__identities-list-wrap">
|
|
74
|
-
<span class="udex-masthead-profile-menu__identities-list-title">{{listTitleText}}</span>
|
|
75
90
|
{{#if identitiesList.length}}
|
|
76
91
|
<udex-list
|
|
77
92
|
class="udex-masthead-profile-menu__identities-list"
|
|
78
93
|
mode="SingleSelect"
|
|
79
94
|
accessible-name="{{listTitleText}}"
|
|
95
|
+
@scroll="{{handleIdentitiesListShadowVisible}}"
|
|
96
|
+
_scroll-into-view="Center"
|
|
80
97
|
controlled>
|
|
81
98
|
{{#each identitiesList}}
|
|
82
99
|
<udex-list-item
|
|
@@ -92,13 +109,13 @@
|
|
|
92
109
|
{{/each}}
|
|
93
110
|
</udex-list>
|
|
94
111
|
{{/if}}
|
|
95
|
-
<udex-button
|
|
96
|
-
@click="{{fireEventAddOrRemoveAccountClick}}"
|
|
97
|
-
class="udex-masthead-profile-menu__add-remove-btn"
|
|
98
|
-
design="Primary"
|
|
99
|
-
end-icon="action"
|
|
100
|
-
size="Large">
|
|
101
|
-
{{addOrRemoveAccountText}}
|
|
102
|
-
</udex-button>
|
|
103
112
|
</div>
|
|
113
|
+
<udex-button
|
|
114
|
+
@click="{{fireEventAddOrRemoveAccountClick}}"
|
|
115
|
+
class="udex-masthead-profile-menu__add-remove-btn"
|
|
116
|
+
design="Primary"
|
|
117
|
+
end-icon="action"
|
|
118
|
+
size="Large">
|
|
119
|
+
{{addOrRemoveAccountText}}
|
|
120
|
+
</udex-button>
|
|
104
121
|
{{/inline}}
|