@fluid-topics/ft-combobox 1.3.26

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.
@@ -0,0 +1,634 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { html, nothing } from "lit";
8
+ import { property, query, state } from "lit/decorators.js";
9
+ import { repeat } from "lit/directives/repeat.js";
10
+ import { classMap } from "lit/directives/class-map.js";
11
+ import { ifDefined } from "lit/directives/if-defined.js";
12
+ import { Debouncer, FtLitElement, numberProperty, screenReaderStyles } from "@fluid-topics/ft-wc-utils";
13
+ import { styles } from "./ft-combobox.styles";
14
+ import { FtInputLabel } from "@fluid-topics/ft-input-label";
15
+ import { FtRipple } from "@fluid-topics/ft-ripple";
16
+ import { FtTypography, FtTypographyBody1, FtTypographyVariants } from "@fluid-topics/ft-typography";
17
+ import { FtIcon } from "@fluid-topics/ft-icon";
18
+ import { withI18n } from "@fluid-topics/ft-i18n";
19
+ import { comboboxContext, defaultComboboxMessages } from "./ComboboxMessages";
20
+ class FtCombobox extends withI18n(FtLitElement) {
21
+ get value() {
22
+ return this._value || "";
23
+ }
24
+ set value(value) {
25
+ const oldValue = this._value;
26
+ this._value = value || "";
27
+ this.filter = this._value;
28
+ this.requestUpdate("value", oldValue);
29
+ }
30
+ constructor() {
31
+ super();
32
+ this.error = false;
33
+ this.filterSuggestions = false;
34
+ this.disabled = false;
35
+ this.outlined = false;
36
+ this.suggestionsProvider = () => [];
37
+ this._value = "";
38
+ this.filter = "";
39
+ this.isOpen = false;
40
+ this.comboboxHasVisualFocus = false;
41
+ this.listboxHasVisualFocus = false;
42
+ this.providedSuggestions = [];
43
+ this.visibleSuggestions = [];
44
+ this.activeIndex = -1;
45
+ this.onComboboxInput = () => {
46
+ this.filter = this.input.value;
47
+ this.activeIndex = -1;
48
+ this.updateSuggestions();
49
+ const total = this.getTotalSuggestionsCount();
50
+ if (total > 0) {
51
+ this.openListbox();
52
+ }
53
+ else {
54
+ this.closeListbox(true);
55
+ }
56
+ };
57
+ this.onComboboxKeyDown = (event) => {
58
+ if (event.ctrlKey || event.shiftKey) {
59
+ return;
60
+ }
61
+ let handled = false;
62
+ switch (event.key) {
63
+ case "Enter":
64
+ this.commitSelectionFromEnter();
65
+ handled = true;
66
+ break;
67
+ case "ArrowDown":
68
+ case "Down": {
69
+ this.moveFocusToNextSuggestion(event);
70
+ handled = true;
71
+ break;
72
+ }
73
+ case "ArrowUp":
74
+ case "Up": {
75
+ this.moveFocusToPreviousSuggestion(event);
76
+ handled = true;
77
+ break;
78
+ }
79
+ case "Escape":
80
+ case "Esc":
81
+ this.handleEscapeKey();
82
+ handled = true;
83
+ break;
84
+ case "Tab":
85
+ this.handleTabKey();
86
+ break;
87
+ case "Home":
88
+ this.moveCaretToHome();
89
+ handled = true;
90
+ break;
91
+ case "End": {
92
+ this.moveCaretToEnd();
93
+ handled = true;
94
+ break;
95
+ }
96
+ }
97
+ if (handled) {
98
+ event.stopPropagation();
99
+ event.preventDefault();
100
+ }
101
+ };
102
+ this.onComboboxKeyUp = (event) => {
103
+ if (event.key === "Escape" || event.key === "Esc") {
104
+ return;
105
+ }
106
+ let handled = false;
107
+ switch (event.key) {
108
+ case "Backspace":
109
+ this.setVisualFocusCombobox();
110
+ handled = true;
111
+ break;
112
+ // Do nothing on Arrow navigation keyup to preserve listbox visual focus
113
+ case "ArrowDown":
114
+ case "Down":
115
+ case "ArrowUp":
116
+ case "Up":
117
+ handled = true;
118
+ break;
119
+ case "ArrowLeft":
120
+ case "Enter":
121
+ case "Left":
122
+ case "ArrowRight":
123
+ case "Right":
124
+ case "Home":
125
+ case "End":
126
+ this.setVisualFocusCombobox();
127
+ handled = true;
128
+ break;
129
+ default:
130
+ // For printable keys, the @input handler will update the list.
131
+ // We only maintain visual focus here for printable characters (not arrows, etc.).
132
+ if (this.isPrintableCharacter(event.key) && this.input.value.length) {
133
+ this.setVisualFocusCombobox();
134
+ }
135
+ break;
136
+ }
137
+ if (handled) {
138
+ event.stopPropagation();
139
+ event.preventDefault();
140
+ }
141
+ };
142
+ this.onComboboxClick = () => {
143
+ if (this.isOpen) {
144
+ this.closeListbox(true);
145
+ }
146
+ else {
147
+ this.openListbox();
148
+ }
149
+ };
150
+ this.onComboboxFocus = () => {
151
+ this.filter = this.input.value;
152
+ this.updateSuggestions();
153
+ this.setVisualFocusCombobox();
154
+ this.activeIndex = -1;
155
+ };
156
+ this.onComboboxBlur = () => {
157
+ this.removeVisualFocusAll();
158
+ };
159
+ this.onBackgroundPointerUp = (event) => {
160
+ const target = event.target;
161
+ if (!this.contains(target)) {
162
+ this.comboboxHasVisualFocus = false;
163
+ this.removeVisualFocusAll();
164
+ setTimeout(() => this.closeListbox(true), 300); // Inspired from the WCAG examples
165
+ }
166
+ };
167
+ this.onListboxPointerout = () => {
168
+ setTimeout(() => this.closeListbox(false), 300); // Inspired from the WCAG examples
169
+ };
170
+ this.onSuggestionClick = (suggestion) => {
171
+ var _a;
172
+ if (suggestion.kind === "new") {
173
+ this.setValue(((_a = this.input) === null || _a === void 0 ? void 0 : _a.value) || this.value);
174
+ }
175
+ else {
176
+ this.setValue(suggestion.label);
177
+ }
178
+ this.closeListbox(true);
179
+ };
180
+ this.onSuggestionPointerout = () => {
181
+ setTimeout(() => this.closeListbox(false), 300); // Inspired from the WCAG examples
182
+ };
183
+ this.addI18nContext(comboboxContext, defaultComboboxMessages);
184
+ }
185
+ willUpdate(props) {
186
+ if (props.has("suggestionsProviderDebouncerTimeout")) {
187
+ this._suggestionsProviderDebouncer = this.suggestionsProviderDebouncerTimeout && this.suggestionsProviderDebouncerTimeout > 0
188
+ ? new Debouncer(this.suggestionsProviderDebouncerTimeout)
189
+ : undefined;
190
+ }
191
+ if (props.has("suggestionsProvider") || props.has("filter")) {
192
+ this.updateSuggestions();
193
+ }
194
+ }
195
+ render() {
196
+ const classes = {
197
+ "ft-combobox": true,
198
+ "ft-combobox--filled": !this.outlined,
199
+ "ft-combobox--outlined": this.outlined,
200
+ "ft-combobox--disabled": this.disabled,
201
+ "ft-combobox--with-label": !!this.label,
202
+ "ft-combobox--with-icon": !!this.icon,
203
+ "ft-combobox--in-error": this.error,
204
+ // Use live filter (updated on input) instead of value (committed later)
205
+ "ft-combobox--raised-label": this.comboboxHasVisualFocus || !!this.filter,
206
+ };
207
+ const listboxClasses = {
208
+ "ft-combobox--listbox": true,
209
+ "focus": this.listboxHasVisualFocus,
210
+ };
211
+ return html `
212
+ <div class="${classMap(classes)}">
213
+ <div class="ft-combobox--main-panel"
214
+ @focusout=${this.onComboboxBlur}>
215
+ <ft-input-label
216
+ text="${this.label}"
217
+ ?outlined=${this.outlined}
218
+ ?raised=${this.comboboxHasVisualFocus || !!this.filter}
219
+ ?disabled=${this.disabled}
220
+ ?error=${this.error}>
221
+ </ft-input-label>
222
+ <div class="ft-combobox--input-panel">
223
+ ${this.outlined ? nothing : html `
224
+ <ft-ripple ?disabled=${this.disabled} activated></ft-ripple>
225
+ `}
226
+ <input
227
+ id="combobox-input"
228
+ class="ft-typography--body1 ft-combobox--input"
229
+ part="input"
230
+ type="text"
231
+ role="combobox"
232
+ aria-autocomplete="list"
233
+ autocomplete="false"
234
+ aria-expanded="${this.isOpen}"
235
+ aria-controls="combobox-listbox"
236
+ aria-activedescendant="${this.getActiveDescendantId()}"
237
+ aria-label="${ifDefined(this.label)}"
238
+ name="${ifDefined(this.name)}"
239
+ ?disabled=${this.disabled}
240
+ .value=${this.value}
241
+ @input=${this.onComboboxInput}
242
+ @keydown=${this.onComboboxKeyDown}
243
+ @keyup=${this.onComboboxKeyUp}
244
+ @click=${this.onComboboxClick}
245
+ @focus=${this.onComboboxFocus}
246
+ />
247
+ ${(this.renderIcon())}
248
+ </div>
249
+ <div class="sr-only" aria-live="polite" aria-atomic="true">
250
+ ${this.renderLiveText()}
251
+ </div>
252
+ <ul
253
+ id="combobox-listbox"
254
+ class="${classMap(listboxClasses)}"
255
+ role="listbox"
256
+ aria-label="${this.label || "Options"}"
257
+ data-visible="${this.isOpen}"
258
+ @pointerout=${this.onListboxPointerout}
259
+ >
260
+ ${repeat(this.visibleSuggestions, (option) => option.id, (option, index) => this.renderSuggestion(option, index))}
261
+ </ul>
262
+ </div>
263
+ ${this.helper ? html `
264
+ <ft-typography class="ft-combobox--helper-text" variant="caption">
265
+ ${this.helper}
266
+ </ft-typography>
267
+ ` : nothing}
268
+ </div>
269
+ `;
270
+ }
271
+ renderIcon() {
272
+ return this.icon ? html `
273
+ <ft-icon class="ft-combobox--icon"
274
+ .variant=${this.iconVariant}
275
+ .value=${this.icon}
276
+ @click=${() => {
277
+ var _a, _b;
278
+ (_a = this.input) === null || _a === void 0 ? void 0 : _a.click();
279
+ (_b = this.input) === null || _b === void 0 ? void 0 : _b.focus();
280
+ }}></ft-icon>
281
+ ` : nothing;
282
+ }
283
+ renderSuggestion(suggestion, index) {
284
+ return html `
285
+ <li
286
+ id="${suggestion.kind === "new" ? "suggestion-new-value" : `option-${index}`}"
287
+ class="ft-combobox--option ${suggestion.kind === "new" ? "ft-combobox--option-new-value" : ""}"
288
+ role="option"
289
+ aria-selected="${index === this.activeIndex}"
290
+ @click=${() => this.onSuggestionClick(suggestion)}
291
+ @pointerout=${this.onSuggestionPointerout}
292
+ >
293
+ ${(() => {
294
+ const isNewValue = suggestion.kind === "new" && !!this.suggestionsHelper;
295
+ const classes = {
296
+ "ft-combobox-suggestion": true,
297
+ "ft-combobox-suggestion--with-helper": isNewValue,
298
+ };
299
+ return html `
300
+ <div class="${classMap(classes)}" tabindex="-1">
301
+ <ft-ripple></ft-ripple>
302
+ ${isNewValue ? html `
303
+ <ft-typography aria-label="${this.suggestionsHelper}," class="ft-combobox-suggestion--helper-text"
304
+ variant="${FtTypographyVariants.caption}">
305
+ ${this.suggestionsHelper}
306
+ </ft-typography>
307
+ ` : nothing}
308
+ <ft-typography part="label" variant="${FtTypographyVariants.body1}" class="ft-combobox-suggestion--label">
309
+ ${suggestion.label}
310
+ </ft-typography>
311
+ </div>
312
+ `;
313
+ })()}
314
+ </li>
315
+ `;
316
+ }
317
+ get activeSuggestion() {
318
+ return this.activeIndex >= 0 && this.activeIndex < this.visibleSuggestions.length
319
+ ? this.visibleSuggestions[this.activeIndex]
320
+ : null;
321
+ }
322
+ shouldOfferNew() {
323
+ var _a;
324
+ const currentValue = ((_a = this.input) === null || _a === void 0 ? void 0 : _a.value) || this.value || "";
325
+ return currentValue !== "" && !this.providedSuggestions.some((o) => o.label === currentValue);
326
+ }
327
+ getTotalSuggestionsCount() {
328
+ return this.visibleSuggestions.length;
329
+ }
330
+ isNewValueSuggestionSelected() {
331
+ var _a;
332
+ return this.activeIndex >= 0
333
+ && this.activeIndex < this.visibleSuggestions.length
334
+ && ((_a = this.visibleSuggestions[this.activeIndex]) === null || _a === void 0 ? void 0 : _a.kind) === "new";
335
+ }
336
+ connectedCallback() {
337
+ super.connectedCallback();
338
+ document.body.addEventListener("pointerup", this.onBackgroundPointerUp);
339
+ }
340
+ disconnectedCallback() {
341
+ super.disconnectedCallback();
342
+ document.body.removeEventListener("pointerup", this.onBackgroundPointerUp);
343
+ }
344
+ renderLiveText() {
345
+ const total = this.getTotalSuggestionsCount();
346
+ if (this.isOpen && total > 0) {
347
+ // Keep message short; SR will announce politely without disrupting typing
348
+ return comboboxContext.messages.ariaLiveOptions(total);
349
+ }
350
+ return "";
351
+ }
352
+ getActiveDescendantId() {
353
+ if (this.activeIndex < 0) {
354
+ return "";
355
+ }
356
+ if (this.isNewValueSuggestionSelected()) {
357
+ return "option-new-value";
358
+ }
359
+ return `option-${this.activeIndex}`;
360
+ }
361
+ async updateSuggestions() {
362
+ var _a;
363
+ if (this._suggestionsProviderDebouncer) {
364
+ await ((_a = this._suggestionsProviderDebouncer) === null || _a === void 0 ? void 0 : _a.run(() => this.updateSuggestionsWithoutDebounce()));
365
+ }
366
+ else {
367
+ await this.updateSuggestionsWithoutDebounce();
368
+ }
369
+ }
370
+ async updateSuggestionsWithoutDebounce() {
371
+ var _a;
372
+ if (this.suggestionsProvider) {
373
+ this.providedSuggestions = await this.suggestionsProvider(this.filter);
374
+ const filteredSuggestion = (this.filterSuggestions
375
+ ? this.providedSuggestions.filter((suggestion) => suggestion.label.toLowerCase().includes(this.filter))
376
+ : this.providedSuggestions).map((o, i) => ({ id: `regular-${i}`, label: o.label, kind: "regular" }));
377
+ this.visibleSuggestions = [
378
+ ...filteredSuggestion,
379
+ ...(this.shouldOfferNew() ? [{ id: "new", label: ((_a = this.input) === null || _a === void 0 ? void 0 : _a.value) || this.value, kind: "new" }] : []),
380
+ ];
381
+ }
382
+ }
383
+ setActiveSuggestion(index, updateInput = false) {
384
+ var _a, _b;
385
+ const totalCount = this.getTotalSuggestionsCount();
386
+ if (index < 0 || index >= totalCount) {
387
+ return;
388
+ }
389
+ this.activeIndex = index;
390
+ const opt = this.visibleSuggestions[index];
391
+ if (!opt) {
392
+ return;
393
+ }
394
+ if (updateInput) {
395
+ const target = opt.kind === "new" ? (((_a = this.input) === null || _a === void 0 ? void 0 : _a.value) || this.value) : opt.label;
396
+ const start = this.filter.length;
397
+ (_b = this.input) === null || _b === void 0 ? void 0 : _b.setSelectionRange(start, target.length);
398
+ }
399
+ this.scrollSuggestionIntoView(index);
400
+ }
401
+ scrollSuggestionIntoView(index) {
402
+ requestAnimationFrame(() => {
403
+ var _a, _b;
404
+ let optionElement;
405
+ if (this.isNewValueSuggestionSelected()) {
406
+ optionElement = (_a = this.listbox) === null || _a === void 0 ? void 0 : _a.querySelector(`#option-new-value`);
407
+ }
408
+ else {
409
+ optionElement = (_b = this.listbox) === null || _b === void 0 ? void 0 : _b.querySelector(`#option-${index}`);
410
+ }
411
+ if (optionElement && this.listbox) {
412
+ if (this.listbox.scrollTop + this.listbox.offsetHeight < optionElement.offsetTop + optionElement.offsetHeight) {
413
+ this.listbox.scrollTop = optionElement.offsetTop + optionElement.offsetHeight - this.listbox.offsetHeight;
414
+ }
415
+ else if (this.listbox.scrollTop > optionElement.offsetTop + 2) {
416
+ this.listbox.scrollTop = optionElement.offsetTop;
417
+ }
418
+ }
419
+ });
420
+ }
421
+ openListbox() {
422
+ this.isOpen = true;
423
+ }
424
+ closeListbox(force = false) {
425
+ if (force || (!this.comboboxHasVisualFocus && !this.listboxHasVisualFocus)) {
426
+ this.isOpen = false;
427
+ }
428
+ }
429
+ setVisualFocusCombobox() {
430
+ this.comboboxHasVisualFocus = true;
431
+ this.listboxHasVisualFocus = false;
432
+ }
433
+ setVisualFocusListbox() {
434
+ this.comboboxHasVisualFocus = false;
435
+ this.listboxHasVisualFocus = true;
436
+ }
437
+ removeVisualFocusAll() {
438
+ this.comboboxHasVisualFocus = false;
439
+ this.listboxHasVisualFocus = false;
440
+ }
441
+ setValue(value) {
442
+ this.filter = value;
443
+ this._value = value;
444
+ this.input.value = value;
445
+ this.input.setSelectionRange(value.length, value.length);
446
+ this.updateSuggestions();
447
+ this.dispatchChangeEvent();
448
+ }
449
+ dispatchChangeEvent() {
450
+ this.dispatchEvent(new CustomEvent("change", {
451
+ detail: { value: this._value },
452
+ bubbles: true,
453
+ composed: true,
454
+ }));
455
+ }
456
+ isPrintableCharacter(str) {
457
+ return str.length === 1 && str.match(/\S| /) !== null;
458
+ }
459
+ commitSelectionFromEnter() {
460
+ var _a, _b;
461
+ if (this.isOpen) {
462
+ if (this.isNewValueSuggestionSelected()) {
463
+ this.setValue(((_a = this.input) === null || _a === void 0 ? void 0 : _a.value) || this.value);
464
+ }
465
+ else if (this.activeSuggestion) {
466
+ this.setValue(this.activeSuggestion.label);
467
+ }
468
+ else if ((((_b = this.input) === null || _b === void 0 ? void 0 : _b.value) || "").length > 0) {
469
+ this.setValue(this.input.value);
470
+ }
471
+ }
472
+ this.setVisualFocusCombobox();
473
+ this.closeListbox(true);
474
+ }
475
+ moveFocusToNextSuggestion(event) {
476
+ const totalCount = this.getTotalSuggestionsCount();
477
+ if (totalCount <= 0) {
478
+ return;
479
+ }
480
+ this.openListbox();
481
+ if (event.altKey) {
482
+ return;
483
+ }
484
+ if (this.listboxHasVisualFocus) {
485
+ const nextIndex = this.activeIndex < totalCount - 1
486
+ ? this.activeIndex + 1
487
+ : 0;
488
+ this.setActiveSuggestion(nextIndex);
489
+ }
490
+ else {
491
+ this.setActiveSuggestion(0, true);
492
+ this.setVisualFocusListbox();
493
+ }
494
+ }
495
+ moveFocusToPreviousSuggestion(event) {
496
+ const totalCount = this.getTotalSuggestionsCount();
497
+ if (totalCount <= 0) {
498
+ return;
499
+ }
500
+ if (this.listboxHasVisualFocus) {
501
+ const prevIndex = this.activeIndex > 0
502
+ ? this.activeIndex - 1
503
+ : totalCount - 1;
504
+ this.setActiveSuggestion(prevIndex);
505
+ }
506
+ else {
507
+ this.openListbox();
508
+ if (!event.altKey) {
509
+ this.setActiveSuggestion(totalCount - 1, true);
510
+ this.setVisualFocusListbox();
511
+ }
512
+ }
513
+ }
514
+ handleEscapeKey() {
515
+ if (this.isOpen) {
516
+ this.closeListbox(true);
517
+ this.filter = this.input.value;
518
+ this.updateSuggestions();
519
+ this.setVisualFocusCombobox();
520
+ }
521
+ else {
522
+ this.setValue("");
523
+ }
524
+ this.activeIndex = -1;
525
+ }
526
+ handleTabKey() {
527
+ var _a;
528
+ this.closeListbox(true);
529
+ if (this.listboxHasVisualFocus) {
530
+ if (this.isNewValueSuggestionSelected()) {
531
+ this.setValue(((_a = this.input) === null || _a === void 0 ? void 0 : _a.value) || this.value);
532
+ }
533
+ else if (this.activeSuggestion) {
534
+ this.setValue(this.activeSuggestion.label);
535
+ }
536
+ }
537
+ }
538
+ moveCaretToHome() {
539
+ this.input.setSelectionRange(0, 0);
540
+ }
541
+ moveCaretToEnd() {
542
+ const length = this.input.value.length;
543
+ this.input.setSelectionRange(length, length);
544
+ }
545
+ focus() {
546
+ var _a;
547
+ (_a = this.input) === null || _a === void 0 ? void 0 : _a.focus();
548
+ }
549
+ blur() {
550
+ var _a;
551
+ (_a = this.input) === null || _a === void 0 ? void 0 : _a.blur();
552
+ }
553
+ }
554
+ FtCombobox.styles = [
555
+ FtTypographyBody1,
556
+ screenReaderStyles,
557
+ styles,
558
+ ];
559
+ FtCombobox.elementDefinitions = {
560
+ "ft-input-label": FtInputLabel,
561
+ "ft-ripple": FtRipple,
562
+ "ft-typography": FtTypography,
563
+ "ft-icon": FtIcon,
564
+ };
565
+ __decorate([
566
+ property()
567
+ ], FtCombobox.prototype, "label", void 0);
568
+ __decorate([
569
+ property()
570
+ ], FtCombobox.prototype, "icon", void 0);
571
+ __decorate([
572
+ property()
573
+ ], FtCombobox.prototype, "iconVariant", void 0);
574
+ __decorate([
575
+ property()
576
+ ], FtCombobox.prototype, "name", void 0);
577
+ __decorate([
578
+ property({ type: Boolean })
579
+ ], FtCombobox.prototype, "error", void 0);
580
+ __decorate([
581
+ property({ type: Boolean })
582
+ ], FtCombobox.prototype, "filterSuggestions", void 0);
583
+ __decorate([
584
+ property()
585
+ ], FtCombobox.prototype, "helper", void 0);
586
+ __decorate([
587
+ property({ type: Boolean })
588
+ ], FtCombobox.prototype, "disabled", void 0);
589
+ __decorate([
590
+ property({ type: Boolean })
591
+ ], FtCombobox.prototype, "outlined", void 0);
592
+ __decorate([
593
+ property()
594
+ ], FtCombobox.prototype, "placeholder", void 0);
595
+ __decorate([
596
+ property()
597
+ ], FtCombobox.prototype, "suggestionsHelper", void 0);
598
+ __decorate([
599
+ property({ attribute: false })
600
+ ], FtCombobox.prototype, "suggestionsProvider", void 0);
601
+ __decorate([
602
+ numberProperty()
603
+ ], FtCombobox.prototype, "suggestionsProviderDebouncerTimeout", void 0);
604
+ __decorate([
605
+ property({ noAccessor: true })
606
+ ], FtCombobox.prototype, "value", null);
607
+ __decorate([
608
+ state()
609
+ ], FtCombobox.prototype, "filter", void 0);
610
+ __decorate([
611
+ state()
612
+ ], FtCombobox.prototype, "isOpen", void 0);
613
+ __decorate([
614
+ state()
615
+ ], FtCombobox.prototype, "comboboxHasVisualFocus", void 0);
616
+ __decorate([
617
+ state()
618
+ ], FtCombobox.prototype, "listboxHasVisualFocus", void 0);
619
+ __decorate([
620
+ state()
621
+ ], FtCombobox.prototype, "providedSuggestions", void 0);
622
+ __decorate([
623
+ state()
624
+ ], FtCombobox.prototype, "visibleSuggestions", void 0);
625
+ __decorate([
626
+ state()
627
+ ], FtCombobox.prototype, "activeIndex", void 0);
628
+ __decorate([
629
+ query(".ft-combobox--input")
630
+ ], FtCombobox.prototype, "input", void 0);
631
+ __decorate([
632
+ query(".ft-combobox--listbox")
633
+ ], FtCombobox.prototype, "listbox", void 0);
634
+ export { FtCombobox };