@triptease/tt-combobox 5.0.3

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,77 @@
1
+ import { LitElement, PropertyValues } from 'lit';
2
+ export declare class TtCombobox extends LitElement {
3
+ static styles: import("lit").CSSResult;
4
+ static formAssociated: boolean;
5
+ static shadowRootOptions: {
6
+ delegatesFocus: boolean;
7
+ mode: ShadowRootMode;
8
+ serializable?: boolean;
9
+ slotAssignment?: SlotAssignmentMode;
10
+ customElements?: CustomElementRegistry;
11
+ registry?: CustomElementRegistry;
12
+ };
13
+ multiselect: boolean;
14
+ disabled: boolean;
15
+ invalid: boolean;
16
+ _extValue: string[];
17
+ displaySelectAll: boolean;
18
+ required: boolean;
19
+ name: string;
20
+ ariaLabelledby: symbol;
21
+ hideCaret: boolean;
22
+ placeholder?: string;
23
+ get form(): HTMLFormElement | null;
24
+ protected _activeOption: number;
25
+ protected _expanded: boolean;
26
+ protected _filter: string;
27
+ options: Array<HTMLOptionElement>;
28
+ activeOptions: Array<HTMLOptionElement>;
29
+ protected errorElements: Array<HTMLElement>;
30
+ protected _visibleOptions: Array<HTMLOptionElement>;
31
+ protected _selectableOptions: Array<HTMLOptionElement>;
32
+ protected _selectableVisibleOptions: Array<HTMLOptionElement>;
33
+ protected _selectedOptions: Array<HTMLOptionElement>;
34
+ protected _selectedVisibleOptions: NodeListOf<HTMLOptionElement>;
35
+ protected _comboboxInput: HTMLInputElement;
36
+ protected _chevronButton: HTMLButtonElement;
37
+ internals: ReturnType<typeof this.attachInternals>;
38
+ get value(): string[];
39
+ set value(selection: string[]);
40
+ private get _isAllSelected();
41
+ private _slotObserver;
42
+ constructor();
43
+ private _handleFocusOut;
44
+ private _onFocus;
45
+ connectedCallback(): void;
46
+ disconnectedCallback(): void;
47
+ protected firstUpdated(changedProperties: PropertyValues): void;
48
+ protected update(changedProperties: PropertyValues): void;
49
+ private _listenForOptionChange;
50
+ reportValidity(): void;
51
+ private _reportValidity;
52
+ private get labels();
53
+ private get labelContent();
54
+ private _onKeyUp;
55
+ private _uncheckOption;
56
+ private _checkOption;
57
+ private _toggleOption;
58
+ private _getActiveOptionId;
59
+ private _onClick;
60
+ private _onChevronClick;
61
+ private _onClickOption;
62
+ private _onInput;
63
+ private _dispatchSelectedOptions;
64
+ private _selectAll;
65
+ private get _isValid();
66
+ private _renderCombobox;
67
+ private _renderSelectAll;
68
+ private _renderOption;
69
+ private _renderChevron;
70
+ private _hasErrorContent;
71
+ render(): import("lit-html").TemplateResult<1>;
72
+ }
73
+ declare global {
74
+ interface HTMLElementTagNameMap {
75
+ 'tt-combobox': TtCombobox;
76
+ }
77
+ }
@@ -0,0 +1,456 @@
1
+ import { __decorate } from "tslib";
2
+ /* eslint-disable lit-a11y/click-events-have-key-events */
3
+ import { html, LitElement, nothing } from 'lit';
4
+ import { property, query, queryAll, queryAssignedElements, state } from 'lit/decorators.js';
5
+ import { ifDefined } from 'lit/directives/if-defined.js';
6
+ import { repeat } from 'lit/directives/repeat.js';
7
+ import { unsafeHTML } from 'lit/directives/unsafe-html.js';
8
+ import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
9
+ import { guard } from 'lit/directives/guard.js';
10
+ import { alert, chevronDown } from '@triptease/icons';
11
+ import { styles } from './styles.js';
12
+ export class TtCombobox extends LitElement {
13
+ get form() {
14
+ return this.internals.form;
15
+ }
16
+ get value() {
17
+ return Array.from(this._selectedOptions).map(option => option.dataset.value);
18
+ }
19
+ set value(selection) {
20
+ this._selectableOptions.forEach(option => {
21
+ if (selection.includes(option.dataset.value)) {
22
+ this._checkOption(option);
23
+ }
24
+ else {
25
+ this._uncheckOption(option);
26
+ }
27
+ });
28
+ }
29
+ get _isAllSelected() {
30
+ return Array.from(this._selectableVisibleOptions).every(option => Array.from(this._selectedVisibleOptions).includes(option));
31
+ }
32
+ constructor() {
33
+ super();
34
+ this.multiselect = false;
35
+ this.disabled = false;
36
+ this.invalid = false;
37
+ this._extValue = [];
38
+ this.displaySelectAll = false;
39
+ this.required = false;
40
+ this.name = '';
41
+ this.ariaLabelledby = nothing;
42
+ this.hideCaret = false;
43
+ this._activeOption = -1;
44
+ this._expanded = false;
45
+ this._filter = '';
46
+ this._slotObserver = new MutationObserver((mutations) => {
47
+ mutations.forEach(mutation => {
48
+ if (mutation.type === 'attributes') {
49
+ this.requestUpdate('options');
50
+ }
51
+ });
52
+ });
53
+ this._listenForOptionChange = () => {
54
+ this.options.forEach(option => {
55
+ this._slotObserver.observe(option, { attributes: true, attributeFilter: ['selected', 'disabled', 'hidden'] });
56
+ });
57
+ };
58
+ this._selectAll = (event) => {
59
+ event.preventDefault();
60
+ event.stopPropagation();
61
+ const oldValue = [...this.value];
62
+ if (this.value.length === this._selectableOptions.length) {
63
+ // this.value = this.value.filter(value => ![...this._selectableOptions].some(option => option.dataset.value === value));
64
+ this._selectableOptions.forEach(option => this._uncheckOption(option));
65
+ }
66
+ else {
67
+ this._selectableOptions.forEach(option => this._checkOption(option));
68
+ }
69
+ this.requestUpdate('value', oldValue);
70
+ };
71
+ this._renderSelectAll = () => {
72
+ if (!this.multiselect || !this.displaySelectAll) {
73
+ return nothing;
74
+ }
75
+ const id = `${this.id}-option-select-all`;
76
+ const active = this._getActiveOptionId() === id;
77
+ const selected = this._isAllSelected;
78
+ // eslint-disable-next-line lit-a11y/click-events-have-key-events
79
+ return html `
80
+ <li
81
+ class="select-all"
82
+ role="option"
83
+ id="${this.id}-option-select-all"
84
+ aria-selected="${selected}"
85
+ data-active=${active}
86
+ @click="${this._selectAll}"
87
+ @mousedown="${(evt) => evt.preventDefault()}"
88
+ data-value="select-all"
89
+ part="option"
90
+ >
91
+ <input type="checkbox" ?checked=${selected} role="presentation" tabindex="-1" part="checkbox">
92
+ Select all
93
+ </li>`;
94
+ };
95
+ this._renderChevron = () => html `
96
+ <button type="button" aria-label="Expand" @click="${this._onChevronClick}" aria-expanded="${this._expanded}"
97
+ aria-controls="${this.id}-list" tabindex="-1" ?disabled=${this.disabled} part="arrow">
98
+ ${unsafeSVG(chevronDown)}
99
+ </button>
100
+ `;
101
+ this.internals = this.attachInternals();
102
+ }
103
+ _handleFocusOut(e) {
104
+ if (!this.shadowRoot.contains(e.relatedTarget)) {
105
+ this._expanded = false;
106
+ }
107
+ }
108
+ _onFocus() {
109
+ this._comboboxInput.focus();
110
+ }
111
+ connectedCallback() {
112
+ super.connectedCallback();
113
+ this.addEventListener('focus', this._onFocus);
114
+ }
115
+ disconnectedCallback() {
116
+ super.disconnectedCallback();
117
+ this.removeEventListener('focus', this._onFocus);
118
+ }
119
+ firstUpdated(changedProperties) {
120
+ this.internals.setFormValue(JSON.stringify(this.value));
121
+ this._reportValidity();
122
+ super.firstUpdated(changedProperties);
123
+ }
124
+ update(changedProperties) {
125
+ if (changedProperties.has('value') && changedProperties.get('value') !== undefined && JSON.stringify(changedProperties.get('value')) !== JSON.stringify(this.value)) {
126
+ this._dispatchSelectedOptions();
127
+ this._reportValidity();
128
+ }
129
+ if (changedProperties.has('_expanded') && changedProperties.get('_expanded') && !this._expanded) {
130
+ this.internals.states.add('interacted');
131
+ }
132
+ if (changedProperties.has('options')) {
133
+ this.updateComplete.then(() => {
134
+ this.value = Array.from(new Set([...this.value, ...Array.from(this._selectedOptions).map(option => option.dataset.value)]));
135
+ this._listenForOptionChange();
136
+ });
137
+ }
138
+ super.update(changedProperties);
139
+ }
140
+ reportValidity() {
141
+ if (!this._isValid) {
142
+ this.internals.states.add('--invalid');
143
+ }
144
+ else if (this.internals.states.has('--invalid')) {
145
+ this.internals.states.delete('--invalid');
146
+ }
147
+ this.internals.reportValidity();
148
+ }
149
+ _reportValidity() {
150
+ if (this.required && !this.value.length) {
151
+ const errorMessage = this.multiselect ? "Please select at least one option" : "Please select an option";
152
+ this.internals.setValidity({
153
+ valueMissing: true
154
+ }, errorMessage, this._comboboxInput);
155
+ }
156
+ else if (!this.internals.validity.valid) {
157
+ this.internals.setValidity({});
158
+ }
159
+ }
160
+ get labels() {
161
+ return [...this.internals.labels];
162
+ }
163
+ get labelContent() {
164
+ if (this.ariaLabel !== null) {
165
+ return this.ariaLabel;
166
+ }
167
+ return this.labels.map(label => label.innerText).join(', ');
168
+ }
169
+ _onKeyUp(event) {
170
+ switch (event.key) {
171
+ case 'ArrowDown':
172
+ event.preventDefault();
173
+ if (!this._expanded) {
174
+ this._expanded = true;
175
+ this._activeOption = -1;
176
+ }
177
+ else {
178
+ this._activeOption = Math.min(this._visibleOptions.length - 1, this._activeOption + 1);
179
+ }
180
+ break;
181
+ case 'ArrowUp':
182
+ event.preventDefault();
183
+ if (this._expanded) {
184
+ this._activeOption = Math.max(0, this._activeOption - 1);
185
+ }
186
+ break;
187
+ case 'Escape':
188
+ event.preventDefault();
189
+ if (this._expanded) {
190
+ this._expanded = false;
191
+ }
192
+ else if (this._filter !== '') {
193
+ this._filter = '';
194
+ }
195
+ break;
196
+ case 'Enter':
197
+ event.preventDefault();
198
+ if (this._expanded) {
199
+ this._visibleOptions[this._activeOption].click();
200
+ }
201
+ break;
202
+ default:
203
+ break;
204
+ }
205
+ }
206
+ _uncheckOption(option) {
207
+ if (option.dataset.deselectable !== 'true')
208
+ return;
209
+ option.setAttribute('aria-selected', 'false');
210
+ const checkbox = option.querySelector('input[type="checkbox"]');
211
+ if (checkbox) {
212
+ checkbox.checked = false;
213
+ }
214
+ }
215
+ _checkOption(option) {
216
+ if (!this.multiselect) {
217
+ this._selectableOptions.forEach(opt => {
218
+ this._uncheckOption(opt);
219
+ });
220
+ }
221
+ option.setAttribute('aria-selected', 'true');
222
+ const checkbox = option.querySelector('input[type="checkbox"]');
223
+ if (checkbox) {
224
+ checkbox.checked = true;
225
+ }
226
+ }
227
+ _toggleOption(option) {
228
+ if (option.getAttribute('aria-selected') === 'true') {
229
+ this._uncheckOption(option);
230
+ }
231
+ else {
232
+ this._checkOption(option);
233
+ }
234
+ }
235
+ _getActiveOptionId() {
236
+ if (this._activeOption === -1 || this._visibleOptions.length === 0) {
237
+ return undefined;
238
+ }
239
+ const option = this._visibleOptions[this._activeOption];
240
+ return option.id;
241
+ }
242
+ _onClick() {
243
+ this._expanded = !this._expanded;
244
+ if (this._expanded) {
245
+ this.shadowRoot?.querySelector('input[role="combobox"]')?.focus();
246
+ }
247
+ }
248
+ _onChevronClick() {
249
+ this.shadowRoot?.querySelector('input[role="combobox"]')?.focus();
250
+ }
251
+ _onClickOption(event) {
252
+ event.preventDefault();
253
+ event.stopPropagation();
254
+ const oldValue = [...this.value];
255
+ this._toggleOption(event.currentTarget);
256
+ this.requestUpdate('value', oldValue);
257
+ }
258
+ _onInput(event) {
259
+ const input = event.target;
260
+ const filter = input.value.toLowerCase();
261
+ if (filter !== '' && !this._expanded) {
262
+ this._expanded = true;
263
+ }
264
+ this._activeOption = -1;
265
+ this._filter = filter;
266
+ }
267
+ _dispatchSelectedOptions() {
268
+ this.dispatchEvent(new Event('change', {
269
+ bubbles: true,
270
+ composed: true
271
+ }));
272
+ this.internals.setFormValue(JSON.stringify(this.value));
273
+ }
274
+ get _isValid() {
275
+ return this.internals.validity.valid && !this.invalid;
276
+ }
277
+ _renderCombobox() {
278
+ const placeHolderValue = guard([this.placeholder, this.disabled, this.value, this.activeOptions.length], () => {
279
+ if (this.placeholder) {
280
+ return this.placeholder;
281
+ }
282
+ if (this.disabled) {
283
+ return 'Disabled';
284
+ }
285
+ if (!this._selectedVisibleOptions.length) {
286
+ return 'No options selected';
287
+ }
288
+ if (this._selectedVisibleOptions.length === 1) {
289
+ return this._selectedVisibleOptions[0].innerText?.trim();
290
+ }
291
+ if (this._isAllSelected) {
292
+ return 'All options selected';
293
+ }
294
+ return `${this._selectedVisibleOptions.length} options selected`;
295
+ });
296
+ return html `
297
+ <input
298
+ type="text"
299
+ id="${this.id}"
300
+ name="${this.name}"
301
+ autocomplete="off"
302
+ aria-label="${this.labelContent}"
303
+ aria-labelledby="${this.ariaLabelledby}"
304
+ role="combobox"
305
+ aria-controls="${this.id}-list"
306
+ aria-expanded="${this._expanded}"
307
+ aria-autocomplete="list"
308
+ aria-haspopup="listbox"
309
+ aria-disabled="${this.disabled}"
310
+ aria-invalid="${!this._isValid}"
311
+ aria-errormessage="${!this._isValid ? `error-msg-${this.id}` : nothing}"
312
+ aria-required="${this.required}"
313
+ ?disabled=${this.disabled}
314
+ aria-activedescendant="${ifDefined(this._getActiveOptionId())}"
315
+ @input="${this._onInput}"
316
+ .value="${this._filter}"
317
+ .placeholder="${placeHolderValue}"
318
+ @focusout="${this._handleFocusOut}"
319
+ part="input"
320
+ class=${this.hideCaret ? 'hide-caret' : ''}
321
+ />`;
322
+ }
323
+ _renderOption(option) {
324
+ if (this._filter !== '' && !option.value.toLowerCase().includes(this._filter) && !option.innerText.toLowerCase().includes(this._filter)) {
325
+ return nothing;
326
+ }
327
+ const id = `${this.id}-option-${option.value}`;
328
+ const active = this._getActiveOptionId() === id;
329
+ const selected = Boolean(this.multiselect && option.selected);
330
+ return html `
331
+ <li
332
+ role="option"
333
+ id="${this.id}-option-${option.value}"
334
+ aria-selected=${this.multiselect && option.selected}
335
+ data-active=${active}
336
+ @click="${this._onClickOption}"
337
+ @mousedown="${(event) => event.preventDefault()}"
338
+ data-value="${option.value}"
339
+ aria-disabled=${option.disabled}
340
+ aria-hidden=${option.hidden || nothing}
341
+ data-deselectable=${!option.selected}
342
+ part="option"
343
+ >
344
+ ${this.multiselect ? html `<input type="checkbox" ?checked=${selected}
345
+ role="presentation" tabindex="-1" part="checkbox">` : nothing}
346
+ <span>${unsafeHTML(option.innerHTML)}</span>
347
+ </li>`;
348
+ }
349
+ _hasErrorContent() {
350
+ return this.errorElements?.length > 0;
351
+ }
352
+ render() {
353
+ return html `
354
+ <div class="tt-combobox-container" @focus="${this._onFocus}" @keydown="${this._onKeyUp}" @click="${this._onClick}"
355
+ aria-disabled="${this.disabled}" part="container">
356
+ <slot name="icon" part="icon"></slot>
357
+ ${this._renderCombobox()}
358
+ ${this._renderChevron()}
359
+ <ul
360
+ id="${this.id}-list"
361
+ role="listbox"
362
+ aria-multiselectable="${this.multiselect}"
363
+ aria-label="${this.labelContent}"
364
+ part="listbox"
365
+ >
366
+ ${this._renderSelectAll()}
367
+
368
+ ${repeat(this.options, opt => opt.value, this._renderOption.bind(this))}
369
+
370
+ <li part="no-results" class="no-results">No results</li>
371
+ </ul>
372
+ </div>
373
+ <slot name="option" @slotchange=${() => this.requestUpdate('options')}></slot>
374
+ <div class="errormessage" id="error-msg-${this.id}" role="alert" aria-atomic="true" ?data-hidden="${!this._hasErrorContent()}" part="error">
375
+ ${unsafeSVG(alert)}
376
+ <slot name="error"></slot>
377
+ </div>
378
+ `;
379
+ }
380
+ }
381
+ TtCombobox.styles = styles;
382
+ TtCombobox.formAssociated = true;
383
+ TtCombobox.shadowRootOptions = {
384
+ ...LitElement.shadowRootOptions,
385
+ delegatesFocus: true
386
+ };
387
+ __decorate([
388
+ property({ type: Boolean })
389
+ ], TtCombobox.prototype, "multiselect", void 0);
390
+ __decorate([
391
+ property({ type: Boolean })
392
+ ], TtCombobox.prototype, "disabled", void 0);
393
+ __decorate([
394
+ property({ type: Boolean })
395
+ ], TtCombobox.prototype, "invalid", void 0);
396
+ __decorate([
397
+ property({ type: Boolean, attribute: 'display-select-all' })
398
+ ], TtCombobox.prototype, "displaySelectAll", void 0);
399
+ __decorate([
400
+ property({ type: Boolean })
401
+ ], TtCombobox.prototype, "required", void 0);
402
+ __decorate([
403
+ property({ type: String })
404
+ ], TtCombobox.prototype, "name", void 0);
405
+ __decorate([
406
+ property({ type: String, attribute: 'aria-labelledby' })
407
+ ], TtCombobox.prototype, "ariaLabelledby", void 0);
408
+ __decorate([
409
+ property({ type: Boolean, attribute: 'hide-caret' })
410
+ ], TtCombobox.prototype, "hideCaret", void 0);
411
+ __decorate([
412
+ property({ type: String })
413
+ ], TtCombobox.prototype, "placeholder", void 0);
414
+ __decorate([
415
+ state()
416
+ ], TtCombobox.prototype, "_activeOption", void 0);
417
+ __decorate([
418
+ state()
419
+ ], TtCombobox.prototype, "_expanded", void 0);
420
+ __decorate([
421
+ state()
422
+ ], TtCombobox.prototype, "_filter", void 0);
423
+ __decorate([
424
+ queryAssignedElements({ slot: 'option', selector: 'option' })
425
+ ], TtCombobox.prototype, "options", void 0);
426
+ __decorate([
427
+ queryAssignedElements({ slot: 'option', selector: 'option:not([disabled])' })
428
+ ], TtCombobox.prototype, "activeOptions", void 0);
429
+ __decorate([
430
+ queryAssignedElements({ slot: 'error' })
431
+ ], TtCombobox.prototype, "errorElements", void 0);
432
+ __decorate([
433
+ queryAll('li[role="option"]:not([aria-disabled="true"], [aria-hidden="true"])')
434
+ ], TtCombobox.prototype, "_visibleOptions", void 0);
435
+ __decorate([
436
+ queryAll('li[role="option"]:not([aria-disabled="true"], [data-value="select-all"])')
437
+ ], TtCombobox.prototype, "_selectableOptions", void 0);
438
+ __decorate([
439
+ queryAll('li[role="option"]:not([aria-disabled="true"], [data-value="select-all"], [aria-hidden="true"])')
440
+ ], TtCombobox.prototype, "_selectableVisibleOptions", void 0);
441
+ __decorate([
442
+ queryAll('li[role="option"]:not([data-value="select-all"])[aria-selected="true"]')
443
+ ], TtCombobox.prototype, "_selectedOptions", void 0);
444
+ __decorate([
445
+ queryAll('li[role="option"]:not([data-value="select-all"], [aria-hidden="true"])[aria-selected="true"]')
446
+ ], TtCombobox.prototype, "_selectedVisibleOptions", void 0);
447
+ __decorate([
448
+ query('input[role="combobox"]')
449
+ ], TtCombobox.prototype, "_comboboxInput", void 0);
450
+ __decorate([
451
+ query('button:has(svg)')
452
+ ], TtCombobox.prototype, "_chevronButton", void 0);
453
+ __decorate([
454
+ property({ type: (Array), attribute: 'value' })
455
+ ], TtCombobox.prototype, "value", null);
456
+ //# sourceMappingURL=TtCombobox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TtCombobox.js","sourceRoot":"","sources":["../../src/TtCombobox.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable lit-a11y/click-events-have-key-events */\nimport { html, LitElement, nothing, PropertyValues } from 'lit';\nimport { property, query, queryAll, queryAssignedElements, state } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport { guard } from 'lit/directives/guard.js';\nimport { alert, chevronDown } from '@triptease/icons';\nimport { styles } from './styles.js';\n\n\nexport class TtCombobox extends LitElement {\n static styles = styles;\n\n static formAssociated = true;\n\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true\n };\n\n @property({type: Boolean})\n multiselect = false;\n\n @property({type: Boolean})\n disabled = false;\n\n @property({type: Boolean})\n invalid = false;\n\n\n _extValue: string[] = [];\n\n @property({type: Boolean, attribute: 'display-select-all'})\n displaySelectAll = false;\n\n @property({type: Boolean})\n required = false;\n\n @property({type: String})\n name = '';\n\n @property({type: String, attribute: 'aria-labelledby' })\n ariaLabelledby = nothing;\n\n @property({type: Boolean, attribute: 'hide-caret'})\n hideCaret = false;\n\n @property({ type: String })\n placeholder?: string;\n\n get form(): HTMLFormElement | null {\n return this.internals.form;\n }\n\n @state()\n protected _activeOption: number = -1;\n\n @state()\n protected _expanded = false;\n\n @state()\n protected _filter: string = '';\n\n @queryAssignedElements({slot: 'option', selector: 'option'})\n options!: Array<HTMLOptionElement>;\n\n @queryAssignedElements({slot: 'option', selector: 'option:not([disabled])'})\n activeOptions!: Array<HTMLOptionElement>;\n\n @queryAssignedElements({slot: 'error'})\n protected errorElements!: Array<HTMLElement>;\n\n @queryAll('li[role=\"option\"]:not([aria-disabled=\"true\"], [aria-hidden=\"true\"])')\n protected _visibleOptions!: Array<HTMLOptionElement>;\n\n @queryAll('li[role=\"option\"]:not([aria-disabled=\"true\"], [data-value=\"select-all\"])')\n protected _selectableOptions!: Array<HTMLOptionElement>;\n\n @queryAll('li[role=\"option\"]:not([aria-disabled=\"true\"], [data-value=\"select-all\"], [aria-hidden=\"true\"])')\n protected _selectableVisibleOptions!: Array<HTMLOptionElement>;\n\n @queryAll('li[role=\"option\"]:not([data-value=\"select-all\"])[aria-selected=\"true\"]')\n protected _selectedOptions!: Array<HTMLOptionElement>;\n\n @queryAll('li[role=\"option\"]:not([data-value=\"select-all\"], [aria-hidden=\"true\"])[aria-selected=\"true\"]')\n protected _selectedVisibleOptions!: NodeListOf<HTMLOptionElement>;\n\n @query('input[role=\"combobox\"]')\n protected _comboboxInput!: HTMLInputElement;\n\n @query('button:has(svg)')\n protected _chevronButton!: HTMLButtonElement;\n\n public internals: ReturnType<typeof this.attachInternals>;\n\n public get value(): string[] {\n return Array.from(this._selectedOptions).map(option => option.dataset.value!);\n }\n\n @property({type: Array<String>, attribute: 'value'})\n public set value(selection: string[]) {\n this._selectableOptions.forEach(option => {\n if (selection.includes(option.dataset.value!)) {\n this._checkOption(option);\n } else {\n this._uncheckOption(option);\n }\n });\n }\n\n private get _isAllSelected(): boolean {\n return Array.from(this._selectableVisibleOptions).every(option => Array.from(this._selectedVisibleOptions).includes(option));\n }\n\n private _slotObserver: MutationObserver = new MutationObserver((mutations) => {\n mutations.forEach(mutation => {\n if (mutation.type === 'attributes') {\n this.requestUpdate('options');\n }\n })\n });\n\n constructor() {\n super();\n this.internals = this.attachInternals();\n }\n\n private _handleFocusOut(e: FocusEvent) {\n if (!this.shadowRoot!.contains(e.relatedTarget as Node | null)) {\n this._expanded = false;\n }\n }\n\n private _onFocus() {\n this._comboboxInput.focus();\n }\n\n public connectedCallback() {\n super.connectedCallback();\n\n this.addEventListener('focus', this._onFocus);\n }\n\n public disconnectedCallback() {\n super.disconnectedCallback();\n\n this.removeEventListener('focus', this._onFocus);\n }\n\n protected firstUpdated(changedProperties: PropertyValues) {\n this.internals.setFormValue(JSON.stringify(this.value));\n\n this._reportValidity();\n\n super.firstUpdated(changedProperties);\n }\n\n protected update(changedProperties: PropertyValues) {\n if (changedProperties.has('value') && changedProperties.get('value') !== undefined && JSON.stringify(changedProperties.get('value')) !== JSON.stringify(this.value)) {\n this._dispatchSelectedOptions();\n this._reportValidity();\n }\n\n if (changedProperties.has('_expanded') && changedProperties.get('_expanded') && !this._expanded) {\n this.internals.states.add('interacted');\n }\n\n if (changedProperties.has('options')) {\n this.updateComplete.then(() => {\n this.value = Array.from(new Set([...this.value, ...Array.from(this._selectedOptions).map(option => option.dataset.value!)]));\n this._listenForOptionChange();\n })\n }\n super.update(changedProperties);\n }\n\n private _listenForOptionChange = () => {\n this.options.forEach(option => {\n this._slotObserver.observe(option, { attributes: true, attributeFilter: ['selected', 'disabled', 'hidden']});\n })\n }\n\n public reportValidity() {\n if (!this._isValid) {\n this.internals.states.add('--invalid');\n } else if (this.internals.states.has('--invalid')) {\n this.internals.states.delete('--invalid')\n }\n this.internals.reportValidity();\n }\n\n private _reportValidity() {\n if (this.required && !this.value.length) {\n const errorMessage = this.multiselect ? \"Please select at least one option\" : \"Please select an option\";\n\n this.internals.setValidity({\n valueMissing: true\n }, errorMessage, this._comboboxInput);\n } else if (!this.internals.validity.valid){\n this.internals.setValidity({});\n }\n }\n\n private get labels(): Array<HTMLElement> {\n return <Array<HTMLElement>>[...this.internals.labels];\n }\n\n private get labelContent(): string {\n if (this.ariaLabel !== null) {\n return this.ariaLabel;\n }\n\n return this.labels.map(label => label.innerText).join(', ');\n }\n\n private _onKeyUp(event: KeyboardEvent) {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n if (!this._expanded) {\n this._expanded = true;\n this._activeOption = -1;\n } else {\n this._activeOption = Math.min(this._visibleOptions.length - 1, this._activeOption + 1);\n }\n break;\n case 'ArrowUp':\n event.preventDefault();\n if (this._expanded) {\n this._activeOption = Math.max(0, this._activeOption - 1);\n }\n break;\n case 'Escape':\n event.preventDefault();\n if (this._expanded) {\n this._expanded = false;\n } else if (this._filter !== '') {\n this._filter = '';\n }\n break;\n case 'Enter':\n event.preventDefault();\n if (this._expanded) {\n this._visibleOptions[this._activeOption].click();\n }\n break;\n default:\n break;\n }\n }\n\n private _uncheckOption(option: HTMLElement) {\n if (option.dataset.deselectable !== 'true') return;\n\n option.setAttribute('aria-selected', 'false');\n const checkbox = <HTMLInputElement>option.querySelector('input[type=\"checkbox\"]');\n if (checkbox) {\n checkbox.checked = false;\n }\n }\n\n private _checkOption(option: HTMLElement) {\n if (!this.multiselect) {\n this._selectableOptions.forEach(opt => {\n this._uncheckOption(opt);\n });\n }\n\n option.setAttribute('aria-selected', 'true');\n const checkbox = <HTMLInputElement>option.querySelector('input[type=\"checkbox\"]');\n if (checkbox) {\n checkbox.checked = true;\n }\n }\n\n private _toggleOption(option: HTMLElement) {\n if (option.getAttribute('aria-selected') === 'true') {\n this._uncheckOption(option);\n } else {\n this._checkOption(option);\n }\n }\n\n private _getActiveOptionId(): string | undefined {\n if (this._activeOption === -1 || this._visibleOptions.length === 0) {\n return undefined;\n }\n\n const option = this._visibleOptions[this._activeOption];\n return option.id;\n }\n\n private _onClick() {\n this._expanded = !this._expanded;\n\n if (this._expanded) {\n (<HTMLElement>this.shadowRoot?.querySelector('input[role=\"combobox\"]'))?.focus();\n }\n }\n\n private _onChevronClick() {\n (<HTMLElement>this.shadowRoot?.querySelector('input[role=\"combobox\"]'))?.focus();\n }\n\n private _onClickOption(event: MouseEvent) {\n event.preventDefault();\n event.stopPropagation();\n const oldValue = [...this.value];\n this._toggleOption(event.currentTarget as HTMLElement);\n this.requestUpdate('value', oldValue);\n }\n\n private _onInput(event: Event) {\n const input = event.target as HTMLInputElement;\n const filter = input.value.toLowerCase();\n if (filter !== '' && !this._expanded) {\n this._expanded = true;\n }\n this._activeOption = -1;\n this._filter = filter;\n }\n\n private _dispatchSelectedOptions() {\n this.dispatchEvent(new Event('change', {\n bubbles: true,\n composed: true\n }));\n\n this.internals.setFormValue(JSON.stringify(this.value));\n }\n\n private _selectAll = (event: MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n const oldValue = [...this.value];\n\n if (this.value.length === this._selectableOptions.length) {\n // this.value = this.value.filter(value => ![...this._selectableOptions].some(option => option.dataset.value === value));\n this._selectableOptions.forEach(option => this._uncheckOption(option));\n } else {\n this._selectableOptions.forEach(option => this._checkOption(option));\n }\n\n this.requestUpdate('value', oldValue);\n };\n\n private get _isValid(): boolean {\n return this.internals.validity.valid && !this.invalid;\n }\n\n private _renderCombobox() {\n const placeHolderValue = guard(\n [this.placeholder, this.disabled, this.value, this.activeOptions.length],\n () => {\n if (this.placeholder) {\n return this.placeholder;\n }\n\n if (this.disabled) {\n return 'Disabled';\n }\n if (!this._selectedVisibleOptions.length) {\n return 'No options selected';\n }\n if (this._selectedVisibleOptions.length === 1) {\n return this._selectedVisibleOptions[0].innerText?.trim();\n }\n\n if (this._isAllSelected) {\n return 'All options selected';\n }\n\n return `${this._selectedVisibleOptions.length} options selected`;\n });\n\n return html`\n <input\n type=\"text\"\n id=\"${this.id}\"\n name=\"${this.name}\"\n autocomplete=\"off\"\n aria-label=\"${this.labelContent}\"\n aria-labelledby=\"${this.ariaLabelledby}\"\n role=\"combobox\"\n aria-controls=\"${this.id}-list\"\n aria-expanded=\"${this._expanded}\"\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n aria-disabled=\"${this.disabled}\"\n aria-invalid=\"${!this._isValid}\"\n aria-errormessage=\"${!this._isValid ? `error-msg-${this.id}` : nothing}\"\n aria-required=\"${this.required}\"\n ?disabled=${this.disabled}\n aria-activedescendant=\"${ifDefined(this._getActiveOptionId())}\"\n @input=\"${this._onInput}\"\n .value=\"${this._filter}\"\n .placeholder=\"${placeHolderValue}\"\n @focusout=\"${this._handleFocusOut}\"\n part=\"input\"\n class=${this.hideCaret ? 'hide-caret' : ''}\n />`;\n }\n\n private _renderSelectAll = () => {\n if (!this.multiselect || !this.displaySelectAll) {\n return nothing;\n }\n const id = `${this.id}-option-select-all`;\n const active = this._getActiveOptionId() === id;\n const selected = this._isAllSelected;\n // eslint-disable-next-line lit-a11y/click-events-have-key-events\n return html`\n <li\n class=\"select-all\"\n role=\"option\"\n id=\"${this.id}-option-select-all\"\n aria-selected=\"${selected}\"\n data-active=${active}\n @click=\"${this._selectAll}\"\n @mousedown=\"${(evt: MouseEvent) => evt.preventDefault()}\"\n data-value=\"select-all\"\n part=\"option\"\n >\n <input type=\"checkbox\" ?checked=${selected} role=\"presentation\" tabindex=\"-1\" part=\"checkbox\">\n Select all\n </li>`;\n };\n\n private _renderOption(option: HTMLOptionElement) {\n if (this._filter !== '' && !option.value.toLowerCase().includes(this._filter) && !option.innerText.toLowerCase().includes(this._filter)) {\n return nothing;\n }\n\n const id = `${this.id}-option-${option.value}`;\n const active = this._getActiveOptionId() === id;\n const selected = Boolean(this.multiselect && option.selected);\n return html`\n <li\n role=\"option\"\n id=\"${this.id}-option-${option.value}\"\n aria-selected=${this.multiselect && option.selected}\n data-active=${active}\n @click=\"${this._onClickOption}\"\n @mousedown=\"${(event: MouseEvent) => event.preventDefault()}\"\n data-value=\"${option.value}\"\n aria-disabled=${option.disabled}\n aria-hidden=${option.hidden || nothing}\n data-deselectable=${!option.selected}\n part=\"option\"\n >\n ${this.multiselect ? html`<input type=\"checkbox\" ?checked=${selected}\n role=\"presentation\" tabindex=\"-1\" part=\"checkbox\">` : nothing}\n <span>${unsafeHTML(option.innerHTML)}</span>\n </li>`;\n }\n\n private _renderChevron = () => html`\n <button type=\"button\" aria-label=\"Expand\" @click=\"${this._onChevronClick}\" aria-expanded=\"${this._expanded}\"\n aria-controls=\"${this.id}-list\" tabindex=\"-1\" ?disabled=${this.disabled} part=\"arrow\">\n ${unsafeSVG(chevronDown)}\n </button>\n `;\n\n private _hasErrorContent(): boolean {\n return this.errorElements?.length > 0;\n }\n\n render() {\n return html`\n <div class=\"tt-combobox-container\" @focus=\"${this._onFocus}\" @keydown=\"${this._onKeyUp}\" @click=\"${this._onClick}\"\n aria-disabled=\"${this.disabled}\" part=\"container\">\n <slot name=\"icon\" part=\"icon\"></slot>\n ${this._renderCombobox()}\n ${this._renderChevron()}\n <ul\n id=\"${this.id}-list\"\n role=\"listbox\"\n aria-multiselectable=\"${this.multiselect}\"\n aria-label=\"${this.labelContent}\"\n part=\"listbox\"\n >\n ${this._renderSelectAll()}\n\n ${repeat(this.options, opt => opt.value, this._renderOption.bind(this))}\n\n <li part=\"no-results\" class=\"no-results\">No results</li>\n </ul>\n </div>\n <slot name=\"option\" @slotchange=${() => this.requestUpdate('options')}></slot>\n <div class=\"errormessage\" id=\"error-msg-${this.id}\" role=\"alert\" aria-atomic=\"true\" ?data-hidden=\"${!this._hasErrorContent()}\" part=\"error\">\n ${unsafeSVG(alert)}\n <slot name=\"error\"></slot>\n </div>\n `;\n }\n}\n\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'tt-combobox': TtCombobox;\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export { TtCombobox } from './tt-combobox.js';
@@ -0,0 +1,2 @@
1
+ export { TtCombobox } from './tt-combobox.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC","sourcesContent":["export { TtCombobox } from './tt-combobox.js';\n"]}
@@ -0,0 +1 @@
1
+ export declare const styles: import("lit").CSSResult;