@sapudex/web-components 2.25.0 → 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/Badge.js.map +1 -1
- 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 +2 -0
- package/dist/MastheadItem.js +14 -1
- package/dist/MastheadItem.js.map +1 -1
- package/dist/MastheadMenu.d.ts +14 -0
- package/dist/MastheadMenu.js +55 -15
- package/dist/MastheadMenu.js.map +1 -1
- package/dist/MastheadMobileMenu.d.ts +1 -0
- package/dist/MastheadMobileMenu.js +6 -0
- package/dist/MastheadMobileMenu.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/MastheadShell.d.ts +5 -0
- package/dist/MastheadShell.js +25 -7
- package/dist/MastheadShell.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/Tag.js +7 -0
- package/dist/Tag.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-DF_pzCn9.js → InputSuggestions-CG5owMFQ.js} +1 -1
- package/dist/assets/{ListItemStandardExpandableTextTemplate-DOYL5Szm.js → ListItemStandardExpandableTextTemplate-DpVr7qdn.js} +1 -1
- package/dist/assets/{bundle.esm-CWBg8c5Q.js → bundle.esm-CTkLMr6f.js} +216 -216
- 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/Search.css +1 -1
- package/dist/css/themes/Slider.css +1 -1
- package/dist/custom-elements-internal.json +10 -2
- package/dist/custom-elements.json +6 -2
- package/dist/generated/templates/MastheadCountrySelectorTemplate.lit.js +1 -1
- package/dist/generated/templates/MastheadCountrySelectorTemplate.lit.js.map +1 -1
- package/dist/generated/templates/MastheadItemTemplate.lit.js +1 -1
- package/dist/generated/templates/MastheadItemTemplate.lit.js.map +1 -1
- package/dist/generated/templates/MastheadMenuTemplate.lit.js +9 -7
- package/dist/generated/templates/MastheadMenuTemplate.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/Search.css.d.ts +1 -1
- package/dist/generated/themes/Search.css.js +1 -1
- package/dist/generated/themes/Search.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/Badge.ts +5 -2
- package/src/List.ts +41 -2
- package/src/MastheadCountrySelector.hbs +20 -16
- package/src/MastheadCountrySelector.ts +83 -16
- package/src/MastheadItem.hbs +1 -1
- package/src/MastheadItem.ts +16 -1
- package/src/MastheadMenu.hbs +33 -12
- package/src/MastheadMenu.ts +67 -13
- package/src/MastheadMobileMenu.ts +9 -1
- package/src/MastheadProfileMenu.hbs +43 -26
- package/src/MastheadProfileMenu.ts +124 -7
- package/src/MastheadShell.ts +29 -7
- package/src/Pagination.ts +32 -6
- package/src/PaginationTemplate.tsx +19 -16
- package/src/Tag.ts +1 -1
- 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/MastheadItemTemplate.lit.ts +1 -1
- package/src/generated/templates/MastheadMenuTemplate.lit.ts +9 -7
- 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/Search.css.ts +1 -1
- package/src/generated/themes/Slider.css.ts +1 -1
- package/src/themes/Badge.css +0 -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/themes/Search.css +2 -3
- 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/MastheadMenu.hbs
CHANGED
|
@@ -22,18 +22,39 @@
|
|
|
22
22
|
{{#*inline "header"}}
|
|
23
23
|
<div class="udex-masthead-menu__header">
|
|
24
24
|
{{#if this.url}}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
25
|
+
{{#if ../_isMobileMode}}
|
|
26
|
+
<udex-masthead-menu-item
|
|
27
|
+
id="category-{{categoryId}}"
|
|
28
|
+
type="Heading"
|
|
29
|
+
part="menu-item"
|
|
30
|
+
exportparts="menu-item"
|
|
31
|
+
label="{{this.category}}"
|
|
32
|
+
has-border>
|
|
33
|
+
</udex-masthead-menu-item>
|
|
34
|
+
<udex-masthead-menu-item
|
|
35
|
+
part="menu-item"
|
|
36
|
+
accessible-role="link"
|
|
37
|
+
exportparts="menu-item"
|
|
38
|
+
part="menu-item"
|
|
39
|
+
exportparts="menu-item"
|
|
40
|
+
label="{{../overviewHeaderLinkText}}"
|
|
41
|
+
url="{{this.url}}"
|
|
42
|
+
has-border>
|
|
43
|
+
</udex-masthead-menu-item>
|
|
44
|
+
{{else}}
|
|
45
|
+
<udex-masthead-menu-item
|
|
46
|
+
id="category-{{categoryId}}"
|
|
47
|
+
type="Heading"
|
|
48
|
+
part="menu-item"
|
|
49
|
+
exportparts="menu-item"
|
|
50
|
+
accessible-role="link"
|
|
51
|
+
@click="{{../../handleMenuItemClick}}"
|
|
52
|
+
url="{{this.url}}"
|
|
53
|
+
label="{{this.category}}"
|
|
54
|
+
icon-end
|
|
55
|
+
has-border>
|
|
56
|
+
</udex-masthead-menu-item>
|
|
57
|
+
{{/if}}
|
|
37
58
|
{{else}}
|
|
38
59
|
<udex-masthead-menu-item
|
|
39
60
|
id="category-{{categoryId}}"
|
package/src/MastheadMenu.ts
CHANGED
|
@@ -2,11 +2,15 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
|
|
|
2
2
|
import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
|
|
3
3
|
import property from "@ui5/webcomponents-base/dist/decorators/property.js";
|
|
4
4
|
import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
|
|
5
|
+
import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js";
|
|
6
|
+
import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js";
|
|
5
7
|
import Icon from "@ui5/webcomponents/dist/Icon.js";
|
|
6
8
|
import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";
|
|
7
9
|
import "@ui5/webcomponents-icons/dist/slim-arrow-right.js";
|
|
8
10
|
import "@ui5/webcomponents-icons/dist/action.js";
|
|
9
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
isUp, isDown, isTabNext, isTabPrevious, isHome, isEnd,
|
|
13
|
+
} from "@ui5/webcomponents-base/dist/Keys.js";
|
|
10
14
|
import UDExBadge from "./Badge.js";
|
|
11
15
|
import UDExMastheadMenuItem, { UDExItemType } from "./MastheadMenuItem.js";
|
|
12
16
|
import type UDExMastheadItem from "./MastheadItem.js";
|
|
@@ -14,6 +18,9 @@ import UDExDivider from "./Divider.js";
|
|
|
14
18
|
import MastheadMenuTemplate from "./generated/templates/MastheadMenuTemplate.lit.js";
|
|
15
19
|
import parseArrayFromString from "./utils/parseArrayFromString.js";
|
|
16
20
|
import AnalyticsName from "./types/AnalyticsName.js";
|
|
21
|
+
import { OVERVIEW } from "./generated/i18n/i18n-defaults.js";
|
|
22
|
+
import type { UDExScrollIntoViewOptions } from "./types/List.js";
|
|
23
|
+
import translate from "./utils/translate.js";
|
|
17
24
|
|
|
18
25
|
// Styles
|
|
19
26
|
import MastheadMenuCss from "./generated/themes/MastheadMenu.css.js";
|
|
@@ -116,25 +123,58 @@ class UDExMastheadMenu extends UI5Element {
|
|
|
116
123
|
@property({ type: Boolean })
|
|
117
124
|
_isMobileMode!: boolean;
|
|
118
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
|
+
|
|
135
|
+
@i18n("@sapudex/web-components")
|
|
136
|
+
static i18nBundle: I18nBundle;
|
|
137
|
+
|
|
119
138
|
handleKeyDown(e: KeyboardEvent): void {
|
|
120
|
-
this.
|
|
121
|
-
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();
|
|
122
166
|
}
|
|
123
167
|
|
|
124
168
|
handleUpArrow(e: KeyboardEvent): void {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
this.focusPreviousItem(currentItem);
|
|
129
|
-
}
|
|
169
|
+
e.preventDefault();
|
|
170
|
+
const currentItem = e.target as UDExMastheadMenuItem;
|
|
171
|
+
this.focusPreviousItem(currentItem);
|
|
130
172
|
}
|
|
131
173
|
|
|
132
174
|
handleDownArrow(e: KeyboardEvent): void {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
this.focusNextItem(currentItem);
|
|
137
|
-
}
|
|
175
|
+
e.preventDefault();
|
|
176
|
+
const currentItem = e.target as UDExMastheadMenuItem;
|
|
177
|
+
this.focusNextItem(currentItem);
|
|
138
178
|
}
|
|
139
179
|
|
|
140
180
|
handleMenuItemClick(e: PointerEvent): void {
|
|
@@ -164,12 +204,18 @@ class UDExMastheadMenu extends UI5Element {
|
|
|
164
204
|
const currentSelectedIndex = this.getCurrentIndex(item);
|
|
165
205
|
const lastItemIndex = this.links.length - 1;
|
|
166
206
|
const previousSelectIndex = currentSelectedIndex - 1 < 0 ? lastItemIndex : currentSelectedIndex - 1;
|
|
207
|
+
if (this._scrollIntoView) {
|
|
208
|
+
this.scrollToItem(this.links[previousSelectIndex]);
|
|
209
|
+
}
|
|
167
210
|
this.links[previousSelectIndex].focus();
|
|
168
211
|
}
|
|
169
212
|
|
|
170
213
|
focusNextItem(item: UDExMastheadMenuItem): void {
|
|
171
214
|
const currentSelectedIndex = this.getCurrentIndex(item);
|
|
172
215
|
const nextSelectIndex = currentSelectedIndex + 1 > this.links.length - 1 ? 0 : currentSelectedIndex + 1;
|
|
216
|
+
if (this._scrollIntoView) {
|
|
217
|
+
this.scrollToItem(this.links[nextSelectIndex]);
|
|
218
|
+
}
|
|
173
219
|
this.links[nextSelectIndex].focus();
|
|
174
220
|
}
|
|
175
221
|
|
|
@@ -177,6 +223,10 @@ class UDExMastheadMenu extends UI5Element {
|
|
|
177
223
|
return this.links.indexOf(item);
|
|
178
224
|
}
|
|
179
225
|
|
|
226
|
+
scrollToItem(item: UDExMastheadMenuItem): void {
|
|
227
|
+
item.scrollIntoView({ block: this._scrollIntoView?.toLowerCase() as ScrollLogicalPosition });
|
|
228
|
+
}
|
|
229
|
+
|
|
180
230
|
get links(): Array<UDExMastheadMenuItem> {
|
|
181
231
|
const menuItems: Array<UDExMastheadMenuItem> = Array.from(this.shadowRoot!.querySelectorAll("[udex-masthead-menu-item]"));
|
|
182
232
|
return menuItems.filter(({ url }) => url && url.length > 0);
|
|
@@ -205,6 +255,10 @@ class UDExMastheadMenu extends UI5Element {
|
|
|
205
255
|
const hasOneColumn = this.itemsList.length === 1 && this.itemsList[0].subMenuLinkItems.length === 1;
|
|
206
256
|
return hasOneColumn ? rowClass : "";
|
|
207
257
|
}
|
|
258
|
+
|
|
259
|
+
get overviewHeaderLinkText(): string {
|
|
260
|
+
return translate(UDExMastheadMenu, OVERVIEW);
|
|
261
|
+
}
|
|
208
262
|
}
|
|
209
263
|
|
|
210
264
|
UDExMastheadMenu.define();
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
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";
|
|
14
|
+
import type UDExSearch from "./Search.js";
|
|
14
15
|
import UDExMastheadMenuItem, { UDExItemType } from "./MastheadMenuItem.js";
|
|
15
16
|
import { OVERVIEW } from "./generated/i18n/i18n-defaults.js";
|
|
16
17
|
import AnalyticsName from "./types/AnalyticsName.js";
|
|
@@ -551,7 +552,14 @@ class UDExMastheadMobileMenu extends UI5Element {
|
|
|
551
552
|
return analyticsPath;
|
|
552
553
|
}
|
|
553
554
|
|
|
554
|
-
|
|
555
|
+
resetSearch(): void {
|
|
556
|
+
const search = this.search[0] as UDExSearch;
|
|
557
|
+
if (search && search.value) {
|
|
558
|
+
search.value = "";
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
closeMenu(): void {
|
|
555
563
|
this._mastheadShell.closeMobileMenu();
|
|
556
564
|
this._mastheadShell.mobileBtn?.focus();
|
|
557
565
|
}
|
|
@@ -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}}
|
|
@@ -5,6 +5,7 @@ import slot from "@ui5/webcomponents-base/dist/decorators/slot.js";
|
|
|
5
5
|
import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";
|
|
6
6
|
import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
|
|
7
7
|
import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js";
|
|
8
|
+
import { isDesktop } from "@ui5/webcomponents-base/dist/Device.js";
|
|
8
9
|
import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js";
|
|
9
10
|
import {
|
|
10
11
|
LOGOUT, SWITCH_ACCOUNT, BACK, OTHER_IDENTITIES, ADD_OR_REMOVE_ACCOUNT,
|
|
@@ -13,6 +14,7 @@ import { isEscape } from "@ui5/webcomponents-base/Keys.js";
|
|
|
13
14
|
import UDExMastheadMenu from "./MastheadMenu.js";
|
|
14
15
|
import UDExButton from "./Button.js";
|
|
15
16
|
import UDExList from "./List.js";
|
|
17
|
+
import UDExLink from "./Link.js";
|
|
16
18
|
import UDExListItem from "./ListItem.js";
|
|
17
19
|
import UDExMastheadMenuItem from "./MastheadMenuItem.js";
|
|
18
20
|
import MastheadProfileMenuTemplate from "./generated/templates/MastheadProfileMenuTemplate.lit.js";
|
|
@@ -37,6 +39,7 @@ export interface UserData {
|
|
|
37
39
|
email?: string,
|
|
38
40
|
avatarUrl?: string,
|
|
39
41
|
avatarInitials?: string
|
|
42
|
+
fallbackIcon?: string,
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
export interface UserIdentity {
|
|
@@ -96,6 +99,7 @@ type UDExMastheadProfileMenuAddOrRemoveClickEventDetail = {
|
|
|
96
99
|
UDExListItem,
|
|
97
100
|
UDExButton,
|
|
98
101
|
UDExList,
|
|
102
|
+
UDExLink,
|
|
99
103
|
],
|
|
100
104
|
})
|
|
101
105
|
|
|
@@ -198,13 +202,29 @@ class UDExMastheadProfileMenu extends UI5Element {
|
|
|
198
202
|
_openIdentities: boolean = false;
|
|
199
203
|
|
|
200
204
|
/**
|
|
201
|
-
*
|
|
205
|
+
* Defines the request render state
|
|
206
|
+
*
|
|
207
|
+
* @private
|
|
208
|
+
*/
|
|
209
|
+
@property({ type: Boolean, noAttribute: true })
|
|
210
|
+
_requestRender = false;
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Slot for message strip.
|
|
202
214
|
*
|
|
203
215
|
* @public
|
|
204
216
|
*/
|
|
205
217
|
@slot({ type: Node, "default": false })
|
|
206
218
|
message!: Array<Node>;
|
|
207
219
|
|
|
220
|
+
/**
|
|
221
|
+
* Slot for logout button.
|
|
222
|
+
*
|
|
223
|
+
* @public
|
|
224
|
+
*/
|
|
225
|
+
@slot({ type: HTMLElement })
|
|
226
|
+
logoutButton!: Array<Node>;
|
|
227
|
+
|
|
208
228
|
@i18n("@sapudex/web-components")
|
|
209
229
|
static i18nBundle: I18nBundle;
|
|
210
230
|
|
|
@@ -212,6 +232,8 @@ class UDExMastheadProfileMenu extends UI5Element {
|
|
|
212
232
|
_handleResizeBound: ResizeObserverCallback;
|
|
213
233
|
_shouldFocusBackBtn!: boolean;
|
|
214
234
|
_shouldFocusSwitchBtn!: boolean;
|
|
235
|
+
_identitiesListClassName = "udex-masthead-profile-menu__identities-list";
|
|
236
|
+
_profileMenuLinksClassName = "udex-masthead-profile-menu__links";
|
|
215
237
|
|
|
216
238
|
constructor() {
|
|
217
239
|
super();
|
|
@@ -223,10 +245,14 @@ class UDExMastheadProfileMenu extends UI5Element {
|
|
|
223
245
|
this.updateFocusState(this._shouldFocusBackBtn, this.focusBackBtn.bind(this));
|
|
224
246
|
this.updateFocusState(this._shouldFocusSwitchBtn, this.focusSwitchBtn.bind(this));
|
|
225
247
|
this.setMenuItemsMobileMode();
|
|
248
|
+
this.checkScrollableElements();
|
|
226
249
|
}
|
|
227
250
|
|
|
228
251
|
onEnterDOM(): void {
|
|
229
252
|
ResizeHandler.register(this, this._handleResizeBound);
|
|
253
|
+
if (isDesktop()) {
|
|
254
|
+
this.setAttribute("desktop", "");
|
|
255
|
+
}
|
|
230
256
|
}
|
|
231
257
|
|
|
232
258
|
onExitDOM(): void {
|
|
@@ -239,6 +265,8 @@ class UDExMastheadProfileMenu extends UI5Element {
|
|
|
239
265
|
if (this.profileMenuLinks) {
|
|
240
266
|
this.profileMenuLinks._isMobileMode = this.isMobile;
|
|
241
267
|
}
|
|
268
|
+
|
|
269
|
+
this.checkScrollableElements();
|
|
242
270
|
}
|
|
243
271
|
|
|
244
272
|
handleSwitcherClick(): void {
|
|
@@ -247,8 +275,8 @@ class UDExMastheadProfileMenu extends UI5Element {
|
|
|
247
275
|
this._shouldFocusSwitchBtn = !this._openIdentities;
|
|
248
276
|
}
|
|
249
277
|
|
|
250
|
-
|
|
251
|
-
this.
|
|
278
|
+
handleUserLogoutClick(e: PointerEvent): void {
|
|
279
|
+
this.fireLogoutClick(e);
|
|
252
280
|
if (this._isMobileMode) {
|
|
253
281
|
this.closeMenu();
|
|
254
282
|
}
|
|
@@ -318,15 +346,18 @@ class UDExMastheadProfileMenu extends UI5Element {
|
|
|
318
346
|
}
|
|
319
347
|
}
|
|
320
348
|
|
|
321
|
-
|
|
349
|
+
fireLogoutClick(e: PointerEvent): void {
|
|
322
350
|
const item = e.target as UDExMastheadMenuItem;
|
|
323
|
-
|
|
324
|
-
this.fireDecoratorEvent("logout", {
|
|
351
|
+
const executeEvent = this.fireDecoratorEvent("logout", {
|
|
325
352
|
item,
|
|
326
|
-
sourceNode: item.shadowRoot?.querySelector("
|
|
353
|
+
sourceNode: item.shadowRoot?.querySelector("a") as HTMLElement,
|
|
327
354
|
originalEvent: e,
|
|
328
355
|
analyticsName: AnalyticsName.Header,
|
|
329
356
|
});
|
|
357
|
+
|
|
358
|
+
if (!executeEvent) {
|
|
359
|
+
e.preventDefault();
|
|
360
|
+
}
|
|
330
361
|
}
|
|
331
362
|
|
|
332
363
|
fireMenuItemClick(e: CustomEvent): void {
|
|
@@ -340,6 +371,84 @@ class UDExMastheadProfileMenu extends UI5Element {
|
|
|
340
371
|
});
|
|
341
372
|
}
|
|
342
373
|
|
|
374
|
+
checkScrollableElements(): void {
|
|
375
|
+
if (this._openIdentities) {
|
|
376
|
+
this.checkScrollableElement(this.identitiesHTMLElement, this._identitiesListClassName);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (this.isMobile) {
|
|
380
|
+
this.checkScrollableElement(this.profileMenuHTMLElement, this._profileMenuLinksClassName);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
checkScrollableElement(element: HTMLElement, className: string): void {
|
|
385
|
+
if (element) {
|
|
386
|
+
requestAnimationFrame(() => {
|
|
387
|
+
if (this.isScrollableElement(element)) {
|
|
388
|
+
element.classList.add(`${className}_scrollable`);
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
scrollToTopProfileMenu(): void {
|
|
395
|
+
setTimeout(() => {
|
|
396
|
+
this.profileMenuHTMLElement.scrollTop = 0;
|
|
397
|
+
}, 0);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
isScrollableElement(element: HTMLElement): boolean {
|
|
401
|
+
return element.scrollHeight > element.clientHeight;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
handleProfileMenuShadowVisible(): void {
|
|
405
|
+
this.toggleScrollableClass(
|
|
406
|
+
this.profileMenuHTMLElement,
|
|
407
|
+
this._profileMenuLinksClassName,
|
|
408
|
+
this.scrollBottomProfileMenu,
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
handleIdentitiesListShadowVisible(): void {
|
|
413
|
+
this.toggleScrollableClass(
|
|
414
|
+
this.identitiesHTMLElement,
|
|
415
|
+
this._identitiesListClassName,
|
|
416
|
+
this.scrollBottomIdentitiesList,
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
toggleScrollableClass(el: HTMLElement, className: string, scrollBottom: number): void {
|
|
421
|
+
if (scrollBottom === 0) {
|
|
422
|
+
el.classList.remove(`${className}_scrollable`);
|
|
423
|
+
} else {
|
|
424
|
+
el.classList.add(`${className}_scrollable`);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
get scrollBottomIdentitiesList(): number {
|
|
429
|
+
return this.calculateScrollBottom(this.identitiesHTMLElement);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
get scrollBottomProfileMenu(): number {
|
|
433
|
+
return this.calculateScrollBottom(this.profileMenuHTMLElement);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
calculateScrollBottom(element: HTMLElement): number {
|
|
437
|
+
return element.scrollHeight - element.scrollTop - element.clientHeight;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
get profileMenuHTMLElement(): HTMLElement {
|
|
441
|
+
return this.getElementByClassName(this._profileMenuLinksClassName);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
get identitiesHTMLElement(): HTMLElement {
|
|
445
|
+
return this.getElementByClassName(this._identitiesListClassName);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
getElementByClassName(className: string): HTMLElement {
|
|
449
|
+
return this.shadowRoot?.querySelector<HTMLElement>(`.${className}`) as HTMLElement;
|
|
450
|
+
}
|
|
451
|
+
|
|
343
452
|
closeMenu():void {
|
|
344
453
|
this._mastheadShell.closeMobileMenu();
|
|
345
454
|
this._mastheadShell.mobileBtn?.focus();
|
|
@@ -381,6 +490,10 @@ class UDExMastheadProfileMenu extends UI5Element {
|
|
|
381
490
|
return !!this.message.length;
|
|
382
491
|
}
|
|
383
492
|
|
|
493
|
+
get hasLogoutButton(): boolean {
|
|
494
|
+
return !!this.logoutButton.length;
|
|
495
|
+
}
|
|
496
|
+
|
|
384
497
|
get logoutLink(): boolean {
|
|
385
498
|
return !!this.logoutUrl?.length;
|
|
386
499
|
}
|
|
@@ -425,6 +538,10 @@ class UDExMastheadProfileMenu extends UI5Element {
|
|
|
425
538
|
get isMobile(): boolean {
|
|
426
539
|
return this.isAtMostBreakpointSizeM || this.mastheadShell?.isMobileMenuMode;
|
|
427
540
|
}
|
|
541
|
+
|
|
542
|
+
get hasActionButton(): boolean {
|
|
543
|
+
return this.logoutLink || this.hasLogoutButton;
|
|
544
|
+
}
|
|
428
545
|
}
|
|
429
546
|
|
|
430
547
|
UDExMastheadProfileMenu.define();
|
package/src/MastheadShell.ts
CHANGED
|
@@ -543,6 +543,7 @@ class UDExMastheadShell extends UI5Element {
|
|
|
543
543
|
static i18nBundle: I18nBundle;
|
|
544
544
|
|
|
545
545
|
_searchOpener!: UDExMastheadItem | null | undefined;
|
|
546
|
+
_desktopSearch!: UDExSearch | null | undefined;
|
|
546
547
|
_mobileMenu!: UDExMastheadMobileMenu | null | undefined;
|
|
547
548
|
_handleResizeBound: ResizeObserverCallback;
|
|
548
549
|
_rootHolder!: HTMLElement | null | undefined;
|
|
@@ -563,9 +564,10 @@ class UDExMastheadShell extends UI5Element {
|
|
|
563
564
|
onAfterRendering() {
|
|
564
565
|
this._rootHolder = this.mastheadHolder;
|
|
565
566
|
this._searchOpener = this.searchOpener;
|
|
567
|
+
this._desktopSearch = this.desktopSearchSlot;
|
|
566
568
|
this._mobileMenu = this.mastheadMobileMenu;
|
|
567
569
|
|
|
568
|
-
if (this._isSearchOpened) {
|
|
570
|
+
if (this._isSearchOpened && this._desktopSearch) {
|
|
569
571
|
this.focusSearchInput();
|
|
570
572
|
}
|
|
571
573
|
|
|
@@ -701,16 +703,19 @@ class UDExMastheadShell extends UI5Element {
|
|
|
701
703
|
handleCartClick(e: PointerEvent): void {
|
|
702
704
|
e.stopPropagation();
|
|
703
705
|
this.fireMastheadEvent("cart-click", e);
|
|
706
|
+
this.mobileMenuReset();
|
|
704
707
|
}
|
|
705
708
|
|
|
706
709
|
handleJouleClick(e: PointerEvent): void {
|
|
707
710
|
e.stopPropagation();
|
|
708
711
|
this.fireMastheadEvent("joule-click", e);
|
|
712
|
+
this.mobileMenuReset();
|
|
709
713
|
}
|
|
710
714
|
|
|
711
715
|
handleProfileClick(e: PointerEvent): void {
|
|
712
716
|
e.stopPropagation();
|
|
713
717
|
this.fireMastheadEvent("profile-click", e);
|
|
718
|
+
this.mobileMenuReset();
|
|
714
719
|
}
|
|
715
720
|
|
|
716
721
|
handleSupportClick(e: PointerEvent): void {
|
|
@@ -721,6 +726,7 @@ class UDExMastheadShell extends UI5Element {
|
|
|
721
726
|
handleCountrySelectorClick(e: PointerEvent): void {
|
|
722
727
|
e.stopPropagation();
|
|
723
728
|
this.fireMastheadEvent("country-selector-click", e);
|
|
729
|
+
this.mobileMenuReset();
|
|
724
730
|
}
|
|
725
731
|
|
|
726
732
|
handleOpenMobileMenu(): void {
|
|
@@ -743,6 +749,7 @@ class UDExMastheadShell extends UI5Element {
|
|
|
743
749
|
this._closeBtnClicked = true;
|
|
744
750
|
this.fireMastheadEvent("search-close-click", e);
|
|
745
751
|
this.closeSearch();
|
|
752
|
+
this.resetSearch();
|
|
746
753
|
}
|
|
747
754
|
|
|
748
755
|
handleEnterAndSpaceOnCloseBtn(e: KeyboardEvent): void {
|
|
@@ -754,11 +761,8 @@ class UDExMastheadShell extends UI5Element {
|
|
|
754
761
|
}
|
|
755
762
|
|
|
756
763
|
focusSearchInput(): void {
|
|
757
|
-
const
|
|
758
|
-
|
|
759
|
-
const input = searchSlot.shadowRoot!.querySelector<HTMLElement>("input");
|
|
760
|
-
input?.focus();
|
|
761
|
-
}
|
|
764
|
+
const input = this._desktopSearch?.shadowRoot!.querySelector<HTMLElement>("input");
|
|
765
|
+
input?.focus();
|
|
762
766
|
}
|
|
763
767
|
|
|
764
768
|
focusPreviousMenuItem(item: UDExMastheadItem): void {
|
|
@@ -787,6 +791,12 @@ class UDExMastheadShell extends UI5Element {
|
|
|
787
791
|
});
|
|
788
792
|
}
|
|
789
793
|
|
|
794
|
+
resetSearch(): void {
|
|
795
|
+
if (this._desktopSearch) {
|
|
796
|
+
this._desktopSearch.value = "";
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
|
|
790
800
|
setSelectedItem(e: CustomEvent): void {
|
|
791
801
|
const clickedItem: UDExMastheadItem = e.detail.item;
|
|
792
802
|
if (clickedItem) {
|
|
@@ -967,6 +977,13 @@ class UDExMastheadShell extends UI5Element {
|
|
|
967
977
|
this.fireDecoratorEvent(eventName, eventDetails);
|
|
968
978
|
}
|
|
969
979
|
|
|
980
|
+
mobileMenuReset(): void {
|
|
981
|
+
if (this._isMobileMenuOpen) {
|
|
982
|
+
this._mobileMenu?.showFirstLevelMenu();
|
|
983
|
+
this._mobileMenu?.resetSearch();
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
970
987
|
/**
|
|
971
988
|
* Close the search panel.
|
|
972
989
|
* @public
|
|
@@ -1023,6 +1040,7 @@ class UDExMastheadShell extends UI5Element {
|
|
|
1023
1040
|
(this.mobileBtn as UDExMastheadItem).selected = false;
|
|
1024
1041
|
this._isMobileMenuOpen = false;
|
|
1025
1042
|
this._mobileMenu?.showFirstLevelMenu();
|
|
1043
|
+
this._mobileMenu?.resetSearch();
|
|
1026
1044
|
|
|
1027
1045
|
if (this.bodyOverflow) {
|
|
1028
1046
|
this.removeOverflowBody();
|
|
@@ -1043,6 +1061,10 @@ class UDExMastheadShell extends UI5Element {
|
|
|
1043
1061
|
];
|
|
1044
1062
|
}
|
|
1045
1063
|
|
|
1064
|
+
get desktopSearchSlot(): UDExSearch | null {
|
|
1065
|
+
return this.querySelector<UDExSearch>("[udex-search]");
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1046
1068
|
get searchOpener(): MastheadItemType {
|
|
1047
1069
|
return this.shadowRoot?.querySelector(".udex-masthead-shell__search-btn");
|
|
1048
1070
|
}
|
|
@@ -1152,7 +1174,7 @@ class UDExMastheadShell extends UI5Element {
|
|
|
1152
1174
|
}
|
|
1153
1175
|
|
|
1154
1176
|
get openSearchButtonAccessibleNameText(): string {
|
|
1155
|
-
return this.openSearchButtonAccessibleName || UDExMastheadShell
|
|
1177
|
+
return this.openSearchButtonAccessibleName || translate(UDExMastheadShell, SEARCH);
|
|
1156
1178
|
}
|
|
1157
1179
|
|
|
1158
1180
|
get mainNavigationAriaLabel(): string {
|