@sapudex/web-components 2.36.0 → 2.38.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/specs/List.cy.tsx +38 -0
- package/cypress/specs/Pagination.cy.tsx +52 -0
- package/cypress/specs/PasswordField.cy.tsx +36 -0
- package/cypress/specs/Search.cy.tsx +265 -0
- package/cypress/specs/SelectBox.cy.tsx +19 -1
- package/cypress/specs/TabNavigation.cy.tsx +314 -0
- package/cypress/specs/Table.cy.tsx +170 -0
- package/cypress/support/component-imports.instrumented.ts +2 -0
- package/cypress/support/component-imports.src.ts +2 -0
- package/dist/CountrySelector.d.ts +2 -0
- package/dist/CountrySelector.js +12 -3
- package/dist/CountrySelector.js.map +1 -1
- package/dist/CountrySelectorTemplate.d.ts +2 -0
- package/dist/CountrySelectorTemplate.js +8 -0
- package/dist/CountrySelectorTemplate.js.map +1 -0
- package/dist/FilterMenu.d.ts +3 -3
- package/dist/FilterMenu.js +8 -9
- package/dist/FilterMenu.js.map +1 -1
- package/dist/FilterMenuTemplate.d.ts +2 -0
- package/dist/FilterMenuTemplate.js +27 -0
- package/dist/FilterMenuTemplate.js.map +1 -0
- package/dist/List.d.ts +1 -0
- package/dist/List.js +4 -0
- package/dist/List.js.map +1 -1
- package/dist/Pagination.js +1 -0
- package/dist/Pagination.js.map +1 -1
- package/dist/PasswordField.d.ts +16 -0
- package/dist/PasswordField.js +40 -0
- package/dist/PasswordField.js.map +1 -1
- package/dist/PasswordFieldTemplate.js +1 -1
- package/dist/PasswordFieldTemplate.js.map +1 -1
- package/dist/Search.d.ts +1 -0
- package/dist/Search.js +6 -0
- package/dist/Search.js.map +1 -1
- package/dist/SearchableListBaseTemplate.d.ts +2 -0
- package/dist/SearchableListBaseTemplate.js +32 -0
- package/dist/SearchableListBaseTemplate.js.map +1 -0
- package/dist/SecondaryNavigation.d.ts +2 -0
- package/dist/SecondaryNavigation.js +20 -0
- package/dist/SecondaryNavigation.js.map +1 -1
- package/dist/SelectBase.d.ts +7 -6
- package/dist/SelectBase.js +2 -2
- package/dist/SelectBase.js.map +1 -1
- package/dist/SelectBox.d.ts +2 -0
- package/dist/SelectBox.js +12 -3
- package/dist/SelectBox.js.map +1 -1
- package/dist/SelectBoxTemplate.d.ts +2 -0
- package/dist/SelectBoxTemplate.js +27 -0
- package/dist/SelectBoxTemplate.js.map +1 -0
- package/dist/Tab.d.ts +9 -0
- package/dist/Tab.js +6 -0
- package/dist/Tab.js.map +1 -1
- package/dist/TabNavigation.js +32 -12
- package/dist/TabNavigation.js.map +1 -1
- package/dist/TableGroupRowTemplate.js +1 -1
- package/dist/TableGroupRowTemplate.js.map +1 -1
- package/dist/TableTemplate.js +1 -1
- package/dist/TableTemplate.js.map +1 -1
- package/dist/TagTemplate.js +2 -4
- package/dist/TagTemplate.js.map +1 -1
- package/dist/TextField.js +1 -0
- package/dist/TextField.js.map +1 -1
- package/dist/Wizard.d.ts +2 -2
- package/dist/Wizard.js +7 -7
- package/dist/Wizard.js.map +1 -1
- package/dist/assets/{InputSuggestions-BIR_sdOv.js → InputSuggestions-BQp20KJM.js} +1 -1
- package/dist/assets/{ListItemStandardExpandableTextTemplate-5xOuY0en.js → ListItemStandardExpandableTextTemplate-D0w0u6f7.js} +1 -1
- package/dist/assets/{bundle.esm-C8GwJvJr.js → bundle.esm-DIFG6k5I.js} +240 -240
- package/dist/assets/messagebundle_bg-4ainC3nj.js +1 -0
- package/dist/assets/messagebundle_cs-CFtmLavu.js +1 -0
- package/dist/assets/messagebundle_en-BxjFAY2S.js +1 -0
- package/dist/css/themes/MastheadMenu.css +1 -1
- package/dist/css/themes/MastheadMobileMenu.css +1 -1
- package/dist/css/themes/MediaPlayer.css +1 -1
- package/dist/css/themes/RatingBar.css +1 -1
- package/dist/css/themes/RatingIndicator.css +1 -1
- package/dist/css/themes/SecondaryNavigationSubItem.css +1 -1
- package/dist/css/themes/Slider.css +1 -1
- package/dist/css/themes/TabNavigation.css +1 -1
- package/dist/css/themes/TableGroupRow.css +1 -1
- package/dist/css/themes/Wizard.css +1 -1
- package/dist/css/themes/WizardTab.css +1 -1
- package/dist/custom-elements-internal.json +65 -0
- package/dist/custom-elements.json +49 -0
- package/dist/features/SearchSuggestionsPopover.d.ts +4 -0
- package/dist/features/SearchSuggestionsPopover.js +56 -3
- package/dist/features/SearchSuggestionsPopover.js.map +1 -1
- package/dist/generated/assets/i18n/messagebundle_bg.json +1 -1
- package/dist/generated/assets/i18n/messagebundle_cs.json +1 -1
- package/dist/generated/assets/i18n/messagebundle_en.json +1 -1
- package/dist/generated/i18n/i18n-defaults.d.ts +2 -3
- package/dist/generated/i18n/i18n-defaults.js +2 -3
- package/dist/generated/i18n/i18n-defaults.js.map +1 -1
- package/dist/generated/templates/ListTemplate.lit.js +1 -1
- package/dist/generated/templates/ListTemplate.lit.js.map +1 -1
- package/dist/generated/templates/TabHeaderTemplate.lit.js +4 -4
- package/dist/generated/templates/TabHeaderTemplate.lit.js.map +1 -1
- package/dist/generated/templates/TabInOverflowTemplate.lit.js +2 -2
- package/dist/generated/templates/TabInOverflowTemplate.lit.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/MastheadMobileMenu.css.d.ts +1 -1
- package/dist/generated/themes/MastheadMobileMenu.css.js +1 -1
- package/dist/generated/themes/MastheadMobileMenu.css.js.map +1 -1
- package/dist/generated/themes/MediaPlayer.css.d.ts +1 -1
- package/dist/generated/themes/MediaPlayer.css.js +1 -1
- package/dist/generated/themes/MediaPlayer.css.js.map +1 -1
- package/dist/generated/themes/RatingBar.css.d.ts +1 -1
- package/dist/generated/themes/RatingBar.css.js +1 -1
- package/dist/generated/themes/RatingBar.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/SecondaryNavigationSubItem.css.d.ts +1 -1
- package/dist/generated/themes/SecondaryNavigationSubItem.css.js +1 -1
- package/dist/generated/themes/SecondaryNavigationSubItem.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/generated/themes/TabNavigation.css.d.ts +1 -1
- package/dist/generated/themes/TabNavigation.css.js +1 -1
- package/dist/generated/themes/TabNavigation.css.js.map +1 -1
- package/dist/generated/themes/TableGroupRow.css.d.ts +1 -1
- package/dist/generated/themes/TableGroupRow.css.js +1 -1
- package/dist/generated/themes/TableGroupRow.css.js.map +1 -1
- package/dist/generated/themes/Wizard.css.d.ts +1 -1
- package/dist/generated/themes/Wizard.css.js +1 -1
- package/dist/generated/themes/Wizard.css.js.map +1 -1
- package/dist/generated/themes/WizardTab.css.d.ts +1 -1
- package/dist/generated/themes/WizardTab.css.js +1 -1
- package/dist/generated/themes/WizardTab.css.js.map +1 -1
- package/dist/messagebundle.properties +1 -6
- package/dist/messagebundle_bg.properties +129 -2
- package/dist/messagebundle_cs.properties +126 -0
- package/dist/messagebundle_en.properties +3 -1
- package/dist/vscode.html-custom-data.json +6 -1
- package/dist/web-types.json +42 -4
- package/package.json +1 -1
- package/src/CountrySelector.ts +14 -3
- package/src/CountrySelectorTemplate.tsx +12 -0
- package/src/FilterMenu.ts +9 -10
- package/src/FilterMenuTemplate.tsx +104 -0
- package/src/List.hbs +1 -1
- package/src/List.ts +5 -0
- package/src/Pagination.ts +1 -0
- package/src/PasswordField.ts +55 -0
- package/src/PasswordFieldTemplate.tsx +3 -0
- package/src/Search.ts +7 -0
- package/src/SearchableListBaseTemplate.tsx +157 -0
- package/src/SecondaryNavigation.ts +20 -0
- package/src/SelectBase.ts +7 -6
- package/src/SelectBox.ts +14 -3
- package/src/SelectBoxTemplate.tsx +165 -0
- package/src/Tab.ts +14 -0
- package/src/TabHeader.hbs +6 -2
- package/src/TabInOverflow.hbs +2 -0
- package/src/TabNavigation.ts +34 -12
- package/src/TableGroupRowTemplate.tsx +26 -17
- package/src/TableTemplate.tsx +1 -1
- package/src/TagTemplate.tsx +2 -4
- package/src/TextField.ts +1 -0
- package/src/Wizard.ts +15 -14
- package/src/features/SearchSuggestionsPopover.ts +59 -3
- package/src/generated/i18n/i18n-defaults.ts +2 -2
- package/src/generated/templates/ListTemplate.lit.ts +1 -1
- package/src/generated/templates/TabHeaderTemplate.lit.ts +4 -4
- package/src/generated/templates/TabInOverflowTemplate.lit.ts +2 -2
- package/src/generated/themes/MastheadMenu.css.ts +1 -1
- package/src/generated/themes/MastheadMobileMenu.css.ts +1 -1
- package/src/generated/themes/MediaPlayer.css.ts +1 -1
- package/src/generated/themes/RatingBar.css.ts +1 -1
- package/src/generated/themes/RatingIndicator.css.ts +1 -1
- package/src/generated/themes/SecondaryNavigationSubItem.css.ts +1 -1
- package/src/generated/themes/Slider.css.ts +1 -1
- package/src/generated/themes/TabNavigation.css.ts +1 -1
- package/src/generated/themes/TableGroupRow.css.ts +1 -1
- package/src/generated/themes/Wizard.css.ts +1 -1
- package/src/generated/themes/WizardTab.css.ts +1 -1
- package/src/i18n/messagebundle.properties +1 -6
- package/src/i18n/messagebundle_bg.properties +129 -2
- package/src/i18n/messagebundle_cs.properties +126 -0
- package/src/i18n/messagebundle_en.properties +3 -1
- package/src/themes/MastheadMenu.css +4 -2
- package/src/themes/MastheadMobileMenu.css +4 -2
- package/src/themes/MediaPlayer.css +12 -0
- package/src/themes/RatingBar.css +14 -5
- package/src/themes/SecondaryNavigationSubItem.css +1 -0
- package/src/themes/TabNavigation.css +6 -0
- package/src/themes/TableGroupRow.css +5 -0
- package/src/themes/Wizard.css +19 -15
- package/src/themes/WizardTab.css +43 -28
- package/dist/assets/messagebundle_bg-4X593TQq.js +0 -1
- package/dist/assets/messagebundle_cs-Bt8XtMib.js +0 -1
- package/dist/assets/messagebundle_en-iNqRB1VZ.js +0 -1
- package/dist/generated/templates/CountrySelectorTemplate.lit.d.ts +0 -3
- package/dist/generated/templates/CountrySelectorTemplate.lit.js +0 -8
- package/dist/generated/templates/CountrySelectorTemplate.lit.js.map +0 -1
- package/dist/generated/templates/FilterMenuTemplate.lit.d.ts +0 -3
- package/dist/generated/templates/FilterMenuTemplate.lit.js +0 -13
- package/dist/generated/templates/FilterMenuTemplate.lit.js.map +0 -1
- package/dist/generated/templates/SearchableListBaseTemplate.lit.d.ts +0 -3
- package/dist/generated/templates/SearchableListBaseTemplate.lit.js +0 -19
- package/dist/generated/templates/SearchableListBaseTemplate.lit.js.map +0 -1
- package/dist/generated/templates/SelectBoxTemplate.lit.d.ts +0 -3
- package/dist/generated/templates/SelectBoxTemplate.lit.js +0 -20
- package/dist/generated/templates/SelectBoxTemplate.lit.js.map +0 -1
- package/src/CountrySelector.hbs +0 -6
- package/src/FilterMenu.hbs +0 -88
- package/src/SearchableListBase.hbs +0 -148
- package/src/SelectBox.hbs +0 -138
- package/src/generated/templates/CountrySelectorTemplate.lit.ts +0 -12
- package/src/generated/templates/FilterMenuTemplate.lit.ts +0 -17
- package/src/generated/templates/SearchableListBaseTemplate.lit.ts +0 -23
- package/src/generated/templates/SelectBoxTemplate.lit.ts +0 -24
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import type UDExSearchableListBase from "./SearchableListBase.js";
|
|
2
|
+
import type { UDExProcessedItem } from "./types/SearchableListBase.js";
|
|
3
|
+
import type UDExListGroupHeaderBase from "./ListGroupHeaderBase.js";
|
|
4
|
+
import UDExSearch, { Mode as UDExSearchMode } from "./Search.js";
|
|
5
|
+
import IllustratedMessage from "@ui5/webcomponents-fiori/dist/IllustratedMessage.js";
|
|
6
|
+
import UDExBusyIndicator from "./BusyIndicator.js";
|
|
7
|
+
import UDExList from "./List.js";
|
|
8
|
+
import UDExListItem from "./ListItem.js";
|
|
9
|
+
import UDExListGroupHeader from "./ListGroupHeader.js";
|
|
10
|
+
import UDExListSelectAll from "./ListSelectAll.js";
|
|
11
|
+
import type { AriaRole } from "@ui5/webcomponents-base/dist/types.js";
|
|
12
|
+
|
|
13
|
+
export default function SearchableListBaseTemplate(this: UDExSearchableListBase) {
|
|
14
|
+
return (
|
|
15
|
+
<>
|
|
16
|
+
{this.showSearch && (
|
|
17
|
+
<>
|
|
18
|
+
<UDExSearch
|
|
19
|
+
slot="header"
|
|
20
|
+
mode={UDExSearchMode.Standard}
|
|
21
|
+
class="udex-filter-menu__search"
|
|
22
|
+
label={this.searchPlaceholder}
|
|
23
|
+
label-animation-disabled
|
|
24
|
+
non-interactive-submit-button
|
|
25
|
+
show-submit-button>
|
|
26
|
+
</UDExSearch>
|
|
27
|
+
<span aria-live="polite" aria-atomic="true" class="hidden">{this._accSearchResultInfo}</span>
|
|
28
|
+
</>
|
|
29
|
+
)}
|
|
30
|
+
{this.isListEmpty ? (
|
|
31
|
+
<div class="udex-no-result">
|
|
32
|
+
<IllustratedMessage
|
|
33
|
+
name="NoSearchResults"
|
|
34
|
+
design="Dot"
|
|
35
|
+
title-text=" "
|
|
36
|
+
subtitle-text=" ">
|
|
37
|
+
</IllustratedMessage>
|
|
38
|
+
<span>{this.getNoResultText}</span>
|
|
39
|
+
</div>
|
|
40
|
+
) : this.busy ? (
|
|
41
|
+
<UDExBusyIndicator
|
|
42
|
+
class="udex-busy-indicator"
|
|
43
|
+
size="M"
|
|
44
|
+
delay={this.busyDelay}
|
|
45
|
+
active>
|
|
46
|
+
</UDExBusyIndicator>
|
|
47
|
+
) : (
|
|
48
|
+
<UDExList
|
|
49
|
+
id="udex-list"
|
|
50
|
+
role={this.roleForGroupList as AriaRole}
|
|
51
|
+
accessible-role={this.accessibleRoleForList}
|
|
52
|
+
class="udex-filter-menu__list"
|
|
53
|
+
tab-navigation-enabled={this.tabNavigationEnabled}
|
|
54
|
+
controlled={this.isControlled}
|
|
55
|
+
mode={this.mode}>
|
|
56
|
+
{this._filteredItems.map((processedItem, index) => (
|
|
57
|
+
processedItem.isGroup
|
|
58
|
+
? renderGroup.call(this, processedItem, index)
|
|
59
|
+
: renderListItem(processedItem.item as UDExListItem, index, "none", this.listItemRole, this.fireFirstIconClickEvent, this.fireSecondIconClickEvent)
|
|
60
|
+
))}
|
|
61
|
+
</UDExList>
|
|
62
|
+
)}
|
|
63
|
+
</>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function renderGroup(this: UDExSearchableListBase, processedItem: UDExProcessedItem, index: number) {
|
|
68
|
+
return (processedItem.item as UDExListGroupHeaderBase).isSelectAllHeader
|
|
69
|
+
? renderSelectAll.call(this, processedItem, index)
|
|
70
|
+
: renderGroupHeader.call(this, processedItem, index);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function renderSelectAll(this: UDExSearchableListBase, processedItem: UDExProcessedItem, index: number) {
|
|
74
|
+
const { item, groupItems } = processedItem;
|
|
75
|
+
const header = item as UDExListGroupHeaderBase;
|
|
76
|
+
return (
|
|
77
|
+
<UDExListSelectAll
|
|
78
|
+
key={index}
|
|
79
|
+
_additional-class-name={this.additionalClassName}
|
|
80
|
+
data-token-id={item._id}
|
|
81
|
+
label={item.label}
|
|
82
|
+
controlled={header.controlled}
|
|
83
|
+
supporting-text={item.supportingText}
|
|
84
|
+
disabled={item.disabled}
|
|
85
|
+
selected={item.selected}
|
|
86
|
+
indeterminate={header.indeterminate}
|
|
87
|
+
onFirstIconClick={this.fireFirstIconClickEvent}
|
|
88
|
+
onSecondIconClick={this.fireSecondIconClickEvent}>
|
|
89
|
+
{groupItems.map((child, i) =>
|
|
90
|
+
renderListItem(child as UDExListItem, i, this.listItemRole, undefined, this.fireFirstIconClickEvent, this.fireSecondIconClickEvent)
|
|
91
|
+
)}
|
|
92
|
+
</UDExListSelectAll>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function renderGroupHeader(this: UDExSearchableListBase, processedItem: UDExProcessedItem, index: number) {
|
|
97
|
+
const { item, groupItems } = processedItem;
|
|
98
|
+
const header = item as UDExListGroupHeaderBase;
|
|
99
|
+
return (
|
|
100
|
+
<UDExListGroupHeader
|
|
101
|
+
key={index}
|
|
102
|
+
role="group"
|
|
103
|
+
_additional-class-name="udex-searchable-list__header"
|
|
104
|
+
class={this.groupClassName}
|
|
105
|
+
non-interactive={header.nonInteractive}
|
|
106
|
+
data-token-id={item._id}
|
|
107
|
+
label={item.label}
|
|
108
|
+
supporting-text={item.supportingText}
|
|
109
|
+
controlled={header.controlled}
|
|
110
|
+
collapsible={header.collapsible}
|
|
111
|
+
collapsed={header.collapsed}
|
|
112
|
+
_filtered={this._shouldFilterItems}
|
|
113
|
+
disabled={item.disabled}
|
|
114
|
+
selected={item.selected}
|
|
115
|
+
onFirstIconClick={this.fireFirstIconClickEvent}
|
|
116
|
+
onSecondIconClick={this.fireSecondIconClickEvent}
|
|
117
|
+
indeterminate={header.indeterminate}>
|
|
118
|
+
{groupItems.map((child, i) =>
|
|
119
|
+
renderListItem(child as UDExListItem, i, "none", undefined, this.fireFirstIconClickEvent, this.fireSecondIconClickEvent)
|
|
120
|
+
)}
|
|
121
|
+
</UDExListGroupHeader>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function renderListItem(
|
|
126
|
+
item: UDExListItem,
|
|
127
|
+
index: number,
|
|
128
|
+
role: string,
|
|
129
|
+
accessibleRole: string | undefined,
|
|
130
|
+
onFirstIconClick: (e: CustomEvent) => void,
|
|
131
|
+
onSecondIconClick: (e: CustomEvent) => void,
|
|
132
|
+
) {
|
|
133
|
+
return (
|
|
134
|
+
<UDExListItem
|
|
135
|
+
key={index}
|
|
136
|
+
role={role as AriaRole}
|
|
137
|
+
data-token-id={item._id}
|
|
138
|
+
controlled={item.controlled}
|
|
139
|
+
mode={item.mode}
|
|
140
|
+
onFirstIconClick={onFirstIconClick}
|
|
141
|
+
onSecondIconClick={onSecondIconClick}
|
|
142
|
+
supporting-text={item.supportingText}
|
|
143
|
+
additional-text={item.additionalText}
|
|
144
|
+
additional-text-state={item.additionalTextState}
|
|
145
|
+
divider={item.divider}
|
|
146
|
+
disabled={item.disabled}
|
|
147
|
+
selected={item.selected}
|
|
148
|
+
rating={item.rating}
|
|
149
|
+
total-count={item.totalCount}
|
|
150
|
+
rating-count={item.ratingCount}
|
|
151
|
+
rating-max={item.ratingMax}
|
|
152
|
+
label={item.label}
|
|
153
|
+
{...(accessibleRole ? { "accessible-role": accessibleRole } : {})}
|
|
154
|
+
{...((item as any).innerHTML ? { dangerouslySetInnerHTML: { __html: (item as any).innerHTML } } : {})}>
|
|
155
|
+
</UDExListItem>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
@@ -201,6 +201,7 @@ class UDExSecondaryNavigation extends UI5Element {
|
|
|
201
201
|
_rootHolder!: HTMLElement | null | undefined;
|
|
202
202
|
_clickedNavItem!: UDExSecondaryNavigationItem;
|
|
203
203
|
_boundReflowItems: () => void;
|
|
204
|
+
_prevSlottedButtons: HTMLElement | null = null;
|
|
204
205
|
|
|
205
206
|
@i18n("@sapudex/web-components")
|
|
206
207
|
static i18nBundle: I18nBundle;
|
|
@@ -220,6 +221,9 @@ class UDExSecondaryNavigation extends UI5Element {
|
|
|
220
221
|
|
|
221
222
|
onExitDOM(): void {
|
|
222
223
|
ResizeHandler.deregister(this, this._boundReflowItems);
|
|
224
|
+
if (this._prevSlottedButtons) {
|
|
225
|
+
ResizeHandler.deregister(this._prevSlottedButtons, this._boundReflowItems);
|
|
226
|
+
}
|
|
223
227
|
}
|
|
224
228
|
|
|
225
229
|
onInvalidation(changeInfo: ChangeInfo): void {
|
|
@@ -234,6 +238,22 @@ class UDExSecondaryNavigation extends UI5Element {
|
|
|
234
238
|
this._showMoreButton = true;
|
|
235
239
|
}
|
|
236
240
|
this.handleOutsideClick();
|
|
241
|
+
this.syncButtonsResizeHandler();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
syncButtonsResizeHandler(): void {
|
|
245
|
+
const buttonsEl = this.optionalButtons || null;
|
|
246
|
+
if (buttonsEl !== this._prevSlottedButtons) {
|
|
247
|
+
if (this._prevSlottedButtons) {
|
|
248
|
+
ResizeHandler.deregister(this._prevSlottedButtons, this._boundReflowItems);
|
|
249
|
+
}
|
|
250
|
+
if (buttonsEl) {
|
|
251
|
+
ResizeHandler.register(buttonsEl, this._boundReflowItems);
|
|
252
|
+
} else {
|
|
253
|
+
this.reflowItems();
|
|
254
|
+
}
|
|
255
|
+
this._prevSlottedButtons = buttonsEl;
|
|
256
|
+
}
|
|
237
257
|
}
|
|
238
258
|
|
|
239
259
|
refreshRendering(): void {
|
package/src/SelectBase.ts
CHANGED
|
@@ -12,8 +12,8 @@ import type UDExSearch from "./Search.js";
|
|
|
12
12
|
import "@ui5/webcomponents-icons/dist/decline.js";
|
|
13
13
|
import "@ui5/webcomponents-icons/dist/navigation-down-arrow.js";
|
|
14
14
|
import { COUNTRY_SELECT, STARS } from "./generated/i18n/i18n-defaults.js";
|
|
15
|
-
import SearchableListBaseTemplate from "./
|
|
16
|
-
import CountrySelectorTemplate from "./
|
|
15
|
+
import SearchableListBaseTemplate from "./SearchableListBaseTemplate.js";
|
|
16
|
+
import CountrySelectorTemplate from "./CountrySelectorTemplate.js";
|
|
17
17
|
import type { ResizeObserverCallback } from "@ui5/webcomponents-base/delegate/ResizeHandler.js";
|
|
18
18
|
import ResizeHandler from "@ui5/webcomponents-base/delegate/ResizeHandler.js";
|
|
19
19
|
import UDExSearchableListBase from "./SearchableListBase.js";
|
|
@@ -22,6 +22,7 @@ import type { UDExSearchableListBaseEvents } from "./SearchableListBase.js";
|
|
|
22
22
|
import { getTokensCountText } from "@ui5/webcomponents/dist/Tokenizer.js";
|
|
23
23
|
import isLetterKey from "./utils/isLetterKeyPressed.js";
|
|
24
24
|
import translate from "./utils/translate.js";
|
|
25
|
+
import type { AriaAutoComplete, AriaHasPopup } from "@ui5/webcomponents-base/dist/types.js";
|
|
25
26
|
|
|
26
27
|
type UDExSelectBaseEvents = {
|
|
27
28
|
"open": void,
|
|
@@ -165,10 +166,10 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
165
166
|
_paneWidthVariableName = "--udex-dropdown-pane-width";
|
|
166
167
|
_labelBaseClass = "udex-text-field__label";
|
|
167
168
|
_dropdownClass = "udex-select-box__dropdown";
|
|
168
|
-
_listBoxRole = "listbox";
|
|
169
|
+
_listBoxRole: AriaHasPopup = "listbox";
|
|
169
170
|
_rootClass = "udex-select-box__root";
|
|
170
171
|
_stickyClass = "udex-list__sticky";
|
|
171
|
-
_ariaAutoComplete = "list";
|
|
172
|
+
_ariaAutoComplete: AriaAutoComplete = "list";
|
|
172
173
|
_trigger!: HTMLElement;
|
|
173
174
|
_search!: UDExSearch | HTMLInputElement;
|
|
174
175
|
_popover!: Popover;
|
|
@@ -423,7 +424,7 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
423
424
|
}
|
|
424
425
|
}
|
|
425
426
|
|
|
426
|
-
handleSearchChange(e:
|
|
427
|
+
handleSearchChange(e: InputEvent) {
|
|
427
428
|
const inputValue = (e.target as HTMLInputElement)?.value || "";
|
|
428
429
|
this._inputValue = inputValue;
|
|
429
430
|
|
|
@@ -586,7 +587,7 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
586
587
|
return `${this._id}_${this._dropdownClass}`;
|
|
587
588
|
}
|
|
588
589
|
|
|
589
|
-
get listboxRole():
|
|
590
|
+
get listboxRole(): AriaHasPopup {
|
|
590
591
|
return this._listBoxRole;
|
|
591
592
|
}
|
|
592
593
|
|
package/src/SelectBox.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
|
|
2
|
-
import
|
|
2
|
+
import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js";
|
|
3
3
|
import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";
|
|
4
4
|
import property from "@ui5/webcomponents-base/dist/decorators/property.js";
|
|
5
5
|
import {
|
|
@@ -30,7 +30,8 @@ import UDExStatusMessage from "./StatusMessage.js";
|
|
|
30
30
|
import UDExBusyIndicator from "./BusyIndicator.js";
|
|
31
31
|
import UDExTagGroup from "./TagGroup.js";
|
|
32
32
|
import UDExSelectBase from "./SelectBase.js";
|
|
33
|
-
import SelectBoxTemplate from "./
|
|
33
|
+
import SelectBoxTemplate from "./SelectBoxTemplate.js";
|
|
34
|
+
import SearchableListBaseTemplate from "./SearchableListBaseTemplate.js";
|
|
34
35
|
import getEffectiveScrollbarStyle from "./utils/getEffectiveScrollbarStyle.js";
|
|
35
36
|
import type { UDExSelectBaseEvents } from "./SelectBase.js";
|
|
36
37
|
|
|
@@ -71,7 +72,7 @@ type UDExSelectBoxRemoveEventDetail = {
|
|
|
71
72
|
*/
|
|
72
73
|
@customElement({
|
|
73
74
|
tag: "udex-select-box",
|
|
74
|
-
renderer:
|
|
75
|
+
renderer: jsxRenderer,
|
|
75
76
|
styles: [
|
|
76
77
|
TextFieldCss,
|
|
77
78
|
SelectBoxCss,
|
|
@@ -239,6 +240,7 @@ class UDExSelectBox extends UDExSelectBase {
|
|
|
239
240
|
|
|
240
241
|
if (this.modeMultiSelect) {
|
|
241
242
|
this.handleUnselectTruncatableTag();
|
|
243
|
+
this._selectedOption = "";
|
|
242
244
|
}
|
|
243
245
|
|
|
244
246
|
this._open = false;
|
|
@@ -460,6 +462,15 @@ class UDExSelectBox extends UDExSelectBase {
|
|
|
460
462
|
|
|
461
463
|
return this._focused || this._open || isCurrentlyExpanded;
|
|
462
464
|
}
|
|
465
|
+
|
|
466
|
+
override get searchableList() {
|
|
467
|
+
this.defaultAccessibleRole = this._listBoxRole;
|
|
468
|
+
return SearchableListBaseTemplate.call(this);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
static override get searchableListBaseTemplate(): any {
|
|
472
|
+
return SearchableListBaseTemplate;
|
|
473
|
+
}
|
|
463
474
|
}
|
|
464
475
|
|
|
465
476
|
UDExSelectBox.define();
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import type UDExSelectBox from "./SelectBox.js";
|
|
2
|
+
import UDExTagGroup from "./TagGroup.js";
|
|
3
|
+
import UDExTag from "./Tag.js";
|
|
4
|
+
import UDExStatusMessage from "./StatusMessage.js";
|
|
5
|
+
import UI5Icon from "@ui5/webcomponents/dist/Icon.js";
|
|
6
|
+
import UI5Popover from "@ui5/webcomponents/dist/Popover.js";
|
|
7
|
+
import UI5PopoverPlacement from "@ui5/webcomponents/dist/types/PopoverPlacement.js";
|
|
8
|
+
import UI5PopoverHAlign from "@ui5/webcomponents/dist/types/PopoverHorizontalAlign.js";
|
|
9
|
+
import { cleanLabel } from "./utils/listItemLabelUtils.js";
|
|
10
|
+
|
|
11
|
+
export default function SelectBoxTemplate(this: UDExSelectBox) {
|
|
12
|
+
return (
|
|
13
|
+
<div class={this._rootClass}>
|
|
14
|
+
<div class="udex-text-field__container">
|
|
15
|
+
<div class="udex-text-field__wrap" {...(this.displayonly ? { displayonly: "" } : {})}>
|
|
16
|
+
{this.showMultiSelectedOptions && renderTagGroup.call(this)}
|
|
17
|
+
<div
|
|
18
|
+
class="udex-text-field__input"
|
|
19
|
+
onFocusIn={this.handleInputFocusIn}
|
|
20
|
+
onFocusOut={this.handleInputFocusOut}
|
|
21
|
+
{...(this.readonly ? { readonly: "" } : {})}
|
|
22
|
+
{...(this.isDisabled ? { disabled: "" } : {})}
|
|
23
|
+
{...(this._open ? { open: "" } : {})}>
|
|
24
|
+
{this.label && (
|
|
25
|
+
<>
|
|
26
|
+
<label for="search-input" class={this.labelClass}>
|
|
27
|
+
{this.label}{this.required && "*"}
|
|
28
|
+
</label>
|
|
29
|
+
<span class="hidden" id={`${this._id}-aria-describedby`}>{this.ariaDescribedbyText}</span>
|
|
30
|
+
</>
|
|
31
|
+
)}
|
|
32
|
+
{this.showImageFlags && this.countryFlag}
|
|
33
|
+
<div class="udex-text-field__holder">
|
|
34
|
+
<input
|
|
35
|
+
role="combobox"
|
|
36
|
+
type="text"
|
|
37
|
+
id="search-input"
|
|
38
|
+
name="search"
|
|
39
|
+
class="udex-text-field__search"
|
|
40
|
+
value={this._inputValue}
|
|
41
|
+
onInput={this.handleSearchChange}
|
|
42
|
+
onClick={this.handleInputClick}
|
|
43
|
+
onKeyDown={this.handleKeyDownSearch}
|
|
44
|
+
disabled={this.isDisabled}
|
|
45
|
+
readonly={this.isReadOrDisplayOnly}
|
|
46
|
+
aria-label={this.accInfo.ariaLabel}
|
|
47
|
+
aria-readonly={this.isReadOrDisplayOnly}
|
|
48
|
+
aria-disabled={this.disabled}
|
|
49
|
+
aria-haspopup={this.listboxRole}
|
|
50
|
+
aria-controls={this.popoverId}
|
|
51
|
+
aria-expanded={this._open}
|
|
52
|
+
aria-autocomplete={this._ariaAutoComplete}
|
|
53
|
+
aria-describedby={`${this._id}-aria-describedby`}
|
|
54
|
+
autocomplete="off"
|
|
55
|
+
/>
|
|
56
|
+
{this._selectedOption && (
|
|
57
|
+
<div class="udex-text-field__text-holder">
|
|
58
|
+
<span
|
|
59
|
+
class="udex-text-field__single-label"
|
|
60
|
+
aria-hidden="true"
|
|
61
|
+
dangerouslySetInnerHTML={{ __html: this._selectedOption }}>
|
|
62
|
+
</span>
|
|
63
|
+
</div>
|
|
64
|
+
)}
|
|
65
|
+
</div>
|
|
66
|
+
{!this.displayonly && (
|
|
67
|
+
<button
|
|
68
|
+
onClick={this.handleButtonClick}
|
|
69
|
+
disabled={this.isDisabled}
|
|
70
|
+
aria-label={this.accInfo.ariaLabel}
|
|
71
|
+
class="udex-text-field__trigger"
|
|
72
|
+
tabindex={-1}>
|
|
73
|
+
<UI5Icon mode="Decorative" name="navigation-down-arrow"></UI5Icon>
|
|
74
|
+
</button>
|
|
75
|
+
)}
|
|
76
|
+
<UI5Popover
|
|
77
|
+
id={this.popoverId}
|
|
78
|
+
allow-target-overlap={this.allowTargetOverlap}
|
|
79
|
+
onKeyDown={this.handleKeyDownDropdown}
|
|
80
|
+
{...({
|
|
81
|
+
onSelectAll: this.handleSelectAll,
|
|
82
|
+
onItemPress: this.handleItemPress,
|
|
83
|
+
onHeaderPress: this.handleHeaderPress,
|
|
84
|
+
} as any)}
|
|
85
|
+
onBeforeOpen={this.handleDropdownBeforeOpen}
|
|
86
|
+
onOpen={this.fireEventDropdownOpen}
|
|
87
|
+
onBeforeClose={this.handleDropdownBeforeClose}
|
|
88
|
+
onClose={this.handleDropdownClose}
|
|
89
|
+
class="udex-select-box__dropdown"
|
|
90
|
+
horizontal-align={UI5PopoverHAlign.Start}
|
|
91
|
+
placement={UI5PopoverPlacement.Bottom}
|
|
92
|
+
prevent-focus-restore
|
|
93
|
+
prevent-initial-focus
|
|
94
|
+
hide-arrow>
|
|
95
|
+
{this._showTagsDropdownContent
|
|
96
|
+
? renderTruncatableTagContent.call(this)
|
|
97
|
+
: this.searchableList}
|
|
98
|
+
</UI5Popover>
|
|
99
|
+
<span aria-live="polite" aria-atomic="true" class="hidden">{this._accSearchResultInfo}</span>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
{this.supportingText && (
|
|
103
|
+
<UDExStatusMessage
|
|
104
|
+
disabled={this.disabled ? "true" : undefined}
|
|
105
|
+
supporting-text={this.supportingText}
|
|
106
|
+
value-state={this.valueState}>
|
|
107
|
+
</UDExStatusMessage>
|
|
108
|
+
)}
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function renderTagGroup(this: UDExSelectBox) {
|
|
115
|
+
return (
|
|
116
|
+
<UDExTagGroup
|
|
117
|
+
class="udex-tag-group"
|
|
118
|
+
displayonly={this.displayonly}
|
|
119
|
+
readonly={this.readonly}
|
|
120
|
+
disabled={this.disabled}
|
|
121
|
+
onFocusOut={this.resetTagsTabIndexes}
|
|
122
|
+
tooltip-placement={this.tooltipPlacement}
|
|
123
|
+
onTagIconClick={this.handleRemoveTag}
|
|
124
|
+
onTagClick={this.handleTagClick}
|
|
125
|
+
onShowMoreTags={this.handlerShowMoreItems}
|
|
126
|
+
onTagKeydown={this.handleKeyDownTag}
|
|
127
|
+
tokenizer-expanded={this.tokenizerExpanded}
|
|
128
|
+
_skip-more-button-focus>
|
|
129
|
+
{this.selectedItems
|
|
130
|
+
.filter(item => !item.isGroup)
|
|
131
|
+
.map((item, index) => (
|
|
132
|
+
item.label ? (
|
|
133
|
+
<UDExTag
|
|
134
|
+
key={index}
|
|
135
|
+
text={cleanLabel(item.label)}
|
|
136
|
+
id={item._id}
|
|
137
|
+
icon="decline">
|
|
138
|
+
</UDExTag>
|
|
139
|
+
) : (
|
|
140
|
+
<UDExTag
|
|
141
|
+
key={index}
|
|
142
|
+
text={`${item.rating} ${this.startsText}`}
|
|
143
|
+
id={item._id}
|
|
144
|
+
icon="decline">
|
|
145
|
+
</UDExTag>
|
|
146
|
+
)
|
|
147
|
+
))
|
|
148
|
+
}
|
|
149
|
+
</UDExTagGroup>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function renderTruncatableTagContent(this: UDExSelectBox) {
|
|
154
|
+
return (
|
|
155
|
+
<div class="udex-truncatable-tag-content">
|
|
156
|
+
<span class="udex-truncatable-tag-content__label">{this.truncatableTagLabel}</span>
|
|
157
|
+
<UI5Icon
|
|
158
|
+
onClick={this.handleRemoveTruncatableTag}
|
|
159
|
+
class="udex-truncatable-tag-content__icon"
|
|
160
|
+
mode="Decorative"
|
|
161
|
+
name="decline">
|
|
162
|
+
</UI5Icon>
|
|
163
|
+
</div>
|
|
164
|
+
);
|
|
165
|
+
}
|
package/src/Tab.ts
CHANGED
|
@@ -143,6 +143,16 @@ class UDExTab extends UI5Element implements ITab {
|
|
|
143
143
|
@property({ type: String })
|
|
144
144
|
icon!: string;
|
|
145
145
|
|
|
146
|
+
/**
|
|
147
|
+
* Defines if the tab is disabled. A disabled tab is not clickable or focusable,
|
|
148
|
+
* but remains reachable by screen readers via aria-disabled.
|
|
149
|
+
*
|
|
150
|
+
* @public
|
|
151
|
+
* @default false
|
|
152
|
+
*/
|
|
153
|
+
@property({ type: Boolean })
|
|
154
|
+
disabled!: boolean;
|
|
155
|
+
|
|
146
156
|
/**
|
|
147
157
|
* Defines the href of the tab.
|
|
148
158
|
*
|
|
@@ -271,6 +281,10 @@ class UDExTab extends UI5Element implements ITab {
|
|
|
271
281
|
return null;
|
|
272
282
|
}
|
|
273
283
|
|
|
284
|
+
get ariaDisabled(): string | null {
|
|
285
|
+
return this.disabled ? "true" : null;
|
|
286
|
+
}
|
|
287
|
+
|
|
274
288
|
get hasItemCountText(): boolean {
|
|
275
289
|
return this._isProcessTab && !!this.itemCountText;
|
|
276
290
|
}
|
package/src/TabHeader.hbs
CHANGED
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
aria-posinset="{{this._posinset}}"
|
|
14
14
|
aria-setsize="{{this._setsize}}"
|
|
15
15
|
aria-controls="{{this._contentId}}"
|
|
16
|
-
aria-selected="{{this.effectiveSelected}}"
|
|
16
|
+
aria-selected="{{this.effectiveSelected}}"
|
|
17
|
+
aria-disabled="{{this.ariaDisabled}}">
|
|
17
18
|
{{>tab-content}}
|
|
18
19
|
{{#if this.ariaDescribedByBodyText}}
|
|
19
20
|
<span class="visually-hidden">{{bodyText}}</span>
|
|
@@ -28,7 +29,8 @@
|
|
|
28
29
|
role="tab"
|
|
29
30
|
tabindex="{{this.linkTabIndex}}"
|
|
30
31
|
aria-posinset="{{this._posinset}}"
|
|
31
|
-
aria-setsize="{{this._setsize}}"
|
|
32
|
+
aria-setsize="{{this._setsize}}"
|
|
33
|
+
aria-disabled="{{this.ariaDisabled}}">
|
|
32
34
|
{{>tab-content}}
|
|
33
35
|
{{#if this.ariaDescribedByBodyText}}
|
|
34
36
|
<span class="visually-hidden">{{bodyText}}</span>
|
|
@@ -57,6 +59,7 @@
|
|
|
57
59
|
aria-setsize="{{this._setsize}}"
|
|
58
60
|
aria-controls="{{this._contentId}}"
|
|
59
61
|
aria-selected="{{this.effectiveSelected}}"
|
|
62
|
+
aria-disabled="{{this.ariaDisabled}}"
|
|
60
63
|
._realTab="{{this}}"
|
|
61
64
|
{{#if this.widthStyle}}style="{{this.widthStyle}}"{{/if}}>
|
|
62
65
|
{{>tab-content}}
|
|
@@ -71,6 +74,7 @@
|
|
|
71
74
|
aria-setsize="{{this._setsize}}"
|
|
72
75
|
href="{{href}}"
|
|
73
76
|
target="{{target}}"
|
|
77
|
+
aria-disabled="{{this.ariaDisabled}}"
|
|
74
78
|
{{#if this.widthStyle}}style="{{this.widthStyle}}"{{/if}}
|
|
75
79
|
._realTab="{{this}}">
|
|
76
80
|
{{>tab-content}}
|
package/src/TabInOverflow.hbs
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
class="udex-tab-overflow__button"
|
|
5
5
|
role="tab"
|
|
6
6
|
aria-selected="{{this.effectiveSelected}}"
|
|
7
|
+
aria-disabled="{{this.ariaDisabled}}"
|
|
7
8
|
tabindex="{{_tabIndex}}">
|
|
8
9
|
{{#if hasIcon}}
|
|
9
10
|
<span class="udex-tab-overflow__button-icon"
|
|
@@ -33,6 +34,7 @@
|
|
|
33
34
|
class="udex-tab-overflow__button"
|
|
34
35
|
role="tab"
|
|
35
36
|
aria-selected="{{this.effectiveSelected}}"
|
|
37
|
+
aria-disabled="{{this.ariaDisabled}}"
|
|
36
38
|
tabindex="{{_tabIndex}}">
|
|
37
39
|
{{#if hasIcon}}
|
|
38
40
|
<span class="udex-tab-overflow__button-icon"
|
package/src/TabNavigation.ts
CHANGED
|
@@ -351,9 +351,10 @@ class UDExTabNavigation extends UI5Element {
|
|
|
351
351
|
}
|
|
352
352
|
|
|
353
353
|
setCurrentSelectedTab() {
|
|
354
|
-
const selectedTabs = this.items.filter(tab => tab.selected);
|
|
355
|
-
|
|
356
|
-
this._selectedTab
|
|
354
|
+
const selectedTabs = this.items.filter(tab => tab.selected && !tab.disabled);
|
|
355
|
+
const firstEnabledTab = this.items.find(tab => !tab.disabled) as Tab;
|
|
356
|
+
this._selectedTab = selectedTabs.length ? selectedTabs[0] as Tab : (firstEnabledTab || this.items[0] as Tab);
|
|
357
|
+
this._selectedTab._selected = Boolean(selectedTabs.length ? selectedTabs.length : (firstEnabledTab || this.items[0]));
|
|
357
358
|
}
|
|
358
359
|
|
|
359
360
|
setRealTabToItems() {
|
|
@@ -421,6 +422,11 @@ class UDExTabNavigation extends UI5Element {
|
|
|
421
422
|
e.preventDefault();
|
|
422
423
|
|
|
423
424
|
const selectedTabIndex = (this.items as Array<Tab>).findIndex(item => item.__id === tab.id);
|
|
425
|
+
|
|
426
|
+
if (this.items[selectedTabIndex]?.disabled) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
|
|
424
430
|
this._selectedTab = this.items[selectedTabIndex] as Tab;
|
|
425
431
|
this.updateSelectedTab(selectedTabIndex);
|
|
426
432
|
this.emitClickEvent(selectedTabIndex + 1);
|
|
@@ -649,7 +655,9 @@ class UDExTabNavigation extends UI5Element {
|
|
|
649
655
|
}
|
|
650
656
|
|
|
651
657
|
setVisibleTabs() {
|
|
652
|
-
this._visibleTabs = this.items
|
|
658
|
+
this._visibleTabs = this.items
|
|
659
|
+
.filter(tab => !tab.disabled)
|
|
660
|
+
.map(tab => tab.getTabInHeaderDomRef()!)
|
|
653
661
|
.filter(tab => !tab.hasAttribute("hidden"));
|
|
654
662
|
|
|
655
663
|
if (!this.getMoreButton().hasAttribute("hidden")) {
|
|
@@ -668,14 +676,18 @@ class UDExTabNavigation extends UI5Element {
|
|
|
668
676
|
|
|
669
677
|
setTabsIndex(currentIndex: number) {
|
|
670
678
|
this.items.forEach((tab, index) => {
|
|
671
|
-
tab._tabIndex = index === currentIndex ? "0" : "-1";
|
|
679
|
+
tab._tabIndex = index === currentIndex && !tab.disabled ? "0" : "-1";
|
|
672
680
|
});
|
|
673
681
|
}
|
|
674
682
|
|
|
675
683
|
handleOverflowItemClick(e: Event) {
|
|
676
684
|
if ((e.target as HTMLElement).localName === "button") {
|
|
677
|
-
e.
|
|
678
|
-
this.
|
|
685
|
+
const targetId = (e.target as HTMLElement).id;
|
|
686
|
+
const [targetTab] = this.items.filter(item => item.__id === targetId);
|
|
687
|
+
if (!targetTab?.disabled) {
|
|
688
|
+
e.preventDefault();
|
|
689
|
+
this.onItemSelect(targetId);
|
|
690
|
+
}
|
|
679
691
|
}
|
|
680
692
|
this.handleClosePopover();
|
|
681
693
|
}
|
|
@@ -943,8 +955,12 @@ class UDExTabNavigation extends UI5Element {
|
|
|
943
955
|
handleEnterOrSpace(e: KeyboardEvent) {
|
|
944
956
|
if (isEnter(e) || isSpace(e)) {
|
|
945
957
|
e.preventDefault();
|
|
946
|
-
|
|
947
|
-
this.
|
|
958
|
+
const targetId = (e.target as HTMLElement).id;
|
|
959
|
+
const [targetTab] = this.items.filter(item => item.__id === targetId);
|
|
960
|
+
if (!targetTab?.disabled) {
|
|
961
|
+
this.onItemSelect(targetId);
|
|
962
|
+
this.handleClosePopover();
|
|
963
|
+
}
|
|
948
964
|
}
|
|
949
965
|
}
|
|
950
966
|
|
|
@@ -1038,9 +1054,15 @@ class UDExTabNavigation extends UI5Element {
|
|
|
1038
1054
|
}
|
|
1039
1055
|
|
|
1040
1056
|
_advanceTab(): void {
|
|
1041
|
-
const
|
|
1042
|
-
|
|
1043
|
-
|
|
1057
|
+
const enabledItems = (this.items as Array<Tab>).filter(item => !item.disabled);
|
|
1058
|
+
if (enabledItems.length === 0) {
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
1061
|
+
const currentEnabledIndex = enabledItems.findIndex(item => item === this._selectedTab);
|
|
1062
|
+
const nextEnabledIndex = (currentEnabledIndex + 1) % enabledItems.length;
|
|
1063
|
+
const nextTab = enabledItems[nextEnabledIndex];
|
|
1064
|
+
const nextIndex = (this.items as Array<Tab>).indexOf(nextTab);
|
|
1065
|
+
this._selectedTab = nextTab;
|
|
1044
1066
|
this.updateSelectedTab(nextIndex);
|
|
1045
1067
|
this.emitClickEvent(nextIndex + 1);
|
|
1046
1068
|
}
|