@krumio/trailhand-ui 1.9.6 → 1.9.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,765 @@
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 { LitElement, html, css, nothing } from 'lit';
8
+ import { property, state } from 'lit/decorators.js';
9
+ import '../icon/icon';
10
+ import '../th-tag/th-tag';
11
+ export class Dropdown extends LitElement {
12
+ constructor() {
13
+ super();
14
+ this.name = '';
15
+ this.options = [];
16
+ this.value = '';
17
+ this.values = [];
18
+ this.placeholder = 'Select...';
19
+ this.disabled = false;
20
+ this.multiselect = false;
21
+ this.label = '';
22
+ this.required = false;
23
+ this.invalid = false;
24
+ this.filterable = false;
25
+ this.size = 'medium';
26
+ this._open = false;
27
+ this._filter = '';
28
+ this.internals = this.attachInternals();
29
+ this._handleOutsideClick = this._handleOutsideClick.bind(this);
30
+ }
31
+ connectedCallback() {
32
+ super.connectedCallback();
33
+ const fieldset = this.closest('fieldset');
34
+ if (fieldset?.disabled) {
35
+ this.disabled = true;
36
+ }
37
+ document.addEventListener('click', this._handleOutsideClick);
38
+ this.addEventListener('invalid', () => {
39
+ this._updateValidity();
40
+ });
41
+ }
42
+ disconnectedCallback() {
43
+ super.disconnectedCallback();
44
+ document.removeEventListener('click', this._handleOutsideClick);
45
+ this._open = false;
46
+ }
47
+ _handleOutsideClick(e) {
48
+ const path = e.composedPath();
49
+ if (!path.includes(this)) {
50
+ this._close();
51
+ }
52
+ }
53
+ _openDropdown() {
54
+ if (this.disabled || this._open)
55
+ return;
56
+ this._open = true;
57
+ this._filter = '';
58
+ if (this.filterable) {
59
+ this.updateComplete.then(() => {
60
+ this.shadowRoot?.querySelector('.search-input')?.focus();
61
+ });
62
+ }
63
+ }
64
+ _close() {
65
+ if (!this._open)
66
+ return;
67
+ this._open = false;
68
+ this._filter = '';
69
+ }
70
+ _toggle() {
71
+ if (this._open) {
72
+ this._close();
73
+ }
74
+ else {
75
+ this._openDropdown();
76
+ }
77
+ }
78
+ get _filteredOptions() {
79
+ if (!this._filter)
80
+ return this.options;
81
+ const lower = this._filter.toLowerCase();
82
+ return this.options.filter((o) => o.label.toLowerCase().includes(lower));
83
+ }
84
+ get _selectedLabel() {
85
+ if (!this.value)
86
+ return '';
87
+ const option = this.options.find((o) => o.value === this.value);
88
+ return option?.label ?? this.value;
89
+ }
90
+ _selectOption(option) {
91
+ if (option.disabled)
92
+ return;
93
+ if (this.multiselect) {
94
+ if (this.values.includes(option.value)) {
95
+ this.values = this.values.filter((v) => v !== option.value);
96
+ }
97
+ else if (option.clearOthers) {
98
+ // This option clears all others when selected
99
+ this.values = [option.value];
100
+ }
101
+ else {
102
+ // If any currently-selected option has clearOthers, remove it first
103
+ const clearOthersValues = this.options
104
+ .filter((o) => o.clearOthers)
105
+ .map((o) => o.value);
106
+ this.values = [...this.values.filter((v) => !clearOthersValues.includes(v)), option.value];
107
+ }
108
+ this._updateFormValue();
109
+ this._emitChangeEvent();
110
+ }
111
+ else {
112
+ this.value = option.value;
113
+ this._updateFormValue();
114
+ this._emitChangeEvent();
115
+ this._close();
116
+ }
117
+ }
118
+ _removeTag(val) {
119
+ this.values = this.values.filter((v) => v !== val);
120
+ this._updateFormValue();
121
+ this._emitChangeEvent();
122
+ }
123
+ _clearAll() {
124
+ if (this.multiselect) {
125
+ this.values = [];
126
+ }
127
+ else {
128
+ this.value = '';
129
+ }
130
+ this._updateFormValue();
131
+ this._emitChangeEvent();
132
+ }
133
+ _clearFilter() {
134
+ this._filter = '';
135
+ this.shadowRoot?.querySelector('.search-input')?.focus();
136
+ }
137
+ _updateFormValue() {
138
+ if (this.multiselect) {
139
+ if (this.values.length > 0) {
140
+ const fd = new FormData();
141
+ this.values.forEach((v) => fd.append(this.name, v));
142
+ this.internals.setFormValue(fd);
143
+ }
144
+ else {
145
+ this.internals.setFormValue(null);
146
+ }
147
+ }
148
+ else {
149
+ this.internals.setFormValue(this.value || null);
150
+ }
151
+ this._updateValidity();
152
+ }
153
+ _updateValidity() {
154
+ const hasValue = this.multiselect ? this.values.length > 0 : !!this.value;
155
+ if (this.required && !hasValue) {
156
+ const anchor = this.shadowRoot?.querySelector('.trigger') ?? undefined;
157
+ this.internals.setValidity({ valueMissing: true }, 'Please select an option', anchor);
158
+ this.invalid = true;
159
+ }
160
+ else {
161
+ this.internals.setValidity({});
162
+ this.invalid = false;
163
+ }
164
+ }
165
+ _emitChangeEvent() {
166
+ this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
167
+ this.dispatchEvent(new CustomEvent('dropdown-change', {
168
+ detail: this.multiselect
169
+ ? { values: this.values, name: this.name }
170
+ : { value: this.value, name: this.name },
171
+ bubbles: true,
172
+ composed: true,
173
+ }));
174
+ }
175
+ _handleFilterInput(e) {
176
+ this._filter = e.target.value;
177
+ }
178
+ _handleSearchKeydown(e) {
179
+ if (e.key === 'Escape') {
180
+ this._close();
181
+ }
182
+ else if (e.key === 'ArrowDown') {
183
+ e.preventDefault();
184
+ this._focusOption(0);
185
+ }
186
+ }
187
+ _handleOptionKeydown(e, index) {
188
+ if (e.key === 'Escape') {
189
+ this._close();
190
+ }
191
+ else if (e.key === 'ArrowDown') {
192
+ e.preventDefault();
193
+ this._focusOption(index + 1);
194
+ }
195
+ else if (e.key === 'ArrowUp') {
196
+ e.preventDefault();
197
+ if (index === 0 && this.filterable) {
198
+ this._focusSearch();
199
+ }
200
+ else if (index > 0) {
201
+ this._focusOption(index - 1);
202
+ }
203
+ }
204
+ else if (e.key === 'Enter' || e.key === ' ') {
205
+ e.preventDefault();
206
+ const option = this._filteredOptions[index];
207
+ if (option)
208
+ this._selectOption(option);
209
+ }
210
+ }
211
+ _handleTriggerKeydown(e) {
212
+ if (e.key === 'Enter' || e.key === ' ') {
213
+ e.preventDefault();
214
+ this._toggle();
215
+ }
216
+ else if (e.key === 'Escape') {
217
+ this._close();
218
+ }
219
+ else if (e.key === 'ArrowDown' && !this._open) {
220
+ e.preventDefault();
221
+ this._openDropdown();
222
+ }
223
+ }
224
+ _focusOption(index) {
225
+ this.updateComplete.then(() => {
226
+ const opts = this.shadowRoot?.querySelectorAll('.option:not(.disabled)');
227
+ opts?.[index]?.focus();
228
+ });
229
+ }
230
+ _focusSearch() {
231
+ this.shadowRoot?.querySelector('.search-input')?.focus();
232
+ }
233
+ get validity() {
234
+ return this.internals.validity;
235
+ }
236
+ checkValidity() {
237
+ return this.internals.checkValidity();
238
+ }
239
+ reportValidity() {
240
+ return this.internals.reportValidity();
241
+ }
242
+ updated(changedProperties) {
243
+ if (changedProperties.has('required') ||
244
+ changedProperties.has('value') ||
245
+ changedProperties.has('values')) {
246
+ // Keep internals in sync so form submission is blocked when required,
247
+ // but do not set this.invalid here — visual state is only shown after
248
+ // the user interacts or a submit is attempted.
249
+ const hasValue = this.multiselect ? this.values.length > 0 : !!this.value;
250
+ if (this.required && !hasValue) {
251
+ const anchor = this.shadowRoot?.querySelector('.trigger') ?? undefined;
252
+ this.internals.setValidity({ valueMissing: true }, 'Please select an option', anchor);
253
+ }
254
+ else {
255
+ this.internals.setValidity({});
256
+ this.invalid = false;
257
+ }
258
+ }
259
+ }
260
+ formAssociatedCallback(form) {
261
+ form?.addEventListener('submit', () => {
262
+ this._updateValidity();
263
+ });
264
+ }
265
+ formResetCallback() {
266
+ this.value = '';
267
+ this.values = [];
268
+ this._updateFormValue();
269
+ }
270
+ formDisableCallback(disabled) {
271
+ this.disabled = disabled;
272
+ }
273
+ _chevronSvg() {
274
+ return html `
275
+ <svg
276
+ width="12"
277
+ height="12"
278
+ viewBox="0 0 12 12"
279
+ fill="none"
280
+ xmlns="http://www.w3.org/2000/svg"
281
+ >
282
+ <path
283
+ d="M2 4L6 8L10 4"
284
+ stroke="currentColor"
285
+ stroke-width="1.5"
286
+ stroke-linecap="round"
287
+ stroke-linejoin="round"
288
+ />
289
+ </svg>
290
+ `;
291
+ }
292
+ _checkSvg() {
293
+ return html `
294
+ <svg
295
+ width="12"
296
+ height="12"
297
+ viewBox="0 0 12 12"
298
+ fill="none"
299
+ xmlns="http://www.w3.org/2000/svg"
300
+ >
301
+ <path
302
+ d="M2 6L5 9L10 3"
303
+ stroke="currentColor"
304
+ stroke-width="1.5"
305
+ stroke-linecap="round"
306
+ stroke-linejoin="round"
307
+ />
308
+ </svg>
309
+ `;
310
+ }
311
+ _renderTriggerContent() {
312
+ if (this.multiselect) {
313
+ const tags = this.values.map((val) => {
314
+ const opt = this.options.find((o) => o.value === val);
315
+ const tagLabel = opt?.label ?? val;
316
+ return html `
317
+ <trailhand-tag
318
+ label=${tagLabel}
319
+ value=${val}
320
+ variant="info"
321
+ size="sm"
322
+ dismissible
323
+ outlined
324
+ ?disabled=${this.disabled}
325
+ @tag-dismiss=${(e) => this._removeTag(e.detail.value)}
326
+ ></trailhand-tag>
327
+ `;
328
+ });
329
+ return html `
330
+ ${tags}
331
+ ${this.values.length === 0
332
+ ? html `<span class="trigger-text placeholder">${this.placeholder}</span>`
333
+ : nothing}
334
+ `;
335
+ }
336
+ const selectedLabel = this._selectedLabel;
337
+ return html `
338
+ <span class="trigger-text ${selectedLabel ? '' : 'placeholder'}"
339
+ >${selectedLabel || this.placeholder}</span
340
+ >
341
+ `;
342
+ }
343
+ _renderDropdownPanel() {
344
+ if (!this._open)
345
+ return html ``;
346
+ const filtered = this._filteredOptions;
347
+ return html `
348
+ <div class="dropdown-panel" role="listbox" aria-multiselectable=${this.multiselect}>
349
+ ${this.filterable
350
+ ? html `
351
+ <div class="search-wrapper">
352
+ <input
353
+ class="search-input"
354
+ type="text"
355
+ placeholder="Search..."
356
+ .value=${this._filter}
357
+ autocomplete="off"
358
+ aria-label="Search options"
359
+ @input=${this._handleFilterInput}
360
+ @keydown=${this._handleSearchKeydown}
361
+ />
362
+ ${this._filter
363
+ ? html `
364
+ <button
365
+ class="search-clear-btn"
366
+ @click=${() => this._clearFilter()}
367
+ aria-label="Clear search"
368
+ >
369
+ <trailhand-icon name="x"></trailhand-icon>
370
+ </button>
371
+ `
372
+ : nothing}
373
+ </div>
374
+ `
375
+ : nothing}
376
+
377
+ <div class="options-list">
378
+ ${filtered.length > 0
379
+ ? filtered.map((option, index) => {
380
+ const isSelected = this.multiselect
381
+ ? this.values.includes(option.value)
382
+ : this.value === option.value;
383
+ return html `
384
+ <div
385
+ class="option ${isSelected ? 'selected' : ''} ${option.disabled
386
+ ? 'disabled'
387
+ : ''}"
388
+ role="option"
389
+ aria-selected=${isSelected}
390
+ aria-disabled=${option.disabled ?? false}
391
+ tabindex=${option.disabled ? -1 : 0}
392
+ @click=${() => this._selectOption(option)}
393
+ @keydown=${(e) => this._handleOptionKeydown(e, index)}
394
+ >
395
+ <span class="option-label">${option.label}</span>
396
+ ${isSelected
397
+ ? html `<span class="option-check">${this._checkSvg()}</span>`
398
+ : html `<span class="option-check"></span>`}
399
+ </div>
400
+ `;
401
+ })
402
+ : html `<div class="no-options">No options found</div>`}
403
+ </div>
404
+ </div>
405
+ `;
406
+ }
407
+ render() {
408
+ const hasSelection = this.multiselect ? this.values.length > 0 : !!this.value;
409
+ return html `
410
+ <div class="wrapper">
411
+ ${this.label
412
+ ? html `
413
+ <label class="input-label">
414
+ ${this.label}
415
+ <span class="required-indicator">${this.required ? '*' : ''}</span>
416
+ </label>
417
+ `
418
+ : ''}
419
+
420
+ <div
421
+ class="trigger ${this._open ? 'open' : ''}"
422
+ role="combobox"
423
+ aria-expanded=${this._open}
424
+ aria-haspopup="listbox"
425
+ tabindex=${this.disabled ? -1 : 0}
426
+ @click=${() => this._toggle()}
427
+ @keydown=${this._handleTriggerKeydown}
428
+ >
429
+ ${this._renderTriggerContent()}
430
+
431
+ <span class="trigger-icons">
432
+ ${hasSelection && !this.disabled
433
+ ? html `
434
+ <button
435
+ class="clear-btn"
436
+ @click=${(e) => {
437
+ e.stopPropagation();
438
+ this._clearAll();
439
+ }}
440
+ aria-label="Clear selection"
441
+ >
442
+ <trailhand-icon name="x"></trailhand-icon>
443
+ </button>
444
+ `
445
+ : ''}
446
+ <span class="chevron ${this._open ? 'open' : ''}">${this._chevronSvg()}</span>
447
+ </span>
448
+ </div>
449
+
450
+ ${this._renderDropdownPanel()}
451
+ </div>
452
+ `;
453
+ }
454
+ }
455
+ Dropdown.formAssociated = true;
456
+ Dropdown.styles = css `
457
+ :host {
458
+ display: inline-block;
459
+ font-family: 'Montserrat', system-ui, sans-serif;
460
+ position: relative;
461
+ min-width: var(--th-dropdown-min-width, 220px);
462
+ }
463
+
464
+ .wrapper {
465
+ display: flex;
466
+ flex-direction: column;
467
+ gap: 0.25rem;
468
+ }
469
+
470
+ .input-label {
471
+ font-size: 11px;
472
+ color: var(--th-input-label, #000000);
473
+ }
474
+
475
+ .required-indicator {
476
+ color: var(--th-color-red, #bf1e1e);
477
+ }
478
+
479
+ /* ── Trigger ── */
480
+ .trigger {
481
+ position: relative;
482
+ display: flex;
483
+ align-items: center;
484
+ flex-wrap: wrap;
485
+ gap: 4px;
486
+ min-height: 2.75em;
487
+ padding: 0.45em 3em 0.45em 12px;
488
+ border-radius: 8px;
489
+ border: 1px solid var(--th-input-border, #d7d7d7);
490
+ background: transparent;
491
+ cursor: pointer;
492
+ transition: border-color 0.2s ease;
493
+ font-size: 14px;
494
+ box-sizing: border-box;
495
+ outline: none;
496
+ }
497
+
498
+ .trigger.open,
499
+ .trigger:focus-within {
500
+ border-color: var(--th-input-focus-border, #0086FF);
501
+ }
502
+
503
+ :host([invalid]) .trigger,
504
+ :host([invalid]) .trigger.open,
505
+ :host([invalid]) .trigger:focus-within {
506
+ border-color: var(--th-input-border-invalid, #9f3a3a);
507
+ }
508
+
509
+ :host([disabled]) .trigger {
510
+ cursor: not-allowed;
511
+ opacity: 0.6;
512
+ background: var(--th-input-bg, #ebebeb);
513
+ }
514
+
515
+ /* Single-select display text */
516
+ .trigger-text {
517
+ flex: 1;
518
+ font-size: 14px;
519
+ color: var(--th-input-text, #333);
520
+ white-space: nowrap;
521
+ overflow: hidden;
522
+ text-overflow: ellipsis;
523
+ user-select: none;
524
+ }
525
+
526
+ .trigger-text.placeholder {
527
+ color: var(--th-input-placeholder, #d7d7d7);
528
+ }
529
+
530
+ /* Chevron + clear row */
531
+ .trigger-icons {
532
+ position: absolute;
533
+ right: 0.75em;
534
+ top: 50%;
535
+ transform: translateY(-50%);
536
+ display: flex;
537
+ align-items: center;
538
+ gap: 2px;
539
+ }
540
+
541
+ .clear-btn {
542
+ background: none;
543
+ border: none;
544
+ cursor: pointer;
545
+ padding: 2px;
546
+ display: flex;
547
+ align-items: center;
548
+ color: var(--th-input-icon-color, #aaa);
549
+ font-size: 0.8em;
550
+ border-radius: 2px;
551
+ line-height: 1;
552
+ }
553
+
554
+ .clear-btn:hover {
555
+ color: var(--th-input-text, #333);
556
+ }
557
+
558
+ .chevron {
559
+ color: var(--th-input-icon-color, #d7d7d7);
560
+ display: flex;
561
+ align-items: center;
562
+ transition: transform 0.2s ease;
563
+ pointer-events: none;
564
+ }
565
+
566
+ .chevron.open {
567
+ transform: rotate(180deg);
568
+ }
569
+
570
+ /* ── Dropdown panel ── */
571
+ .dropdown-panel {
572
+ position: absolute;
573
+ top: calc(100% + 4px);
574
+ left: 0;
575
+ right: 0;
576
+ background: var(--th-dropdown-bg, #ffffff);
577
+ border: 1px solid var(--th-input-border, #d7d7d7);
578
+ border-radius: 8px;
579
+ box-shadow: var(--th-dropdown-shadow, 0 4px 16px rgba(0, 0, 0, 0.1));
580
+ z-index: 100;
581
+ }
582
+
583
+ /* Search row inside panel */
584
+ .search-wrapper {
585
+ display: flex;
586
+ align-items: center;
587
+ gap: 4px;
588
+ padding: 8px;
589
+ border-bottom: 1px solid var(--th-input-border, #d7d7d7);
590
+ border-radius: 8px 8px 0 0;
591
+ overflow: hidden;
592
+ box-sizing: border-box;
593
+ }
594
+
595
+ .search-input {
596
+ flex: 1;
597
+ min-width: 0;
598
+ padding: 0.4em 10px;
599
+ border-radius: 6px;
600
+ border: 1px solid var(--th-input-border, #d7d7d7);
601
+ outline: none;
602
+ font-family: inherit;
603
+ font-size: 13px;
604
+ color: var(--th-input-text, #333);
605
+ background: var(--th-dropdown-bg, #ffffff);
606
+ transition: border-color 0.2s ease;
607
+ box-sizing: border-box;
608
+ }
609
+
610
+ .search-input:focus {
611
+ border-color: var(--th-input-focus-border, #0086FF);
612
+ }
613
+
614
+ .search-input::placeholder {
615
+ color: var(--th-input-placeholder, #d7d7d7);
616
+ }
617
+
618
+ .search-clear-btn {
619
+ background: none;
620
+ border: none;
621
+ cursor: pointer;
622
+ padding: 4px;
623
+ display: flex;
624
+ align-items: center;
625
+ color: var(--th-input-icon-color, #aaa);
626
+ font-size: 0.85em;
627
+ border-radius: 4px;
628
+ flex-shrink: 0;
629
+ }
630
+
631
+ .search-clear-btn:hover {
632
+ color: var(--th-input-text, #333);
633
+ }
634
+
635
+ /* Options */
636
+ .options-list {
637
+ max-height: 240px;
638
+ overflow-y: auto;
639
+ padding: 4px 0;
640
+ border-radius: 8px;
641
+ }
642
+
643
+ .search-wrapper + .options-list {
644
+ border-radius: 0 0 8px 8px;
645
+ }
646
+
647
+ .option {
648
+ display: flex;
649
+ align-items: center;
650
+ justify-content: space-between;
651
+ padding: 0.55em 16px;
652
+ cursor: pointer;
653
+ font-size: 14px;
654
+ color: var(--th-dropdown-option-text, var(--th-input-text, #333));
655
+ transition: background 0.1s ease;
656
+ outline: none;
657
+ gap: 8px;
658
+ }
659
+
660
+ .option:hover:not(.disabled),
661
+ .option:focus:not(.disabled) {
662
+ background: var(--th-dropdown-option-hover-bg, color-mix(in srgb, var(--th-input-focus-border, #0086FF) 6%, transparent));
663
+ }
664
+
665
+ .option.selected {
666
+ background: var(--th-dropdown-option-selected-bg, color-mix(in srgb, var(--th-input-focus-border, #0086FF) 10%, transparent));
667
+ color: var(--th-dropdown-option-selected-text, var(--th-input-focus-border, #0086FF));
668
+ }
669
+
670
+ .option.disabled {
671
+ opacity: 0.45;
672
+ cursor: not-allowed;
673
+ }
674
+
675
+ .option-label {
676
+ flex: 1;
677
+ }
678
+
679
+ .option-check {
680
+ display: flex;
681
+ align-items: center;
682
+ justify-content: center;
683
+ width: 14px;
684
+ height: 14px;
685
+ flex-shrink: 0;
686
+ color: var(--th-dropdown-option-selected-text, var(--th-input-focus-border, #0086FF));
687
+ }
688
+
689
+ .no-options {
690
+ padding: 1em 16px;
691
+ font-size: 13px;
692
+ color: var(--th-dropdown-no-options-text, var(--th-input-placeholder, #aaa));
693
+ text-align: center;
694
+ }
695
+
696
+ /* ── Size: small ── */
697
+ :host([size='small']) .trigger {
698
+ font-size: 12px;
699
+ min-height: 2.25em;
700
+ padding: 0.4em 2.5em 0.4em 10px;
701
+ }
702
+ :host([size='small']) .trigger-text,
703
+ :host([size='small']) .option {
704
+ font-size: 12px;
705
+ }
706
+
707
+ /* ── Size: large ── */
708
+ :host([size='large']) .trigger {
709
+ font-size: 16px;
710
+ min-height: 3.1em;
711
+ }
712
+ :host([size='large']) .trigger-text,
713
+ :host([size='large']) .option {
714
+ font-size: 16px;
715
+ }
716
+
717
+ /* Disabled label */
718
+ :host([disabled]) .input-label {
719
+ color: var(--th-input-label-disabled, #999);
720
+ }
721
+ `;
722
+ __decorate([
723
+ property({ type: String })
724
+ ], Dropdown.prototype, "name", void 0);
725
+ __decorate([
726
+ property({ attribute: false })
727
+ ], Dropdown.prototype, "options", void 0);
728
+ __decorate([
729
+ property({ type: String })
730
+ ], Dropdown.prototype, "value", void 0);
731
+ __decorate([
732
+ property({ attribute: false })
733
+ ], Dropdown.prototype, "values", void 0);
734
+ __decorate([
735
+ property({ type: String })
736
+ ], Dropdown.prototype, "placeholder", void 0);
737
+ __decorate([
738
+ property({ type: Boolean, reflect: true })
739
+ ], Dropdown.prototype, "disabled", void 0);
740
+ __decorate([
741
+ property({ type: Boolean, reflect: true })
742
+ ], Dropdown.prototype, "multiselect", void 0);
743
+ __decorate([
744
+ property({ type: String })
745
+ ], Dropdown.prototype, "label", void 0);
746
+ __decorate([
747
+ property({ type: Boolean })
748
+ ], Dropdown.prototype, "required", void 0);
749
+ __decorate([
750
+ property({ type: Boolean, reflect: true })
751
+ ], Dropdown.prototype, "invalid", void 0);
752
+ __decorate([
753
+ property({ type: Boolean })
754
+ ], Dropdown.prototype, "filterable", void 0);
755
+ __decorate([
756
+ property({ type: String, reflect: true })
757
+ ], Dropdown.prototype, "size", void 0);
758
+ __decorate([
759
+ state()
760
+ ], Dropdown.prototype, "_open", void 0);
761
+ __decorate([
762
+ state()
763
+ ], Dropdown.prototype, "_filter", void 0);
764
+ customElements.define('trailhand-dropdown', Dropdown);
765
+ //# sourceMappingURL=dropdown.js.map