@vaadin/multi-select-combo-box 23.1.0-alpha2

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,599 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import './vaadin-multi-select-combo-box-chip.js';
7
+ import './vaadin-multi-select-combo-box-container.js';
8
+ import './vaadin-multi-select-combo-box-internal.js';
9
+ import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
10
+ import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
11
+ import { processTemplates } from '@vaadin/component-base/src/templates.js';
12
+ import { InputControlMixin } from '@vaadin/field-base/src/input-control-mixin.js';
13
+ import { InputController } from '@vaadin/field-base/src/input-controller.js';
14
+ import { LabelledInputController } from '@vaadin/field-base/src/labelled-input-controller.js';
15
+ import { inputFieldShared } from '@vaadin/field-base/src/styles/input-field-shared-styles.js';
16
+ import { css, registerStyles, ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
17
+
18
+ const multiSelectComboBox = css`
19
+ [hidden] {
20
+ display: none !important;
21
+ }
22
+
23
+ :host([has-value]) ::slotted(input:placeholder-shown) {
24
+ color: transparent !important;
25
+ }
26
+
27
+ :host([has-value]) [class$='container'] {
28
+ width: auto;
29
+ }
30
+
31
+ ::slotted(input) {
32
+ box-sizing: border-box;
33
+ flex: 1 0 4em;
34
+ }
35
+
36
+ [part~='chip'] {
37
+ flex: 0 1 auto;
38
+ }
39
+
40
+ :host([readonly]) [part~='chip'] {
41
+ pointer-events: none;
42
+ }
43
+ `;
44
+
45
+ registerStyles('vaadin-multi-select-combo-box', [inputFieldShared, multiSelectComboBox], {
46
+ moduleId: 'vaadin-multi-select-combo-box-styles'
47
+ });
48
+
49
+ /**
50
+ * `<vaadin-multi-select-combo-box>` is a web component that wraps `<vaadin-combo-box>` and extends
51
+ * its functionality to allow selecting multiple items, in addition to basic features.
52
+ *
53
+ * ```html
54
+ * <vaadin-multi-select-combo-box id="comboBox"></vaadin-multi-select-combo-box>
55
+ * ```
56
+ *
57
+ * ```js
58
+ * const comboBox = document.querySelector('#comboBox');
59
+ * comboBox.items = ['apple', 'banana', 'lemon', 'orange'];
60
+ * comboBox.selectedItems = ['lemon', 'orange'];
61
+ * ```
62
+ *
63
+ * ### Styling
64
+ *
65
+ * The following shadow DOM parts are available for styling:
66
+ *
67
+ * Part name | Description
68
+ * -----------------------|----------------
69
+ * `chip` | Chip shown for every selected item
70
+ * `label` | The label element
71
+ * `input-field` | The element that wraps prefix, value and suffix
72
+ * `clear-button` | The clear button
73
+ * `error-message` | The error message element
74
+ * `helper-text` | The helper text element wrapper
75
+ * `required-indicator` | The `required` state indicator element
76
+ * `toggle-button` | The toggle button
77
+ *
78
+ * The following state attributes are available for styling:
79
+ *
80
+ * Attribute | Description
81
+ * -----------------------|-----------------
82
+ * `disabled` | Set to a disabled element
83
+ * `has-value` | Set when the element has a value
84
+ * `has-label` | Set when the element has a label
85
+ * `has-helper` | Set when the element has helper text or slot
86
+ * `has-error-message` | Set when the element has an error message
87
+ * `invalid` | Set when the element is invalid
88
+ * `focused` | Set when the element is focused
89
+ * `focus-ring` | Set when the element is keyboard focused
90
+ * `opened` | Set when the dropdown is open
91
+ * `readonly` | Set to a readonly element
92
+ *
93
+ * ### Internal components
94
+ *
95
+ * In addition to `<vaadin-multi-select-combo-box>` itself, the following internal
96
+ * components are themable:
97
+ *
98
+ * - `<vaadin-multi-select-combo-box-overlay>` - has the same API as `<vaadin-overlay>`.
99
+ * - `<vaadin-multi-select-combo-box-item>` - has the same API as `<vaadin-item>`.
100
+ * - `<vaadin-multi-select-combo-box-container>` - has the same API as `<vaadin-input-container>`.
101
+ *
102
+ * Note: the `theme` attribute value set on `<vaadin-multi-select-combo-box>` is
103
+ * propagated to these components.
104
+ *
105
+ * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
106
+ *
107
+ * @fires {Event} change - Fired when the user commits a value change.
108
+ * @fires {CustomEvent} custom-values-set - Fired when the user sets a custom value.
109
+ * @fires {CustomEvent} filter-changed - Fired when the `filter` property changes.
110
+ * @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
111
+ * @fires {CustomEvent} selected-items-changed - Fired when the `selectedItems` property changes.
112
+ *
113
+ * @extends HTMLElement
114
+ * @mixes ElementMixin
115
+ * @mixes ThemableMixin
116
+ * @mixes InputControlMixin
117
+ */
118
+ class MultiSelectComboBox extends InputControlMixin(ThemableMixin(ElementMixin(PolymerElement))) {
119
+ static get is() {
120
+ return 'vaadin-multi-select-combo-box';
121
+ }
122
+
123
+ static get template() {
124
+ return html`
125
+ <div class="vaadin-multi-select-combo-box-container">
126
+ <div part="label">
127
+ <slot name="label"></slot>
128
+ <span part="required-indicator" aria-hidden="true" on-click="focus"></span>
129
+ </div>
130
+
131
+ <vaadin-multi-select-combo-box-internal
132
+ id="comboBox"
133
+ items="[[items]]"
134
+ item-id-path="[[itemIdPath]]"
135
+ item-label-path="[[itemLabelPath]]"
136
+ item-value-path="[[itemValuePath]]"
137
+ disabled="[[disabled]]"
138
+ readonly="[[readonly]]"
139
+ auto-open-disabled="[[autoOpenDisabled]]"
140
+ allow-custom-value="[[allowCustomValues]]"
141
+ data-provider="[[dataProvider]]"
142
+ filter="{{filter}}"
143
+ filtered-items="[[filteredItems]]"
144
+ opened="{{opened}}"
145
+ renderer="[[renderer]]"
146
+ theme$="[[theme]]"
147
+ on-combo-box-item-selected="_onComboBoxItemSelected"
148
+ on-change="_onComboBoxChange"
149
+ on-custom-value-set="_onCustomValueSet"
150
+ >
151
+ <vaadin-multi-select-combo-box-container
152
+ part="input-field"
153
+ readonly="[[readonly]]"
154
+ disabled="[[disabled]]"
155
+ invalid="[[invalid]]"
156
+ theme$="[[theme]]"
157
+ >
158
+ <slot name="input"></slot>
159
+ <div id="clearButton" part="clear-button" slot="suffix"></div>
160
+ <div id="toggleButton" class="toggle-button" part="toggle-button" slot="suffix"></div>
161
+ </vaadin-multi-select-combo-box-container>
162
+ </vaadin-multi-select-combo-box-internal>
163
+
164
+ <div part="helper-text">
165
+ <slot name="helper"></slot>
166
+ </div>
167
+
168
+ <div part="error-message">
169
+ <slot name="error-message"></slot>
170
+ </div>
171
+ </div>
172
+ `;
173
+ }
174
+
175
+ static get properties() {
176
+ return {
177
+ /**
178
+ * Set true to prevent the overlay from opening automatically.
179
+ * @attr {boolean} auto-open-disabled
180
+ */
181
+ autoOpenDisabled: Boolean,
182
+
183
+ /**
184
+ * A full set of items to filter the visible options from.
185
+ * The items can be of either `String` or `Object` type.
186
+ */
187
+ items: {
188
+ type: Array
189
+ },
190
+
191
+ /**
192
+ * The item property used for a visual representation of the item.
193
+ * @attr {string} item-label-path
194
+ */
195
+ itemLabelPath: {
196
+ type: String
197
+ },
198
+
199
+ /**
200
+ * Path for the value of the item. If `items` is an array of objects,
201
+ * this property is used as a string value for the selected item.
202
+ * @attr {string} item-value-path
203
+ */
204
+ itemValuePath: {
205
+ type: String
206
+ },
207
+
208
+ /**
209
+ * Path for the id of the item, used to detect whether the item is selected.
210
+ * @attr {string} item-id-path
211
+ */
212
+ itemIdPath: {
213
+ type: String
214
+ },
215
+
216
+ /**
217
+ * The list of selected items.
218
+ * Note: modifying the selected items creates a new array each time.
219
+ */
220
+ selectedItems: {
221
+ type: Array,
222
+ value: () => [],
223
+ notify: true
224
+ },
225
+
226
+ /**
227
+ * True if the dropdown is open, false otherwise.
228
+ */
229
+ opened: {
230
+ type: Boolean,
231
+ notify: true,
232
+ value: false,
233
+ reflectToAttribute: true
234
+ },
235
+
236
+ /**
237
+ * Number of items fetched at a time from the data provider.
238
+ * @attr {number} page-size
239
+ */
240
+ pageSize: {
241
+ type: Number,
242
+ value: 50,
243
+ observer: '_pageSizeChanged'
244
+ },
245
+
246
+ /**
247
+ * Function that provides items lazily. Receives two arguments:
248
+ *
249
+ * - `params` - Object with the following properties:
250
+ * - `params.page` Requested page index
251
+ * - `params.pageSize` Current page size
252
+ * - `params.filter` Currently applied filter
253
+ *
254
+ * - `callback(items, size)` - Callback function with arguments:
255
+ * - `items` Current page of items
256
+ * - `size` Total number of items.
257
+ */
258
+ dataProvider: {
259
+ type: Object,
260
+ observer: '_dataProviderChanged'
261
+ },
262
+
263
+ /**
264
+ * When true, the user can input a value that is not present in the items list.
265
+ * @attr {boolean} allow-custom-values
266
+ */
267
+ allowCustomValues: {
268
+ type: Boolean,
269
+ value: false
270
+ },
271
+
272
+ /**
273
+ * Custom function for rendering the content of every item.
274
+ * Receives three arguments:
275
+ *
276
+ * - `root` The `<vaadin-multi-select-combo-box-item>` internal container DOM element.
277
+ * - `comboBox` The reference to the `<vaadin-combo-box>` element.
278
+ * - `model` The object with the properties related with the rendered
279
+ * item, contains:
280
+ * - `model.index` The index of the rendered item.
281
+ * - `model.item` The item.
282
+ */
283
+ renderer: Function,
284
+
285
+ /**
286
+ * Filtering string the user has typed into the input field.
287
+ */
288
+ filter: {
289
+ type: String,
290
+ value: '',
291
+ notify: true
292
+ },
293
+
294
+ /**
295
+ * A subset of items, filtered based on the user input. Filtered items
296
+ * can be assigned directly to omit the internal filtering functionality.
297
+ * The items can be of either `String` or `Object` type.
298
+ */
299
+ filteredItems: Array,
300
+
301
+ /** @protected */
302
+ _hasValue: {
303
+ type: Boolean,
304
+ value: false
305
+ }
306
+ };
307
+ }
308
+
309
+ static get observers() {
310
+ return ['_selectedItemsChanged(selectedItems, selectedItems.*)'];
311
+ }
312
+
313
+ /**
314
+ * Used by `ClearButtonMixin` as a reference to the clear button element.
315
+ * @protected
316
+ * @return {!HTMLElement}
317
+ */
318
+ get clearElement() {
319
+ return this.$.clearButton;
320
+ }
321
+
322
+ /** @protected */
323
+ get _chips() {
324
+ return this.shadowRoot.querySelectorAll('[part~="chip"]');
325
+ }
326
+
327
+ /** @protected */
328
+ ready() {
329
+ super.ready();
330
+
331
+ this.addController(
332
+ new InputController(this, (input) => {
333
+ this._setInputElement(input);
334
+ this._setFocusElement(input);
335
+ this.stateTarget = input;
336
+ this.ariaTarget = input;
337
+ })
338
+ );
339
+ this.addController(new LabelledInputController(this.inputElement, this._labelController));
340
+
341
+ this._inputField = this.shadowRoot.querySelector('[part="input-field"]');
342
+ this.__updateChips();
343
+
344
+ processTemplates(this);
345
+ }
346
+
347
+ /**
348
+ * Returns true if the current input value satisfies all constraints (if any).
349
+ * @return {boolean}
350
+ */
351
+ checkValidity() {
352
+ return this.required ? this._hasValue : true;
353
+ }
354
+
355
+ /**
356
+ * Override method inherited from `DisabledMixin` to forward disabled to chips.
357
+ * @protected
358
+ * @override
359
+ */
360
+ _disabledChanged(disabled, oldDisabled) {
361
+ super._disabledChanged(disabled, oldDisabled);
362
+
363
+ if (disabled || oldDisabled) {
364
+ this._chips.forEach((chip) => {
365
+ chip.toggleAttribute('disabled', disabled);
366
+ });
367
+ }
368
+ }
369
+
370
+ /**
371
+ * Override method inherited from `InputMixin` to forward the input to combo-box.
372
+ * @protected
373
+ * @override
374
+ */
375
+ _inputElementChanged(input) {
376
+ super._inputElementChanged(input);
377
+
378
+ if (input) {
379
+ this.$.comboBox._setInputElement(input);
380
+ }
381
+ }
382
+
383
+ /**
384
+ * Override method inherited from `FocusMixin` to validate on blur.
385
+ * @param {boolean} focused
386
+ * @protected
387
+ */
388
+ _setFocused(focused) {
389
+ super._setFocused(focused);
390
+
391
+ if (!focused) {
392
+ this.validate();
393
+ }
394
+ }
395
+
396
+ /**
397
+ * Override method inherited from `InputMixin`
398
+ * to keep attribute after clearing the input.
399
+ * @protected
400
+ * @override
401
+ */
402
+ _toggleHasValue() {
403
+ super._toggleHasValue(this._hasValue);
404
+ }
405
+
406
+ /** @private */
407
+ _pageSizeChanged(pageSize, oldPageSize) {
408
+ if (Math.floor(pageSize) !== pageSize || pageSize <= 0) {
409
+ this.pageSize = oldPageSize;
410
+ console.error('"pageSize" value must be an integer > 0');
411
+ }
412
+
413
+ this.$.comboBox.pageSize = this.pageSize;
414
+ }
415
+
416
+ /** @private */
417
+ _selectedItemsChanged(selectedItems) {
418
+ this._hasValue = Boolean(selectedItems && selectedItems.length);
419
+
420
+ this._toggleHasValue();
421
+
422
+ // Re-render chips
423
+ this.__updateChips();
424
+
425
+ // Re-render scroller
426
+ this.$.comboBox.$.dropdown._scroller.requestContentUpdate();
427
+
428
+ // Wait for chips to render
429
+ requestAnimationFrame(() => {
430
+ this.$.comboBox.$.dropdown._setOverlayWidth();
431
+ });
432
+ }
433
+
434
+ /** @private */
435
+ _getItemLabel(item, itemLabelPath) {
436
+ return item && Object.prototype.hasOwnProperty.call(item, itemLabelPath) ? item[itemLabelPath] : item;
437
+ }
438
+
439
+ /** @private */
440
+ _findIndex(item, selectedItems, itemIdPath) {
441
+ if (itemIdPath && item) {
442
+ for (let index = 0; index < selectedItems.length; index++) {
443
+ if (selectedItems[index] && selectedItems[index][itemIdPath] === item[itemIdPath]) {
444
+ return index;
445
+ }
446
+ }
447
+ return -1;
448
+ }
449
+
450
+ return selectedItems.indexOf(item);
451
+ }
452
+
453
+ /** @private */
454
+ __clearFilter() {
455
+ this.$.comboBox.clear();
456
+ }
457
+
458
+ /** @private */
459
+ __removeItem(item) {
460
+ const itemsCopy = [...this.selectedItems];
461
+ itemsCopy.splice(itemsCopy.indexOf(item), 1);
462
+ this.__updateSelection(itemsCopy);
463
+ }
464
+
465
+ /** @private */
466
+ __selectItem(item) {
467
+ const itemsCopy = [...this.selectedItems];
468
+
469
+ const index = this._findIndex(item, itemsCopy, this.itemIdPath);
470
+ if (index !== -1) {
471
+ // Do not unselect when manually typing and committing an already selected item.
472
+ if (this.filter.toLowerCase() === this._getItemLabel(item, this.itemLabelPath).toLowerCase()) {
473
+ this.__clearFilter();
474
+ return;
475
+ }
476
+
477
+ itemsCopy.splice(index, 1);
478
+ } else {
479
+ itemsCopy.push(item);
480
+ }
481
+
482
+ this.__updateSelection(itemsCopy);
483
+
484
+ // Suppress `value-changed` event.
485
+ this.__clearFilter();
486
+ }
487
+
488
+ /** @private */
489
+ __updateSelection(selectedItems) {
490
+ this.selectedItems = selectedItems;
491
+
492
+ this.validate();
493
+
494
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true }));
495
+ }
496
+
497
+ /** @private */
498
+ __createChip(item) {
499
+ const chip = document.createElement('vaadin-multi-select-combo-box-chip');
500
+ chip.setAttribute('part', 'chip');
501
+ chip.setAttribute('slot', 'prefix');
502
+
503
+ chip.item = item;
504
+ chip.label = this._getItemLabel(item, this.itemLabelPath);
505
+ chip.toggleAttribute('disabled', this.disabled);
506
+
507
+ chip.addEventListener('item-removed', (e) => this._onItemRemoved(e));
508
+ chip.addEventListener('mousedown', (e) => this._preventBlur(e));
509
+
510
+ return chip;
511
+ }
512
+
513
+ /** @private */
514
+ __updateChips() {
515
+ if (!this._inputField) {
516
+ return;
517
+ }
518
+
519
+ this._chips.forEach((chip) => {
520
+ chip.remove();
521
+ });
522
+
523
+ const items = [...this.selectedItems];
524
+
525
+ for (let i = items.length - 1; i >= 0; i--) {
526
+ const chip = this.__createChip(items[i]);
527
+ this._inputField.insertBefore(chip, this._inputField.firstElementChild);
528
+ }
529
+ }
530
+
531
+ /**
532
+ * Override method inherited from `ClearButtonMixin` and clear items.
533
+ * @protected
534
+ * @override
535
+ */
536
+ _onClearButtonClick(event) {
537
+ event.stopPropagation();
538
+
539
+ this.__updateSelection([]);
540
+ }
541
+
542
+ /**
543
+ * Override an event listener from `KeyboardMixin`.
544
+ * @param {KeyboardEvent} event
545
+ * @protected
546
+ * @override
547
+ */
548
+ _onKeyDown(event) {
549
+ const items = this.selectedItems || [];
550
+ if (!this.readonly && event.key === 'Backspace' && items.length && this.inputElement.value === '') {
551
+ this.__removeItem(items[items.length - 1]);
552
+ }
553
+ }
554
+
555
+ /** @private */
556
+ _onComboBoxChange() {
557
+ const item = this.$.comboBox.selectedItem;
558
+ if (item) {
559
+ this.__selectItem(item);
560
+ }
561
+ }
562
+
563
+ /** @private */
564
+ _onComboBoxItemSelected(event) {
565
+ this.__selectItem(event.detail.item);
566
+ }
567
+
568
+ /** @private */
569
+ _onCustomValueSet(event) {
570
+ // Do not set combo-box value
571
+ event.preventDefault();
572
+
573
+ this.__clearFilter();
574
+
575
+ this.dispatchEvent(
576
+ new CustomEvent('custom-values-set', {
577
+ detail: event.detail,
578
+ composed: true,
579
+ bubbles: true
580
+ })
581
+ );
582
+ }
583
+
584
+ /** @private */
585
+ _onItemRemoved(event) {
586
+ this.__removeItem(event.detail.item);
587
+ }
588
+
589
+ /** @private */
590
+ _preventBlur(event) {
591
+ // Prevent mousedown event to keep the input focused
592
+ // and keep the overlay opened when clicking a chip.
593
+ event.preventDefault();
594
+ }
595
+ }
596
+
597
+ customElements.define(MultiSelectComboBox.is, MultiSelectComboBox);
598
+
599
+ export { MultiSelectComboBox };
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import '@vaadin/vaadin-lumo-styles/color.js';
7
+ import '@vaadin/vaadin-lumo-styles/font-icons.js';
8
+ import '@vaadin/vaadin-lumo-styles/spacing.js';
9
+ import '@vaadin/vaadin-lumo-styles/style.js';
10
+ import '@vaadin/vaadin-lumo-styles/typography.js';
11
+ import { fieldButton } from '@vaadin/vaadin-lumo-styles/mixins/field-button.js';
12
+ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
13
+
14
+ const chip = css`
15
+ :host {
16
+ display: inline-flex;
17
+ align-items: center;
18
+ align-self: center;
19
+ font-family: var(--lumo-font-family);
20
+ font-size: var(--lumo-font-size-xxs);
21
+ line-height: 1;
22
+ padding: 0.3125em 0 0.3125em calc(0.5em + var(--lumo-border-radius-s) / 4);
23
+ border-radius: var(--lumo-border-radius-s);
24
+ border-radius: var(--lumo-border-radius);
25
+ background-color: var(--lumo-contrast-20pct);
26
+ cursor: var(--lumo-clickable-cursor);
27
+ white-space: nowrap;
28
+ box-sizing: border-box;
29
+ min-width: 0;
30
+ }
31
+
32
+ [part='label'] {
33
+ color: var(--lumo-body-text-color);
34
+ font-weight: 500;
35
+ overflow: hidden;
36
+ text-overflow: ellipsis;
37
+ line-height: 1.25;
38
+ }
39
+
40
+ [part='remove-button'] {
41
+ display: flex;
42
+ align-items: center;
43
+ justify-content: center;
44
+ margin-top: -0.3125em;
45
+ margin-bottom: -0.3125em;
46
+ width: var(--lumo-icon-size-s);
47
+ height: var(--lumo-icon-size-s);
48
+ font-size: 1.5em;
49
+ }
50
+
51
+ [part='remove-button']::before {
52
+ content: var(--lumo-icons-cross);
53
+ }
54
+
55
+ :host([disabled]) [part] {
56
+ color: var(--lumo-disabled-text-color);
57
+ -webkit-text-fill-color: var(--lumo-disabled-text-color);
58
+ pointer-events: none;
59
+ }
60
+ `;
61
+
62
+ registerStyles('vaadin-multi-select-combo-box-chip', [fieldButton, chip], {
63
+ moduleId: 'lumo-multi-select-combo-box-chip'
64
+ });
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import '@vaadin/vaadin-lumo-styles/color.js';
7
+ import '@vaadin/vaadin-lumo-styles/font-icons.js';
8
+ import '@vaadin/vaadin-lumo-styles/style.js';
9
+ import '@vaadin/vaadin-lumo-styles/typography.js';
10
+ import { inputFieldShared } from '@vaadin/vaadin-lumo-styles/mixins/input-field-shared.js';
11
+ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
12
+
13
+ const multiSelectComboBox = css`
14
+ :host([has-value]) {
15
+ padding-inline-start: 0;
16
+ }
17
+
18
+ :host([readonly]) [part~='chip'] {
19
+ opacity: 0.7;
20
+ }
21
+
22
+ [part~='chip']:not(:last-of-type) {
23
+ margin-inline-end: var(--lumo-space-xs);
24
+ }
25
+
26
+ [part='toggle-button']::before {
27
+ content: var(--lumo-icons-dropdown);
28
+ }
29
+ `;
30
+
31
+ registerStyles('vaadin-multi-select-combo-box', [inputFieldShared, multiSelectComboBox], {
32
+ moduleId: 'lumo-multi-select-combo-box'
33
+ });
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import '@vaadin/combo-box/theme/lumo/vaadin-combo-box-item-styles.js';
7
+ import '@vaadin/combo-box/theme/lumo/vaadin-combo-box-dropdown-styles.js';
8
+ import '@vaadin/input-container/theme/lumo/vaadin-input-container.js';
9
+ import './vaadin-multi-select-combo-box-chip-styles.js';
10
+ import './vaadin-multi-select-combo-box-styles.js';
11
+ import '../../src/vaadin-multi-select-combo-box.js';