@vaadin/multi-select-combo-box 24.3.0-alpha4 → 24.3.0-alpha6

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.3.0-alpha4",
3
+ "version": "24.3.0-alpha6",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -37,27 +37,27 @@
37
37
  ],
38
38
  "dependencies": {
39
39
  "@polymer/polymer": "^3.0.0",
40
- "@vaadin/a11y-base": "24.3.0-alpha4",
41
- "@vaadin/combo-box": "24.3.0-alpha4",
42
- "@vaadin/component-base": "24.3.0-alpha4",
43
- "@vaadin/field-base": "24.3.0-alpha4",
44
- "@vaadin/input-container": "24.3.0-alpha4",
45
- "@vaadin/item": "24.3.0-alpha4",
46
- "@vaadin/lit-renderer": "24.3.0-alpha4",
47
- "@vaadin/overlay": "24.3.0-alpha4",
48
- "@vaadin/vaadin-lumo-styles": "24.3.0-alpha4",
49
- "@vaadin/vaadin-material-styles": "24.3.0-alpha4",
50
- "@vaadin/vaadin-themable-mixin": "24.3.0-alpha4"
40
+ "@vaadin/a11y-base": "24.3.0-alpha6",
41
+ "@vaadin/combo-box": "24.3.0-alpha6",
42
+ "@vaadin/component-base": "24.3.0-alpha6",
43
+ "@vaadin/field-base": "24.3.0-alpha6",
44
+ "@vaadin/input-container": "24.3.0-alpha6",
45
+ "@vaadin/item": "24.3.0-alpha6",
46
+ "@vaadin/lit-renderer": "24.3.0-alpha6",
47
+ "@vaadin/overlay": "24.3.0-alpha6",
48
+ "@vaadin/vaadin-lumo-styles": "24.3.0-alpha6",
49
+ "@vaadin/vaadin-material-styles": "24.3.0-alpha6",
50
+ "@vaadin/vaadin-themable-mixin": "24.3.0-alpha6"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@esm-bundle/chai": "^4.3.4",
54
- "@vaadin/testing-helpers": "^0.5.0",
55
- "lit": "^2.0.0",
54
+ "@vaadin/testing-helpers": "^0.6.0",
55
+ "lit": "^3.0.0",
56
56
  "sinon": "^13.0.2"
57
57
  },
58
58
  "web-types": [
59
59
  "web-types.json",
60
60
  "web-types.lit.json"
61
61
  ],
62
- "gitHead": "d6884bc788b98a4e8dfd14f3f399c6eb9022bd44"
62
+ "gitHead": "2721ab38ba3bc7d38dc1241016915354617ff659"
63
63
  }
@@ -14,6 +14,10 @@ registerStyles(
14
14
  display: flex;
15
15
  width: 100%;
16
16
  }
17
+
18
+ :host([all-chips-visible]) #wrapper {
19
+ flex-wrap: wrap;
20
+ }
17
21
  `,
18
22
  {
19
23
  moduleId: 'vaadin-multi-select-combo-box-container-styles',
@@ -49,6 +53,20 @@ class MultiSelectComboBoxContainer extends InputContainer {
49
53
  }
50
54
  return memoizedTemplate;
51
55
  }
56
+
57
+ static get properties() {
58
+ return {
59
+ /**
60
+ * Set true to not collapse selected items chips into the overflow
61
+ * chip and instead always show them, causing input field to grow.
62
+ * @attr {boolean} all-chips-visible
63
+ */
64
+ allChipsVisible: {
65
+ type: Boolean,
66
+ reflectToAttribute: true,
67
+ },
68
+ };
69
+ }
52
70
  }
53
71
 
54
72
  defineCustomElement(MultiSelectComboBoxContainer);
@@ -60,6 +60,15 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
60
60
  notify: true,
61
61
  },
62
62
 
63
+ /**
64
+ * Set to true to group selected items at the top of the overlay.
65
+ * @attr {boolean} group-selected-items
66
+ */
67
+ groupSelectedItems: {
68
+ type: Boolean,
69
+ value: false,
70
+ },
71
+
63
72
  /**
64
73
  * When set to `true`, "loading" attribute is set
65
74
  * on the host and the overlay element.
@@ -97,6 +106,14 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
97
106
  notify: true,
98
107
  },
99
108
 
109
+ /**
110
+ * A subset of items to be shown at the top of the overlay.
111
+ */
112
+ topGroup: {
113
+ type: Array,
114
+ observer: '_topGroupChanged',
115
+ },
116
+
100
117
  _target: {
101
118
  type: Object,
102
119
  },
@@ -140,6 +157,42 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
140
157
  this._toggleElement = this.querySelector('.toggle-button');
141
158
  }
142
159
 
160
+ /**
161
+ * Override combo-box method to group selected
162
+ * items at the top of the overlay.
163
+ *
164
+ * @protected
165
+ * @override
166
+ */
167
+ _setDropdownItems(items) {
168
+ if (this.readonly || !this.groupSelectedItems) {
169
+ this._dropdownItems = items;
170
+ return;
171
+ }
172
+
173
+ if (this.topGroup) {
174
+ const filteredTopItems = [];
175
+ const filteredItems = [];
176
+
177
+ (items || []).forEach((item) => {
178
+ if (this.topGroup.some((selectedItem) => this._getItemValue(item) === this._getItemValue(selectedItem))) {
179
+ filteredTopItems.push(item);
180
+ } else {
181
+ filteredItems.push(item);
182
+ }
183
+ });
184
+
185
+ this._dropdownItems = [...filteredTopItems, ...filteredItems];
186
+ }
187
+ }
188
+
189
+ /** @private */
190
+ _topGroupChanged(topGroup) {
191
+ if (topGroup) {
192
+ this._setDropdownItems(this.filteredItems);
193
+ }
194
+ }
195
+
143
196
  /**
144
197
  * Override combo-box method to set correct owner for using by item renderers.
145
198
  * This needs to be done before the scroller gets added to the DOM to ensure
@@ -172,9 +225,9 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
172
225
  this.close();
173
226
  } else {
174
227
  // Keep selected item focused after committing on Enter.
175
- const focusedItem = this.filteredItems[this._focusedIndex];
228
+ const focusedItem = this._dropdownItems[this._focusedIndex];
176
229
  this._commitValue();
177
- this._focusedIndex = this.filteredItems.indexOf(focusedItem);
230
+ this._focusedIndex = this._dropdownItems.indexOf(focusedItem);
178
231
  }
179
232
 
180
233
  return;
@@ -171,6 +171,14 @@ export interface MultiSelectComboBoxEventMap<TItem> extends HTMLElementEventMap
171
171
  * @fires {CustomEvent} validated - Fired whenever the field is validated.
172
172
  */
173
173
  declare class MultiSelectComboBox<TItem = ComboBoxDefaultItem> extends HTMLElement {
174
+ /**
175
+ * Set to true to not collapse selected items chips into the overflow
176
+ * chip and instead always show them all, causing input field to grow
177
+ * and wrap into multiple lines when width is limited.
178
+ * @attr {boolean} all-chips-visible
179
+ */
180
+ allChipsVisible: boolean;
181
+
174
182
  /**
175
183
  * When true, the user can input a value that is not present in the items list.
176
184
  * @attr {boolean} allow-custom-value
@@ -209,6 +217,12 @@ declare class MultiSelectComboBox<TItem = ComboBoxDefaultItem> extends HTMLEleme
209
217
  */
210
218
  filter: string;
211
219
 
220
+ /**
221
+ * Set to true to group selected items at the top of the overlay.
222
+ * @attr {boolean} group-selected-items
223
+ */
224
+ groupSelectedItems: boolean;
225
+
212
226
  /**
213
227
  * A full set of items to filter the visible options from.
214
228
  * The items can be of either `String` or `Object` type.
@@ -45,6 +45,14 @@ const multiSelectComboBox = css`
45
45
  flex-basis: 0;
46
46
  padding: 0;
47
47
  }
48
+
49
+ :host([all-chips-visible]) #chips {
50
+ display: contents;
51
+ }
52
+
53
+ :host([all-chips-visible]) [class$='container'] {
54
+ width: fit-content;
55
+ }
48
56
  `;
49
57
 
50
58
  registerStyles('vaadin-multi-select-combo-box', [inputFieldShared, multiSelectComboBox], {
@@ -165,6 +173,8 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
165
173
  size="{{size}}"
166
174
  filtered-items="[[__effectiveFilteredItems]]"
167
175
  selected-items="[[selectedItems]]"
176
+ group-selected-items="[[groupSelectedItems]]"
177
+ top-group="[[_topGroup]]"
168
178
  opened="{{opened}}"
169
179
  renderer="[[renderer]]"
170
180
  theme$="[[_theme]]"
@@ -175,6 +185,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
175
185
  >
176
186
  <vaadin-multi-select-combo-box-container
177
187
  part="input-field"
188
+ all-chips-visible="[[allChipsVisible]]"
178
189
  readonly="[[readonly]]"
179
190
  disabled="[[disabled]]"
180
191
  invalid="[[invalid]]"
@@ -211,6 +222,19 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
211
222
 
212
223
  static get properties() {
213
224
  return {
225
+ /**
226
+ * Set to true to not collapse selected items chips into the overflow
227
+ * chip and instead always show them all, causing input field to grow
228
+ * and wrap into multiple lines when width is limited.
229
+ * @attr {boolean} all-chips-visible
230
+ */
231
+ allChipsVisible: {
232
+ type: Boolean,
233
+ value: false,
234
+ reflectToAttribute: true,
235
+ observer: '_allChipsVisibleChanged',
236
+ },
237
+
214
238
  /**
215
239
  * Set true to prevent the overlay from opening automatically.
216
240
  * @attr {boolean} auto-open-disabled
@@ -228,6 +252,15 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
228
252
  value: false,
229
253
  },
230
254
 
255
+ /**
256
+ * Set to true to group selected items at the top of the overlay.
257
+ * @attr {boolean} group-selected-items
258
+ */
259
+ groupSelectedItems: {
260
+ type: Boolean,
261
+ value: false,
262
+ },
263
+
231
264
  /**
232
265
  * A full set of items to filter the visible options from.
233
266
  * The items can be of either `String` or `Object` type.
@@ -464,6 +497,11 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
464
497
  _lastFilter: {
465
498
  type: String,
466
499
  },
500
+
501
+ /** @private */
502
+ _topGroup: {
503
+ type: Array,
504
+ },
467
505
  };
468
506
  }
469
507
 
@@ -471,6 +509,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
471
509
  return [
472
510
  '_selectedItemsChanged(selectedItems, selectedItems.*)',
473
511
  '__updateOverflowChip(_overflow, _overflowItems, disabled, readonly)',
512
+ '__updateTopGroup(groupSelectedItems, selectedItems, opened)',
474
513
  ];
475
514
  }
476
515
 
@@ -657,6 +696,13 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
657
696
  super._delegateAttribute(name, value);
658
697
  }
659
698
 
699
+ /** @private */
700
+ _allChipsVisibleChanged(visible, oldVisible) {
701
+ if (visible || oldVisible) {
702
+ this.__updateChips();
703
+ }
704
+ }
705
+
660
706
  /**
661
707
  * Setting clear button visible reduces total space available
662
708
  * for rendering chips, and making it hidden increases it.
@@ -823,6 +869,15 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
823
869
  this.dispatchEvent(new CustomEvent('change', { bubbles: true }));
824
870
  }
825
871
 
872
+ /** @private */
873
+ __updateTopGroup(groupSelectedItems, selectedItems, opened) {
874
+ if (!groupSelectedItems) {
875
+ this._topGroup = [];
876
+ } else if (!opened) {
877
+ this._topGroup = [...selectedItems];
878
+ }
879
+ }
880
+
826
881
  /** @private */
827
882
  __createChip(item) {
828
883
  const chip = document.createElement('vaadin-multi-select-combo-box-chip');
@@ -892,7 +947,8 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
892
947
  const chip = this.__createChip(items[i]);
893
948
  this.insertBefore(chip, refNode);
894
949
 
895
- if (this.$.chips.clientWidth > remainingWidth) {
950
+ // If all the chips are visible, no need to measure remaining width
951
+ if (!this.allChipsVisible && this.$.chips.clientWidth > remainingWidth) {
896
952
  chip.remove();
897
953
  break;
898
954
  }
@@ -48,6 +48,16 @@ registerStyles(
48
48
  { moduleId: 'lumo-multi-select-combo-box-overlay' },
49
49
  );
50
50
 
51
+ registerStyles(
52
+ 'vaadin-multi-select-combo-box-container',
53
+ css`
54
+ :host([all-chips-visible]) {
55
+ padding-block: var(--lumo-space-xs);
56
+ }
57
+ `,
58
+ { moduleId: 'lumo-multi-select-combo-box-container' },
59
+ );
60
+
51
61
  const multiSelectComboBox = css`
52
62
  :host([has-value]) {
53
63
  padding-inline-start: 0;
@@ -67,17 +77,25 @@ const multiSelectComboBox = css`
67
77
  mask-image: none;
68
78
  }
69
79
 
80
+ :host([all-chips-visible]) ::slotted([slot='chip']) {
81
+ margin-block: calc(var(--lumo-space-xs) / 2);
82
+ }
83
+
70
84
  ::slotted([slot='chip']:not([readonly]):not([disabled])) {
71
85
  padding-inline-end: 0;
72
86
  }
73
87
 
88
+ :host([all-chips-visible]) ::slotted([slot='input']) {
89
+ min-height: calc(var(--lumo-text-field-size, var(--lumo-size-m)) - 2 * var(--lumo-space-xs));
90
+ }
91
+
74
92
  ::slotted([slot='chip']:not(:last-of-type)),
75
93
  ::slotted([slot='overflow']:not(:last-of-type)) {
76
94
  margin-inline-end: var(--lumo-space-xs);
77
95
  }
78
96
 
79
97
  ::slotted([slot='chip'][focused]) {
80
- background-color: var(--lumo-primary-color);
98
+ background-color: var(--vaadin-selection-color, var(--lumo-primary-color));
81
99
  color: var(--lumo-primary-contrast-color);
82
100
  }
83
101
 
@@ -56,6 +56,11 @@ const multiSelectComboBox = css`
56
56
  padding: 0 0.5rem;
57
57
  }
58
58
 
59
+ :host([all-chips-visible]) ::slotted([slot='chip']) {
60
+ margin-top: 0.25rem;
61
+ align-self: flex-start;
62
+ }
63
+
59
64
  ::slotted([slot='chip']:not([readonly]):not([disabled])) {
60
65
  padding-inline-end: 0;
61
66
  }
package/web-types.json CHANGED
@@ -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.3.0-alpha4",
4
+ "version": "24.3.0-alpha6",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
@@ -197,6 +197,17 @@
197
197
  ]
198
198
  }
199
199
  },
200
+ {
201
+ "name": "all-chips-visible",
202
+ "description": "Set to true to not collapse selected items chips into the overflow\nchip and instead always show them all, causing input field to grow\nand wrap into multiple lines when width is limited.",
203
+ "value": {
204
+ "type": [
205
+ "boolean",
206
+ "null",
207
+ "undefined"
208
+ ]
209
+ }
210
+ },
200
211
  {
201
212
  "name": "auto-open-disabled",
202
213
  "description": "Set true to prevent the overlay from opening automatically.",
@@ -208,6 +219,17 @@
208
219
  ]
209
220
  }
210
221
  },
222
+ {
223
+ "name": "group-selected-items",
224
+ "description": "Set to true to group selected items at the top of the overlay.",
225
+ "value": {
226
+ "type": [
227
+ "boolean",
228
+ "null",
229
+ "undefined"
230
+ ]
231
+ }
232
+ },
211
233
  {
212
234
  "name": "item-label-path",
213
235
  "description": "The item property used for a visual representation of the item.",
@@ -508,6 +530,17 @@
508
530
  ]
509
531
  }
510
532
  },
533
+ {
534
+ "name": "allChipsVisible",
535
+ "description": "Set to true to not collapse selected items chips into the overflow\nchip and instead always show them all, causing input field to grow\nand wrap into multiple lines when width is limited.",
536
+ "value": {
537
+ "type": [
538
+ "boolean",
539
+ "null",
540
+ "undefined"
541
+ ]
542
+ }
543
+ },
511
544
  {
512
545
  "name": "autoOpenDisabled",
513
546
  "description": "Set true to prevent the overlay from opening automatically.",
@@ -519,6 +552,17 @@
519
552
  ]
520
553
  }
521
554
  },
555
+ {
556
+ "name": "groupSelectedItems",
557
+ "description": "Set to true to group selected items at the top of the overlay.",
558
+ "value": {
559
+ "type": [
560
+ "boolean",
561
+ "null",
562
+ "undefined"
563
+ ]
564
+ }
565
+ },
522
566
  {
523
567
  "name": "items",
524
568
  "description": "A full set of items to filter the visible options from.\nThe items can be of either `String` or `Object` type.",
@@ -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.3.0-alpha4",
4
+ "version": "24.3.0-alpha6",
5
5
  "description-markup": "markdown",
6
6
  "framework": "lit",
7
7
  "framework-config": {
@@ -68,6 +68,13 @@
68
68
  "kind": "expression"
69
69
  }
70
70
  },
71
+ {
72
+ "name": "?allChipsVisible",
73
+ "description": "Set to true to not collapse selected items chips into the overflow\nchip and instead always show them all, causing input field to grow\nand wrap into multiple lines when width is limited.",
74
+ "value": {
75
+ "kind": "expression"
76
+ }
77
+ },
71
78
  {
72
79
  "name": "?autoOpenDisabled",
73
80
  "description": "Set true to prevent the overlay from opening automatically.",
@@ -75,6 +82,13 @@
75
82
  "kind": "expression"
76
83
  }
77
84
  },
85
+ {
86
+ "name": "?groupSelectedItems",
87
+ "description": "Set to true to group selected items at the top of the overlay.",
88
+ "value": {
89
+ "kind": "expression"
90
+ }
91
+ },
78
92
  {
79
93
  "name": "?loading",
80
94
  "description": "True when loading items from the data provider, false otherwise.",