@sapudex/web-components 2.51.0 → 2.52.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/CountrySelector.cy.tsx +21 -0
- package/cypress/specs/List.cy.tsx +119 -10
- package/cypress/specs/SelectBox.cy.tsx +414 -70
- package/dist/CountrySelector.js +1 -0
- package/dist/CountrySelector.js.map +1 -1
- package/dist/List.d.ts +10 -0
- package/dist/List.js +35 -0
- package/dist/List.js.map +1 -1
- package/dist/ListGroupHeaderBase.js +3 -0
- package/dist/ListGroupHeaderBase.js.map +1 -1
- package/dist/ListItem.d.ts +1 -0
- package/dist/ListItem.js +11 -3
- package/dist/ListItem.js.map +1 -1
- package/dist/ListItemBase.d.ts +9 -0
- package/dist/ListItemBase.js +12 -0
- package/dist/ListItemBase.js.map +1 -1
- package/dist/ListSelectAll.js +1 -1
- package/dist/ListSelectAll.js.map +1 -1
- package/dist/SearchableListBase.d.ts +10 -0
- package/dist/SearchableListBase.js +29 -6
- package/dist/SearchableListBase.js.map +1 -1
- package/dist/SearchableListBaseTemplate.js +32 -5
- package/dist/SearchableListBaseTemplate.js.map +1 -1
- package/dist/SelectBase.d.ts +65 -1
- package/dist/SelectBase.js +446 -59
- package/dist/SelectBase.js.map +1 -1
- package/dist/SelectBox.js +24 -2
- package/dist/SelectBox.js.map +1 -1
- package/dist/SelectBoxTemplate.js +2 -2
- package/dist/SelectBoxTemplate.js.map +1 -1
- package/dist/assets/{InputSuggestions-7eP5S95I.js → InputSuggestions-0wafO-g3.js} +1 -1
- package/dist/assets/{ListItemStandardExpandableTextTemplate-CLcWBFcg.js → ListItemStandardExpandableTextTemplate-DoOYtqI8.js} +1 -1
- package/dist/assets/{bundle.esm-D4--IDh7.js → bundle.esm-DwHZ3nCW.js} +241 -241
- package/dist/assets/messagebundle_nl-BKUpVV-D.js +1 -0
- package/dist/css/themes/AccordionItem.css +1 -1
- package/dist/css/themes/Divider.css +1 -1
- package/dist/css/themes/Link.css +1 -1
- package/dist/css/themes/ListGroupHeader.css +1 -1
- package/dist/css/themes/ListItem.css +1 -1
- package/dist/css/themes/SelectBase.css +1 -1
- package/dist/css/themes/SelectBox.css +1 -1
- package/dist/generated/assets/i18n/messagebundle_nl.json +1 -1
- package/dist/generated/templates/ListTemplate.lit.js +1 -1
- package/dist/generated/templates/ListTemplate.lit.js.map +1 -1
- package/dist/generated/themes/AccordionItem.css.d.ts +1 -1
- package/dist/generated/themes/AccordionItem.css.js +1 -1
- package/dist/generated/themes/AccordionItem.css.js.map +1 -1
- package/dist/generated/themes/Divider.css.d.ts +1 -1
- package/dist/generated/themes/Divider.css.js +1 -1
- package/dist/generated/themes/Divider.css.js.map +1 -1
- package/dist/generated/themes/Link.css.d.ts +1 -1
- package/dist/generated/themes/Link.css.js +1 -1
- package/dist/generated/themes/Link.css.js.map +1 -1
- package/dist/generated/themes/ListGroupHeader.css.d.ts +1 -1
- package/dist/generated/themes/ListGroupHeader.css.js +1 -1
- package/dist/generated/themes/ListGroupHeader.css.js.map +1 -1
- package/dist/generated/themes/ListItem.css.d.ts +1 -1
- package/dist/generated/themes/ListItem.css.js +1 -1
- package/dist/generated/themes/ListItem.css.js.map +1 -1
- package/dist/generated/themes/SelectBase.css.d.ts +1 -1
- package/dist/generated/themes/SelectBase.css.js +1 -1
- package/dist/generated/themes/SelectBase.css.js.map +1 -1
- package/dist/generated/themes/SelectBox.css.d.ts +1 -1
- package/dist/generated/themes/SelectBox.css.js +1 -1
- package/dist/generated/themes/SelectBox.css.js.map +1 -1
- package/dist/messagebundle_nl.properties +126 -0
- package/dist/web-types.json +1 -1
- package/package.json +1 -1
- package/src/CountrySelector.ts +1 -0
- package/src/List.hbs +2 -1
- package/src/List.ts +36 -0
- package/src/ListGroupHeaderBase.ts +3 -0
- package/src/ListItem.ts +12 -3
- package/src/ListItemBase.ts +11 -0
- package/src/ListSelectAll.ts +1 -1
- package/src/SearchableListBase.ts +31 -8
- package/src/SearchableListBaseTemplate.tsx +38 -6
- package/src/SelectBase.ts +466 -69
- package/src/SelectBox.ts +27 -2
- package/src/SelectBoxTemplate.tsx +4 -3
- package/src/generated/templates/ListTemplate.lit.ts +1 -1
- package/src/generated/themes/AccordionItem.css.ts +1 -1
- package/src/generated/themes/Divider.css.ts +1 -1
- package/src/generated/themes/Link.css.ts +1 -1
- package/src/generated/themes/ListGroupHeader.css.ts +1 -1
- package/src/generated/themes/ListItem.css.ts +1 -1
- package/src/generated/themes/SelectBase.css.ts +1 -1
- package/src/generated/themes/SelectBox.css.ts +1 -1
- package/src/i18n/messagebundle_nl.properties +126 -0
- package/src/themes/AccordionItem.css +8 -3
- package/src/themes/Divider.css +2 -0
- package/src/themes/Link.css +20 -2
- package/src/themes/ListGroupHeader.css +18 -1
- package/src/themes/ListItem.css +2 -1
- package/src/themes/SelectBase.css +2 -1
- package/src/themes/SelectBox.css +10 -0
- package/dist/assets/messagebundle_nl-etaldyfo.js +0 -1
package/dist/SelectBase.js
CHANGED
|
@@ -7,19 +7,21 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import property from "@ui5/webcomponents-base/dist/decorators/property.js";
|
|
8
8
|
import slot from "@ui5/webcomponents-base/dist/decorators/slot-strict.js";
|
|
9
9
|
import executeTemplate from "@ui5/webcomponents-base/dist/renderer/executeTemplate.js";
|
|
10
|
-
import { isEscape, isDown, isUp, isHome, isEnd, isTabNext, isTabPrevious, isLeft, isRight, } from "@ui5/webcomponents-base/dist/Keys.js";
|
|
10
|
+
import { isEscape, isDown, isUp, isHome, isEnd, isTabNext, isTabPrevious, isLeft, isRight, isEnter, isSpace, } from "@ui5/webcomponents-base/dist/Keys.js";
|
|
11
11
|
import { getAllAccessibleNameRefTexts } from "@ui5/webcomponents-base/dist/util/AccessibilityTextsHelper.js";
|
|
12
|
+
import { cleanLabel } from "./utils/listItemLabelUtils.js";
|
|
12
13
|
import "@ui5/webcomponents-icons/dist/decline.js";
|
|
13
14
|
import "@ui5/webcomponents-icons/dist/navigation-down-arrow.js";
|
|
14
|
-
import { COUNTRY_SELECT, STARS } from "./generated/i18n/i18n-defaults.js";
|
|
15
|
+
import { COUNTRY_SELECT, STARS, SELECTED, UNSELECTED, INDETERMINATE, DISABLED, } from "./generated/i18n/i18n-defaults.js";
|
|
15
16
|
import SearchableListBaseTemplate from "./SearchableListBaseTemplate.js";
|
|
16
17
|
import CountrySelectorTemplate from "./CountrySelectorTemplate.js";
|
|
17
18
|
import ResizeHandler from "@ui5/webcomponents-base/delegate/ResizeHandler.js";
|
|
18
19
|
import UDExSearchableListBase from "./SearchableListBase.js";
|
|
19
20
|
import UDExValueState from "./types/common.js";
|
|
20
|
-
import { getTokensCountText } from "@ui5/webcomponents/dist/Tokenizer.js";
|
|
21
|
+
import Tokenizer, { getTokensCountText } from "@ui5/webcomponents/dist/Tokenizer.js";
|
|
21
22
|
import isLetterKey from "./utils/isLetterKeyPressed.js";
|
|
22
23
|
import translate from "./utils/translate.js";
|
|
24
|
+
import { renderFinished } from "@ui5/webcomponents-base/dist/Render.js";
|
|
23
25
|
/**
|
|
24
26
|
* @class
|
|
25
27
|
*
|
|
@@ -52,6 +54,22 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
52
54
|
* @private
|
|
53
55
|
*/
|
|
54
56
|
this._requestRender = false;
|
|
57
|
+
/**
|
|
58
|
+
* True while keyboard list navigation is active (aria-activedescendant set).
|
|
59
|
+
* Used in CSS to suppress the input focus ring and show the active item ring.
|
|
60
|
+
*
|
|
61
|
+
* @private
|
|
62
|
+
*/
|
|
63
|
+
this._navigating = false;
|
|
64
|
+
/**
|
|
65
|
+
* Text read by screen readers when the active item changes.
|
|
66
|
+
* Announced via an aria-live="assertive" region in the template.
|
|
67
|
+
* This works regardless of shadow DOM / popover teleportation because
|
|
68
|
+
* the live region lives inside SelectBox's own shadow root.
|
|
69
|
+
*
|
|
70
|
+
* @private
|
|
71
|
+
*/
|
|
72
|
+
this._liveRegionText = "";
|
|
55
73
|
this._paneWidthVariableName = "--udex-dropdown-pane-width";
|
|
56
74
|
this._labelBaseClass = "udex-text-field__label";
|
|
57
75
|
this._dropdownClass = "udex-select-box__dropdown";
|
|
@@ -62,6 +80,7 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
62
80
|
this._inputValue = "";
|
|
63
81
|
this._lastSelectedItemId = "";
|
|
64
82
|
this._listKeyDownListenerAdded = false;
|
|
83
|
+
this._activeDescendantItem = null;
|
|
65
84
|
this._handleResizeBound = this._handleResize.bind(this);
|
|
66
85
|
this._handleListKeyDownBound = this._handleListKeyDownCapture.bind(this);
|
|
67
86
|
}
|
|
@@ -84,6 +103,7 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
84
103
|
}
|
|
85
104
|
}
|
|
86
105
|
onAfterRendering() {
|
|
106
|
+
super.onAfterRendering();
|
|
87
107
|
this._popover = this.getPopover();
|
|
88
108
|
this._search = this.getSearch();
|
|
89
109
|
this._list = this.getList();
|
|
@@ -91,6 +111,10 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
91
111
|
this.handleDirection();
|
|
92
112
|
if (this._list) {
|
|
93
113
|
this._list._scrollIntoView = "Nearest";
|
|
114
|
+
// Set a stable HTML id on the udex-list host so aria-controls can reference it.
|
|
115
|
+
if (!this._list.id) {
|
|
116
|
+
this._list.id = `${this._id}-list`;
|
|
117
|
+
}
|
|
94
118
|
}
|
|
95
119
|
if (this._requestRender) {
|
|
96
120
|
this._requestRender = false;
|
|
@@ -103,6 +127,98 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
103
127
|
_handleResize() {
|
|
104
128
|
this.updatePopoverWidth();
|
|
105
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Given a candidate index, skips over a non-interactive non-collapsible header if needed.
|
|
132
|
+
* Returns the effective target index.
|
|
133
|
+
*/
|
|
134
|
+
_skipNonInteractive(items, raw, lastIndex, direction) {
|
|
135
|
+
if (!items[raw]?.nonInteractive || items[raw].collapsible) {
|
|
136
|
+
return raw;
|
|
137
|
+
}
|
|
138
|
+
if (direction === "down") {
|
|
139
|
+
return raw + 1 > lastIndex ? 0 : raw + 1;
|
|
140
|
+
}
|
|
141
|
+
return raw === 0 ? lastIndex : raw - 1;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Sets or clears the aria-activedescendant on the combobox input and updates
|
|
145
|
+
* the aria-live region so JAWS/VoiceOver announce the item name and position.
|
|
146
|
+
* The live region is the primary announcement mechanism because aria-activedescendant
|
|
147
|
+
* across a UI5 Popover (which teleports content to document.body) is unreliable —
|
|
148
|
+
* screen readers cannot follow the ID reference across shadow root boundaries.
|
|
149
|
+
*/
|
|
150
|
+
_setActiveDescendant(item, scroll = true) {
|
|
151
|
+
this._activeDescendantItem = item;
|
|
152
|
+
// Query the SelectBox's OWN shadow DOM for all elements bearing the class —
|
|
153
|
+
// this reaches the rendered udex-list-group-header / udex-list-item elements
|
|
154
|
+
// regardless of whether they are the current or a previously stale instance.
|
|
155
|
+
this.shadowRoot?.querySelectorAll("._udex-active-descendant")
|
|
156
|
+
.forEach(el => {
|
|
157
|
+
el.classList.remove("_udex-active-descendant");
|
|
158
|
+
el.removeAttribute("_active-descendant");
|
|
159
|
+
});
|
|
160
|
+
if (!item) {
|
|
161
|
+
this._search.removeAttribute("aria-activedescendant");
|
|
162
|
+
this._liveRegionText = "";
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
item.classList.add("_udex-active-descendant");
|
|
166
|
+
item.setAttribute("_active-descendant", "");
|
|
167
|
+
this._search.setAttribute("aria-activedescendant", item._id);
|
|
168
|
+
// Update the live region with tree-aware position and state so JAWS/VoiceOver
|
|
169
|
+
// announce the active item regardless of whether the popover is teleported to document.body.
|
|
170
|
+
if (this._list) {
|
|
171
|
+
const label = cleanLabel(item.label ?? "");
|
|
172
|
+
const supporting = item.supportingText ? cleanLabel(item.supportingText) : "";
|
|
173
|
+
const stateParts = this._itemStateLabels(item);
|
|
174
|
+
const posText = this._treePositionText(item);
|
|
175
|
+
this._liveRegionText = [label, supporting, posText, ...stateParts].filter(Boolean).join(", ");
|
|
176
|
+
}
|
|
177
|
+
if (scroll && this._list?._scrollIntoView) {
|
|
178
|
+
// Only scroll if the item is not already fully visible in the dropdown.
|
|
179
|
+
const popoverContent = this._popover?.shadowRoot?.querySelector("[part=content]");
|
|
180
|
+
if (popoverContent) {
|
|
181
|
+
const itemRect = item.getBoundingClientRect();
|
|
182
|
+
const containerRect = popoverContent.getBoundingClientRect();
|
|
183
|
+
const isVisible = itemRect.top >= containerRect.top && itemRect.bottom <= containerRect.bottom;
|
|
184
|
+
if (!isVisible) {
|
|
185
|
+
this._list.scrollToItem(item);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
this._list.scrollToItem(item);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Activates the first navigable item as the aria-activedescendant without moving DOM focus.
|
|
195
|
+
*/
|
|
196
|
+
_activateFirstItem() {
|
|
197
|
+
const items = this._list?.getKeyboardNavigationItems();
|
|
198
|
+
if (!items?.length) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const firstIndex = (items[0]?.nonInteractive && !items[0]?.collapsible) ? 1 : 0;
|
|
202
|
+
this._list.setTabIndexByIndex(items, firstIndex);
|
|
203
|
+
this._setActiveDescendant(items[firstIndex], false);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Navigates to the item at the given index, updating aria-activedescendant and _selectedOption.
|
|
207
|
+
*/
|
|
208
|
+
_navigateToIndex(items, nextIndex) {
|
|
209
|
+
const currentIndex = this._activeDescendantItem
|
|
210
|
+
? this._list.getCurrentIndex(items, this._activeDescendantItem)
|
|
211
|
+
: -1;
|
|
212
|
+
if (currentIndex >= 0) {
|
|
213
|
+
this._list.unsetTabIndexByIndex(items, currentIndex);
|
|
214
|
+
}
|
|
215
|
+
this._list.setTabIndexByIndex(items, nextIndex);
|
|
216
|
+
this._selectedOption = items[nextIndex].label;
|
|
217
|
+
if (this.showImageFlags) {
|
|
218
|
+
this.handleImagePosition(items, nextIndex);
|
|
219
|
+
}
|
|
220
|
+
this._setActiveDescendant(items[nextIndex]);
|
|
221
|
+
}
|
|
106
222
|
handleKeyDownDropdown(e) {
|
|
107
223
|
const items = this._list?.getKeyboardNavigationItems();
|
|
108
224
|
if (isLetterKey(e.key)) {
|
|
@@ -153,39 +269,40 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
153
269
|
if (!items) {
|
|
154
270
|
return;
|
|
155
271
|
}
|
|
156
|
-
if (isRight(e)) {
|
|
272
|
+
if (isRight(e) || isLeft(e)) {
|
|
157
273
|
e.preventDefault();
|
|
158
|
-
|
|
274
|
+
// Resolve the collapsible group header from the active descendant (not e.target,
|
|
275
|
+
// since DOM focus stays on the input and e.target is the input element).
|
|
276
|
+
const activeHeader = this._activeDescendantItem
|
|
277
|
+
? this._resolveCollapsibleGroupHeader(this._activeDescendantItem)
|
|
278
|
+
: null;
|
|
279
|
+
if (activeHeader && this._handleGroupHeaderCollapse(activeHeader, isLeft(e))) {
|
|
159
280
|
return;
|
|
160
281
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
return;
|
|
282
|
+
// Fall through to icon-row navigation when focus is on an icon button
|
|
283
|
+
if (isRight(e)) {
|
|
284
|
+
this._handleArrowRightInRow(e.target);
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
this._handleArrowLeftInRow(e.target);
|
|
168
288
|
}
|
|
169
|
-
this._handleArrowLeftInRow(e.target);
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
const iconSlot = this._getIconButtonSlot(e.target);
|
|
173
|
-
const effectiveTarget = iconSlot
|
|
174
|
-
? e.target.parentElement
|
|
175
|
-
: undefined;
|
|
176
|
-
this.handleListNavigationKeys(e, items, effectiveTarget);
|
|
177
|
-
}
|
|
178
|
-
handleListNavigationKeys(e, items, effectiveTarget) {
|
|
179
|
-
const currentSelectedIndex = this._list?.getCurrentIndex(items, effectiveTarget ?? e.target);
|
|
180
|
-
const lastItemIndex = items.length - 1;
|
|
181
|
-
if (isDown(e)) {
|
|
182
|
-
e.preventDefault();
|
|
183
|
-
this.handleDownKeyPress(items, currentSelectedIndex, lastItemIndex);
|
|
184
289
|
return;
|
|
185
290
|
}
|
|
186
|
-
if (isUp(e)) {
|
|
291
|
+
if (isDown(e) || isUp(e)) {
|
|
187
292
|
e.preventDefault();
|
|
188
|
-
|
|
293
|
+
const lastIndex = items.length - 1;
|
|
294
|
+
const currentItem = this._activeDescendantItem;
|
|
295
|
+
const currentIndex = currentItem ? this._list.getCurrentIndex(items, currentItem) : -1;
|
|
296
|
+
let nextIndex;
|
|
297
|
+
if (isDown(e)) {
|
|
298
|
+
const raw = currentIndex + 1 > lastIndex ? 0 : currentIndex + 1;
|
|
299
|
+
nextIndex = this._skipNonInteractive(items, raw, lastIndex, "down");
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
const raw = currentIndex - 1 < 0 ? lastIndex : currentIndex - 1;
|
|
303
|
+
nextIndex = this._skipNonInteractive(items, raw, lastIndex, "up");
|
|
304
|
+
}
|
|
305
|
+
this._navigateToIndex(items, nextIndex);
|
|
189
306
|
return;
|
|
190
307
|
}
|
|
191
308
|
if (isHome(e)) {
|
|
@@ -195,21 +312,17 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
195
312
|
}
|
|
196
313
|
if (isEnd(e)) {
|
|
197
314
|
e.preventDefault();
|
|
198
|
-
this.handleEndKeyPress(items,
|
|
315
|
+
this.handleEndKeyPress(items, items.length - 1);
|
|
199
316
|
}
|
|
317
|
+
// Icon-button slot: Up/Down while an icon button is focused (handled by capture listener).
|
|
318
|
+
// _handleListKeyDownCapture fires first via capture; nothing else needed here.
|
|
200
319
|
}
|
|
201
320
|
handleEndKeyPress(items, lastItemIndex) {
|
|
202
|
-
|
|
203
|
-
this.handleImagePosition(items, lastItemIndex);
|
|
204
|
-
}
|
|
205
|
-
this._selectedOption = items[lastItemIndex].label;
|
|
321
|
+
this._navigateToIndex(items, lastItemIndex);
|
|
206
322
|
}
|
|
207
323
|
handleHomeKeyPress(items) {
|
|
208
324
|
const firstIndex = (items[0]?.nonInteractive && !items[0]?.collapsible) ? 1 : 0;
|
|
209
|
-
this.
|
|
210
|
-
if (this.showImageFlags) {
|
|
211
|
-
this.handleImagePosition(items, firstIndex);
|
|
212
|
-
}
|
|
325
|
+
this._navigateToIndex(items, firstIndex);
|
|
213
326
|
}
|
|
214
327
|
handleDownKeyPress(items, currentSelectedIndex, lastItemIndex) {
|
|
215
328
|
const nextIndex = currentSelectedIndex + 1;
|
|
@@ -257,6 +370,7 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
257
370
|
handleEscKeyPress(e) {
|
|
258
371
|
e.preventDefault();
|
|
259
372
|
e.stopPropagation();
|
|
373
|
+
this._setActiveDescendant(null);
|
|
260
374
|
this.closeDropdown();
|
|
261
375
|
this._search.focus();
|
|
262
376
|
this._selectedOption = "";
|
|
@@ -267,9 +381,30 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
267
381
|
this._lastSelectedItemId = this.getDataTokenId(item);
|
|
268
382
|
this.resetSearchState();
|
|
269
383
|
if (this.modeSingleSelect) {
|
|
384
|
+
// SingleSelect closes the dropdown — clear active descendant.
|
|
385
|
+
this._setActiveDescendant(null);
|
|
270
386
|
this._search.focus();
|
|
271
387
|
this.closeDropdown();
|
|
388
|
+
return;
|
|
272
389
|
}
|
|
390
|
+
// MultiSelect: ensure active descendant tracks the interacted item so there
|
|
391
|
+
// is only one ring. Find the rendered item in the navigation list by matching
|
|
392
|
+
// data-token-id (the source item's _id set by the template) since e.detail.item
|
|
393
|
+
// is the source element, not the rendered udex-list-item.
|
|
394
|
+
const tokenId = this.getDataTokenId(item);
|
|
395
|
+
const navItems = this._list?.getKeyboardNavigationItems();
|
|
396
|
+
const renderedItem = navItems?.find(i => (i.getAttribute("data-token-id") ?? i._id) === tokenId);
|
|
397
|
+
if (renderedItem && renderedItem !== this._activeDescendantItem) {
|
|
398
|
+
this._setActiveDescendant(renderedItem);
|
|
399
|
+
}
|
|
400
|
+
// Return DOM focus to the input so the clicked item loses its :focus ring.
|
|
401
|
+
// Without this, the browser keeps focus on the item (from the click) and a
|
|
402
|
+
// second ring appears when arrow keys move _activeDescendantItem elsewhere.
|
|
403
|
+
this._search.focus();
|
|
404
|
+
// Re-announce with the updated checked/unchecked state. The rendered item's
|
|
405
|
+
// `selected` prop is updated on the next render cycle (template re-render),
|
|
406
|
+
// so we wait for it before re-reading state labels.
|
|
407
|
+
renderFinished().then(() => this._announceCurrentOrFirst()).catch(() => { });
|
|
273
408
|
}
|
|
274
409
|
onKeyDownSearch(e) {
|
|
275
410
|
const items = this._list?.getKeyboardNavigationItems();
|
|
@@ -281,31 +416,135 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
281
416
|
const isEscAndPopoverOpened = isEscape(e) && popoverOpened;
|
|
282
417
|
const isDownAndPopoverClosed = isDown(e) && !popoverOpened;
|
|
283
418
|
const isDownAndPopoverOpened = isDown(e) && popoverOpened;
|
|
419
|
+
const isUpAndPopoverOpened = isUp(e) && popoverOpened;
|
|
420
|
+
// Tab while popup is open: move focus to the first footer element if one exists,
|
|
421
|
+
// otherwise close the dropdown and move past the component.
|
|
422
|
+
if (popoverOpened && isTabNext(e)) {
|
|
423
|
+
e.preventDefault();
|
|
424
|
+
if (this.hasFooter) {
|
|
425
|
+
this._setActiveDescendant(null);
|
|
426
|
+
(this._firstFocusableIn(this.footer[0]) ?? this.footer[0])?.focus();
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
this.closeDropdown();
|
|
430
|
+
this._moveFocusAfterComponent();
|
|
431
|
+
}
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
// Shift+Tab while popup is open: close the dropdown.
|
|
435
|
+
// DOM focus stays on the search input throughout (our aria-activedescendant model
|
|
436
|
+
// never moves focus away from the input), so no explicit re-focus is needed.
|
|
437
|
+
if (popoverOpened && isTabPrevious(e)) {
|
|
438
|
+
e.preventDefault();
|
|
439
|
+
this._setActiveDescendant(null);
|
|
440
|
+
this.closeDropdown();
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
284
443
|
if (!hasItems) {
|
|
285
444
|
return;
|
|
286
445
|
}
|
|
287
446
|
const firstIndex = (items[0]?.nonInteractive && !items[0]?.collapsible) ? 1 : 0;
|
|
288
|
-
const firstItem = items[firstIndex];
|
|
289
447
|
if (isEscAndPopoverOpened) {
|
|
290
448
|
return this.closeDropdown();
|
|
291
449
|
}
|
|
292
450
|
if (isDownAndPopoverClosed) {
|
|
293
451
|
e.preventDefault();
|
|
294
452
|
this.openDropdown();
|
|
295
|
-
this.
|
|
296
|
-
this._selectedOption = firstItem.label;
|
|
453
|
+
this._activateFirstItem();
|
|
297
454
|
if (this.showImageFlags) {
|
|
298
|
-
this.handleImagePosition(items,
|
|
455
|
+
this.handleImagePosition(items, firstIndex);
|
|
299
456
|
}
|
|
300
457
|
return;
|
|
301
458
|
}
|
|
302
459
|
if (isDownAndPopoverOpened) {
|
|
303
460
|
e.preventDefault();
|
|
304
|
-
if (this.
|
|
305
|
-
|
|
461
|
+
if (this._activeDescendantItem) {
|
|
462
|
+
const lastIndex = items.length - 1;
|
|
463
|
+
const currentIndex = this._list.getCurrentIndex(items, this._activeDescendantItem);
|
|
464
|
+
const raw = currentIndex + 1 > lastIndex ? 0 : currentIndex + 1;
|
|
465
|
+
const nextIndex = this._skipNonInteractive(items, raw, lastIndex, "down");
|
|
466
|
+
this._navigateToIndex(items, nextIndex);
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
this._activateFirstItem();
|
|
470
|
+
// Also update _selectedOption so the input reflects the active item.
|
|
471
|
+
const activeIdx = (items[0]?.nonInteractive && !items[0]?.collapsible) ? 1 : 0;
|
|
472
|
+
this._selectedOption = items[activeIdx].label;
|
|
473
|
+
if (this.showImageFlags) {
|
|
474
|
+
this.handleImagePosition(items, activeIdx);
|
|
475
|
+
}
|
|
306
476
|
}
|
|
307
|
-
|
|
308
|
-
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
if (isUpAndPopoverOpened) {
|
|
480
|
+
e.preventDefault();
|
|
481
|
+
if (this._activeDescendantItem) {
|
|
482
|
+
const lastIndex = items.length - 1;
|
|
483
|
+
const currentIndex = this._list.getCurrentIndex(items, this._activeDescendantItem);
|
|
484
|
+
const raw = currentIndex - 1 < 0 ? lastIndex : currentIndex - 1;
|
|
485
|
+
const nextIndex = this._skipNonInteractive(items, raw, lastIndex, "up");
|
|
486
|
+
this._navigateToIndex(items, nextIndex);
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
this._navigateToIndex(items, items.length - 1);
|
|
490
|
+
}
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
if (popoverOpened && isHome(e)) {
|
|
494
|
+
e.preventDefault();
|
|
495
|
+
const homeIndex = (items[0]?.nonInteractive && !items[0]?.collapsible) ? 1 : 0;
|
|
496
|
+
this._navigateToIndex(items, homeIndex);
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
if (popoverOpened && isEnd(e)) {
|
|
500
|
+
e.preventDefault();
|
|
501
|
+
this._navigateToIndex(items, items.length - 1);
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
// Enter/Space: select the active descendant item (or toggle for MultiSelect).
|
|
505
|
+
if (popoverOpened && this._activeDescendantItem && (isEnter(e) || isSpace(e))) {
|
|
506
|
+
e.preventDefault();
|
|
507
|
+
const activeItem = this._activeDescendantItem;
|
|
508
|
+
if (activeItem.isGroup) {
|
|
509
|
+
// Group header: fire header-press (same event the click handler fires) so
|
|
510
|
+
// handleHeaderPress → onHeaderPress → handleGroupHeaderSelection runs.
|
|
511
|
+
activeItem.fireDecoratorEvent("header-press", { item: activeItem });
|
|
512
|
+
}
|
|
513
|
+
else {
|
|
514
|
+
// Leaf item: fire item-press so the list handles selection consistently.
|
|
515
|
+
// Do NOT toggle .selected directly — handleItemClick (called via onItemPress)
|
|
516
|
+
// handles the toggle, and double-toggling would be a no-op.
|
|
517
|
+
activeItem.fireDecoratorEvent("item-press", {
|
|
518
|
+
selected: activeItem.selected,
|
|
519
|
+
item: activeItem,
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
// Left/Right: collapse/expand the active group header when popup is open.
|
|
525
|
+
if (popoverOpened && (isLeft(e) || isRight(e))) {
|
|
526
|
+
e.preventDefault();
|
|
527
|
+
const activeHeader = this._activeDescendantItem
|
|
528
|
+
? this._resolveCollapsibleGroupHeader(this._activeDescendantItem)
|
|
529
|
+
: null;
|
|
530
|
+
if (activeHeader) {
|
|
531
|
+
this._handleGroupHeaderCollapse(activeHeader, isLeft(e));
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
// Fall through to icon-row navigation when the active item has icon slots.
|
|
535
|
+
if (this._activeDescendantItem) {
|
|
536
|
+
if (isRight(e)) {
|
|
537
|
+
this._handleArrowRightInRow(this._activeDescendantItem);
|
|
538
|
+
}
|
|
539
|
+
else {
|
|
540
|
+
this._handleArrowLeftInRow(this._activeDescendantItem);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
// Sync _selectedOption display for the first item (used when popover just opened via click).
|
|
546
|
+
if (!this._activeDescendantItem && hasItems) {
|
|
547
|
+
this._selectedOption = items[firstIndex].label;
|
|
309
548
|
}
|
|
310
549
|
}
|
|
311
550
|
handleSearchChange(e) {
|
|
@@ -319,6 +558,14 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
319
558
|
this.openDropdown();
|
|
320
559
|
}
|
|
321
560
|
}
|
|
561
|
+
onSearch(value) {
|
|
562
|
+
super.onSearch(value);
|
|
563
|
+
// Route search result count into the shared live region so SelectBox
|
|
564
|
+
// only needs one aria-live span (no separate polite span in the template).
|
|
565
|
+
if (this._accSearchResultInfo) {
|
|
566
|
+
this._liveRegionText = this._accSearchResultInfo;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
322
569
|
handleDirection() {
|
|
323
570
|
const directionStyles = window.getComputedStyle(this).getPropertyValue("direction");
|
|
324
571
|
this._direction = directionStyles || "ltr";
|
|
@@ -334,11 +581,81 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
334
581
|
this.fireEventDropdownBeforeOpen();
|
|
335
582
|
}
|
|
336
583
|
handleDropdownOpen() {
|
|
337
|
-
if
|
|
584
|
+
// Scroll to the previously selected/active item if there is one,
|
|
585
|
+
// otherwise scroll to top. Do NOT pre-activate any item — that is done
|
|
586
|
+
// by the first ArrowDown so that ArrowDown[1]=item[0], ArrowDown[2]=item[1].
|
|
587
|
+
if (this.activeItem) {
|
|
588
|
+
const items = this._list?.getKeyboardNavigationItems();
|
|
589
|
+
const active = items?.find(i => !i.isGroup && i.selected);
|
|
590
|
+
if (active && this._list?._scrollIntoView) {
|
|
591
|
+
this._list.scrollToItem(active);
|
|
592
|
+
}
|
|
593
|
+
else {
|
|
594
|
+
this._dropdownScrollToTop();
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
else {
|
|
338
598
|
this._dropdownScrollToTop();
|
|
339
599
|
}
|
|
600
|
+
// Announce the visually focused item (fake focus outline on first item).
|
|
601
|
+
// Using polite politeness — it waits for the AT to finish announcing
|
|
602
|
+
// "expanded" before reading the item, so no timeout is needed.
|
|
603
|
+
// Clear first so the mutation fires even if the text is unchanged from
|
|
604
|
+
// the previous open, then populate after render completes.
|
|
605
|
+
this._liveRegionText = "";
|
|
606
|
+
renderFinished().then(() => this._announceCurrentOrFirst()).catch(() => { });
|
|
340
607
|
this.fireEventDropdownOpen();
|
|
341
608
|
}
|
|
609
|
+
/**
|
|
610
|
+
* Announces the currently active descendant item (if set), or the first
|
|
611
|
+
* navigable item as a fallback. Used on open and after state changes.
|
|
612
|
+
*/
|
|
613
|
+
_announceCurrentOrFirst() {
|
|
614
|
+
const items = this._list?.getKeyboardNavigationItems();
|
|
615
|
+
if (!items?.length) {
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
const item = this._activeDescendantItem ?? items.find(i => !i.nonInteractive || i.collapsible) ?? items[0];
|
|
619
|
+
if (!item) {
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
const label = cleanLabel(item.label ?? "");
|
|
623
|
+
const stateParts = this._itemStateLabels(item);
|
|
624
|
+
const posText = this._treePositionText(item);
|
|
625
|
+
this._liveRegionText = [label, posText, ...stateParts].filter(Boolean).join(", ");
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Returns the positional announcement text for an item, tree-aware when the
|
|
629
|
+
* list has groups. Matches the JAWS reading pattern of FilterMenu:
|
|
630
|
+
* group header → "level 0, X of Y" (Y = total navigable groups)
|
|
631
|
+
* group child → "level 1, X of Y" (Y = siblings in that group)
|
|
632
|
+
* flat item → "X of Y" (Y = total items, no level prefix)
|
|
633
|
+
*/
|
|
634
|
+
_treePositionText(item) {
|
|
635
|
+
if (!this.isTreeStructure) {
|
|
636
|
+
const items = this._list?.getKeyboardNavigationItems() ?? [];
|
|
637
|
+
const pos = items.indexOf(item);
|
|
638
|
+
return pos >= 0 ? `${pos + 1} of ${items.length}` : "";
|
|
639
|
+
}
|
|
640
|
+
if (item.isGroup) {
|
|
641
|
+
// Position among navigable group headers.
|
|
642
|
+
const groups = (this._list?.getKeyboardNavigationItems() ?? []).filter(i => i.isGroup);
|
|
643
|
+
const pos = groups.indexOf(item);
|
|
644
|
+
return pos >= 0 ? `level 0, ${pos + 1} of ${groups.length}` : "level 0";
|
|
645
|
+
}
|
|
646
|
+
// Child item — find parent group and count siblings visible in navigation.
|
|
647
|
+
const parentGroup = item.parentElement;
|
|
648
|
+
if (parentGroup?.isGroup) {
|
|
649
|
+
const navItems = this._list?.getKeyboardNavigationItems() ?? [];
|
|
650
|
+
const siblings = navItems.filter(i => !i.isGroup && i.parentElement === parentGroup);
|
|
651
|
+
const pos = siblings.indexOf(item);
|
|
652
|
+
return pos >= 0 ? `level 1, ${pos + 1} of ${siblings.length}` : "level 1";
|
|
653
|
+
}
|
|
654
|
+
// Fallback: flat position.
|
|
655
|
+
const all = this._list?.getKeyboardNavigationItems() ?? [];
|
|
656
|
+
const pos = all.indexOf(item);
|
|
657
|
+
return pos >= 0 ? `${pos + 1} of ${all.length}` : "";
|
|
658
|
+
}
|
|
342
659
|
fireEventDropdownBeforeOClose() {
|
|
343
660
|
this.fireDecoratorEvent("before-close");
|
|
344
661
|
}
|
|
@@ -372,11 +689,14 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
372
689
|
this._popover.opener = this._trigger;
|
|
373
690
|
this._popover.open = true;
|
|
374
691
|
this._open = true;
|
|
692
|
+
this._navigating = true;
|
|
693
|
+
this._focused = false;
|
|
375
694
|
}
|
|
376
695
|
closeDropdown() {
|
|
377
696
|
if (this._popover.open) {
|
|
378
697
|
this._open = false;
|
|
379
698
|
this._popover.open = false;
|
|
699
|
+
this._navigating = false;
|
|
380
700
|
}
|
|
381
701
|
}
|
|
382
702
|
inputFocusIn() {
|
|
@@ -436,11 +756,13 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
436
756
|
if (collapse && !header.collapsed) {
|
|
437
757
|
header.collapsed = true;
|
|
438
758
|
this._list.setCollapsedItems(true, header);
|
|
759
|
+
renderFinished().then(() => this._announceCurrentOrFirst()).catch(() => { });
|
|
439
760
|
return true;
|
|
440
761
|
}
|
|
441
762
|
if (!collapse && header.collapsed) {
|
|
442
763
|
header.collapsed = false;
|
|
443
764
|
this._list.setCollapsedItems(false, header);
|
|
765
|
+
renderFinished().then(() => this._announceCurrentOrFirst()).catch(() => { });
|
|
444
766
|
return true;
|
|
445
767
|
}
|
|
446
768
|
// Target is a collapsible header but already in the requested state — still consume
|
|
@@ -467,7 +789,12 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
467
789
|
const iconSlot = this._getIconButtonSlot(target);
|
|
468
790
|
if (!iconSlot) {
|
|
469
791
|
const firstIcon = target.querySelector("[slot=\"firstIcon\"]");
|
|
470
|
-
firstIcon
|
|
792
|
+
if (firstIcon) {
|
|
793
|
+
// Entering icon row: clear the active descendant ring so the list item
|
|
794
|
+
// doesn't show two simultaneous outlines alongside the icon's :focus ring.
|
|
795
|
+
this._setActiveDescendant(null);
|
|
796
|
+
firstIcon.focus();
|
|
797
|
+
}
|
|
471
798
|
return;
|
|
472
799
|
}
|
|
473
800
|
if (iconSlot === "firstIcon") {
|
|
@@ -492,7 +819,18 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
492
819
|
firstIcon?.focus();
|
|
493
820
|
}
|
|
494
821
|
else if (iconSlot === "firstIcon") {
|
|
495
|
-
|
|
822
|
+
// Return to the list item: restore the active descendant ring and return
|
|
823
|
+
// DOM focus to the input so the icon's :focus ring is cleared.
|
|
824
|
+
const navItems = this._list?.getKeyboardNavigationItems();
|
|
825
|
+
const tokenId = this.getDataTokenId(parentItem);
|
|
826
|
+
const renderedItem = navItems?.find(i => (i.getAttribute("data-token-id") ?? i._id) === tokenId);
|
|
827
|
+
if (renderedItem) {
|
|
828
|
+
this._setActiveDescendant(renderedItem);
|
|
829
|
+
}
|
|
830
|
+
else {
|
|
831
|
+
this._list.focusItem(parentItem);
|
|
832
|
+
}
|
|
833
|
+
this._search.focus();
|
|
496
834
|
}
|
|
497
835
|
}
|
|
498
836
|
_handleListKeyDownCapture(e) {
|
|
@@ -533,7 +871,7 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
533
871
|
}
|
|
534
872
|
this._list.unsetTabIndexByIndex(items, currentIndex);
|
|
535
873
|
this._list.setTabIndexByIndex(items, targetIndex);
|
|
536
|
-
this.
|
|
874
|
+
this._setActiveDescendant(items[targetIndex]);
|
|
537
875
|
this._selectedOption = items[targetIndex].label;
|
|
538
876
|
}
|
|
539
877
|
_focusLastListItem() {
|
|
@@ -543,15 +881,11 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
543
881
|
return;
|
|
544
882
|
}
|
|
545
883
|
const lastIndex = items.length - 1;
|
|
546
|
-
const lastItem = items[lastIndex];
|
|
547
884
|
this._list.setTabIndexByIndex(items, lastIndex);
|
|
548
|
-
this._selectedOption =
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
else {
|
|
553
|
-
this._list.focusItem(lastItem);
|
|
554
|
-
}
|
|
885
|
+
this._selectedOption = items[lastIndex].label;
|
|
886
|
+
this._setActiveDescendant(items[lastIndex]);
|
|
887
|
+
// Return DOM focus to the search input (aria-activedescendant model).
|
|
888
|
+
this._search.focus();
|
|
555
889
|
}
|
|
556
890
|
_firstFocusableIn(el) {
|
|
557
891
|
if (!(el instanceof HTMLElement)) {
|
|
@@ -580,11 +914,49 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
580
914
|
};
|
|
581
915
|
findAndFocus(this);
|
|
582
916
|
}
|
|
917
|
+
/**
|
|
918
|
+
* Builds the state portion of the live region announcement for a navigation item.
|
|
919
|
+
* Returns an array of state strings (e.g. ["collapsed", "Checked"]) to be joined
|
|
920
|
+
* with the label and position. Handles:
|
|
921
|
+
* - collapsible group headers: expanded / collapsed
|
|
922
|
+
* - MultiSelect: Checked / Unchecked / Indeterminate
|
|
923
|
+
* - SingleSelect (tree): Selected / Unselected
|
|
924
|
+
* - disabled: Disabled
|
|
925
|
+
*/
|
|
926
|
+
_itemStateLabels(item) {
|
|
927
|
+
const parts = [];
|
|
928
|
+
if (item.collapsible) {
|
|
929
|
+
// Use plain English — matches what AT announce for aria-expanded.
|
|
930
|
+
parts.push(item.expanded ? "expanded" : "collapsed");
|
|
931
|
+
}
|
|
932
|
+
if (item.disabled) {
|
|
933
|
+
parts.push(translate(UDExSearchableListBase, DISABLED));
|
|
934
|
+
}
|
|
935
|
+
else if (item.modeMultiSelect || (item.isGroup && this.modeMultiSelect)) {
|
|
936
|
+
if (item.indeterminate) {
|
|
937
|
+
parts.push(translate(UDExSearchableListBase, INDETERMINATE));
|
|
938
|
+
}
|
|
939
|
+
else {
|
|
940
|
+
parts.push(translate(UDExSearchableListBase, item.selected ? SELECTED : UNSELECTED));
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
else if (this.isTreeStructure && item.selected) {
|
|
944
|
+
// SingleSelect tree: only announce "Selected" when the item is actually selected.
|
|
945
|
+
parts.push(translate(UDExSearchableListBase, SELECTED));
|
|
946
|
+
}
|
|
947
|
+
return parts;
|
|
948
|
+
}
|
|
583
949
|
get ariaDescribedbyText() {
|
|
584
950
|
if (this.modeSingleSelect) {
|
|
585
|
-
return this._selectedOption;
|
|
951
|
+
return this._navigating ? "" : this._selectedOption;
|
|
586
952
|
}
|
|
587
953
|
const tags = this.selectedItems.filter(item => !item.isGroup);
|
|
954
|
+
// Tokenizer.i18nBundle may not be loaded yet on direct page load.
|
|
955
|
+
// Return empty string until the bundle is available; the component re-renders
|
|
956
|
+
// once i18n is ready and will pick up the correct text.
|
|
957
|
+
if (!Tokenizer.i18nBundle) {
|
|
958
|
+
return "";
|
|
959
|
+
}
|
|
588
960
|
return getTokensCountText(tags.length);
|
|
589
961
|
}
|
|
590
962
|
get trigger() {
|
|
@@ -624,6 +996,15 @@ class UDExSelectBase extends UDExSearchableListBase {
|
|
|
624
996
|
get listboxRole() {
|
|
625
997
|
return this._listBoxRole;
|
|
626
998
|
}
|
|
999
|
+
get listAriaControlsId() {
|
|
1000
|
+
return this._list?.id || this.popoverId;
|
|
1001
|
+
}
|
|
1002
|
+
get _activeDescendantMode() {
|
|
1003
|
+
return true;
|
|
1004
|
+
}
|
|
1005
|
+
get isTreeStructure() {
|
|
1006
|
+
return this._filteredItems.some(e => e.isGroup);
|
|
1007
|
+
}
|
|
627
1008
|
get hideDropdownSearch() {
|
|
628
1009
|
return true;
|
|
629
1010
|
}
|
|
@@ -686,6 +1067,12 @@ __decorate([
|
|
|
686
1067
|
__decorate([
|
|
687
1068
|
property({ type: Boolean, noAttribute: true })
|
|
688
1069
|
], UDExSelectBase.prototype, "_requestRender", void 0);
|
|
1070
|
+
__decorate([
|
|
1071
|
+
property({ type: Boolean })
|
|
1072
|
+
], UDExSelectBase.prototype, "_navigating", void 0);
|
|
1073
|
+
__decorate([
|
|
1074
|
+
property({ type: String, noAttribute: true })
|
|
1075
|
+
], UDExSelectBase.prototype, "_liveRegionText", void 0);
|
|
689
1076
|
__decorate([
|
|
690
1077
|
slot({ type: HTMLElement })
|
|
691
1078
|
], UDExSelectBase.prototype, "footer", void 0);
|