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