@ebay/ui-core-react 7.4.0-alpha.7 → 7.4.0-alpha.8
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/array.polyfill.flat-DyxysTxZ.js +21 -0
- package/badge-CR5t7-2L.js +8 -0
- package/button-B4bZIgwB.js +83 -0
- package/calendar-D-DWjrMU.js +333 -0
- package/common/component-utils/forwardRef/index.js +10 -1
- package/common/component-utils/index.js +9 -1
- package/common/component-utils/utils/index.js +25 -1
- package/common/event-utils/index.js +113 -1
- package/common/floating-label-utils/hooks/index.js +106 -1
- package/common/notice-utils/notice-cta/index.js +5 -1
- package/common/random-id/index.js +13 -1
- package/common/tooltip-utils/constants/index.js +97 -1
- package/common/tooltip-utils/index.js +11 -1
- package/debounce-v8bWAUnY.js +9 -0
- package/dialog-previous-button-EC_Y6KaT.js +370 -0
- package/drawer-DBDktEBZ.js +69 -0
- package/ebay-alert-dialog/index.js +26 -1
- package/ebay-badge/index.js +4 -1
- package/ebay-breadcrumbs/index.js +47 -1
- package/ebay-button/index.js +5 -1
- package/ebay-calendar/index.js +4 -1
- package/ebay-carousel/index.js +345 -1
- package/ebay-checkbox/index.js +52 -1
- package/ebay-confirm-dialog/index.js +28 -1
- package/ebay-cta-button/index.js +22 -1
- package/ebay-date-textbox/index.js +140 -1
- package/ebay-dialog-base/components/animation/index.js +92 -1
- package/ebay-dialog-base/components/dialog-footer/index.js +4 -1
- package/ebay-dialog-base/components/dialog-header/index.js +4 -1
- package/ebay-dialog-base/index.js +13 -1
- package/ebay-drawer-dialog/index.js +4 -1
- package/ebay-eek/index.js +54 -1
- package/ebay-fake-menu/index.js +10 -1
- package/ebay-fake-menu/menu-item/index.js +49 -1
- package/ebay-fake-menu-button/index.js +7 -1
- package/ebay-fake-menu-button/menu-button/index.js +12 -1
- package/ebay-fake-tabs/index.js +30 -1
- package/ebay-field/index.js +21 -1
- package/ebay-fullscreen-dialog/index.js +10 -1
- package/ebay-icon/index.js +4 -1
- package/ebay-icon-button/index.js +4 -1
- package/ebay-infotip/index.js +76 -1
- package/ebay-inline-notice/index.js +36 -1
- package/ebay-lightbox-dialog/index.js +12 -1
- package/ebay-listbox/index.js +6 -1
- package/ebay-listbox-button/index.js +151 -1
- package/ebay-menu/index.js +9 -1
- package/ebay-menu-button/index.js +113 -1
- package/ebay-notice-base/index.js +7 -1
- package/ebay-page-notice/index.js +50 -1
- package/ebay-pagination/index.js +244 -1
- package/ebay-panel-dialog/index.js +12 -1
- package/ebay-progress-bar/index.js +6 -1
- package/ebay-progress-spinner/index.js +4 -1
- package/ebay-progress-stepper/index.js +72 -1
- package/ebay-radio/index.js +4 -1
- package/ebay-radio/radio/index.js +48 -1
- package/ebay-section-notice/index.js +69 -1
- package/ebay-section-title/index.js +38 -1
- package/ebay-segmented-buttons/index.js +46 -1
- package/ebay-select/index.js +98 -1
- package/ebay-signal/index.js +9 -1
- package/ebay-snackbar-dialog/index.js +81 -1
- package/ebay-split-button/index.js +22 -1
- package/ebay-star-rating/index.js +9 -1
- package/ebay-star-rating-select/index.js +55 -1
- package/ebay-svg/index.js +5189 -1
- package/ebay-switch/index.js +27 -1
- package/ebay-tabs/index.js +88 -1
- package/ebay-textbox/index.js +10 -1
- package/ebay-toast-dialog/index.js +9 -1
- package/ebay-tooltip/index.js +64 -1
- package/ebay-tourtip/index.js +54 -1
- package/ebay-video/index.js +229 -1
- package/events/index.js +18 -1
- package/icon-B17Di3YL.js +56 -0
- package/icon-button-BQWoMgX1.js +31 -0
- package/index-BXizW4ue.js +89 -0
- package/index-DcH7Tjjd.js +272 -0
- package/label-C0AS4fnO.js +19 -0
- package/listbox-DGbY99kq.js +674 -0
- package/menu-Bsy48CE1.js +163 -0
- package/menu-button-CKGsgg6G.js +89 -0
- package/menu-fCOy6wBS.js +29 -0
- package/notice-content-BTXVxttv.js +8 -0
- package/notice-content-BhUeK1pd.js +3 -0
- package/notice-footer-CIQ8SM6N.js +10 -0
- package/package.json +1 -1
- package/progress-spinner-DOFKRtuu.js +20 -0
- package/range-C5qzyhg4.js +3 -0
- package/textbox-J291yCpJ.js +136 -0
- package/use-roving-index-CEM_UsCH.js +58 -0
- package/use-tooltip-7JxcZHJn.js +92 -0
- package/utils/index.js +13 -1
- package/array.polyfill.flat-5BAolFdk.js +0 -1
- package/badge-CoHKfiPt.js +0 -1
- package/button-DGuEBUDJ.js +0 -1
- package/calendar-lAu6VfAb.js +0 -1
- package/debounce-BQsYxxOL.js +0 -1
- package/dialog-previous-button-5cTKpmJ-.js +0 -1
- package/drawer-xTtCoO3F.js +0 -1
- package/icon-TuxfQndO.js +0 -1
- package/icon-button-Cwaj-eT9.js +0 -1
- package/index-D3xZmuzJ.js +0 -1
- package/index-Dkz0UnlJ.js +0 -1
- package/label-CnrpYJ-g.js +0 -1
- package/listbox-Br0AMj3v.js +0 -1
- package/menu-CV-INYLM.js +0 -1
- package/menu-_LzP6yje.js +0 -1
- package/menu-button-BZ66jxvI.js +0 -1
- package/notice-content-9iF4T8uB.js +0 -1
- package/notice-content-C0ZStfuX.js +0 -1
- package/notice-footer-Cw1DMzoB.js +0 -1
- package/progress-spinner-U2qOANON.js +0 -1
- package/range-DOsPN0h5.js +0 -1
- package/textbox-dUhinDwj.js +0 -1
- package/use-roving-index-DoAVBgsp.js +0 -1
- package/use-tooltip-CL3_zAeg.js +0 -1
|
@@ -0,0 +1,674 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const React = require("react");
|
|
3
|
+
const index = require("./index-BXizW4ue.js");
|
|
4
|
+
const classNames = require("classnames");
|
|
5
|
+
const common_componentUtils_utils = require("./common/component-utils/utils/index.js");
|
|
6
|
+
const icon = require("./icon-B17Di3YL.js");
|
|
7
|
+
function uncapitalizeFirstLetter(str) {
|
|
8
|
+
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
9
|
+
}
|
|
10
|
+
function onKeyDownOrUp(evt, el, keyEventType) {
|
|
11
|
+
if (!evt.shiftKey) {
|
|
12
|
+
const key = evt.key;
|
|
13
|
+
switch (key) {
|
|
14
|
+
case "Enter":
|
|
15
|
+
case "Escape":
|
|
16
|
+
case "PageUp":
|
|
17
|
+
case "PageDown":
|
|
18
|
+
case "End":
|
|
19
|
+
case "Home":
|
|
20
|
+
case "ArrowLeft":
|
|
21
|
+
case "ArrowUp":
|
|
22
|
+
case "ArrowRight":
|
|
23
|
+
case "ArrowDown":
|
|
24
|
+
el.dispatchEvent(
|
|
25
|
+
new CustomEvent(uncapitalizeFirstLetter(`${key}Key${keyEventType}`), {
|
|
26
|
+
detail: evt,
|
|
27
|
+
bubbles: true
|
|
28
|
+
})
|
|
29
|
+
);
|
|
30
|
+
break;
|
|
31
|
+
case " ":
|
|
32
|
+
el.dispatchEvent(
|
|
33
|
+
new CustomEvent(`spacebarKey${keyEventType}`, {
|
|
34
|
+
detail: evt,
|
|
35
|
+
bubbles: true
|
|
36
|
+
})
|
|
37
|
+
);
|
|
38
|
+
break;
|
|
39
|
+
default:
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function onKeyDown(e) {
|
|
45
|
+
onKeyDownOrUp(e, this, "Down");
|
|
46
|
+
}
|
|
47
|
+
function addKeyDown(el) {
|
|
48
|
+
el.addEventListener("keydown", onKeyDown);
|
|
49
|
+
}
|
|
50
|
+
function removeKeyDown(el) {
|
|
51
|
+
el.removeEventListener("keydown", onKeyDown);
|
|
52
|
+
}
|
|
53
|
+
const defaultOptions$1 = {
|
|
54
|
+
axis: "both",
|
|
55
|
+
autoInit: "interactive",
|
|
56
|
+
autoReset: "current",
|
|
57
|
+
ignoreByDelegateSelector: null,
|
|
58
|
+
wrap: false
|
|
59
|
+
};
|
|
60
|
+
function isItemNavigable(el) {
|
|
61
|
+
return !el.hidden && el.getAttribute("aria-disabled") !== "true";
|
|
62
|
+
}
|
|
63
|
+
function isIndexNavigable(items, index2) {
|
|
64
|
+
return index2 >= 0 && index2 < items.length ? isItemNavigable(items[index2]) : false;
|
|
65
|
+
}
|
|
66
|
+
function findNavigableItems(items) {
|
|
67
|
+
return items.filter(isItemNavigable);
|
|
68
|
+
}
|
|
69
|
+
function findFirstNavigableIndex(items) {
|
|
70
|
+
return items.findIndex((item) => isItemNavigable(item));
|
|
71
|
+
}
|
|
72
|
+
function findLastNavigableIndex(items) {
|
|
73
|
+
return items.indexOf(findNavigableItems(items).reverse()[0]);
|
|
74
|
+
}
|
|
75
|
+
function findIndexByAttribute(items, attribute, value) {
|
|
76
|
+
return items.findIndex((item) => isItemNavigable(item) && item.getAttribute(attribute) === value);
|
|
77
|
+
}
|
|
78
|
+
function findFirstNavigableAriaCheckedIndex(items) {
|
|
79
|
+
return findIndexByAttribute(items, "aria-checked", "true");
|
|
80
|
+
}
|
|
81
|
+
function findFirstNavigableAriaSelectedIndex(items) {
|
|
82
|
+
return findIndexByAttribute(items, "aria-selected", "true");
|
|
83
|
+
}
|
|
84
|
+
function findIgnoredByDelegateItems(el, options) {
|
|
85
|
+
return options.ignoreByDelegateSelector !== null ? [...el.querySelectorAll(options.ignoreByDelegateSelector)] : [];
|
|
86
|
+
}
|
|
87
|
+
function findPreviousNavigableIndex(items, index2, wrap) {
|
|
88
|
+
let previousNavigableIndex = -1;
|
|
89
|
+
if (index2 === null || atStart(items, index2)) {
|
|
90
|
+
if (wrap === true) {
|
|
91
|
+
previousNavigableIndex = findLastNavigableIndex(items);
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
let i = index2;
|
|
95
|
+
while (--i >= 0) {
|
|
96
|
+
if (isItemNavigable(items[i])) {
|
|
97
|
+
previousNavigableIndex = i;
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return previousNavigableIndex;
|
|
103
|
+
}
|
|
104
|
+
function findNextNavigableIndex(items, index2, wrap) {
|
|
105
|
+
let nextNavigableIndex = -1;
|
|
106
|
+
if (index2 === null) {
|
|
107
|
+
nextNavigableIndex = findFirstNavigableIndex(items);
|
|
108
|
+
} else if (atEnd(items, index2)) {
|
|
109
|
+
if (wrap === true) {
|
|
110
|
+
nextNavigableIndex = findFirstNavigableIndex(items);
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
let i = index2;
|
|
114
|
+
while (++i < items.length) {
|
|
115
|
+
if (isItemNavigable(items[i])) {
|
|
116
|
+
nextNavigableIndex = i;
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return nextNavigableIndex;
|
|
122
|
+
}
|
|
123
|
+
function findIndexPositionByType(typeOrNum, items, currentIndex) {
|
|
124
|
+
let index2 = -1;
|
|
125
|
+
switch (typeOrNum) {
|
|
126
|
+
case "none":
|
|
127
|
+
index2 = null;
|
|
128
|
+
break;
|
|
129
|
+
case "current":
|
|
130
|
+
index2 = currentIndex;
|
|
131
|
+
break;
|
|
132
|
+
case "interactive":
|
|
133
|
+
index2 = findFirstNavigableIndex(items);
|
|
134
|
+
break;
|
|
135
|
+
case "ariaChecked":
|
|
136
|
+
index2 = findFirstNavigableAriaCheckedIndex(items);
|
|
137
|
+
break;
|
|
138
|
+
case "ariaSelected":
|
|
139
|
+
index2 = findFirstNavigableAriaSelectedIndex(items);
|
|
140
|
+
break;
|
|
141
|
+
case "ariaSelectedOrInteractive":
|
|
142
|
+
index2 = findFirstNavigableAriaSelectedIndex(items);
|
|
143
|
+
index2 = index2 === -1 ? findFirstNavigableIndex(items) : index2;
|
|
144
|
+
break;
|
|
145
|
+
default:
|
|
146
|
+
index2 = typeof typeOrNum === "number" || typeOrNum === null ? typeOrNum : -1;
|
|
147
|
+
}
|
|
148
|
+
return index2;
|
|
149
|
+
}
|
|
150
|
+
function atStart(items, index2) {
|
|
151
|
+
return index2 === findFirstNavigableIndex(items);
|
|
152
|
+
}
|
|
153
|
+
function atEnd(items, index2) {
|
|
154
|
+
return index2 === findLastNavigableIndex(items);
|
|
155
|
+
}
|
|
156
|
+
function onKeyPrev(e) {
|
|
157
|
+
const ignoredByDelegateItems = findIgnoredByDelegateItems(this._el, this.options);
|
|
158
|
+
if (ignoredByDelegateItems.length === 0 || !ignoredByDelegateItems.includes(e.detail.target)) {
|
|
159
|
+
this.index = findPreviousNavigableIndex(this.items, this.index, this.options.wrap);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function onKeyNext(e) {
|
|
163
|
+
const ignoredByDelegateItems = findIgnoredByDelegateItems(this._el, this.options);
|
|
164
|
+
if (ignoredByDelegateItems.length === 0 || !ignoredByDelegateItems.includes(e.detail.target)) {
|
|
165
|
+
this.index = findNextNavigableIndex(this.items, this.index, this.options.wrap);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function onClick(e) {
|
|
169
|
+
const itemIndex = this.indexOf(e.target.closest(this._itemSelector));
|
|
170
|
+
if (isIndexNavigable(this.items, itemIndex)) {
|
|
171
|
+
this.index = itemIndex;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function onKeyHome(e) {
|
|
175
|
+
const ignoredByDelegateItems = findIgnoredByDelegateItems(this._el, this.options);
|
|
176
|
+
if (ignoredByDelegateItems.length === 0 || !ignoredByDelegateItems.includes(e.detail.target)) {
|
|
177
|
+
this.index = findFirstNavigableIndex(this.items);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function onKeyEnd(e) {
|
|
181
|
+
const ignoredByDelegateItems = findIgnoredByDelegateItems(this._el, this.options);
|
|
182
|
+
if (ignoredByDelegateItems.length === 0 || !ignoredByDelegateItems.includes(e.detail.target)) {
|
|
183
|
+
this.index = findLastNavigableIndex(this.items);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function onFocusExit() {
|
|
187
|
+
if (this.options.autoReset !== null) {
|
|
188
|
+
this.reset();
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function onMutation(e) {
|
|
192
|
+
const fromIndex = this.index;
|
|
193
|
+
let toIndex = this.index;
|
|
194
|
+
const { addedNodes, attributeName, removedNodes, target, type } = e[0];
|
|
195
|
+
if (type === "attributes") {
|
|
196
|
+
if (target === this.currentItem) {
|
|
197
|
+
if (attributeName === "aria-disabled") {
|
|
198
|
+
toIndex = this.index;
|
|
199
|
+
} else if (attributeName === "hidden") {
|
|
200
|
+
toIndex = findFirstNavigableIndex(this.items);
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
toIndex = this.index;
|
|
204
|
+
}
|
|
205
|
+
} else if (type === "childList") {
|
|
206
|
+
if (removedNodes.length > 0 && [...removedNodes].includes(this._cachedElement)) {
|
|
207
|
+
toIndex = findFirstNavigableIndex(this.items);
|
|
208
|
+
} else if (removedNodes.length > 0 || addedNodes.length > 0) {
|
|
209
|
+
toIndex = this.indexOf(this._cachedElement);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
this._index = toIndex;
|
|
213
|
+
this._el.dispatchEvent(
|
|
214
|
+
new CustomEvent("navigationModelMutation", {
|
|
215
|
+
bubbles: false,
|
|
216
|
+
detail: { fromIndex, toIndex }
|
|
217
|
+
})
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
class NavigationModel {
|
|
221
|
+
/**
|
|
222
|
+
* @param {HTMLElement} el
|
|
223
|
+
* @param {string} itemSelector
|
|
224
|
+
* @param {typeof defaultOptions} selectedOptions
|
|
225
|
+
*/
|
|
226
|
+
constructor(el, itemSelector, selectedOptions) {
|
|
227
|
+
this.options = Object.assign({}, defaultOptions$1, selectedOptions);
|
|
228
|
+
this._el = el;
|
|
229
|
+
this._itemSelector = itemSelector;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
class LinearNavigationModel extends NavigationModel {
|
|
233
|
+
/**
|
|
234
|
+
* @param {HTMLElement} el
|
|
235
|
+
* @param {string} itemSelector
|
|
236
|
+
* @param {typeof defaultOptions} selectedOptions
|
|
237
|
+
*/
|
|
238
|
+
constructor(el, itemSelector, selectedOptions) {
|
|
239
|
+
super(el, itemSelector, selectedOptions);
|
|
240
|
+
const fromIndex = this._index;
|
|
241
|
+
const toIndex = findIndexPositionByType(this.options.autoInit, this.items, this.index);
|
|
242
|
+
this._index = toIndex;
|
|
243
|
+
this._cachedElement = this.items[toIndex];
|
|
244
|
+
this._el.dispatchEvent(
|
|
245
|
+
new CustomEvent("navigationModelInit", {
|
|
246
|
+
bubbles: false,
|
|
247
|
+
detail: {
|
|
248
|
+
firstInteractiveIndex: this.firstNavigableIndex,
|
|
249
|
+
fromIndex,
|
|
250
|
+
items: this.items,
|
|
251
|
+
toIndex
|
|
252
|
+
}
|
|
253
|
+
})
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
get currentItem() {
|
|
257
|
+
return this.items[this.index];
|
|
258
|
+
}
|
|
259
|
+
// todo: code smell as getter abstracts that the query selector re-runs every time getter is accessed
|
|
260
|
+
get items() {
|
|
261
|
+
return [...this._el.querySelectorAll(`${this._itemSelector}`)];
|
|
262
|
+
}
|
|
263
|
+
get index() {
|
|
264
|
+
return this._index;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* @param {number} toIndex - update index position in this.items (non-interactive indexes fail silently)
|
|
268
|
+
*/
|
|
269
|
+
set index(toIndex) {
|
|
270
|
+
if (toIndex === this.index) {
|
|
271
|
+
return;
|
|
272
|
+
} else if (!isIndexNavigable(this.items, toIndex)) ;
|
|
273
|
+
else {
|
|
274
|
+
const fromIndex = this.index;
|
|
275
|
+
this._cachedElement = this.items[toIndex];
|
|
276
|
+
this._index = toIndex;
|
|
277
|
+
this._el.dispatchEvent(
|
|
278
|
+
new CustomEvent("navigationModelChange", {
|
|
279
|
+
bubbles: false,
|
|
280
|
+
detail: { fromIndex, toIndex }
|
|
281
|
+
})
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
indexOf(element) {
|
|
286
|
+
return this.items.indexOf(element);
|
|
287
|
+
}
|
|
288
|
+
reset() {
|
|
289
|
+
const fromIndex = this.index;
|
|
290
|
+
const toIndex = findIndexPositionByType(this.options.autoReset, this.items, this.index);
|
|
291
|
+
if (toIndex !== fromIndex) {
|
|
292
|
+
this._index = toIndex;
|
|
293
|
+
this._el.dispatchEvent(
|
|
294
|
+
new CustomEvent("navigationModelReset", {
|
|
295
|
+
bubbles: false,
|
|
296
|
+
detail: { fromIndex, toIndex }
|
|
297
|
+
})
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
class NavigationEmitter {
|
|
303
|
+
/**
|
|
304
|
+
* @param {HTMLElement} el
|
|
305
|
+
* @param {LinearNavigationModel} model
|
|
306
|
+
*/
|
|
307
|
+
constructor(el, model) {
|
|
308
|
+
this.model = model;
|
|
309
|
+
this.el = el;
|
|
310
|
+
this._keyPrevListener = onKeyPrev.bind(model);
|
|
311
|
+
this._keyNextListener = onKeyNext.bind(model);
|
|
312
|
+
this._keyHomeListener = onKeyHome.bind(model);
|
|
313
|
+
this._keyEndListener = onKeyEnd.bind(model);
|
|
314
|
+
this._clickListener = onClick.bind(model);
|
|
315
|
+
this._focusExitListener = onFocusExit.bind(model);
|
|
316
|
+
this._observer = new MutationObserver(onMutation.bind(model));
|
|
317
|
+
addKeyDown(this.el);
|
|
318
|
+
index.addFocusExit(this.el);
|
|
319
|
+
const axis = model.options.axis;
|
|
320
|
+
if (axis === "both" || axis === "x") {
|
|
321
|
+
this.el.addEventListener("arrowLeftKeyDown", this._keyPrevListener);
|
|
322
|
+
this.el.addEventListener("arrowRightKeyDown", this._keyNextListener);
|
|
323
|
+
}
|
|
324
|
+
if (axis === "both" || axis === "y") {
|
|
325
|
+
this.el.addEventListener("arrowUpKeyDown", this._keyPrevListener);
|
|
326
|
+
this.el.addEventListener("arrowDownKeyDown", this._keyNextListener);
|
|
327
|
+
}
|
|
328
|
+
this.el.addEventListener("homeKeyDown", this._keyHomeListener);
|
|
329
|
+
this.el.addEventListener("endKeyDown", this._keyEndListener);
|
|
330
|
+
this.el.addEventListener("click", this._clickListener);
|
|
331
|
+
this.el.addEventListener("focusExit", this._focusExitListener);
|
|
332
|
+
this._observer.observe(this.el, {
|
|
333
|
+
childList: true,
|
|
334
|
+
subtree: true,
|
|
335
|
+
attributeFilter: ["aria-disabled", "hidden"],
|
|
336
|
+
attributes: true,
|
|
337
|
+
attributeOldValue: true
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
destroy() {
|
|
341
|
+
removeKeyDown(this.el);
|
|
342
|
+
index.removeFocusExit(this.el);
|
|
343
|
+
this.el.removeEventListener("arrowLeftKeyDown", this._keyPrevListener);
|
|
344
|
+
this.el.removeEventListener("arrowRightKeyDown", this._keyNextListener);
|
|
345
|
+
this.el.removeEventListener("arrowUpKeyDown", this._keyPrevListener);
|
|
346
|
+
this.el.removeEventListener("arrowDownKeyDown", this._keyNextListener);
|
|
347
|
+
this.el.removeEventListener("homeKeyDown", this._keyHomeListener);
|
|
348
|
+
this.el.removeEventListener("endKeyDown", this._keyEndListener);
|
|
349
|
+
this.el.removeEventListener("click", this._clickListener);
|
|
350
|
+
this.el.removeEventListener("focusExit", this._focusExitListener);
|
|
351
|
+
this._observer.disconnect();
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
function createLinear$1(el, itemSelector, selectedOptions) {
|
|
355
|
+
const model = new LinearNavigationModel(el, itemSelector, selectedOptions);
|
|
356
|
+
return new NavigationEmitter(el, model);
|
|
357
|
+
}
|
|
358
|
+
const defaultOptions = {
|
|
359
|
+
activeDescendantClassName: "active-descendant",
|
|
360
|
+
autoInit: "none",
|
|
361
|
+
autoReset: "none",
|
|
362
|
+
autoScroll: false,
|
|
363
|
+
axis: "both",
|
|
364
|
+
wrap: false
|
|
365
|
+
};
|
|
366
|
+
function onModelInit(e) {
|
|
367
|
+
const { items, toIndex } = e.detail;
|
|
368
|
+
const itemEl = items[toIndex];
|
|
369
|
+
if (itemEl) {
|
|
370
|
+
itemEl.classList.add(this._options.activeDescendantClassName);
|
|
371
|
+
this._focusEl.setAttribute("aria-activedescendant", itemEl.id);
|
|
372
|
+
}
|
|
373
|
+
this._el.dispatchEvent(new CustomEvent("activeDescendantInit", { detail: e.detail }));
|
|
374
|
+
}
|
|
375
|
+
function onModelChange(e) {
|
|
376
|
+
const { fromIndex, toIndex } = e.detail;
|
|
377
|
+
const fromItem = this.items[fromIndex];
|
|
378
|
+
const toItem = this.items[toIndex];
|
|
379
|
+
if (fromItem) {
|
|
380
|
+
fromItem.classList.remove(this._options.activeDescendantClassName);
|
|
381
|
+
}
|
|
382
|
+
if (toItem) {
|
|
383
|
+
toItem.classList.add(this._options.activeDescendantClassName);
|
|
384
|
+
this._focusEl.setAttribute("aria-activedescendant", toItem.id);
|
|
385
|
+
if (this._options.autoScroll && this._itemContainerEl) {
|
|
386
|
+
toItem.scrollIntoView({ block: "center" });
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
this._el.dispatchEvent(new CustomEvent("activeDescendantChange", { detail: e.detail }));
|
|
390
|
+
}
|
|
391
|
+
function onModelReset(e) {
|
|
392
|
+
const toIndex = e.detail.toIndex;
|
|
393
|
+
const activeClassName = this._options.activeDescendantClassName;
|
|
394
|
+
this.items.forEach(function(el) {
|
|
395
|
+
el.classList.remove(activeClassName);
|
|
396
|
+
});
|
|
397
|
+
if (toIndex !== null && toIndex !== -1) {
|
|
398
|
+
const itemEl = this.items[toIndex];
|
|
399
|
+
itemEl.classList.add(activeClassName);
|
|
400
|
+
this._focusEl.setAttribute("aria-activedescendant", itemEl.id);
|
|
401
|
+
} else {
|
|
402
|
+
this._focusEl.removeAttribute("aria-activedescendant");
|
|
403
|
+
}
|
|
404
|
+
this._el.dispatchEvent(new CustomEvent("activeDescendantReset", { detail: e.detail }));
|
|
405
|
+
}
|
|
406
|
+
function onModelMutation(e) {
|
|
407
|
+
const { toIndex } = e.detail;
|
|
408
|
+
const activeDescendantClassName = this._options.activeDescendantClassName;
|
|
409
|
+
this.items.forEach(function(item, index$1) {
|
|
410
|
+
index.src_default(item);
|
|
411
|
+
if (index$1 !== toIndex) {
|
|
412
|
+
item.classList.remove(activeDescendantClassName);
|
|
413
|
+
} else {
|
|
414
|
+
item.classList.add(activeDescendantClassName);
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
this._el.dispatchEvent(new CustomEvent("activeDescendantMutation", { detail: e.detail }));
|
|
418
|
+
}
|
|
419
|
+
class ActiveDescendant {
|
|
420
|
+
constructor(el) {
|
|
421
|
+
this._el = el;
|
|
422
|
+
this._onMutationListener = onModelMutation.bind(this);
|
|
423
|
+
this._onChangeListener = onModelChange.bind(this);
|
|
424
|
+
this._onResetListener = onModelReset.bind(this);
|
|
425
|
+
this._onInitListener = onModelInit.bind(this);
|
|
426
|
+
this._el.addEventListener("navigationModelMutation", this._onMutationListener);
|
|
427
|
+
this._el.addEventListener("navigationModelChange", this._onChangeListener);
|
|
428
|
+
this._el.addEventListener("navigationModelReset", this._onResetListener);
|
|
429
|
+
this._el.addEventListener("navigationModelInit", this._onInitListener);
|
|
430
|
+
}
|
|
431
|
+
destroy() {
|
|
432
|
+
this._el.removeEventListener("navigationModelMutation", this._onMutationListener);
|
|
433
|
+
this._el.removeEventListener("navigationModelChange", this._onChangeListener);
|
|
434
|
+
this._el.removeEventListener("navigationModelReset", this._onResetListener);
|
|
435
|
+
this._el.removeEventListener("navigationModelInit", this._onInitListener);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
class LinearActiveDescendant extends ActiveDescendant {
|
|
439
|
+
constructor(el, focusEl, itemContainerEl, itemSelector, selectedOptions) {
|
|
440
|
+
super(el);
|
|
441
|
+
this._options = Object.assign({}, defaultOptions, selectedOptions);
|
|
442
|
+
this._focusEl = focusEl;
|
|
443
|
+
this._itemContainerEl = itemContainerEl;
|
|
444
|
+
this._itemSelector = itemSelector;
|
|
445
|
+
index.src_default(this._itemContainerEl);
|
|
446
|
+
if (this._itemContainerEl !== this._focusEl) {
|
|
447
|
+
focusEl.setAttribute("aria-owns", this._itemContainerEl.id);
|
|
448
|
+
}
|
|
449
|
+
this._navigationEmitter = createLinear$1(el, itemSelector, {
|
|
450
|
+
autoInit: this._options.autoInit,
|
|
451
|
+
autoReset: this._options.autoReset,
|
|
452
|
+
axis: this._options.axis,
|
|
453
|
+
ignoreByDelegateSelector: this._options.ignoreByDelegateSelector,
|
|
454
|
+
wrap: this._options.wrap
|
|
455
|
+
});
|
|
456
|
+
this.items.forEach(function(itemEl) {
|
|
457
|
+
index.src_default(itemEl);
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
get index() {
|
|
461
|
+
return this._navigationEmitter.model.index;
|
|
462
|
+
}
|
|
463
|
+
set index(newIndex) {
|
|
464
|
+
this._navigationEmitter.model.index = newIndex;
|
|
465
|
+
}
|
|
466
|
+
reset() {
|
|
467
|
+
this._navigationEmitter.model.reset();
|
|
468
|
+
}
|
|
469
|
+
get currentItem() {
|
|
470
|
+
return this._navigationEmitter.model.currentItem;
|
|
471
|
+
}
|
|
472
|
+
get items() {
|
|
473
|
+
return this._navigationEmitter.model.items;
|
|
474
|
+
}
|
|
475
|
+
set wrap(newWrap) {
|
|
476
|
+
this._navigationEmitter.model.options.wrap = newWrap;
|
|
477
|
+
}
|
|
478
|
+
destroy() {
|
|
479
|
+
super.destroy();
|
|
480
|
+
this._navigationEmitter.destroy();
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
function createLinear(el, focusEl, itemContainerEl, itemSelector, selectedOptions) {
|
|
484
|
+
return new LinearActiveDescendant(el, focusEl, itemContainerEl, itemSelector, selectedOptions);
|
|
485
|
+
}
|
|
486
|
+
function src_default() {
|
|
487
|
+
let timeout;
|
|
488
|
+
let typeStr = "";
|
|
489
|
+
return {
|
|
490
|
+
getIndex: function(nodeList, char, timeoutLength) {
|
|
491
|
+
typeStr = typeStr.concat(char);
|
|
492
|
+
let index2;
|
|
493
|
+
if (nodeList == null) return -1;
|
|
494
|
+
const lowerTypeStr = typeStr.toLocaleLowerCase();
|
|
495
|
+
index2 = [...nodeList].findIndex((el) => el.textContent.toLocaleLowerCase().startsWith(lowerTypeStr));
|
|
496
|
+
if (index2 === -1) {
|
|
497
|
+
index2 = [...nodeList].findIndex((el) => el.textContent.toLocaleLowerCase().includes(lowerTypeStr));
|
|
498
|
+
}
|
|
499
|
+
setTimeout(() => {
|
|
500
|
+
clearTimeout(timeout);
|
|
501
|
+
typeStr = "";
|
|
502
|
+
}, timeoutLength);
|
|
503
|
+
return index2;
|
|
504
|
+
},
|
|
505
|
+
destroy: function() {
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
function scroll(el) {
|
|
510
|
+
if (!el) {
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
const parentEl = el.parentElement;
|
|
514
|
+
const offsetBottom = el.offsetTop + el.offsetHeight;
|
|
515
|
+
const scrollBottom = parentEl.scrollTop + parentEl.offsetHeight;
|
|
516
|
+
if (el.offsetTop < parentEl.scrollTop) {
|
|
517
|
+
parentEl.scrollTop = el.offsetTop;
|
|
518
|
+
} else if (offsetBottom > scrollBottom) {
|
|
519
|
+
parentEl.scrollTop = offsetBottom - parentEl.offsetHeight;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
const EbayListboxOptionDescription = ({ children, className, ...rest }) => React.createElement("div", { className: classNames("listbox__description", className), ...rest }, children);
|
|
523
|
+
const EbayListboxOption = ({ className, icon: icon$1, text, children, disabled, tabIndex, selected, ...rest }) => {
|
|
524
|
+
const description = common_componentUtils_utils.filterByType(children, EbayListboxOptionDescription);
|
|
525
|
+
const displayText = text || (!(description == null ? void 0 : description.length) ? children : "");
|
|
526
|
+
return React.createElement(
|
|
527
|
+
"div",
|
|
528
|
+
{ ...rest, tabIndex: disabled ? -1 : tabIndex, className: classNames("listbox__option", className), "aria-disabled": disabled, "aria-selected": selected, role: "option" },
|
|
529
|
+
icon$1 ? React.createElement(
|
|
530
|
+
"span",
|
|
531
|
+
{ className: "listbox__value" },
|
|
532
|
+
icon$1,
|
|
533
|
+
displayText ? React.createElement("span", null, displayText) : null,
|
|
534
|
+
(description == null ? void 0 : description.length) ? description : null
|
|
535
|
+
) : React.createElement(
|
|
536
|
+
React.Fragment,
|
|
537
|
+
null,
|
|
538
|
+
React.createElement("span", { className: "listbox__value" }, displayText),
|
|
539
|
+
(description == null ? void 0 : description.length) ? description : null
|
|
540
|
+
),
|
|
541
|
+
React.createElement(icon.EbayIcon, { name: "tick16" })
|
|
542
|
+
);
|
|
543
|
+
};
|
|
544
|
+
const TYPEAHEAD_TIMEOUT_LENGTH = 1300;
|
|
545
|
+
const EbayListbox = ({ name, className, disabled, children, tabIndex = 0, listSelection, maxHeight, typeaheadTimeoutLength, selectClassName, onChange = () => {
|
|
546
|
+
}, onEscape = () => {
|
|
547
|
+
}, ...rest }) => {
|
|
548
|
+
var _a;
|
|
549
|
+
const options = common_componentUtils_utils.filterByType(children, EbayListboxOption);
|
|
550
|
+
const selectedOptionComponentIndex = options.findIndex((option) => option.props.selected);
|
|
551
|
+
const [selectedIndex, setSelectedIndex] = React.useState(options.findIndex((option) => option.props.selected));
|
|
552
|
+
React.useEffect(() => {
|
|
553
|
+
if (selectedOptionComponentIndex !== selectedIndex) {
|
|
554
|
+
setSelectedIndex(selectedOptionComponentIndex);
|
|
555
|
+
}
|
|
556
|
+
}, [selectedOptionComponentIndex]);
|
|
557
|
+
const containerRef = React.useRef();
|
|
558
|
+
const activeDescendantRef = React.useRef();
|
|
559
|
+
const typeaheadRef = React.useRef();
|
|
560
|
+
const wasClickedRef = React.useRef(false);
|
|
561
|
+
function handleChange(event, nextSelectedIndex, wasClicked) {
|
|
562
|
+
if (nextSelectedIndex === selectedIndex) {
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
const option = options[nextSelectedIndex];
|
|
566
|
+
if (option.props.disabled) {
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
setSelectedIndex(nextSelectedIndex);
|
|
570
|
+
onChange(event, {
|
|
571
|
+
index: nextSelectedIndex,
|
|
572
|
+
selected: [options[nextSelectedIndex].props.value],
|
|
573
|
+
wasClicked
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
function handleKeyDown(event) {
|
|
577
|
+
switch (event.code) {
|
|
578
|
+
case "Esc":
|
|
579
|
+
case "Escape":
|
|
580
|
+
onEscape();
|
|
581
|
+
break;
|
|
582
|
+
case "Space":
|
|
583
|
+
case "Enter":
|
|
584
|
+
handleChange(event, activeDescendantRef.current.index, false);
|
|
585
|
+
break;
|
|
586
|
+
default:
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
const itemIndex = typeaheadRef.current.getIndex(containerRef.current.children, event.key, typeaheadTimeoutLength || TYPEAHEAD_TIMEOUT_LENGTH);
|
|
590
|
+
if (itemIndex !== -1) {
|
|
591
|
+
activeDescendantRef.current.index = itemIndex;
|
|
592
|
+
scrollOptions(itemIndex);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
function scrollOptions(index2) {
|
|
596
|
+
const listboxOptionsContainerNode = containerRef.current;
|
|
597
|
+
const currentTarget = listboxOptionsContainerNode.querySelectorAll("[role=option]")[index2];
|
|
598
|
+
if (listboxOptionsContainerNode.scrollHeight > listboxOptionsContainerNode.clientHeight) {
|
|
599
|
+
const scrollBottom = listboxOptionsContainerNode.clientHeight + listboxOptionsContainerNode.scrollTop;
|
|
600
|
+
const elementBottom = currentTarget.offsetTop + currentTarget.offsetHeight;
|
|
601
|
+
if (elementBottom > scrollBottom) {
|
|
602
|
+
listboxOptionsContainerNode.scrollTop = elementBottom - listboxOptionsContainerNode.clientHeight;
|
|
603
|
+
} else if (currentTarget.offsetTop < listboxOptionsContainerNode.scrollTop) {
|
|
604
|
+
listboxOptionsContainerNode.scrollTop = currentTarget.offsetTop;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
function handleMouseDown() {
|
|
609
|
+
wasClickedRef.current = true;
|
|
610
|
+
}
|
|
611
|
+
React.useEffect(() => {
|
|
612
|
+
const handleListboxChange = (event) => {
|
|
613
|
+
const nextSelectedIndex = parseInt(event.detail.toIndex, 10);
|
|
614
|
+
const el = containerRef.current ? containerRef.current.querySelectorAll("[role=option]")[selectedIndex] : null;
|
|
615
|
+
const wasClicked = wasClickedRef.current;
|
|
616
|
+
scroll(el);
|
|
617
|
+
if (wasClickedRef.current) {
|
|
618
|
+
wasClickedRef.current = false;
|
|
619
|
+
}
|
|
620
|
+
handleChange(event, nextSelectedIndex, wasClicked);
|
|
621
|
+
};
|
|
622
|
+
if (options.length && !disabled) {
|
|
623
|
+
const container = containerRef.current;
|
|
624
|
+
const optionsContainer = containerRef.current;
|
|
625
|
+
activeDescendantRef.current = createLinear(container, optionsContainer, optionsContainer, ".listbox__option[role=option]", {
|
|
626
|
+
activeDescendantClassName: "listbox__option--active",
|
|
627
|
+
autoInit: selectedIndex,
|
|
628
|
+
autoReset: null,
|
|
629
|
+
autoScroll: listSelection !== "auto"
|
|
630
|
+
});
|
|
631
|
+
typeaheadRef.current = src_default();
|
|
632
|
+
}
|
|
633
|
+
if (listSelection === "auto") {
|
|
634
|
+
containerRef.current.addEventListener("activeDescendantChange", handleListboxChange);
|
|
635
|
+
}
|
|
636
|
+
return () => {
|
|
637
|
+
if (activeDescendantRef.current) {
|
|
638
|
+
activeDescendantRef.current.reset();
|
|
639
|
+
activeDescendantRef.current.destroy();
|
|
640
|
+
activeDescendantRef.current = void 0;
|
|
641
|
+
}
|
|
642
|
+
if (typeaheadRef.current) {
|
|
643
|
+
typeaheadRef.current.destroy();
|
|
644
|
+
typeaheadRef.current = void 0;
|
|
645
|
+
}
|
|
646
|
+
if (containerRef.current) {
|
|
647
|
+
containerRef.current.removeEventListener("activeDescendantChange", handleListboxChange);
|
|
648
|
+
}
|
|
649
|
+
};
|
|
650
|
+
}, [selectedIndex, disabled, listSelection]);
|
|
651
|
+
return React.createElement(
|
|
652
|
+
React.Fragment,
|
|
653
|
+
null,
|
|
654
|
+
React.createElement("div", { ...rest, tabIndex, ref: containerRef, role: "listbox", onKeyDown: listSelection !== "auto" ? handleKeyDown : void 0, className: classNames("listbox__options", className), style: { maxHeight } }, options.map((option, index2) => React.cloneElement(option, {
|
|
655
|
+
key: option.props.value || index2,
|
|
656
|
+
...option.props,
|
|
657
|
+
onMouseDown: listSelection === "auto" ? handleMouseDown : void 0,
|
|
658
|
+
onClick: (event) => {
|
|
659
|
+
if (listSelection !== "auto") {
|
|
660
|
+
handleChange(event, index2, true);
|
|
661
|
+
}
|
|
662
|
+
},
|
|
663
|
+
selected: index2 === selectedIndex
|
|
664
|
+
}))),
|
|
665
|
+
React.createElement("select", { hidden: true, className: classNames("listbox__native", selectClassName), name, value: (_a = options[selectedIndex]) == null ? void 0 : _a.props.value, onChange: (
|
|
666
|
+
/* NO-OP, this is to hide React warnings */
|
|
667
|
+
() => {
|
|
668
|
+
}
|
|
669
|
+
) }, options.map((option, index2) => React.createElement("option", { key: index2, value: option.props.value, disabled: option.props.disabled })))
|
|
670
|
+
);
|
|
671
|
+
};
|
|
672
|
+
exports.EbayListbox = EbayListbox;
|
|
673
|
+
exports.EbayListboxOption = EbayListboxOption;
|
|
674
|
+
exports.EbayListboxOptionDescription = EbayListboxOptionDescription;
|