@vonage/vivid 4.14.1 → 4.14.2

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.
Files changed (66) hide show
  1. package/custom-elements.json +22 -174
  2. package/lib/divider/divider.d.ts +1 -1
  3. package/lib/divider/divider.template.d.ts +1 -1
  4. package/package.json +1 -1
  5. package/shared/affix.js +1 -1
  6. package/shared/definition.js +1 -1
  7. package/shared/definition11.js +1 -1
  8. package/shared/definition16.cjs +1 -2
  9. package/shared/definition16.js +2 -3
  10. package/shared/definition17.cjs +9 -7
  11. package/shared/definition17.js +9 -7
  12. package/shared/definition22.cjs +2 -1
  13. package/shared/definition22.js +2 -1
  14. package/shared/definition24.js +1 -1
  15. package/shared/definition27.cjs +1 -1
  16. package/shared/definition27.js +1 -1
  17. package/shared/definition29.js +1 -1
  18. package/shared/definition30.js +1 -1
  19. package/shared/definition31.js +1 -1
  20. package/shared/definition33.js +1 -1
  21. package/shared/definition34.cjs +88 -19
  22. package/shared/definition34.js +72 -3
  23. package/shared/definition35.cjs +2 -201
  24. package/shared/definition35.js +4 -201
  25. package/shared/definition4.js +1 -1
  26. package/shared/definition42.cjs +3 -3
  27. package/shared/definition42.js +3 -3
  28. package/shared/definition43.cjs +9 -9
  29. package/shared/definition43.js +5 -5
  30. package/shared/definition47.js +1 -1
  31. package/shared/definition50.js +1 -1
  32. package/shared/definition51.cjs +39 -17
  33. package/shared/definition51.js +24 -2
  34. package/shared/definition53.js +1 -1
  35. package/shared/definition59.js +1 -1
  36. package/shared/definition7.js +1 -1
  37. package/shared/definition8.js +1 -1
  38. package/shared/foundation-element.cjs +1417 -0
  39. package/shared/foundation-element.js +1414 -0
  40. package/shared/key-codes2.cjs +0 -1469
  41. package/shared/key-codes2.js +1 -1464
  42. package/shared/listbox.cjs +3 -3
  43. package/shared/listbox.js +1 -1
  44. package/shared/option.cjs +205 -0
  45. package/shared/option.js +202 -0
  46. package/shared/start-end.cjs +52 -0
  47. package/shared/start-end.js +50 -0
  48. package/shared/text-anchor.js +1 -1
  49. package/shared/text-field2.js +1 -1
  50. package/styles/core/all.css +1 -1
  51. package/styles/core/theme.css +1 -1
  52. package/styles/core/typography.css +1 -1
  53. package/styles/tokens/theme-dark.css +4 -4
  54. package/styles/tokens/theme-light.css +4 -4
  55. package/styles/tokens/vivid-2-compat.css +1 -1
  56. package/lib/listbox/definition.d.ts +0 -2
  57. package/lib/listbox/listbox.d.ts +0 -14
  58. package/lib/listbox/listbox.template.d.ts +0 -2
  59. package/listbox/index.cjs +0 -54
  60. package/listbox/index.js +0 -52
  61. package/shared/aria-global2.cjs +0 -75
  62. package/shared/aria-global2.js +0 -73
  63. package/shared/listbox2.cjs +0 -1267
  64. package/shared/listbox2.js +0 -1264
  65. package/shared/strings2.cjs +0 -37
  66. package/shared/strings2.js +0 -33
@@ -1,1264 +0,0 @@
1
- import { h as keyArrowLeft, i as keyArrowRight } from './key-codes.js';
2
- import { _ as __decorate, S as StartEnd, F as FoundationElement, g as keySpace, h as keyEscape, k as keyEnter, i as keyTab, e as keyEnd, d as keyArrowUp, c as keyArrowDown, f as keyHome } from './key-codes2.js';
3
- import { A as ARIAGlobalStatesAndProperties } from './aria-global2.js';
4
- import { a as applyMixins } from './apply-mixins2.js';
5
- import { o as observable, a as attr, O as Observable, D as DOM, n as nullableNumberConverter } from './vivid-element.js';
6
- import { u as uniqueId, i as inRange } from './strings2.js';
7
-
8
- /**
9
- * Returns the index of the last element in the array where predicate is true, and -1 otherwise.
10
- *
11
- * @param array - the array to test
12
- * @param predicate - find calls predicate once for each element of the array, in descending order, until it finds one where predicate returns true. If such an element is found, findLastIndex immediately returns that element index. Otherwise, findIndex returns -1.
13
- */
14
- function findLastIndex(array, predicate) {
15
- let k = array.length;
16
- while (k--) {
17
- if (predicate(array[k], k, array)) {
18
- return k;
19
- }
20
- }
21
- return -1;
22
- }
23
-
24
- /**
25
- * A test that ensures that all arguments are HTML Elements
26
- */
27
- function isHTMLElement(...args) {
28
- return args.every((arg) => arg instanceof HTMLElement);
29
- }
30
-
31
- /**
32
- * Determines if the element is a {@link (ListboxOption:class)}
33
- *
34
- * @param element - the element to test.
35
- * @public
36
- */
37
- function isListboxOption(el) {
38
- return (isHTMLElement(el) &&
39
- (el.getAttribute("role") === "option" ||
40
- el instanceof HTMLOptionElement));
41
- }
42
- /**
43
- * An Option Custom HTML Element.
44
- * Implements {@link https://www.w3.org/TR/wai-aria-1.1/#option | ARIA option }.
45
- *
46
- * @slot start - Content which can be provided before the listbox option content
47
- * @slot end - Content which can be provided after the listbox option content
48
- * @slot - The default slot for listbox option content
49
- * @csspart content - Wraps the listbox option content
50
- *
51
- * @public
52
- */
53
- class ListboxOption extends FoundationElement {
54
- constructor(text, value, defaultSelected, selected) {
55
- super();
56
- /**
57
- * The defaultSelected state of the option.
58
- * @public
59
- */
60
- this.defaultSelected = false;
61
- /**
62
- * Tracks whether the "selected" property has been changed.
63
- * @internal
64
- */
65
- this.dirtySelected = false;
66
- /**
67
- * The checked state of the control.
68
- *
69
- * @public
70
- */
71
- this.selected = this.defaultSelected;
72
- /**
73
- * Track whether the value has been changed from the initial value
74
- */
75
- this.dirtyValue = false;
76
- if (text) {
77
- this.textContent = text;
78
- }
79
- if (value) {
80
- this.initialValue = value;
81
- }
82
- if (defaultSelected) {
83
- this.defaultSelected = defaultSelected;
84
- }
85
- if (selected) {
86
- this.selected = selected;
87
- }
88
- this.proxy = new Option(`${this.textContent}`, this.initialValue, this.defaultSelected, this.selected);
89
- this.proxy.disabled = this.disabled;
90
- }
91
- /**
92
- * Updates the ariaChecked property when the checked property changes.
93
- *
94
- * @param prev - the previous checked value
95
- * @param next - the current checked value
96
- *
97
- * @public
98
- */
99
- checkedChanged(prev, next) {
100
- if (typeof next === "boolean") {
101
- this.ariaChecked = next ? "true" : "false";
102
- return;
103
- }
104
- this.ariaChecked = null;
105
- }
106
- /**
107
- * Updates the proxy's text content when the default slot changes.
108
- * @param prev - the previous content value
109
- * @param next - the current content value
110
- *
111
- * @internal
112
- */
113
- contentChanged(prev, next) {
114
- if (this.proxy instanceof HTMLOptionElement) {
115
- this.proxy.textContent = this.textContent;
116
- }
117
- this.$emit("contentchange", null, { bubbles: true });
118
- }
119
- defaultSelectedChanged() {
120
- if (!this.dirtySelected) {
121
- this.selected = this.defaultSelected;
122
- if (this.proxy instanceof HTMLOptionElement) {
123
- this.proxy.selected = this.defaultSelected;
124
- }
125
- }
126
- }
127
- disabledChanged(prev, next) {
128
- this.ariaDisabled = this.disabled ? "true" : "false";
129
- if (this.proxy instanceof HTMLOptionElement) {
130
- this.proxy.disabled = this.disabled;
131
- }
132
- }
133
- selectedAttributeChanged() {
134
- this.defaultSelected = this.selectedAttribute;
135
- if (this.proxy instanceof HTMLOptionElement) {
136
- this.proxy.defaultSelected = this.defaultSelected;
137
- }
138
- }
139
- selectedChanged() {
140
- this.ariaSelected = this.selected ? "true" : "false";
141
- if (!this.dirtySelected) {
142
- this.dirtySelected = true;
143
- }
144
- if (this.proxy instanceof HTMLOptionElement) {
145
- this.proxy.selected = this.selected;
146
- }
147
- }
148
- initialValueChanged(previous, next) {
149
- // If the value is clean and the component is connected to the DOM
150
- // then set value equal to the attribute value.
151
- if (!this.dirtyValue) {
152
- this.value = this.initialValue;
153
- this.dirtyValue = false;
154
- }
155
- }
156
- get label() {
157
- var _a;
158
- return (_a = this.value) !== null && _a !== void 0 ? _a : this.text;
159
- }
160
- get text() {
161
- var _a, _b;
162
- return (_b = (_a = this.textContent) === null || _a === void 0 ? void 0 : _a.replace(/\s+/g, " ").trim()) !== null && _b !== void 0 ? _b : "";
163
- }
164
- set value(next) {
165
- const newValue = `${next !== null && next !== void 0 ? next : ""}`;
166
- this._value = newValue;
167
- this.dirtyValue = true;
168
- if (this.proxy instanceof HTMLOptionElement) {
169
- this.proxy.value = newValue;
170
- }
171
- Observable.notify(this, "value");
172
- }
173
- get value() {
174
- var _a;
175
- Observable.track(this, "value");
176
- return (_a = this._value) !== null && _a !== void 0 ? _a : this.text;
177
- }
178
- get form() {
179
- return this.proxy ? this.proxy.form : null;
180
- }
181
- }
182
- __decorate([
183
- observable
184
- ], ListboxOption.prototype, "checked", void 0);
185
- __decorate([
186
- observable
187
- ], ListboxOption.prototype, "content", void 0);
188
- __decorate([
189
- observable
190
- ], ListboxOption.prototype, "defaultSelected", void 0);
191
- __decorate([
192
- attr({ mode: "boolean" })
193
- ], ListboxOption.prototype, "disabled", void 0);
194
- __decorate([
195
- attr({ attribute: "selected", mode: "boolean" })
196
- ], ListboxOption.prototype, "selectedAttribute", void 0);
197
- __decorate([
198
- observable
199
- ], ListboxOption.prototype, "selected", void 0);
200
- __decorate([
201
- attr({ attribute: "value", mode: "fromView" })
202
- ], ListboxOption.prototype, "initialValue", void 0);
203
- /**
204
- * States and properties relating to the ARIA `option` role.
205
- *
206
- * @public
207
- */
208
- class DelegatesARIAListboxOption {
209
- }
210
- __decorate([
211
- observable
212
- ], DelegatesARIAListboxOption.prototype, "ariaChecked", void 0);
213
- __decorate([
214
- observable
215
- ], DelegatesARIAListboxOption.prototype, "ariaPosInSet", void 0);
216
- __decorate([
217
- observable
218
- ], DelegatesARIAListboxOption.prototype, "ariaSelected", void 0);
219
- __decorate([
220
- observable
221
- ], DelegatesARIAListboxOption.prototype, "ariaSetSize", void 0);
222
- applyMixins(DelegatesARIAListboxOption, ARIAGlobalStatesAndProperties);
223
- applyMixins(ListboxOption, StartEnd, DelegatesARIAListboxOption);
224
-
225
- /**
226
- * A Listbox Custom HTML Element.
227
- * Implements the {@link https://www.w3.org/TR/wai-aria-1.1/#listbox | ARIA listbox }.
228
- *
229
- * @slot - The default slot for the listbox options
230
- *
231
- * @public
232
- */
233
- let Listbox$1 = class Listbox extends FoundationElement {
234
- constructor() {
235
- super(...arguments);
236
- /**
237
- * The internal unfiltered list of selectable options.
238
- *
239
- * @internal
240
- */
241
- this._options = [];
242
- /**
243
- * The index of the selected option.
244
- *
245
- * @public
246
- */
247
- this.selectedIndex = -1;
248
- /**
249
- * A collection of the selected options.
250
- *
251
- * @public
252
- */
253
- this.selectedOptions = [];
254
- /**
255
- * A standard `click` event creates a `focus` event before firing, so a
256
- * `mousedown` event is used to skip that initial focus.
257
- *
258
- * @internal
259
- */
260
- this.shouldSkipFocus = false;
261
- /**
262
- * The current typeahead buffer string.
263
- *
264
- * @internal
265
- */
266
- this.typeaheadBuffer = "";
267
- /**
268
- * Flag for the typeahead timeout expiration.
269
- *
270
- * @internal
271
- */
272
- this.typeaheadExpired = true;
273
- /**
274
- * The timeout ID for the typeahead handler.
275
- *
276
- * @internal
277
- */
278
- this.typeaheadTimeout = -1;
279
- }
280
- /**
281
- * The first selected option.
282
- *
283
- * @internal
284
- */
285
- get firstSelectedOption() {
286
- var _a;
287
- return (_a = this.selectedOptions[0]) !== null && _a !== void 0 ? _a : null;
288
- }
289
- /**
290
- * Returns true if there is one or more selectable option.
291
- *
292
- * @internal
293
- */
294
- get hasSelectableOptions() {
295
- return this.options.length > 0 && !this.options.every(o => o.disabled);
296
- }
297
- /**
298
- * The number of options.
299
- *
300
- * @public
301
- */
302
- get length() {
303
- var _a, _b;
304
- return (_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
305
- }
306
- /**
307
- * The list of options.
308
- *
309
- * @public
310
- */
311
- get options() {
312
- Observable.track(this, "options");
313
- return this._options;
314
- }
315
- set options(value) {
316
- this._options = value;
317
- Observable.notify(this, "options");
318
- }
319
- /**
320
- * Flag for the typeahead timeout expiration.
321
- *
322
- * @deprecated use `Listbox.typeaheadExpired`
323
- * @internal
324
- */
325
- get typeAheadExpired() {
326
- return this.typeaheadExpired;
327
- }
328
- set typeAheadExpired(value) {
329
- this.typeaheadExpired = value;
330
- }
331
- /**
332
- * Handle click events for listbox options.
333
- *
334
- * @internal
335
- */
336
- clickHandler(e) {
337
- const captured = e.target.closest(`option,[role=option]`);
338
- if (captured && !captured.disabled) {
339
- this.selectedIndex = this.options.indexOf(captured);
340
- return true;
341
- }
342
- }
343
- /**
344
- * Ensures that the provided option is focused and scrolled into view.
345
- *
346
- * @param optionToFocus - The option to focus
347
- * @internal
348
- */
349
- focusAndScrollOptionIntoView(optionToFocus = this.firstSelectedOption) {
350
- // To ensure that the browser handles both `focus()` and `scrollIntoView()`, the
351
- // timing here needs to guarantee that they happen on different frames. Since this
352
- // function is typically called from the `openChanged` observer, `DOM.queueUpdate`
353
- // causes the calls to be grouped into the same frame. To prevent this,
354
- // `requestAnimationFrame` is used instead of `DOM.queueUpdate`.
355
- if (this.contains(document.activeElement) && optionToFocus !== null) {
356
- optionToFocus.focus();
357
- requestAnimationFrame(() => {
358
- optionToFocus.scrollIntoView({ block: "nearest" });
359
- });
360
- }
361
- }
362
- /**
363
- * Handles `focusin` actions for the component. When the component receives focus,
364
- * the list of selected options is refreshed and the first selected option is scrolled
365
- * into view.
366
- *
367
- * @internal
368
- */
369
- focusinHandler(e) {
370
- if (!this.shouldSkipFocus && e.target === e.currentTarget) {
371
- this.setSelectedOptions();
372
- this.focusAndScrollOptionIntoView();
373
- }
374
- this.shouldSkipFocus = false;
375
- }
376
- /**
377
- * Returns the options which match the current typeahead buffer.
378
- *
379
- * @internal
380
- */
381
- getTypeaheadMatches() {
382
- const pattern = this.typeaheadBuffer.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&");
383
- const re = new RegExp(`^${pattern}`, "gi");
384
- return this.options.filter((o) => o.text.trim().match(re));
385
- }
386
- /**
387
- * Determines the index of the next option which is selectable, if any.
388
- *
389
- * @param prev - the previous selected index
390
- * @param next - the next index to select
391
- *
392
- * @internal
393
- */
394
- getSelectableIndex(prev = this.selectedIndex, next) {
395
- const direction = prev > next ? -1 : prev < next ? 1 : 0;
396
- const potentialDirection = prev + direction;
397
- let nextSelectableOption = null;
398
- switch (direction) {
399
- case -1: {
400
- nextSelectableOption = this.options.reduceRight((nextSelectableOption, thisOption, index) => !nextSelectableOption &&
401
- !thisOption.disabled &&
402
- index < potentialDirection
403
- ? thisOption
404
- : nextSelectableOption, nextSelectableOption);
405
- break;
406
- }
407
- case 1: {
408
- nextSelectableOption = this.options.reduce((nextSelectableOption, thisOption, index) => !nextSelectableOption &&
409
- !thisOption.disabled &&
410
- index > potentialDirection
411
- ? thisOption
412
- : nextSelectableOption, nextSelectableOption);
413
- break;
414
- }
415
- }
416
- return this.options.indexOf(nextSelectableOption);
417
- }
418
- /**
419
- * Handles external changes to child options.
420
- *
421
- * @param source - the source object
422
- * @param propertyName - the property
423
- *
424
- * @internal
425
- */
426
- handleChange(source, propertyName) {
427
- switch (propertyName) {
428
- case "selected": {
429
- if (Listbox.slottedOptionFilter(source)) {
430
- this.selectedIndex = this.options.indexOf(source);
431
- }
432
- this.setSelectedOptions();
433
- break;
434
- }
435
- }
436
- }
437
- /**
438
- * Moves focus to an option whose label matches characters typed by the user.
439
- * Consecutive keystrokes are batched into a buffer of search text used
440
- * to match against the set of options. If `TYPE_AHEAD_TIMEOUT_MS` passes
441
- * between consecutive keystrokes, the search restarts.
442
- *
443
- * @param key - the key to be evaluated
444
- *
445
- * @internal
446
- */
447
- handleTypeAhead(key) {
448
- if (this.typeaheadTimeout) {
449
- window.clearTimeout(this.typeaheadTimeout);
450
- }
451
- this.typeaheadTimeout = window.setTimeout(() => (this.typeaheadExpired = true), Listbox.TYPE_AHEAD_TIMEOUT_MS);
452
- if (key.length > 1) {
453
- return;
454
- }
455
- this.typeaheadBuffer = `${this.typeaheadExpired ? "" : this.typeaheadBuffer}${key}`;
456
- }
457
- /**
458
- * Handles `keydown` actions for listbox navigation and typeahead.
459
- *
460
- * @internal
461
- */
462
- keydownHandler(e) {
463
- if (this.disabled) {
464
- return true;
465
- }
466
- this.shouldSkipFocus = false;
467
- const key = e.key;
468
- switch (key) {
469
- // Select the first available option
470
- case keyHome: {
471
- if (!e.shiftKey) {
472
- e.preventDefault();
473
- this.selectFirstOption();
474
- }
475
- break;
476
- }
477
- // Select the next selectable option
478
- case keyArrowDown: {
479
- if (!e.shiftKey) {
480
- e.preventDefault();
481
- this.selectNextOption();
482
- }
483
- break;
484
- }
485
- // Select the previous selectable option
486
- case keyArrowUp: {
487
- if (!e.shiftKey) {
488
- e.preventDefault();
489
- this.selectPreviousOption();
490
- }
491
- break;
492
- }
493
- // Select the last available option
494
- case keyEnd: {
495
- e.preventDefault();
496
- this.selectLastOption();
497
- break;
498
- }
499
- case keyTab: {
500
- this.focusAndScrollOptionIntoView();
501
- return true;
502
- }
503
- case keyEnter:
504
- case keyEscape: {
505
- return true;
506
- }
507
- case keySpace: {
508
- if (this.typeaheadExpired) {
509
- return true;
510
- }
511
- }
512
- // Send key to Typeahead handler
513
- default: {
514
- if (key.length === 1) {
515
- this.handleTypeAhead(`${key}`);
516
- }
517
- return true;
518
- }
519
- }
520
- }
521
- /**
522
- * Prevents `focusin` events from firing before `click` events when the
523
- * element is unfocused.
524
- *
525
- * @internal
526
- */
527
- mousedownHandler(e) {
528
- this.shouldSkipFocus = !this.contains(document.activeElement);
529
- return true;
530
- }
531
- /**
532
- * Switches between single-selection and multi-selection mode.
533
- *
534
- * @param prev - the previous value of the `multiple` attribute
535
- * @param next - the next value of the `multiple` attribute
536
- *
537
- * @internal
538
- */
539
- multipleChanged(prev, next) {
540
- this.ariaMultiSelectable = next ? "true" : null;
541
- }
542
- /**
543
- * Updates the list of selected options when the `selectedIndex` changes.
544
- *
545
- * @param prev - the previous selected index value
546
- * @param next - the current selected index value
547
- *
548
- * @internal
549
- */
550
- selectedIndexChanged(prev, next) {
551
- var _a;
552
- if (!this.hasSelectableOptions) {
553
- this.selectedIndex = -1;
554
- return;
555
- }
556
- if (((_a = this.options[this.selectedIndex]) === null || _a === void 0 ? void 0 : _a.disabled) && typeof prev === "number") {
557
- const selectableIndex = this.getSelectableIndex(prev, next);
558
- const newNext = selectableIndex > -1 ? selectableIndex : prev;
559
- this.selectedIndex = newNext;
560
- if (next === newNext) {
561
- this.selectedIndexChanged(next, newNext);
562
- }
563
- return;
564
- }
565
- this.setSelectedOptions();
566
- }
567
- /**
568
- * Updates the selectedness of each option when the list of selected options changes.
569
- *
570
- * @param prev - the previous list of selected options
571
- * @param next - the current list of selected options
572
- *
573
- * @internal
574
- */
575
- selectedOptionsChanged(prev, next) {
576
- var _a;
577
- const filteredNext = next.filter(Listbox.slottedOptionFilter);
578
- (_a = this.options) === null || _a === void 0 ? void 0 : _a.forEach(o => {
579
- const notifier = Observable.getNotifier(o);
580
- notifier.unsubscribe(this, "selected");
581
- o.selected = filteredNext.includes(o);
582
- notifier.subscribe(this, "selected");
583
- });
584
- }
585
- /**
586
- * Moves focus to the first selectable option.
587
- *
588
- * @public
589
- */
590
- selectFirstOption() {
591
- var _a, _b;
592
- if (!this.disabled) {
593
- this.selectedIndex = (_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.findIndex(o => !o.disabled)) !== null && _b !== void 0 ? _b : -1;
594
- }
595
- }
596
- /**
597
- * Moves focus to the last selectable option.
598
- *
599
- * @internal
600
- */
601
- selectLastOption() {
602
- if (!this.disabled) {
603
- this.selectedIndex = findLastIndex(this.options, o => !o.disabled);
604
- }
605
- }
606
- /**
607
- * Moves focus to the next selectable option.
608
- *
609
- * @internal
610
- */
611
- selectNextOption() {
612
- if (!this.disabled && this.selectedIndex < this.options.length - 1) {
613
- this.selectedIndex += 1;
614
- }
615
- }
616
- /**
617
- * Moves focus to the previous selectable option.
618
- *
619
- * @internal
620
- */
621
- selectPreviousOption() {
622
- if (!this.disabled && this.selectedIndex > 0) {
623
- this.selectedIndex = this.selectedIndex - 1;
624
- }
625
- }
626
- /**
627
- * Updates the selected index to match the first selected option.
628
- *
629
- * @internal
630
- */
631
- setDefaultSelectedOption() {
632
- var _a, _b;
633
- this.selectedIndex = (_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.findIndex(el => el.defaultSelected)) !== null && _b !== void 0 ? _b : -1;
634
- }
635
- /**
636
- * Sets an option as selected and gives it focus.
637
- *
638
- * @public
639
- */
640
- setSelectedOptions() {
641
- var _a, _b, _c;
642
- if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.length) {
643
- this.selectedOptions = [this.options[this.selectedIndex]];
644
- this.ariaActiveDescendant = (_c = (_b = this.firstSelectedOption) === null || _b === void 0 ? void 0 : _b.id) !== null && _c !== void 0 ? _c : "";
645
- this.focusAndScrollOptionIntoView();
646
- }
647
- }
648
- /**
649
- * Updates the list of options and resets the selected option when the slotted option content changes.
650
- *
651
- * @param prev - the previous list of slotted options
652
- * @param next - the current list of slotted options
653
- *
654
- * @internal
655
- */
656
- slottedOptionsChanged(prev, next) {
657
- this.options = next.reduce((options, item) => {
658
- if (isListboxOption(item)) {
659
- options.push(item);
660
- }
661
- return options;
662
- }, []);
663
- const setSize = `${this.options.length}`;
664
- this.options.forEach((option, index) => {
665
- if (!option.id) {
666
- option.id = uniqueId("option-");
667
- }
668
- option.ariaPosInSet = `${index + 1}`;
669
- option.ariaSetSize = setSize;
670
- });
671
- if (this.$fastController.isConnected) {
672
- this.setSelectedOptions();
673
- this.setDefaultSelectedOption();
674
- }
675
- }
676
- /**
677
- * Updates the filtered list of options when the typeahead buffer changes.
678
- *
679
- * @param prev - the previous typeahead buffer value
680
- * @param next - the current typeahead buffer value
681
- *
682
- * @internal
683
- */
684
- typeaheadBufferChanged(prev, next) {
685
- if (this.$fastController.isConnected) {
686
- const typeaheadMatches = this.getTypeaheadMatches();
687
- if (typeaheadMatches.length) {
688
- const selectedIndex = this.options.indexOf(typeaheadMatches[0]);
689
- if (selectedIndex > -1) {
690
- this.selectedIndex = selectedIndex;
691
- }
692
- }
693
- this.typeaheadExpired = false;
694
- }
695
- }
696
- };
697
- /**
698
- * A static filter to include only selectable options.
699
- *
700
- * @param n - element to filter
701
- * @public
702
- */
703
- Listbox$1.slottedOptionFilter = (n) => isListboxOption(n) && !n.hidden;
704
- /**
705
- * Typeahead timeout in milliseconds.
706
- *
707
- * @internal
708
- */
709
- Listbox$1.TYPE_AHEAD_TIMEOUT_MS = 1000;
710
- __decorate([
711
- attr({ mode: "boolean" })
712
- ], Listbox$1.prototype, "disabled", void 0);
713
- __decorate([
714
- observable
715
- ], Listbox$1.prototype, "selectedIndex", void 0);
716
- __decorate([
717
- observable
718
- ], Listbox$1.prototype, "selectedOptions", void 0);
719
- __decorate([
720
- observable
721
- ], Listbox$1.prototype, "slottedOptions", void 0);
722
- __decorate([
723
- observable
724
- ], Listbox$1.prototype, "typeaheadBuffer", void 0);
725
- /**
726
- * Includes ARIA states and properties relating to the ARIA listbox role
727
- *
728
- * @public
729
- */
730
- class DelegatesARIAListbox {
731
- }
732
- __decorate([
733
- observable
734
- ], DelegatesARIAListbox.prototype, "ariaActiveDescendant", void 0);
735
- __decorate([
736
- observable
737
- ], DelegatesARIAListbox.prototype, "ariaDisabled", void 0);
738
- __decorate([
739
- observable
740
- ], DelegatesARIAListbox.prototype, "ariaExpanded", void 0);
741
- __decorate([
742
- observable
743
- ], DelegatesARIAListbox.prototype, "ariaMultiSelectable", void 0);
744
- applyMixins(DelegatesARIAListbox, ARIAGlobalStatesAndProperties);
745
- applyMixins(Listbox$1, DelegatesARIAListbox);
746
-
747
- /**
748
- * A Listbox Custom HTML Element.
749
- * Implements the {@link https://w3c.github.io/aria/#listbox | ARIA listbox }.
750
- *
751
- * @public
752
- */
753
- class ListboxElement extends Listbox$1 {
754
- constructor() {
755
- super(...arguments);
756
- /**
757
- * The index of the most recently checked option.
758
- *
759
- * @internal
760
- * @remarks
761
- * Multiple-selection mode only.
762
- */
763
- this.activeIndex = -1;
764
- /**
765
- * The start index when checking a range of options.
766
- *
767
- * @internal
768
- */
769
- this.rangeStartIndex = -1;
770
- }
771
- /**
772
- * Returns the last checked option.
773
- *
774
- * @internal
775
- */
776
- get activeOption() {
777
- return this.options[this.activeIndex];
778
- }
779
- /**
780
- * Returns the list of checked options.
781
- *
782
- * @internal
783
- */
784
- get checkedOptions() {
785
- var _a;
786
- return (_a = this.options) === null || _a === void 0 ? void 0 : _a.filter(o => o.checked);
787
- }
788
- /**
789
- * Returns the index of the first selected option.
790
- *
791
- * @internal
792
- */
793
- get firstSelectedOptionIndex() {
794
- return this.options.indexOf(this.firstSelectedOption);
795
- }
796
- /**
797
- * Updates the `ariaActiveDescendant` property when the active index changes.
798
- *
799
- * @param prev - the previous active index
800
- * @param next - the next active index
801
- *
802
- * @internal
803
- */
804
- activeIndexChanged(prev, next) {
805
- var _a, _b;
806
- this.ariaActiveDescendant = (_b = (_a = this.options[next]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : "";
807
- this.focusAndScrollOptionIntoView();
808
- }
809
- /**
810
- * Toggles the checked state for the currently active option.
811
- *
812
- * @remarks
813
- * Multiple-selection mode only.
814
- *
815
- * @internal
816
- */
817
- checkActiveIndex() {
818
- if (!this.multiple) {
819
- return;
820
- }
821
- const activeItem = this.activeOption;
822
- if (activeItem) {
823
- activeItem.checked = true;
824
- }
825
- }
826
- /**
827
- * Sets the active index to the first option and marks it as checked.
828
- *
829
- * @remarks
830
- * Multi-selection mode only.
831
- *
832
- * @param preserveChecked - mark all options unchecked before changing the active index
833
- *
834
- * @internal
835
- */
836
- checkFirstOption(preserveChecked = false) {
837
- if (preserveChecked) {
838
- if (this.rangeStartIndex === -1) {
839
- this.rangeStartIndex = this.activeIndex + 1;
840
- }
841
- this.options.forEach((o, i) => {
842
- o.checked = inRange(i, this.rangeStartIndex);
843
- });
844
- }
845
- else {
846
- this.uncheckAllOptions();
847
- }
848
- this.activeIndex = 0;
849
- this.checkActiveIndex();
850
- }
851
- /**
852
- * Decrements the active index and sets the matching option as checked.
853
- *
854
- * @remarks
855
- * Multi-selection mode only.
856
- *
857
- * @param preserveChecked - mark all options unchecked before changing the active index
858
- *
859
- * @internal
860
- */
861
- checkLastOption(preserveChecked = false) {
862
- if (preserveChecked) {
863
- if (this.rangeStartIndex === -1) {
864
- this.rangeStartIndex = this.activeIndex;
865
- }
866
- this.options.forEach((o, i) => {
867
- o.checked = inRange(i, this.rangeStartIndex, this.options.length);
868
- });
869
- }
870
- else {
871
- this.uncheckAllOptions();
872
- }
873
- this.activeIndex = this.options.length - 1;
874
- this.checkActiveIndex();
875
- }
876
- /**
877
- * @override
878
- * @internal
879
- */
880
- connectedCallback() {
881
- super.connectedCallback();
882
- this.addEventListener("focusout", this.focusoutHandler);
883
- }
884
- /**
885
- * @override
886
- * @internal
887
- */
888
- disconnectedCallback() {
889
- this.removeEventListener("focusout", this.focusoutHandler);
890
- super.disconnectedCallback();
891
- }
892
- /**
893
- * Increments the active index and marks the matching option as checked.
894
- *
895
- * @remarks
896
- * Multiple-selection mode only.
897
- *
898
- * @param preserveChecked - mark all options unchecked before changing the active index
899
- *
900
- * @internal
901
- */
902
- checkNextOption(preserveChecked = false) {
903
- if (preserveChecked) {
904
- if (this.rangeStartIndex === -1) {
905
- this.rangeStartIndex = this.activeIndex;
906
- }
907
- this.options.forEach((o, i) => {
908
- o.checked = inRange(i, this.rangeStartIndex, this.activeIndex + 1);
909
- });
910
- }
911
- else {
912
- this.uncheckAllOptions();
913
- }
914
- this.activeIndex += this.activeIndex < this.options.length - 1 ? 1 : 0;
915
- this.checkActiveIndex();
916
- }
917
- /**
918
- * Decrements the active index and marks the matching option as checked.
919
- *
920
- * @remarks
921
- * Multiple-selection mode only.
922
- *
923
- * @param preserveChecked - mark all options unchecked before changing the active index
924
- *
925
- * @internal
926
- */
927
- checkPreviousOption(preserveChecked = false) {
928
- if (preserveChecked) {
929
- if (this.rangeStartIndex === -1) {
930
- this.rangeStartIndex = this.activeIndex;
931
- }
932
- if (this.checkedOptions.length === 1) {
933
- this.rangeStartIndex += 1;
934
- }
935
- this.options.forEach((o, i) => {
936
- o.checked = inRange(i, this.activeIndex, this.rangeStartIndex);
937
- });
938
- }
939
- else {
940
- this.uncheckAllOptions();
941
- }
942
- this.activeIndex -= this.activeIndex > 0 ? 1 : 0;
943
- this.checkActiveIndex();
944
- }
945
- /**
946
- * Handles click events for listbox options.
947
- *
948
- * @param e - the event object
949
- *
950
- * @override
951
- * @internal
952
- */
953
- clickHandler(e) {
954
- var _a;
955
- if (!this.multiple) {
956
- return super.clickHandler(e);
957
- }
958
- const captured = (_a = e.target) === null || _a === void 0 ? void 0 : _a.closest(`[role=option]`);
959
- if (!captured || captured.disabled) {
960
- return;
961
- }
962
- this.uncheckAllOptions();
963
- this.activeIndex = this.options.indexOf(captured);
964
- this.checkActiveIndex();
965
- this.toggleSelectedForAllCheckedOptions();
966
- return true;
967
- }
968
- /**
969
- * @override
970
- * @internal
971
- */
972
- focusAndScrollOptionIntoView() {
973
- super.focusAndScrollOptionIntoView(this.activeOption);
974
- }
975
- /**
976
- * In multiple-selection mode:
977
- * If any options are selected, the first selected option is checked when
978
- * the listbox receives focus. If no options are selected, the first
979
- * selectable option is checked.
980
- *
981
- * @override
982
- * @internal
983
- */
984
- focusinHandler(e) {
985
- if (!this.multiple) {
986
- return super.focusinHandler(e);
987
- }
988
- if (!this.shouldSkipFocus && e.target === e.currentTarget) {
989
- this.uncheckAllOptions();
990
- if (this.activeIndex === -1) {
991
- this.activeIndex =
992
- this.firstSelectedOptionIndex !== -1
993
- ? this.firstSelectedOptionIndex
994
- : 0;
995
- }
996
- this.checkActiveIndex();
997
- this.setSelectedOptions();
998
- this.focusAndScrollOptionIntoView();
999
- }
1000
- this.shouldSkipFocus = false;
1001
- }
1002
- /**
1003
- * Unchecks all options when the listbox loses focus.
1004
- *
1005
- * @internal
1006
- */
1007
- focusoutHandler(e) {
1008
- if (this.multiple) {
1009
- this.uncheckAllOptions();
1010
- }
1011
- }
1012
- /**
1013
- * Handles keydown actions for listbox navigation and typeahead
1014
- *
1015
- * @override
1016
- * @internal
1017
- */
1018
- keydownHandler(e) {
1019
- if (!this.multiple) {
1020
- return super.keydownHandler(e);
1021
- }
1022
- if (this.disabled) {
1023
- return true;
1024
- }
1025
- const { key, shiftKey } = e;
1026
- this.shouldSkipFocus = false;
1027
- switch (key) {
1028
- // Select the first available option
1029
- case keyHome: {
1030
- this.checkFirstOption(shiftKey);
1031
- return;
1032
- }
1033
- // Select the next selectable option
1034
- case keyArrowDown: {
1035
- this.checkNextOption(shiftKey);
1036
- return;
1037
- }
1038
- // Select the previous selectable option
1039
- case keyArrowUp: {
1040
- this.checkPreviousOption(shiftKey);
1041
- return;
1042
- }
1043
- // Select the last available option
1044
- case keyEnd: {
1045
- this.checkLastOption(shiftKey);
1046
- return;
1047
- }
1048
- case keyTab: {
1049
- this.focusAndScrollOptionIntoView();
1050
- return true;
1051
- }
1052
- case keyEscape: {
1053
- this.uncheckAllOptions();
1054
- this.checkActiveIndex();
1055
- return true;
1056
- }
1057
- case keySpace: {
1058
- e.preventDefault();
1059
- if (this.typeAheadExpired) {
1060
- this.toggleSelectedForAllCheckedOptions();
1061
- return;
1062
- }
1063
- }
1064
- // Send key to Typeahead handler
1065
- default: {
1066
- if (key.length === 1) {
1067
- this.handleTypeAhead(`${key}`);
1068
- }
1069
- return true;
1070
- }
1071
- }
1072
- }
1073
- /**
1074
- * Prevents `focusin` events from firing before `click` events when the
1075
- * element is unfocused.
1076
- *
1077
- * @override
1078
- * @internal
1079
- */
1080
- mousedownHandler(e) {
1081
- if (e.offsetX >= 0 && e.offsetX <= this.scrollWidth) {
1082
- return super.mousedownHandler(e);
1083
- }
1084
- }
1085
- /**
1086
- * Switches between single-selection and multi-selection mode.
1087
- *
1088
- * @internal
1089
- */
1090
- multipleChanged(prev, next) {
1091
- var _a;
1092
- this.ariaMultiSelectable = next ? "true" : null;
1093
- (_a = this.options) === null || _a === void 0 ? void 0 : _a.forEach(o => {
1094
- o.checked = next ? false : undefined;
1095
- });
1096
- this.setSelectedOptions();
1097
- }
1098
- /**
1099
- * Sets an option as selected and gives it focus.
1100
- *
1101
- * @override
1102
- * @public
1103
- */
1104
- setSelectedOptions() {
1105
- if (!this.multiple) {
1106
- super.setSelectedOptions();
1107
- return;
1108
- }
1109
- if (this.$fastController.isConnected && this.options) {
1110
- this.selectedOptions = this.options.filter(o => o.selected);
1111
- this.focusAndScrollOptionIntoView();
1112
- }
1113
- }
1114
- /**
1115
- * Ensures the size is a positive integer when the property is updated.
1116
- *
1117
- * @param prev - the previous size value
1118
- * @param next - the current size value
1119
- *
1120
- * @internal
1121
- */
1122
- sizeChanged(prev, next) {
1123
- var _a;
1124
- const size = Math.max(0, parseInt((_a = next === null || next === void 0 ? void 0 : next.toFixed()) !== null && _a !== void 0 ? _a : "", 10));
1125
- if (size !== next) {
1126
- DOM.queueUpdate(() => {
1127
- this.size = size;
1128
- });
1129
- }
1130
- }
1131
- /**
1132
- * Toggles the selected state of the provided options. If any provided items
1133
- * are in an unselected state, all items are set to selected. If every
1134
- * provided item is selected, they are all unselected.
1135
- *
1136
- * @internal
1137
- */
1138
- toggleSelectedForAllCheckedOptions() {
1139
- const enabledCheckedOptions = this.checkedOptions.filter(o => !o.disabled);
1140
- const force = !enabledCheckedOptions.every(o => o.selected);
1141
- enabledCheckedOptions.forEach(o => (o.selected = force));
1142
- this.selectedIndex = this.options.indexOf(enabledCheckedOptions[enabledCheckedOptions.length - 1]);
1143
- this.setSelectedOptions();
1144
- }
1145
- /**
1146
- * @override
1147
- * @internal
1148
- */
1149
- typeaheadBufferChanged(prev, next) {
1150
- if (!this.multiple) {
1151
- super.typeaheadBufferChanged(prev, next);
1152
- return;
1153
- }
1154
- if (this.$fastController.isConnected) {
1155
- const typeaheadMatches = this.getTypeaheadMatches();
1156
- const activeIndex = this.options.indexOf(typeaheadMatches[0]);
1157
- if (activeIndex > -1) {
1158
- this.activeIndex = activeIndex;
1159
- this.uncheckAllOptions();
1160
- this.checkActiveIndex();
1161
- }
1162
- this.typeAheadExpired = false;
1163
- }
1164
- }
1165
- /**
1166
- * Unchecks all options.
1167
- *
1168
- * @remarks
1169
- * Multiple-selection mode only.
1170
- *
1171
- * @param preserveChecked - reset the rangeStartIndex
1172
- *
1173
- * @internal
1174
- */
1175
- uncheckAllOptions(preserveChecked = false) {
1176
- this.options.forEach(o => (o.checked = this.multiple ? false : undefined));
1177
- if (!preserveChecked) {
1178
- this.rangeStartIndex = -1;
1179
- }
1180
- }
1181
- }
1182
- __decorate([
1183
- observable
1184
- ], ListboxElement.prototype, "activeIndex", void 0);
1185
- __decorate([
1186
- attr({ mode: "boolean" })
1187
- ], ListboxElement.prototype, "multiple", void 0);
1188
- __decorate([
1189
- attr({ converter: nullableNumberConverter })
1190
- ], ListboxElement.prototype, "size", void 0);
1191
-
1192
- var __defProp = Object.defineProperty;
1193
- var __decorateClass = (decorators, target, key, kind) => {
1194
- var result = void 0 ;
1195
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
1196
- if (decorator = decorators[i])
1197
- result = (decorator(target, key, result) ) || result;
1198
- if (result) __defProp(target, key, result);
1199
- return result;
1200
- };
1201
- class Listbox extends ListboxElement {
1202
- orientationChanged() {
1203
- if (this.orientation === "horizontal") {
1204
- this.addEventListener("keydown", this.#horizontalKeydownHandler);
1205
- } else {
1206
- this.removeEventListener("keydown", this.#horizontalKeydownHandler);
1207
- }
1208
- }
1209
- /**
1210
- * Handles `keydown` actions for horizontal listbox navigation and typeahead.
1211
- *
1212
- * @internal
1213
- */
1214
- #horizontalKeydownHandler(e) {
1215
- if (this.disabled) {
1216
- return true;
1217
- }
1218
- const key = e.key;
1219
- switch (key) {
1220
- case keyArrowRight: {
1221
- if (!e.shiftKey) {
1222
- e.preventDefault();
1223
- this.selectNextOption();
1224
- }
1225
- break;
1226
- }
1227
- case keyArrowLeft: {
1228
- if (!e.shiftKey) {
1229
- e.preventDefault();
1230
- this.selectPreviousOption();
1231
- }
1232
- break;
1233
- }
1234
- }
1235
- }
1236
- slottedOptionsChanged(prev, next) {
1237
- super.slottedOptionsChanged(prev, next);
1238
- this.#disableSlottedChildren();
1239
- }
1240
- attributeChangedCallback(name, oldValue, newValue) {
1241
- super.attributeChangedCallback(name, oldValue, newValue);
1242
- if (name === "disabled") {
1243
- this.#disableSlottedChildren();
1244
- }
1245
- }
1246
- #disableSlottedChildren() {
1247
- this.options.forEach((optionElement) => {
1248
- if (!optionElement.disabled) {
1249
- optionElement.disabled = this.disabled;
1250
- }
1251
- });
1252
- }
1253
- }
1254
- __decorateClass([
1255
- attr
1256
- ], Listbox.prototype, "appearance");
1257
- __decorateClass([
1258
- attr
1259
- ], Listbox.prototype, "orientation");
1260
- __decorateClass([
1261
- attr
1262
- ], Listbox.prototype, "shape");
1263
-
1264
- export { ListboxElement as L, Listbox as a };