@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 +9 -9
- package/src/vaadin-multi-select-combo-box-chip.js +11 -2
- package/src/vaadin-multi-select-combo-box-container.js +2 -3
- package/src/vaadin-multi-select-combo-box-scroller.js +13 -0
- package/src/vaadin-multi-select-combo-box.d.ts +30 -1
- package/src/vaadin-multi-select-combo-box.js +128 -56
- package/theme/lumo/vaadin-multi-select-combo-box-chip-styles.js +1 -5
- package/theme/lumo/vaadin-multi-select-combo-box-styles.js +4 -4
- package/theme/material/vaadin-multi-select-combo-box-chip-styles.js +1 -5
- package/theme/material/vaadin-multi-select-combo-box-styles.js +0 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/multi-select-combo-box",
|
|
3
|
-
"version": "23.1.0-
|
|
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-
|
|
37
|
-
"@vaadin/component-base": "23.1.0-
|
|
38
|
-
"@vaadin/field-base": "23.1.0-
|
|
39
|
-
"@vaadin/input-container": "23.1.0-
|
|
40
|
-
"@vaadin/vaadin-lumo-styles": "23.1.0-
|
|
41
|
-
"@vaadin/vaadin-material-styles": "23.1.0-
|
|
42
|
-
"@vaadin/vaadin-themable-mixin": "23.1.0-
|
|
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": "
|
|
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
|
-
|
|
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('
|
|
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]
|
|
44
|
-
|
|
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.
|
|
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() ===
|
|
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.
|
|
630
|
-
chip.
|
|
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
|
-
|
|
720
|
+
__getOverflowWidth() {
|
|
721
|
+
const chip = this.$.overflow;
|
|
722
|
+
|
|
644
723
|
chip.style.visibility = 'hidden';
|
|
645
|
-
chip.
|
|
646
|
-
chip.style.minWidth = 'var(--chip-min-width)';
|
|
724
|
+
chip.removeAttribute('hidden');
|
|
647
725
|
|
|
648
|
-
|
|
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.
|
|
651
|
-
chip.style.display = '';
|
|
731
|
+
chip.setAttribute('hidden', '');
|
|
652
732
|
chip.style.visibility = '';
|
|
653
733
|
|
|
654
|
-
return
|
|
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
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
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
|
-
|
|
674
|
-
|
|
675
|
-
|
|
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
|
-
|
|
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 (
|
|
689
|
-
|
|
758
|
+
if (items.length > 1) {
|
|
759
|
+
remainingWidth -= this.__getOverflowWidth();
|
|
690
760
|
}
|
|
691
761
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
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
|
-
|
|
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], {
|