@vaadin/multi-select-combo-box 24.0.0-alpha1 → 24.0.0-alpha11

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": "24.0.0-alpha1",
3
+ "version": "24.0.0-alpha11",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -37,14 +37,14 @@
37
37
  ],
38
38
  "dependencies": {
39
39
  "@polymer/polymer": "^3.0.0",
40
- "@vaadin/combo-box": "24.0.0-alpha1",
41
- "@vaadin/component-base": "24.0.0-alpha1",
42
- "@vaadin/field-base": "24.0.0-alpha1",
43
- "@vaadin/input-container": "24.0.0-alpha1",
44
- "@vaadin/lit-renderer": "24.0.0-alpha1",
45
- "@vaadin/vaadin-lumo-styles": "24.0.0-alpha1",
46
- "@vaadin/vaadin-material-styles": "24.0.0-alpha1",
47
- "@vaadin/vaadin-themable-mixin": "24.0.0-alpha1"
40
+ "@vaadin/combo-box": "24.0.0-alpha11",
41
+ "@vaadin/component-base": "24.0.0-alpha11",
42
+ "@vaadin/field-base": "24.0.0-alpha11",
43
+ "@vaadin/input-container": "24.0.0-alpha11",
44
+ "@vaadin/lit-renderer": "24.0.0-alpha11",
45
+ "@vaadin/vaadin-lumo-styles": "24.0.0-alpha11",
46
+ "@vaadin/vaadin-material-styles": "24.0.0-alpha11",
47
+ "@vaadin/vaadin-themable-mixin": "24.0.0-alpha11"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@esm-bundle/chai": "^4.3.4",
@@ -56,5 +56,5 @@
56
56
  "web-types.json",
57
57
  "web-types.lit.json"
58
58
  ],
59
- "gitHead": "427527c27c4b27822d61fd41d38d7b170134770b"
59
+ "gitHead": "641b3d96ceeb3e503a093682ebe686afdd8c3a68"
60
60
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2017 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2017 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import type { TemplateResult } from 'lit';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2017 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2017 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { directive } from 'lit/directive.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
@@ -66,7 +66,8 @@ class MultiSelectComboBoxChip extends ThemableMixin(PolymerElement) {
66
66
  text-overflow: ellipsis;
67
67
  }
68
68
 
69
- :host(:is([readonly], [disabled], [part~='overflow'])) [part='remove-button'] {
69
+ :host([hidden]),
70
+ :host(:is([readonly], [disabled], [slot='overflow'])) [part='remove-button'] {
70
71
  display: none !important;
71
72
  }
72
73
  </style>
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { InputContainer } from '@vaadin/input-container/src/vaadin-input-container.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import './vaadin-multi-select-combo-box-item.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { ComboBoxItem } from '@vaadin/combo-box/src/vaadin-combo-box-item.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { ComboBoxOverlay } from '@vaadin/combo-box/src/vaadin-combo-box-overlay.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { ComboBoxPlaceholder } from '@vaadin/combo-box/src/vaadin-combo-box-placeholder.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import type {
@@ -9,13 +9,13 @@ import type {
9
9
  ComboBoxItemModel,
10
10
  } from '@vaadin/combo-box/src/vaadin-combo-box.js';
11
11
  import type { ControllerMixinClass } from '@vaadin/component-base/src/controller-mixin.js';
12
+ import type { DelegateFocusMixinClass } from '@vaadin/component-base/src/delegate-focus-mixin.js';
13
+ import type { DelegateStateMixinClass } from '@vaadin/component-base/src/delegate-state-mixin.js';
12
14
  import type { DisabledMixinClass } from '@vaadin/component-base/src/disabled-mixin.js';
13
15
  import type { ElementMixinClass } from '@vaadin/component-base/src/element-mixin.js';
14
16
  import type { FocusMixinClass } from '@vaadin/component-base/src/focus-mixin.js';
15
17
  import type { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js';
16
18
  import type { ResizeMixinClass } from '@vaadin/component-base/src/resize-mixin.js';
17
- import type { DelegateFocusMixinClass } from '@vaadin/field-base/src/delegate-focus-mixin.js';
18
- import type { DelegateStateMixinClass } from '@vaadin/field-base/src/delegate-state-mixin.js';
19
19
  import type { FieldMixinClass } from '@vaadin/field-base/src/field-mixin.js';
20
20
  import type { InputConstraintsMixinClass } from '@vaadin/field-base/src/input-constraints-mixin.js';
21
21
  import type { InputControlMixinClass } from '@vaadin/field-base/src/input-control-mixin.js';
@@ -106,17 +106,13 @@ export interface MultiSelectComboBoxEventMap<TItem> extends HTMLElementEventMap
106
106
  *
107
107
  * Part name | Description
108
108
  * -----------------------|----------------
109
- * `chips` | The element that wraps chips for selected items
110
- * `chip` | Chip shown for every selected item
109
+ * `chips` | The element that wraps slotted chips for selected items
111
110
  * `label` | The label element
112
111
  * `input-field` | The element that wraps prefix, value and suffix
113
112
  * `clear-button` | The clear button
114
113
  * `error-message` | The error message element
115
114
  * `helper-text` | The helper text element wrapper
116
115
  * `required-indicator` | The `required` state indicator element
117
- * `overflow` | The chip shown when component width is not enough to fit all chips
118
- * `overflow-one` | Set on the overflow chip when only one chip does not fit
119
- * `overflow-two` | Set on the overflow chip when two chips do not fit
120
116
  * `toggle-button` | The toggle button
121
117
  *
122
118
  * The following state attributes are available for styling:
@@ -258,6 +254,13 @@ declare class MultiSelectComboBox<TItem = ComboBoxDefaultItem> extends HTMLEleme
258
254
  */
259
255
  loading: boolean;
260
256
 
257
+ /**
258
+ * A space-delimited list of CSS class names to set on the overlay element.
259
+ *
260
+ * @attr {string} overlay-class
261
+ */
262
+ overlayClass: string;
263
+
261
264
  /**
262
265
  * True if the dropdown is open, false otherwise.
263
266
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import './vaadin-multi-select-combo-box-chip.js';
@@ -10,6 +10,7 @@ import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
10
10
  import { announce } from '@vaadin/component-base/src/a11y-announcer.js';
11
11
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
12
12
  import { ResizeMixin } from '@vaadin/component-base/src/resize-mixin.js';
13
+ import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
13
14
  import { processTemplates } from '@vaadin/component-base/src/templates.js';
14
15
  import { TooltipController } from '@vaadin/component-base/src/tooltip-controller.js';
15
16
  import { InputControlMixin } from '@vaadin/field-base/src/input-control-mixin.js';
@@ -23,10 +24,6 @@ const multiSelectComboBox = css`
23
24
  --input-min-width: var(--vaadin-multi-select-combo-box-input-min-width, 4em);
24
25
  }
25
26
 
26
- [hidden] {
27
- display: none !important;
28
- }
29
-
30
27
  #chips {
31
28
  display: flex;
32
29
  align-items: center;
@@ -37,7 +34,8 @@ const multiSelectComboBox = css`
37
34
  flex: 1 0 var(--input-min-width);
38
35
  }
39
36
 
40
- [part='chip'] {
37
+ ::slotted([slot='chip']),
38
+ ::slotted([slot='overflow']) {
41
39
  flex: 0 1 auto;
42
40
  }
43
41
 
@@ -72,17 +70,13 @@ registerStyles('vaadin-multi-select-combo-box', [inputFieldShared, multiSelectCo
72
70
  *
73
71
  * Part name | Description
74
72
  * -----------------------|----------------
75
- * `chips` | The element that wraps chips for selected items
76
- * `chip` | Chip shown for every selected item
73
+ * `chips` | The element that wraps slotted chips for selected items
77
74
  * `label` | The label element
78
75
  * `input-field` | The element that wraps prefix, value and suffix
79
76
  * `clear-button` | The clear button
80
77
  * `error-message` | The error message element
81
78
  * `helper-text` | The helper text element wrapper
82
79
  * `required-indicator` | The `required` state indicator element
83
- * `overflow` | The chip shown when component width is not enough to fit all chips
84
- * `overflow-one` | Set on the overflow chip when only one chip does not fit
85
- * `overflow-two` | Set on the overflow chip when two chips do not fit
86
80
  * `toggle-button` | The toggle button
87
81
  *
88
82
  * The following state attributes are available for styling:
@@ -160,6 +154,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
160
154
  readonly="[[readonly]]"
161
155
  auto-open-disabled="[[autoOpenDisabled]]"
162
156
  allow-custom-value="[[allowCustomValue]]"
157
+ overlay-class="[[overlayClass]]"
163
158
  data-provider="[[dataProvider]]"
164
159
  filter="{{filter}}"
165
160
  last-filter="{{_lastFilter}}"
@@ -182,18 +177,10 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
182
177
  invalid="[[invalid]]"
183
178
  theme$="[[_theme]]"
184
179
  >
185
- <vaadin-multi-select-combo-box-chip
186
- id="overflow"
187
- slot="prefix"
188
- part$="[[_getOverflowPart(_overflowItems.length)]]"
189
- disabled="[[disabled]]"
190
- readonly="[[readonly]]"
191
- label="[[_getOverflowLabel(_overflowItems.length)]]"
192
- title$="[[_getOverflowTitle(_overflowItems)]]"
193
- hidden$="[[_isOverflowHidden(_overflowItems.length)]]"
194
- on-mousedown="_preventBlur"
195
- ></vaadin-multi-select-combo-box-chip>
196
- <div id="chips" part="chips" slot="prefix"></div>
180
+ <slot name="overflow" slot="prefix"></slot>
181
+ <div id="chips" part="chips" slot="prefix">
182
+ <slot name="chip"></slot>
183
+ </div>
197
184
  <slot name="input"></slot>
198
185
  <div
199
186
  id="clearButton"
@@ -319,6 +306,15 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
319
306
  reflectToAttribute: true,
320
307
  },
321
308
 
309
+ /**
310
+ * A space-delimited list of CSS class names to set on the overlay element.
311
+ *
312
+ * @attr {string} overlay-class
313
+ */
314
+ overlayClass: {
315
+ type: String,
316
+ },
317
+
322
318
  /**
323
319
  * When present, it specifies that the field is read-only.
324
320
  */
@@ -469,7 +465,10 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
469
465
  }
470
466
 
471
467
  static get observers() {
472
- return ['_selectedItemsChanged(selectedItems, selectedItems.*)'];
468
+ return [
469
+ '_selectedItemsChanged(selectedItems, selectedItems.*)',
470
+ '__updateOverflowChip(_overflow, _overflowItems, disabled, readonly)',
471
+ ];
473
472
  }
474
473
 
475
474
  /** @protected */
@@ -496,7 +495,18 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
496
495
 
497
496
  /** @protected */
498
497
  get _chips() {
499
- return this.shadowRoot.querySelectorAll('[part~="chip"]');
498
+ return [...this.querySelectorAll('[slot="chip"]')];
499
+ }
500
+
501
+ /**
502
+ * Override a getter from `InputMixin` to compute
503
+ * the presence of value based on `selectedItems`.
504
+ *
505
+ * @protected
506
+ * @override
507
+ */
508
+ get _hasValue() {
509
+ return this.selectedItems && this.selectedItems.length > 0;
500
510
  }
501
511
 
502
512
  /** @protected */
@@ -519,6 +529,15 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
519
529
  this._tooltipController.setShouldShow((target) => !target.opened);
520
530
 
521
531
  this._inputField = this.shadowRoot.querySelector('[part="input-field"]');
532
+
533
+ this._overflowController = new SlotController(this, 'overflow', 'vaadin-multi-select-combo-box-chip', {
534
+ initializer: (chip) => {
535
+ chip.addEventListener('mousedown', (e) => this._preventBlur(e));
536
+ this._overflow = chip;
537
+ },
538
+ });
539
+ this.addController(this._overflowController);
540
+
522
541
  this.__updateChips();
523
542
 
524
543
  processTemplates(this);
@@ -716,34 +735,6 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
716
735
  return this.$.comboBox._getItemLabel(item);
717
736
  }
718
737
 
719
- /** @private */
720
- _getOverflowLabel(length) {
721
- return length;
722
- }
723
-
724
- /** @private */
725
- _getOverflowPart(length) {
726
- let part = `chip overflow`;
727
-
728
- if (length === 1) {
729
- part += ' overflow-one';
730
- } else if (length === 2) {
731
- part += ' overflow-two';
732
- }
733
-
734
- return part;
735
- }
736
-
737
- /** @private */
738
- _getOverflowTitle(items) {
739
- return this._mergeItemLabels(items);
740
- }
741
-
742
- /** @private */
743
- _isOverflowHidden(length) {
744
- return length === 0;
745
- }
746
-
747
738
  /** @private */
748
739
  _mergeItemLabels(items) {
749
740
  return items.map((item) => this._getItemLabel(item)).join(', ');
@@ -828,8 +819,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
828
819
  /** @private */
829
820
  __createChip(item) {
830
821
  const chip = document.createElement('vaadin-multi-select-combo-box-chip');
831
- chip.setAttribute('part', 'chip');
832
- chip.setAttribute('slot', 'prefix');
822
+ chip.setAttribute('slot', 'chip');
833
823
 
834
824
  chip.item = item;
835
825
  chip.disabled = this.disabled;
@@ -847,16 +837,20 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
847
837
 
848
838
  /** @private */
849
839
  __getOverflowWidth() {
850
- const chip = this.$.overflow;
840
+ const chip = this._overflow;
851
841
 
852
842
  chip.style.visibility = 'hidden';
853
843
  chip.removeAttribute('hidden');
854
844
 
845
+ const count = chip.getAttribute('count');
846
+
855
847
  // Detect max possible width of the overflow chip
856
- chip.setAttribute('part', 'chip overflow');
848
+ // by measuring it with widest number (2 digits)
849
+ chip.setAttribute('count', '99');
857
850
  const overflowStyle = getComputedStyle(chip);
858
851
  const overflowWidth = chip.clientWidth + parseInt(overflowStyle.marginInlineStart);
859
852
 
853
+ chip.setAttribute('count', count);
860
854
  chip.setAttribute('hidden', '');
861
855
  chip.style.visibility = '';
862
856
 
@@ -870,10 +864,8 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
870
864
  }
871
865
 
872
866
  // Clear all chips except the overflow
873
- Array.from(this._chips).forEach((chip) => {
874
- if (chip !== this.$.overflow) {
875
- chip.remove();
876
- }
867
+ this._chips.forEach((chip) => {
868
+ chip.remove();
877
869
  });
878
870
 
879
871
  const items = [...this.selectedItems];
@@ -891,7 +883,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
891
883
  // Add chips until remaining width is exceeded
892
884
  for (let i = items.length - 1, refNode = null; i >= 0; i--) {
893
885
  const chip = this.__createChip(items[i]);
894
- this.$.chips.insertBefore(chip, refNode);
886
+ this.insertBefore(chip, refNode);
895
887
 
896
888
  if (this.$.chips.clientWidth > remainingWidth) {
897
889
  chip.remove();
@@ -905,6 +897,21 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
905
897
  this._overflowItems = items;
906
898
  }
907
899
 
900
+ /** @private */
901
+ __updateOverflowChip(overflow, items, disabled, readonly) {
902
+ if (overflow) {
903
+ const count = items.length;
904
+
905
+ overflow.label = `${count}`;
906
+ overflow.setAttribute('count', `${count}`);
907
+ overflow.setAttribute('title', this._mergeItemLabels(items));
908
+ overflow.toggleAttribute('hidden', count === 0);
909
+
910
+ overflow.disabled = disabled;
911
+ overflow.readonly = readonly;
912
+ }
913
+ }
914
+
908
915
  /** @private */
909
916
  _onClearButtonTouchend(event) {
910
917
  // Cancel the following click and focus events
@@ -961,7 +968,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
961
968
  _onKeyDown(event) {
962
969
  super._onKeyDown(event);
963
970
 
964
- const chips = Array.from(this._chips).slice(1);
971
+ const chips = this._chips;
965
972
 
966
973
  if (!this.readonly && chips.length > 0) {
967
974
  switch (event.key) {
@@ -969,10 +976,10 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
969
976
  this._onBackSpace(chips);
970
977
  break;
971
978
  case 'ArrowLeft':
972
- this._onArrowLeft(chips);
979
+ this._onArrowLeft(chips, event);
973
980
  break;
974
981
  case 'ArrowRight':
975
- this._onArrowRight(chips);
982
+ this._onArrowRight(chips, event);
976
983
  break;
977
984
  default:
978
985
  this._focusedChipIndex = -1;
@@ -982,15 +989,18 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
982
989
  }
983
990
 
984
991
  /** @private */
985
- _onArrowLeft(chips) {
986
- if (this.inputElement.value !== '' || this.opened) {
992
+ _onArrowLeft(chips, event) {
993
+ if (this.inputElement.selectionStart !== 0) {
987
994
  return;
988
995
  }
989
996
 
990
997
  const idx = this._focusedChipIndex;
998
+ if (idx !== -1) {
999
+ event.preventDefault();
1000
+ }
991
1001
  let newIdx;
992
1002
 
993
- if (this.getAttribute('dir') !== 'rtl') {
1003
+ if (!this.__isRTL) {
994
1004
  if (idx === -1) {
995
1005
  // Focus last chip
996
1006
  newIdx = chips.length - 1;
@@ -1012,15 +1022,18 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
1012
1022
  }
1013
1023
 
1014
1024
  /** @private */
1015
- _onArrowRight(chips) {
1016
- if (this.inputElement.value !== '' || this.opened) {
1025
+ _onArrowRight(chips, event) {
1026
+ if (this.inputElement.selectionStart !== 0) {
1017
1027
  return;
1018
1028
  }
1019
1029
 
1020
1030
  const idx = this._focusedChipIndex;
1031
+ if (idx !== -1) {
1032
+ event.preventDefault();
1033
+ }
1021
1034
  let newIdx;
1022
1035
 
1023
- if (this.getAttribute('dir') === 'rtl') {
1036
+ if (this.__isRTL) {
1024
1037
  if (idx === -1) {
1025
1038
  // Focus last chip
1026
1039
  newIdx = chips.length - 1;
@@ -1043,7 +1056,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
1043
1056
 
1044
1057
  /** @private */
1045
1058
  _onBackSpace(chips) {
1046
- if (this.inputElement.value !== '' || this.opened) {
1059
+ if (this.inputElement.selectionStart !== 0) {
1047
1060
  return;
1048
1061
  }
1049
1062
 
@@ -1059,7 +1072,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
1059
1072
  /** @private */
1060
1073
  _focusedChipIndexChanged(focusedIndex, oldFocusedIndex) {
1061
1074
  if (focusedIndex > -1 || oldFocusedIndex > -1) {
1062
- const chips = Array.from(this._chips).slice(1);
1075
+ const chips = this._chips;
1063
1076
  chips.forEach((chip, index) => {
1064
1077
  chip.toggleAttribute('focused', index === focusedIndex);
1065
1078
  });
@@ -1126,17 +1139,6 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
1126
1139
  __computeEffectiveFilteredItems(items, filteredItems, selectedItems, readonly) {
1127
1140
  return !items && readonly ? selectedItems : filteredItems;
1128
1141
  }
1129
-
1130
- /**
1131
- * Override a method from `InputMixin` to
1132
- * compute the presence of value based on `selectedItems`.
1133
- *
1134
- * @protected
1135
- * @override
1136
- */
1137
- get _hasValue() {
1138
- return this.selectedItems && this.selectedItems.length > 0;
1139
- }
1140
1142
  }
1141
1143
 
1142
1144
  customElements.define(MultiSelectComboBox.is, MultiSelectComboBox);
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import '@vaadin/vaadin-lumo-styles/color.js';
@@ -15,34 +15,26 @@ const chip = css`
15
15
  :host {
16
16
  font-size: var(--lumo-font-size-xxs);
17
17
  line-height: 1;
18
- padding: 0.3125em calc(0.5em + var(--lumo-border-radius-s) / 4);
19
18
  color: var(--lumo-body-text-color);
20
19
  border-radius: var(--lumo-border-radius-s);
21
20
  background-color: var(--lumo-contrast-20pct);
22
21
  cursor: var(--lumo-clickable-cursor);
23
- }
24
-
25
- :host([focused]) {
26
- background-color: var(--lumo-primary-color);
27
- color: var(--lumo-primary-contrast-color);
22
+ -webkit-font-smoothing: antialiased;
23
+ -moz-osx-font-smoothing: grayscale;
28
24
  }
29
25
 
30
26
  :host([focused]) [part='remove-button'] {
31
27
  color: inherit;
32
28
  }
33
29
 
34
- :host(:not([part~='overflow']):not([readonly]):not([disabled])) {
35
- padding-inline-end: 0;
36
- }
37
-
38
- :host([part~='overflow']) {
30
+ :host([slot='overflow']) {
39
31
  position: relative;
40
32
  min-width: var(--lumo-size-xxs);
41
33
  margin-inline-start: var(--lumo-space-s);
42
34
  }
43
35
 
44
- :host([part~='overflow'])::before,
45
- :host([part~='overflow'])::after {
36
+ :host([slot='overflow'])::before,
37
+ :host([slot='overflow'])::after {
46
38
  position: absolute;
47
39
  content: '';
48
40
  width: 100%;
@@ -52,28 +44,28 @@ const chip = css`
52
44
  border-color: var(--lumo-contrast-30pct);
53
45
  }
54
46
 
55
- :host([part~='overflow'])::before {
47
+ :host([slot='overflow'])::before {
56
48
  left: calc(-1 * var(--lumo-space-s) / 2);
57
49
  }
58
50
 
59
- :host([part~='overflow'])::after {
51
+ :host([slot='overflow'])::after {
60
52
  left: calc(-1 * var(--lumo-space-s));
61
53
  }
62
54
 
63
- :host([part~='overflow-two']) {
55
+ :host([count='2']) {
64
56
  margin-inline-start: calc(var(--lumo-space-s) / 2);
65
57
  }
66
58
 
67
- :host([part~='overflow-two'])::after {
59
+ :host([count='2'])::after {
68
60
  display: none;
69
61
  }
70
62
 
71
- :host([part~='overflow-one']) {
63
+ :host([count='1']) {
72
64
  margin-inline-start: 0;
73
65
  }
74
66
 
75
- :host([part~='overflow-one'])::before,
76
- :host([part~='overflow-one'])::after {
67
+ :host([count='1'])::before,
68
+ :host([count='1'])::after {
77
69
  display: none;
78
70
  }
79
71
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import '@vaadin/vaadin-lumo-styles/color.js';
@@ -34,12 +34,28 @@ const multiSelectComboBox = css`
34
34
  caret-color: var(--lumo-body-text-color) !important;
35
35
  }
36
36
 
37
- [part~='chip']:not(:last-of-type) {
37
+ /* Override input-container styles */
38
+ ::slotted([slot='chip']),
39
+ ::slotted([slot='overflow']) {
40
+ min-height: auto;
41
+ padding: 0.3125em calc(0.5em + var(--lumo-border-radius-s) / 4);
42
+ color: var(--lumo-body-text-color);
43
+ -webkit-mask-image: none;
44
+ mask-image: none;
45
+ }
46
+
47
+ ::slotted([slot='chip']:not([readonly]):not([disabled])) {
48
+ padding-inline-end: 0;
49
+ }
50
+
51
+ ::slotted([slot='chip']:not(:last-of-type)),
52
+ ::slotted([slot='overflow']:not(:last-of-type)) {
38
53
  margin-inline-end: var(--lumo-space-xs);
39
54
  }
40
55
 
41
- [part~='overflow']:not([hidden]) + :not(:empty) {
42
- margin-inline-start: var(--lumo-space-xs);
56
+ ::slotted([slot='chip'][focused]) {
57
+ background-color: var(--lumo-primary-color);
58
+ color: var(--lumo-primary-contrast-color);
43
59
  }
44
60
 
45
61
  [part='toggle-button']::before {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import '@vaadin/combo-box/theme/lumo/vaadin-combo-box-item-styles.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import '@vaadin/vaadin-material-styles/color.js';
@@ -13,28 +13,25 @@ const chip = css`
13
13
  :host {
14
14
  height: 1.25rem;
15
15
  margin-inline-end: 0.25rem;
16
- padding: 0 0.5rem;
17
16
  border-radius: 4px;
18
17
  background-color: rgba(0, 0, 0, 0.08);
19
18
  cursor: default;
20
19
  font-family: var(--material-font-family);
20
+ -webkit-font-smoothing: antialiased;
21
+ -moz-osx-font-smoothing: grayscale;
21
22
  }
22
23
 
23
24
  :host([focused]) {
24
25
  background-color: rgba(0, 0, 0, 0.16);
25
26
  }
26
27
 
27
- :host(:not([part~='overflow']):not([readonly]):not([disabled])) {
28
- padding-inline-end: 0;
29
- }
30
-
31
- :host([part~='overflow']) {
28
+ :host([slot='overflow']) {
32
29
  position: relative;
33
30
  margin-inline-start: 0.5rem;
34
31
  }
35
32
 
36
- :host([part~='overflow'])::before,
37
- :host([part~='overflow'])::after {
33
+ :host([slot='overflow'])::before,
34
+ :host([slot='overflow'])::after {
38
35
  position: absolute;
39
36
  content: '';
40
37
  width: 100%;
@@ -44,28 +41,28 @@ const chip = css`
44
41
  border-color: rgba(0, 0, 0, 0.08);
45
42
  }
46
43
 
47
- :host([part~='overflow'])::before {
44
+ :host([slot='overflow'])::before {
48
45
  left: -0.25rem;
49
46
  }
50
47
 
51
- :host([part~='overflow'])::after {
48
+ :host([slot='overflow'])::after {
52
49
  left: -0.5rem;
53
50
  }
54
51
 
55
- :host([part~='overflow-two']) {
52
+ :host([count='2']) {
56
53
  margin-inline-start: 0.25rem;
57
54
  }
58
55
 
59
- :host([part~='overflow-two'])::after {
56
+ :host([count='2'])::after {
60
57
  display: none;
61
58
  }
62
59
 
63
- :host([part~='overflow-one']) {
60
+ :host([count='1']) {
64
61
  margin-inline-start: 0;
65
62
  }
66
63
 
67
- :host([part~='overflow-one'])::before,
68
- :host([part~='overflow-one'])::after {
64
+ :host([count='1'])::before,
65
+ :host([count='1'])::after {
69
66
  display: none;
70
67
  }
71
68
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import '@vaadin/vaadin-material-styles/color.js';
@@ -29,6 +29,16 @@ const multiSelectComboBox = css`
29
29
  caret-color: var(--material-body-text-color) !important;
30
30
  }
31
31
 
32
+ /* Override input-container styles */
33
+ ::slotted([slot='chip']),
34
+ ::slotted([slot='overflow']) {
35
+ padding: 0 0.5rem;
36
+ }
37
+
38
+ ::slotted([slot='chip']:not([readonly]):not([disabled])) {
39
+ padding-inline-end: 0;
40
+ }
41
+
32
42
  [part='input-field'] {
33
43
  height: auto;
34
44
  min-height: 32px;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import '@vaadin/combo-box/theme/material/vaadin-combo-box-item-styles.js';
package/web-types.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/multi-select-combo-box",
4
- "version": "24.0.0-alpha1",
4
+ "version": "24.0.0-alpha11",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
8
8
  "elements": [
9
9
  {
10
10
  "name": "vaadin-multi-select-combo-box",
11
- "description": "`<vaadin-multi-select-combo-box>` is a web component that wraps `<vaadin-combo-box>` and extends\nits functionality to allow selecting multiple items, in addition to basic features.\n\n```html\n<vaadin-multi-select-combo-box id=\"comboBox\"></vaadin-multi-select-combo-box>\n```\n```js\nconst comboBox = document.querySelector('#comboBox');\ncomboBox.items = ['apple', 'banana', 'lemon', 'orange'];\ncomboBox.selectedItems = ['lemon', 'orange'];\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------------------|----------------\n`chips` | The element that wraps chips for selected items\n`chip` | Chip shown for every selected item\n`label` | The label element\n`input-field` | The element that wraps prefix, value and suffix\n`clear-button` | The clear button\n`error-message` | The error message element\n`helper-text` | The helper text element wrapper\n`required-indicator` | The `required` state indicator element\n`overflow` | The chip shown when component width is not enough to fit all chips\n`overflow-one` | Set on the overflow chip when only one chip does not fit\n`overflow-two` | Set on the overflow chip when two chips do not fit\n`toggle-button` | The toggle button\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n-----------------------|-----------------\n`disabled` | Set to a disabled element\n`has-value` | Set when the element has a value\n`has-label` | Set when the element has a label\n`has-helper` | Set when the element has helper text or slot\n`has-error-message` | Set when the element has an error message\n`invalid` | Set when the element is invalid\n`focused` | Set when the element is focused\n`focus-ring` | Set when the element is keyboard focused\n`loading` | Set when loading items from the data provider\n`opened` | Set when the dropdown is open\n`readonly` | Set to a readonly element\n\nThe following custom CSS properties are available for styling:\n\nCustom property | Description | Default\n-----------------------------------------------------|----------------------------|--------\n`--vaadin-field-default-width` | Default width of the field | `12em`\n`--vaadin-multi-select-combo-box-overlay-width` | Width of the overlay | `auto`\n`--vaadin-multi-select-combo-box-overlay-max-height` | Max height of the overlay | `65vh`\n`--vaadin-multi-select-combo-box-input-min-width` | Min width of the input | `4em`\n\n### Internal components\n\nIn addition to `<vaadin-multi-select-combo-box>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-multi-select-combo-box-overlay>` - has the same API as `<vaadin-overlay>`.\n- `<vaadin-multi-select-combo-box-item>` - has the same API as `<vaadin-item>`.\n- `<vaadin-multi-select-combo-box-container>` - has the same API as `<vaadin-input-container>`.\n\nNote: the `theme` attribute value set on `<vaadin-multi-select-combo-box>` is\npropagated to these components.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
11
+ "description": "`<vaadin-multi-select-combo-box>` is a web component that wraps `<vaadin-combo-box>` and extends\nits functionality to allow selecting multiple items, in addition to basic features.\n\n```html\n<vaadin-multi-select-combo-box id=\"comboBox\"></vaadin-multi-select-combo-box>\n```\n```js\nconst comboBox = document.querySelector('#comboBox');\ncomboBox.items = ['apple', 'banana', 'lemon', 'orange'];\ncomboBox.selectedItems = ['lemon', 'orange'];\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------------------|----------------\n`chips` | The element that wraps slotted chips for selected items\n`label` | The label element\n`input-field` | The element that wraps prefix, value and suffix\n`clear-button` | The clear button\n`error-message` | The error message element\n`helper-text` | The helper text element wrapper\n`required-indicator` | The `required` state indicator element\n`toggle-button` | The toggle button\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n-----------------------|-----------------\n`disabled` | Set to a disabled element\n`has-value` | Set when the element has a value\n`has-label` | Set when the element has a label\n`has-helper` | Set when the element has helper text or slot\n`has-error-message` | Set when the element has an error message\n`invalid` | Set when the element is invalid\n`focused` | Set when the element is focused\n`focus-ring` | Set when the element is keyboard focused\n`loading` | Set when loading items from the data provider\n`opened` | Set when the dropdown is open\n`readonly` | Set to a readonly element\n\nThe following custom CSS properties are available for styling:\n\nCustom property | Description | Default\n-----------------------------------------------------|----------------------------|--------\n`--vaadin-field-default-width` | Default width of the field | `12em`\n`--vaadin-multi-select-combo-box-overlay-width` | Width of the overlay | `auto`\n`--vaadin-multi-select-combo-box-overlay-max-height` | Max height of the overlay | `65vh`\n`--vaadin-multi-select-combo-box-input-min-width` | Min width of the input | `4em`\n\n### Internal components\n\nIn addition to `<vaadin-multi-select-combo-box>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-multi-select-combo-box-overlay>` - has the same API as `<vaadin-overlay>`.\n- `<vaadin-multi-select-combo-box-item>` - has the same API as `<vaadin-item>`.\n- `<vaadin-multi-select-combo-box-container>` - has the same API as `<vaadin-input-container>`.\n\nNote: the `theme` attribute value set on `<vaadin-multi-select-combo-box>` is\npropagated to these components.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
12
12
  "attributes": [
13
13
  {
14
14
  "name": "disabled",
@@ -230,6 +230,17 @@
230
230
  ]
231
231
  }
232
232
  },
233
+ {
234
+ "name": "overlay-class",
235
+ "description": "A space-delimited list of CSS class names to set on the overlay element.",
236
+ "value": {
237
+ "type": [
238
+ "string",
239
+ "null",
240
+ "undefined"
241
+ ]
242
+ }
243
+ },
233
244
  {
234
245
  "name": "opened",
235
246
  "description": "True if the dropdown is open, false otherwise.",
@@ -528,6 +539,17 @@
528
539
  ]
529
540
  }
530
541
  },
542
+ {
543
+ "name": "overlayClass",
544
+ "description": "A space-delimited list of CSS class names to set on the overlay element.",
545
+ "value": {
546
+ "type": [
547
+ "string",
548
+ "null",
549
+ "undefined"
550
+ ]
551
+ }
552
+ },
531
553
  {
532
554
  "name": "selectedItems",
533
555
  "description": "The list of selected items.\nNote: modifying the selected items creates a new array each time.",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/multi-select-combo-box",
4
- "version": "24.0.0-alpha1",
4
+ "version": "24.0.0-alpha11",
5
5
  "description-markup": "markdown",
6
6
  "framework": "lit",
7
7
  "framework-config": {
@@ -16,7 +16,7 @@
16
16
  "elements": [
17
17
  {
18
18
  "name": "vaadin-multi-select-combo-box",
19
- "description": "`<vaadin-multi-select-combo-box>` is a web component that wraps `<vaadin-combo-box>` and extends\nits functionality to allow selecting multiple items, in addition to basic features.\n\n```html\n<vaadin-multi-select-combo-box id=\"comboBox\"></vaadin-multi-select-combo-box>\n```\n```js\nconst comboBox = document.querySelector('#comboBox');\ncomboBox.items = ['apple', 'banana', 'lemon', 'orange'];\ncomboBox.selectedItems = ['lemon', 'orange'];\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------------------|----------------\n`chips` | The element that wraps chips for selected items\n`chip` | Chip shown for every selected item\n`label` | The label element\n`input-field` | The element that wraps prefix, value and suffix\n`clear-button` | The clear button\n`error-message` | The error message element\n`helper-text` | The helper text element wrapper\n`required-indicator` | The `required` state indicator element\n`overflow` | The chip shown when component width is not enough to fit all chips\n`overflow-one` | Set on the overflow chip when only one chip does not fit\n`overflow-two` | Set on the overflow chip when two chips do not fit\n`toggle-button` | The toggle button\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n-----------------------|-----------------\n`disabled` | Set to a disabled element\n`has-value` | Set when the element has a value\n`has-label` | Set when the element has a label\n`has-helper` | Set when the element has helper text or slot\n`has-error-message` | Set when the element has an error message\n`invalid` | Set when the element is invalid\n`focused` | Set when the element is focused\n`focus-ring` | Set when the element is keyboard focused\n`loading` | Set when loading items from the data provider\n`opened` | Set when the dropdown is open\n`readonly` | Set to a readonly element\n\nThe following custom CSS properties are available for styling:\n\nCustom property | Description | Default\n-----------------------------------------------------|----------------------------|--------\n`--vaadin-field-default-width` | Default width of the field | `12em`\n`--vaadin-multi-select-combo-box-overlay-width` | Width of the overlay | `auto`\n`--vaadin-multi-select-combo-box-overlay-max-height` | Max height of the overlay | `65vh`\n`--vaadin-multi-select-combo-box-input-min-width` | Min width of the input | `4em`\n\n### Internal components\n\nIn addition to `<vaadin-multi-select-combo-box>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-multi-select-combo-box-overlay>` - has the same API as `<vaadin-overlay>`.\n- `<vaadin-multi-select-combo-box-item>` - has the same API as `<vaadin-item>`.\n- `<vaadin-multi-select-combo-box-container>` - has the same API as `<vaadin-input-container>`.\n\nNote: the `theme` attribute value set on `<vaadin-multi-select-combo-box>` is\npropagated to these components.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
19
+ "description": "`<vaadin-multi-select-combo-box>` is a web component that wraps `<vaadin-combo-box>` and extends\nits functionality to allow selecting multiple items, in addition to basic features.\n\n```html\n<vaadin-multi-select-combo-box id=\"comboBox\"></vaadin-multi-select-combo-box>\n```\n```js\nconst comboBox = document.querySelector('#comboBox');\ncomboBox.items = ['apple', 'banana', 'lemon', 'orange'];\ncomboBox.selectedItems = ['lemon', 'orange'];\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------------------|----------------\n`chips` | The element that wraps slotted chips for selected items\n`label` | The label element\n`input-field` | The element that wraps prefix, value and suffix\n`clear-button` | The clear button\n`error-message` | The error message element\n`helper-text` | The helper text element wrapper\n`required-indicator` | The `required` state indicator element\n`toggle-button` | The toggle button\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n-----------------------|-----------------\n`disabled` | Set to a disabled element\n`has-value` | Set when the element has a value\n`has-label` | Set when the element has a label\n`has-helper` | Set when the element has helper text or slot\n`has-error-message` | Set when the element has an error message\n`invalid` | Set when the element is invalid\n`focused` | Set when the element is focused\n`focus-ring` | Set when the element is keyboard focused\n`loading` | Set when loading items from the data provider\n`opened` | Set when the dropdown is open\n`readonly` | Set to a readonly element\n\nThe following custom CSS properties are available for styling:\n\nCustom property | Description | Default\n-----------------------------------------------------|----------------------------|--------\n`--vaadin-field-default-width` | Default width of the field | `12em`\n`--vaadin-multi-select-combo-box-overlay-width` | Width of the overlay | `auto`\n`--vaadin-multi-select-combo-box-overlay-max-height` | Max height of the overlay | `65vh`\n`--vaadin-multi-select-combo-box-input-min-width` | Min width of the input | `4em`\n\n### Internal components\n\nIn addition to `<vaadin-multi-select-combo-box>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-multi-select-combo-box-overlay>` - has the same API as `<vaadin-overlay>`.\n- `<vaadin-multi-select-combo-box-item>` - has the same API as `<vaadin-item>`.\n- `<vaadin-multi-select-combo-box-container>` - has the same API as `<vaadin-input-container>`.\n\nNote: the `theme` attribute value set on `<vaadin-multi-select-combo-box>` is\npropagated to these components.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
20
20
  "extension": true,
21
21
  "attributes": [
22
22
  {
@@ -180,6 +180,13 @@
180
180
  "kind": "expression"
181
181
  }
182
182
  },
183
+ {
184
+ "name": ".overlayClass",
185
+ "description": "A space-delimited list of CSS class names to set on the overlay element.",
186
+ "value": {
187
+ "kind": "expression"
188
+ }
189
+ },
183
190
  {
184
191
  "name": ".selectedItems",
185
192
  "description": "The list of selected items.\nNote: modifying the selected items creates a new array each time.",