@vaadin/multi-select-combo-box 23.1.0-alpha4 → 23.1.0-beta1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/multi-select-combo-box",
3
- "version": "23.1.0-alpha4",
3
+ "version": "23.1.0-beta1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -33,18 +33,18 @@
33
33
  ],
34
34
  "dependencies": {
35
35
  "@polymer/polymer": "^3.0.0",
36
- "@vaadin/combo-box": "23.1.0-alpha4",
37
- "@vaadin/component-base": "23.1.0-alpha4",
38
- "@vaadin/field-base": "23.1.0-alpha4",
39
- "@vaadin/input-container": "23.1.0-alpha4",
40
- "@vaadin/vaadin-lumo-styles": "23.1.0-alpha4",
41
- "@vaadin/vaadin-material-styles": "23.1.0-alpha4",
42
- "@vaadin/vaadin-themable-mixin": "23.1.0-alpha4"
36
+ "@vaadin/combo-box": "23.1.0-beta1",
37
+ "@vaadin/component-base": "23.1.0-beta1",
38
+ "@vaadin/field-base": "23.1.0-beta1",
39
+ "@vaadin/input-container": "23.1.0-beta1",
40
+ "@vaadin/vaadin-lumo-styles": "23.1.0-beta1",
41
+ "@vaadin/vaadin-material-styles": "23.1.0-beta1",
42
+ "@vaadin/vaadin-themable-mixin": "23.1.0-beta1"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@esm-bundle/chai": "^4.3.4",
46
46
  "@vaadin/testing-helpers": "^0.3.2",
47
47
  "sinon": "^13.0.2"
48
48
  },
49
- "gitHead": "aacdb7fe09811894751f0378ff7fb66071892c71"
49
+ "gitHead": "8be43cf83102a6b9ccf309687446e590ce0164e8"
50
50
  }
@@ -30,6 +30,16 @@ class MultiSelectComboBoxChip extends ThemableMixin(PolymerElement) {
30
30
 
31
31
  static get properties() {
32
32
  return {
33
+ disabled: {
34
+ type: Boolean,
35
+ reflectToAttribute: true,
36
+ },
37
+
38
+ readonly: {
39
+ type: Boolean,
40
+ reflectToAttribute: true,
41
+ },
42
+
33
43
  label: {
34
44
  type: String,
35
45
  },
@@ -49,7 +59,6 @@ class MultiSelectComboBoxChip extends ThemableMixin(PolymerElement) {
49
59
  align-self: center;
50
60
  white-space: nowrap;
51
61
  box-sizing: border-box;
52
- min-width: 0;
53
62
  }
54
63
 
55
64
  [part='label'] {
@@ -57,7 +66,7 @@ class MultiSelectComboBoxChip extends ThemableMixin(PolymerElement) {
57
66
  text-overflow: ellipsis;
58
67
  }
59
68
 
60
- :host([part~='overflow']) [part='remove-button'] {
69
+ :host(:is([readonly], [disabled], [part~='overflow'])) [part='remove-button'] {
61
70
  display: none !important;
62
71
  }
63
72
  </style>
@@ -9,10 +9,9 @@ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themab
9
9
  registerStyles(
10
10
  'vaadin-multi-select-combo-box-container',
11
11
  css`
12
- .wrapper {
12
+ #wrapper {
13
13
  display: flex;
14
14
  width: 100%;
15
- min-width: 0;
16
15
  }
17
16
  `,
18
17
  {
@@ -40,7 +39,7 @@ class MultiSelectComboBoxContainer extends InputContainer {
40
39
  const slots = content.querySelectorAll('slot');
41
40
 
42
41
  const wrapper = document.createElement('div');
43
- wrapper.setAttribute('class', 'wrapper');
42
+ wrapper.setAttribute('id', 'wrapper');
44
43
  content.insertBefore(wrapper, slots[2]);
45
44
 
46
45
  wrapper.appendChild(slots[0]);
@@ -17,6 +17,19 @@ class MultiSelectComboBoxScroller extends ComboBoxScroller {
17
17
  return 'vaadin-multi-select-combo-box-scroller';
18
18
  }
19
19
 
20
+ /** @protected */
21
+ ready() {
22
+ super.ready();
23
+
24
+ this.setAttribute('aria-multiselectable', 'true');
25
+ }
26
+
27
+ /** @private */
28
+ __getAriaSelected(_focusedIndex, itemIndex) {
29
+ const item = this.items[itemIndex];
30
+ return this.__isItemSelected(item, null, this.itemIdPath).toString();
31
+ }
32
+
20
33
  /** @private */
21
34
  __isItemSelected(item, _selectedItem, itemIdPath) {
22
35
  if (item instanceof ComboBoxPlaceholder) {
@@ -20,6 +20,13 @@ import { LabelMixinClass } from '@vaadin/field-base/src/label-mixin.js';
20
20
  import { ValidateMixinClass } from '@vaadin/field-base/src/validate-mixin.js';
21
21
  import { ThemableMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
22
22
 
23
+ export interface MultiSelectComboBoxI18n {
24
+ cleared: string;
25
+ selected: string;
26
+ deselected: string;
27
+ total: string;
28
+ }
29
+
23
30
  /**
24
31
  * Fired when the user commits a value change.
25
32
  */
@@ -79,6 +86,7 @@ export interface MultiSelectComboBoxEventMap<TItem> extends HTMLElementEventMap
79
86
  *
80
87
  * Part name | Description
81
88
  * -----------------------|----------------
89
+ * `chips` | The element that wraps chips for selected items
82
90
  * `chip` | Chip shown for every selected item
83
91
  * `label` | The label element
84
92
  * `input-field` | The element that wraps prefix, value and suffix
@@ -112,7 +120,6 @@ export interface MultiSelectComboBoxEventMap<TItem> extends HTMLElementEventMap
112
120
  * -----------------------------------------------------|----------------------------|--------
113
121
  * `--vaadin-field-default-width` | Default width of the field | `12em`
114
122
  * `--vaadin-multi-select-combo-box-overlay-max-height` | Max height of the overlay | `65vh`
115
- * `--vaadin-multi-select-combo-box-chip-min-width` | Min width of the chip | `60px`
116
123
  * `--vaadin-multi-select-combo-box-input-min-width` | Min width of the input | `4em`
117
124
  *
118
125
  * ### Internal components
@@ -199,6 +206,28 @@ declare class MultiSelectComboBox<TItem = ComboBoxDefaultItem> extends HTMLEleme
199
206
  */
200
207
  itemValuePath: string;
201
208
 
209
+ /**
210
+ * The object used to localize this component.
211
+ * To change the default localization, replace the entire
212
+ * _i18n_ object or just the property you want to modify.
213
+ *
214
+ * The object has the following JSON structure and default values:
215
+ * ```
216
+ * {
217
+ * // Screen reader announcement on clear button click.
218
+ * cleared: 'Selection cleared',
219
+ * // Screen reader announcement when item is selected.
220
+ * selected: 'added to selection',
221
+ * // Screen reader announcement when item is deselected.
222
+ * deselected: 'removed from selection',
223
+ * // Screen reader announcement of the selected items count.
224
+ * // {count} is replaced with the actual count of items.
225
+ * total: '{count} items selected',
226
+ * }
227
+ * ```
228
+ */
229
+ i18n: MultiSelectComboBoxI18n;
230
+
202
231
  /**
203
232
  * True if the dropdown is open, false otherwise.
204
233
  */
@@ -7,6 +7,7 @@ import './vaadin-multi-select-combo-box-chip.js';
7
7
  import './vaadin-multi-select-combo-box-container.js';
8
8
  import './vaadin-multi-select-combo-box-internal.js';
9
9
  import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
10
+ import { announce } from '@vaadin/component-base/src/a11y-announcer.js';
10
11
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
11
12
  import { ResizeMixin } from '@vaadin/component-base/src/resize-mixin.js';
12
13
  import { processTemplates } from '@vaadin/component-base/src/templates.js';
@@ -18,7 +19,6 @@ import { css, registerStyles, ThemableMixin } from '@vaadin/vaadin-themable-mixi
18
19
 
19
20
  const multiSelectComboBox = css`
20
21
  :host {
21
- --chip-min-width: var(--vaadin-multi-select-combo-box-chip-min-width, 4em);
22
22
  --input-min-width: var(--vaadin-multi-select-combo-box-input-min-width, 4em);
23
23
  }
24
24
 
@@ -26,6 +26,11 @@ const multiSelectComboBox = css`
26
26
  display: none !important;
27
27
  }
28
28
 
29
+ #chips {
30
+ display: flex;
31
+ align-items: center;
32
+ }
33
+
29
34
  :host([has-value]) ::slotted(input:placeholder-shown) {
30
35
  color: transparent !important;
31
36
  }
@@ -37,11 +42,12 @@ const multiSelectComboBox = css`
37
42
 
38
43
  [part='chip'] {
39
44
  flex: 0 1 auto;
40
- min-width: var(--chip-min-width);
41
45
  }
42
46
 
43
- :host([readonly]) [part~='chip'] {
44
- pointer-events: none;
47
+ :host(:is([readonly], [disabled])) ::slotted(input) {
48
+ flex-grow: 0;
49
+ flex-basis: 0;
50
+ padding: 0;
45
51
  }
46
52
  `;
47
53
 
@@ -69,6 +75,7 @@ registerStyles('vaadin-multi-select-combo-box', [inputFieldShared, multiSelectCo
69
75
  *
70
76
  * Part name | Description
71
77
  * -----------------------|----------------
78
+ * `chips` | The element that wraps chips for selected items
72
79
  * `chip` | Chip shown for every selected item
73
80
  * `label` | The label element
74
81
  * `input-field` | The element that wraps prefix, value and suffix
@@ -102,7 +109,6 @@ registerStyles('vaadin-multi-select-combo-box', [inputFieldShared, multiSelectCo
102
109
  * -----------------------------------------------------|----------------------------|--------
103
110
  * `--vaadin-field-default-width` | Default width of the field | `12em`
104
111
  * `--vaadin-multi-select-combo-box-overlay-max-height` | Max height of the overlay | `65vh`
105
- * `--vaadin-multi-select-combo-box-chip-min-width` | Min width of the chip | `60px`
106
112
  * `--vaadin-multi-select-combo-box-input-min-width` | Min width of the input | `4em`
107
113
  *
108
114
  * ### Internal components
@@ -172,14 +178,17 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
172
178
  theme$="[[theme]]"
173
179
  >
174
180
  <vaadin-multi-select-combo-box-chip
181
+ id="overflow"
175
182
  slot="prefix"
176
183
  part$="[[_getOverflowPart(_overflowItems.length)]]"
177
184
  disabled="[[disabled]]"
185
+ readonly="[[readonly]]"
178
186
  label="[[_getOverflowLabel(_overflowItems.length)]]"
179
187
  title$="[[_getOverflowTitle(_overflowItems)]]"
180
188
  hidden$="[[_isOverflowHidden(_overflowItems.length)]]"
181
189
  on-mousedown="_preventBlur"
182
190
  ></vaadin-multi-select-combo-box-chip>
191
+ <div id="chips" part="chips" slot="prefix"></div>
183
192
  <slot name="input"></slot>
184
193
  <div id="clearButton" part="clear-button" slot="suffix"></div>
185
194
  <div id="toggleButton" class="toggle-button" part="toggle-button" slot="suffix"></div>
@@ -249,6 +258,40 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
249
258
  type: String,
250
259
  },
251
260
 
261
+ /**
262
+ * The object used to localize this component.
263
+ * To change the default localization, replace the entire
264
+ * _i18n_ object or just the property you want to modify.
265
+ *
266
+ * The object has the following JSON structure and default values:
267
+ * ```
268
+ * {
269
+ * // Screen reader announcement on clear button click.
270
+ * cleared: 'Selection cleared',
271
+ * // Screen reader announcement when item is selected.
272
+ * selected: 'added to selection',
273
+ * // Screen reader announcement when item is deselected.
274
+ * deselected: 'removed from selection',
275
+ * // Screen reader announcement of the selected items count.
276
+ * // {count} is replaced with the actual count of items.
277
+ * total: '{count} items selected',
278
+ * }
279
+ * ```
280
+ * @type {!MultiSelectComboBoxI18n}
281
+ * @default {English/US}
282
+ */
283
+ i18n: {
284
+ type: Object,
285
+ value: () => {
286
+ return {
287
+ cleared: 'Selection cleared',
288
+ selected: 'added to selection',
289
+ deselected: 'removed from selection',
290
+ total: '{count} items selected',
291
+ };
292
+ },
293
+ },
294
+
252
295
  /**
253
296
  * When present, it specifies that the field is read-only.
254
297
  */
@@ -401,7 +444,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
401
444
  * @return {boolean}
402
445
  */
403
446
  checkValidity() {
404
- return this.required ? this._hasValue : true;
447
+ return this.required && !this.readonly ? this._hasValue : true;
405
448
  }
406
449
 
407
450
  /**
@@ -413,9 +456,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
413
456
  super._disabledChanged(disabled, oldDisabled);
414
457
 
415
458
  if (disabled || oldDisabled) {
416
- this._chips.forEach((chip) => {
417
- chip.toggleAttribute('disabled', disabled);
418
- });
459
+ this.__updateChips();
419
460
  }
420
461
  }
421
462
 
@@ -464,6 +505,26 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
464
505
  this.__updateChips();
465
506
  }
466
507
 
508
+ /**
509
+ * Override method from `DelegateStateMixin` to set required state
510
+ * using `aria-required` attribute instead of `required`, in order
511
+ * to prevent screen readers from announcing "invalid entry".
512
+ * @protected
513
+ * @override
514
+ */
515
+ _delegateAttribute(name, value) {
516
+ if (!this.stateTarget) {
517
+ return;
518
+ }
519
+
520
+ if (name === 'required') {
521
+ this._delegateAttribute('aria-required', value ? 'true' : false);
522
+ return;
523
+ }
524
+
525
+ super._delegateAttribute(name, value);
526
+ }
527
+
467
528
  /**
468
529
  * Setting clear button visible reduces total space available
469
530
  * for rendering chips, and making it hidden increases it.
@@ -480,18 +541,11 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
480
541
  if (readonly) {
481
542
  this.__savedItems = this.$.comboBox._getOverlayItems();
482
543
  this.$.comboBox._setOverlayItems(Array.from(this.selectedItems));
483
-
484
- // Update chips to hide remove button
485
- this._chips.forEach((chip) => {
486
- chip.setAttribute('readonly', '');
487
- });
544
+ this.__updateChips();
488
545
  } else if (oldReadonly) {
489
546
  this.$.comboBox._setOverlayItems(this.__savedItems);
490
547
  this.__savedItems = null;
491
-
492
- this._chips.forEach((chip) => {
493
- chip.removeAttribute('readonly');
494
- });
548
+ this.__updateChips();
495
549
  }
496
550
  }
497
551
 
@@ -511,6 +565,14 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
511
565
 
512
566
  this._toggleHasValue();
513
567
 
568
+ // Use placeholder for announcing items
569
+ if (this._hasValue) {
570
+ this.__savedPlaceholder = this.placeholder;
571
+ this.placeholder = selectedItems.map((item) => this._getItemLabel(item, this.itemLabelPath)).join(', ');
572
+ } else {
573
+ this.placeholder = this.__savedPlaceholder;
574
+ }
575
+
514
576
  // Re-render chips
515
577
  this.__updateChips();
516
578
 
@@ -580,11 +642,19 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
580
642
  this.$.comboBox.clear();
581
643
  }
582
644
 
645
+ /** @private */
646
+ __announceItem(itemLabel, isSelected, itemCount) {
647
+ const state = isSelected ? 'selected' : 'deselected';
648
+ const total = this.i18n.total.replace('{count}', itemCount || 0);
649
+ announce(`${itemLabel} ${this.i18n[state]} ${total}`);
650
+ }
651
+
583
652
  /** @private */
584
653
  __removeItem(item) {
585
654
  const itemsCopy = [...this.selectedItems];
586
655
  itemsCopy.splice(itemsCopy.indexOf(item), 1);
587
656
  this.__updateSelection(itemsCopy);
657
+ this.__announceItem(item, false, itemsCopy.length);
588
658
  }
589
659
 
590
660
  /** @private */
@@ -592,9 +662,13 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
592
662
  const itemsCopy = [...this.selectedItems];
593
663
 
594
664
  const index = this._findIndex(item, itemsCopy, this.itemIdPath);
665
+ const itemLabel = this._getItemLabel(item, this.itemLabelPath);
666
+
667
+ let isSelected = false;
668
+
595
669
  if (index !== -1) {
596
670
  // Do not unselect when manually typing and committing an already selected item.
597
- if (this.filter.toLowerCase() === this._getItemLabel(item, this.itemLabelPath).toLowerCase()) {
671
+ if (this.filter.toLowerCase() === itemLabel.toLowerCase()) {
598
672
  this.__clearFilter();
599
673
  return;
600
674
  }
@@ -602,12 +676,15 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
602
676
  itemsCopy.splice(index, 1);
603
677
  } else {
604
678
  itemsCopy.push(item);
679
+ isSelected = true;
605
680
  }
606
681
 
607
682
  this.__updateSelection(itemsCopy);
608
683
 
609
684
  // Suppress `value-changed` event.
610
685
  this.__clearFilter();
686
+
687
+ this.__announceItem(itemLabel, isSelected, itemsCopy.length);
611
688
  }
612
689
 
613
690
  /** @private */
@@ -626,8 +703,8 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
626
703
  chip.setAttribute('slot', 'prefix');
627
704
 
628
705
  chip.item = item;
629
- chip.toggleAttribute('disabled', this.disabled);
630
- chip.toggleAttribute('readonly', this.readonly);
706
+ chip.disabled = this.disabled;
707
+ chip.readonly = this.readonly;
631
708
 
632
709
  const label = this._getItemLabel(item, this.itemLabelPath);
633
710
  chip.label = label;
@@ -640,18 +717,21 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
640
717
  }
641
718
 
642
719
  /** @private */
643
- __getMinWidth(chip) {
720
+ __getOverflowWidth() {
721
+ const chip = this.$.overflow;
722
+
644
723
  chip.style.visibility = 'hidden';
645
- chip.style.display = 'block';
646
- chip.style.minWidth = 'var(--chip-min-width)';
724
+ chip.removeAttribute('hidden');
647
725
 
648
- const result = parseInt(getComputedStyle(chip).minWidth);
726
+ // Detect max possible width of the overflow chip
727
+ chip.setAttribute('part', 'chip overflow');
728
+ const overflowStyle = getComputedStyle(chip);
729
+ const overflowWidth = chip.clientWidth + parseInt(overflowStyle.marginInlineStart);
649
730
 
650
- chip.style.minWidth = '';
651
- chip.style.display = '';
731
+ chip.setAttribute('hidden', '');
652
732
  chip.style.visibility = '';
653
733
 
654
- return result;
734
+ return overflowWidth;
655
735
  }
656
736
 
657
737
  /** @private */
@@ -661,46 +741,36 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
661
741
  }
662
742
 
663
743
  // Clear all chips except the overflow
664
- const chips = Array.from(this._chips).reverse();
665
- const overflow = chips.pop();
666
-
667
- chips.forEach((chip) => {
668
- chip.remove();
744
+ Array.from(this._chips).forEach((chip) => {
745
+ if (chip !== this.$.overflow) {
746
+ chip.remove();
747
+ }
669
748
  });
670
749
 
671
750
  const items = [...this.selectedItems];
672
751
 
673
- let refNode = overflow.nextElementSibling;
674
-
675
- // Use overflow chip to measure min-width
676
- const chipMinWidth = this.__getMinWidth(overflow);
677
- const inputMinWidth = parseInt(getComputedStyle(this.inputElement).flexBasis);
678
- const containerStyle = getComputedStyle(this._inputField);
752
+ // Detect available remaining width for chips
753
+ const totalWidth = this._inputField.$.wrapper.clientWidth;
754
+ const inputWidth = parseInt(getComputedStyle(this.inputElement).flexBasis);
679
755
 
680
- // Detect available width for chips
681
- let totalWidth =
682
- parseInt(containerStyle.width) -
683
- parseInt(containerStyle.paddingLeft) -
684
- parseInt(containerStyle.paddingRight) -
685
- this.$.toggleButton.clientWidth -
686
- inputMinWidth;
756
+ let remainingWidth = totalWidth - inputWidth;
687
757
 
688
- if (this.clearButtonVisible) {
689
- totalWidth -= this.$.clearButton.clientWidth;
758
+ if (items.length > 1) {
759
+ remainingWidth -= this.__getOverflowWidth();
690
760
  }
691
761
 
692
- for (let i = items.length - 1; i >= 0; i--) {
693
- // Ensure there is enough space for another chip
694
- if (totalWidth < chipMinWidth) {
762
+ // Add chips until remaining width is exceeded
763
+ for (let i = items.length - 1, refNode = null; i >= 0; i--) {
764
+ const chip = this.__createChip(items[i]);
765
+ this.$.chips.insertBefore(chip, refNode);
766
+
767
+ if (this.$.chips.clientWidth > remainingWidth) {
768
+ chip.remove();
695
769
  break;
696
770
  }
697
771
 
698
- const item = items.pop();
699
- const chip = this.__createChip(item);
700
- this._inputField.insertBefore(chip, refNode);
701
-
772
+ items.pop();
702
773
  refNode = chip;
703
- totalWidth -= chipMinWidth;
704
774
  }
705
775
 
706
776
  this._overflowItems = items;
@@ -715,6 +785,8 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
715
785
  event.stopPropagation();
716
786
 
717
787
  this.__updateSelection([]);
788
+
789
+ announce(this.i18n.cleared);
718
790
  }
719
791
 
720
792
  /**
@@ -79,6 +79,7 @@ const chip = css`
79
79
  justify-content: center;
80
80
  margin-top: -0.3125em;
81
81
  margin-bottom: -0.3125em;
82
+ margin-inline-start: auto;
82
83
  width: 1.25em;
83
84
  height: 1.25em;
84
85
  font-size: 1.5em;
@@ -93,11 +94,6 @@ const chip = css`
93
94
  -webkit-text-fill-color: var(--lumo-disabled-text-color);
94
95
  pointer-events: none;
95
96
  }
96
-
97
- :host([readonly]) [part='remove-button'],
98
- :host([disabled]) [part='remove-button'] {
99
- display: none;
100
- }
101
97
  `;
102
98
 
103
99
  registerStyles('vaadin-multi-select-combo-box-chip', [fieldButton, chip], {
@@ -30,14 +30,14 @@ const multiSelectComboBox = css`
30
30
  padding-inline-start: 0;
31
31
  }
32
32
 
33
- :host([readonly]) [part~='chip'] {
34
- opacity: 0.7;
35
- }
36
-
37
33
  [part~='chip']:not(:last-of-type) {
38
34
  margin-inline-end: var(--lumo-space-xs);
39
35
  }
40
36
 
37
+ [part~='overflow']:not([hidden]) + :not(:empty) {
38
+ margin-inline-start: var(--lumo-space-xs);
39
+ }
40
+
41
41
  [part='toggle-button']::before {
42
42
  content: var(--lumo-icons-dropdown);
43
43
  }
@@ -79,6 +79,7 @@ const chip = css`
79
79
  box-sizing: border-box;
80
80
  width: 20px;
81
81
  height: 20px;
82
+ margin-inline-start: auto;
82
83
  line-height: 20px;
83
84
  padding: 0;
84
85
  font-size: 0.75em;
@@ -93,11 +94,6 @@ const chip = css`
93
94
  -webkit-text-fill-color: var(--material-disabled-text-color);
94
95
  pointer-events: none;
95
96
  }
96
-
97
- :host([readonly]) [part='remove-button'],
98
- :host([disabled]) [part='remove-button'] {
99
- display: none;
100
- }
101
97
  `;
102
98
 
103
99
  registerStyles('vaadin-multi-select-combo-box-chip', [fieldButton, chip], {
@@ -25,10 +25,6 @@ registerStyles(
25
25
  );
26
26
 
27
27
  const multiSelectComboBox = css`
28
- :host([readonly]) [part~='chip'] {
29
- opacity: 0.5;
30
- }
31
-
32
28
  [part='input-field'] {
33
29
  height: auto;
34
30
  min-height: 32px;