@vaadin/multi-select-combo-box 23.1.0-alpha2 → 23.1.0-alpha3
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 +10 -10
- package/src/vaadin-multi-select-combo-box-chip.js +19 -0
- package/src/vaadin-multi-select-combo-box-container.js +3 -2
- package/src/vaadin-multi-select-combo-box-internal.js +7 -14
- package/src/vaadin-multi-select-combo-box.d.ts +14 -0
- package/src/vaadin-multi-select-combo-box.js +154 -11
- package/theme/lumo/vaadin-multi-select-combo-box-chip-styles.js +50 -14
- package/theme/material/vaadin-multi-select-combo-box-chip-styles.js +42 -5
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-alpha3",
|
|
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-alpha3",
|
|
37
|
+
"@vaadin/component-base": "23.1.0-alpha3",
|
|
38
|
+
"@vaadin/field-base": "23.1.0-alpha3",
|
|
39
|
+
"@vaadin/input-container": "23.1.0-alpha3",
|
|
40
|
+
"@vaadin/vaadin-lumo-styles": "23.1.0-alpha3",
|
|
41
|
+
"@vaadin/vaadin-material-styles": "23.1.0-alpha3",
|
|
42
|
+
"@vaadin/vaadin-themable-mixin": "23.1.0-alpha3"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@esm-bundle/chai": "^4.3.4",
|
|
46
46
|
"@vaadin/testing-helpers": "^0.3.2",
|
|
47
|
-
"sinon": "^
|
|
47
|
+
"sinon": "^13.0.2"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "8c9e64e8dfa158dd52a9bf6da351ff038c88ca85"
|
|
50
50
|
}
|
|
@@ -42,6 +42,25 @@ class MultiSelectComboBoxChip extends ThemableMixin(PolymerElement) {
|
|
|
42
42
|
|
|
43
43
|
static get template() {
|
|
44
44
|
return html`
|
|
45
|
+
<style>
|
|
46
|
+
:host {
|
|
47
|
+
display: inline-flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
align-self: center;
|
|
50
|
+
white-space: nowrap;
|
|
51
|
+
box-sizing: border-box;
|
|
52
|
+
min-width: 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
[part='label'] {
|
|
56
|
+
overflow: hidden;
|
|
57
|
+
text-overflow: ellipsis;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
:host([part~='overflow']) [part='remove-button'] {
|
|
61
|
+
display: none !important;
|
|
62
|
+
}
|
|
63
|
+
</style>
|
|
45
64
|
<div part="label">[[label]]</div>
|
|
46
65
|
<div part="remove-button" role="button" on-click="_onRemoveClick"></div>
|
|
47
66
|
`;
|
|
@@ -9,9 +9,10 @@ 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;
|
|
15
16
|
}
|
|
16
17
|
`,
|
|
17
18
|
{
|
|
@@ -39,7 +40,7 @@ class MultiSelectComboBoxContainer extends InputContainer {
|
|
|
39
40
|
const slots = content.querySelectorAll('slot');
|
|
40
41
|
|
|
41
42
|
const wrapper = document.createElement('div');
|
|
42
|
-
wrapper.setAttribute('
|
|
43
|
+
wrapper.setAttribute('class', 'wrapper');
|
|
43
44
|
content.insertBefore(wrapper, slots[2]);
|
|
44
45
|
|
|
45
46
|
wrapper.appendChild(slots[0]);
|
|
@@ -81,24 +81,17 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
|
|
|
81
81
|
this._toggleElement = this.querySelector('.toggle-button');
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
/** @protected */
|
|
85
|
-
_isClearButton(event) {
|
|
86
|
-
return (
|
|
87
|
-
super._isClearButton(event) ||
|
|
88
|
-
(event.type === 'input' && !event.isTrusted) || // fake input event dispatched by clear button
|
|
89
|
-
event.composedPath()[0].getAttribute('part') === 'clear-button'
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
84
|
/**
|
|
94
|
-
*
|
|
85
|
+
* Override method from `InputMixin`.
|
|
86
|
+
*
|
|
95
87
|
* @protected
|
|
88
|
+
* @override
|
|
96
89
|
*/
|
|
97
|
-
|
|
98
|
-
super.
|
|
90
|
+
clear() {
|
|
91
|
+
super.clear();
|
|
99
92
|
|
|
100
|
-
if (this.
|
|
101
|
-
this.
|
|
93
|
+
if (this.inputElement) {
|
|
94
|
+
this.inputElement.value = '';
|
|
102
95
|
}
|
|
103
96
|
}
|
|
104
97
|
|
|
@@ -9,6 +9,7 @@ import { DisabledMixinClass } from '@vaadin/component-base/src/disabled-mixin.js
|
|
|
9
9
|
import { ElementMixinClass } from '@vaadin/component-base/src/element-mixin.js';
|
|
10
10
|
import { FocusMixinClass } from '@vaadin/component-base/src/focus-mixin.js';
|
|
11
11
|
import { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js';
|
|
12
|
+
import { ResizeMixinClass } from '@vaadin/component-base/src/resize-mixin.js';
|
|
12
13
|
import { DelegateFocusMixinClass } from '@vaadin/field-base/src/delegate-focus-mixin.js';
|
|
13
14
|
import { DelegateStateMixinClass } from '@vaadin/field-base/src/delegate-state-mixin.js';
|
|
14
15
|
import { FieldMixinClass } from '@vaadin/field-base/src/field-mixin.js';
|
|
@@ -85,6 +86,9 @@ export interface MultiSelectComboBoxEventMap<TItem> extends HTMLElementEventMap
|
|
|
85
86
|
* `error-message` | The error message element
|
|
86
87
|
* `helper-text` | The helper text element wrapper
|
|
87
88
|
* `required-indicator` | The `required` state indicator element
|
|
89
|
+
* `overflow` | The chip shown when component width is not enough to fit all chips
|
|
90
|
+
* `overflow-one` | Set on the overflow chip when only one chip does not fit
|
|
91
|
+
* `overflow-two` | Set on the overflow chip when two chips do not fit
|
|
88
92
|
* `toggle-button` | The toggle button
|
|
89
93
|
*
|
|
90
94
|
* The following state attributes are available for styling:
|
|
@@ -102,6 +106,15 @@ export interface MultiSelectComboBoxEventMap<TItem> extends HTMLElementEventMap
|
|
|
102
106
|
* `opened` | Set when the dropdown is open
|
|
103
107
|
* `readonly` | Set to a readonly element
|
|
104
108
|
*
|
|
109
|
+
* The following custom CSS properties are available for styling:
|
|
110
|
+
*
|
|
111
|
+
* Custom property | Description | Default
|
|
112
|
+
* -----------------------------------------------------|----------------------------|--------
|
|
113
|
+
* `--vaadin-field-default-width` | Default width of the field | `12em`
|
|
114
|
+
* `--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
|
+
* `--vaadin-multi-select-combo-box-input-min-width` | Min width of the input | `4em`
|
|
117
|
+
*
|
|
105
118
|
* ### Internal components
|
|
106
119
|
*
|
|
107
120
|
* In addition to `<vaadin-multi-select-combo-box>` itself, the following internal
|
|
@@ -241,6 +254,7 @@ interface MultiSelectComboBox
|
|
|
241
254
|
DisabledMixinClass,
|
|
242
255
|
DelegateStateMixinClass,
|
|
243
256
|
DelegateFocusMixinClass,
|
|
257
|
+
ResizeMixinClass,
|
|
244
258
|
ThemableMixinClass,
|
|
245
259
|
ElementMixinClass,
|
|
246
260
|
ControllerMixinClass {}
|
|
@@ -8,6 +8,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
10
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
11
|
+
import { ResizeMixin } from '@vaadin/component-base/src/resize-mixin.js';
|
|
11
12
|
import { processTemplates } from '@vaadin/component-base/src/templates.js';
|
|
12
13
|
import { InputControlMixin } from '@vaadin/field-base/src/input-control-mixin.js';
|
|
13
14
|
import { InputController } from '@vaadin/field-base/src/input-controller.js';
|
|
@@ -16,6 +17,11 @@ import { inputFieldShared } from '@vaadin/field-base/src/styles/input-field-shar
|
|
|
16
17
|
import { css, registerStyles, ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
17
18
|
|
|
18
19
|
const multiSelectComboBox = css`
|
|
20
|
+
:host {
|
|
21
|
+
--chip-min-width: var(--vaadin-multi-select-combo-box-chip-min-width, 4em);
|
|
22
|
+
--input-min-width: var(--vaadin-multi-select-combo-box-input-min-width, 4em);
|
|
23
|
+
}
|
|
24
|
+
|
|
19
25
|
[hidden] {
|
|
20
26
|
display: none !important;
|
|
21
27
|
}
|
|
@@ -24,17 +30,14 @@ const multiSelectComboBox = css`
|
|
|
24
30
|
color: transparent !important;
|
|
25
31
|
}
|
|
26
32
|
|
|
27
|
-
:host([has-value]) [class$='container'] {
|
|
28
|
-
width: auto;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
33
|
::slotted(input) {
|
|
32
34
|
box-sizing: border-box;
|
|
33
|
-
flex: 1 0
|
|
35
|
+
flex: 1 0 var(--input-min-width);
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
[part
|
|
38
|
+
[part='chip'] {
|
|
37
39
|
flex: 0 1 auto;
|
|
40
|
+
min-width: var(--chip-min-width);
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
:host([readonly]) [part~='chip'] {
|
|
@@ -73,6 +76,9 @@ registerStyles('vaadin-multi-select-combo-box', [inputFieldShared, multiSelectCo
|
|
|
73
76
|
* `error-message` | The error message element
|
|
74
77
|
* `helper-text` | The helper text element wrapper
|
|
75
78
|
* `required-indicator` | The `required` state indicator element
|
|
79
|
+
* `overflow` | The chip shown when component width is not enough to fit all chips
|
|
80
|
+
* `overflow-one` | Set on the overflow chip when only one chip does not fit
|
|
81
|
+
* `overflow-two` | Set on the overflow chip when two chips do not fit
|
|
76
82
|
* `toggle-button` | The toggle button
|
|
77
83
|
*
|
|
78
84
|
* The following state attributes are available for styling:
|
|
@@ -90,6 +96,15 @@ registerStyles('vaadin-multi-select-combo-box', [inputFieldShared, multiSelectCo
|
|
|
90
96
|
* `opened` | Set when the dropdown is open
|
|
91
97
|
* `readonly` | Set to a readonly element
|
|
92
98
|
*
|
|
99
|
+
* The following custom CSS properties are available for styling:
|
|
100
|
+
*
|
|
101
|
+
* Custom property | Description | Default
|
|
102
|
+
* -----------------------------------------------------|----------------------------|--------
|
|
103
|
+
* `--vaadin-field-default-width` | Default width of the field | `12em`
|
|
104
|
+
* `--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
|
+
* `--vaadin-multi-select-combo-box-input-min-width` | Min width of the input | `4em`
|
|
107
|
+
*
|
|
93
108
|
* ### Internal components
|
|
94
109
|
*
|
|
95
110
|
* In addition to `<vaadin-multi-select-combo-box>` itself, the following internal
|
|
@@ -114,8 +129,9 @@ registerStyles('vaadin-multi-select-combo-box', [inputFieldShared, multiSelectCo
|
|
|
114
129
|
* @mixes ElementMixin
|
|
115
130
|
* @mixes ThemableMixin
|
|
116
131
|
* @mixes InputControlMixin
|
|
132
|
+
* @mixes ResizeMixin
|
|
117
133
|
*/
|
|
118
|
-
class MultiSelectComboBox extends InputControlMixin(ThemableMixin(ElementMixin(PolymerElement))) {
|
|
134
|
+
class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(ElementMixin(PolymerElement)))) {
|
|
119
135
|
static get is() {
|
|
120
136
|
return 'vaadin-multi-select-combo-box';
|
|
121
137
|
}
|
|
@@ -155,6 +171,15 @@ class MultiSelectComboBox extends InputControlMixin(ThemableMixin(ElementMixin(P
|
|
|
155
171
|
invalid="[[invalid]]"
|
|
156
172
|
theme$="[[theme]]"
|
|
157
173
|
>
|
|
174
|
+
<vaadin-multi-select-combo-box-chip
|
|
175
|
+
slot="prefix"
|
|
176
|
+
part$="[[_getOverflowPart(_overflowItems.length)]]"
|
|
177
|
+
disabled="[[disabled]]"
|
|
178
|
+
label="[[_getOverflowLabel(_overflowItems.length)]]"
|
|
179
|
+
title$="[[_getOverflowTitle(_overflowItems)]]"
|
|
180
|
+
hidden$="[[_isOverflowHidden(_overflowItems.length)]]"
|
|
181
|
+
on-mousedown="_preventBlur"
|
|
182
|
+
></vaadin-multi-select-combo-box-chip>
|
|
158
183
|
<slot name="input"></slot>
|
|
159
184
|
<div id="clearButton" part="clear-button" slot="suffix"></div>
|
|
160
185
|
<div id="toggleButton" class="toggle-button" part="toggle-button" slot="suffix"></div>
|
|
@@ -180,6 +205,17 @@ class MultiSelectComboBox extends InputControlMixin(ThemableMixin(ElementMixin(P
|
|
|
180
205
|
*/
|
|
181
206
|
autoOpenDisabled: Boolean,
|
|
182
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Set to true to display the clear icon which clears the input.
|
|
210
|
+
* @attr {boolean} clear-button-visible
|
|
211
|
+
*/
|
|
212
|
+
clearButtonVisible: {
|
|
213
|
+
type: Boolean,
|
|
214
|
+
reflectToAttribute: true,
|
|
215
|
+
observer: '_clearButtonVisibleChanged',
|
|
216
|
+
value: false
|
|
217
|
+
},
|
|
218
|
+
|
|
183
219
|
/**
|
|
184
220
|
* A full set of items to filter the visible options from.
|
|
185
221
|
* The items can be of either `String` or `Object` type.
|
|
@@ -302,6 +338,12 @@ class MultiSelectComboBox extends InputControlMixin(ThemableMixin(ElementMixin(P
|
|
|
302
338
|
_hasValue: {
|
|
303
339
|
type: Boolean,
|
|
304
340
|
value: false
|
|
341
|
+
},
|
|
342
|
+
|
|
343
|
+
/** @private */
|
|
344
|
+
_overflowItems: {
|
|
345
|
+
type: Array,
|
|
346
|
+
value: () => []
|
|
305
347
|
}
|
|
306
348
|
};
|
|
307
349
|
}
|
|
@@ -403,6 +445,26 @@ class MultiSelectComboBox extends InputControlMixin(ThemableMixin(ElementMixin(P
|
|
|
403
445
|
super._toggleHasValue(this._hasValue);
|
|
404
446
|
}
|
|
405
447
|
|
|
448
|
+
/**
|
|
449
|
+
* Implement callback from `ResizeMixin` to update chips.
|
|
450
|
+
* @protected
|
|
451
|
+
* @override
|
|
452
|
+
*/
|
|
453
|
+
_onResize() {
|
|
454
|
+
this.__updateChips();
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Setting clear button visible reduces total space available
|
|
459
|
+
* for rendering chips, and making it hidden increases it.
|
|
460
|
+
* @private
|
|
461
|
+
*/
|
|
462
|
+
_clearButtonVisibleChanged(visible, oldVisible) {
|
|
463
|
+
if (visible || oldVisible) {
|
|
464
|
+
this.__updateChips();
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
406
468
|
/** @private */
|
|
407
469
|
_pageSizeChanged(pageSize, oldPageSize) {
|
|
408
470
|
if (Math.floor(pageSize) !== pageSize || pageSize <= 0) {
|
|
@@ -436,6 +498,34 @@ class MultiSelectComboBox extends InputControlMixin(ThemableMixin(ElementMixin(P
|
|
|
436
498
|
return item && Object.prototype.hasOwnProperty.call(item, itemLabelPath) ? item[itemLabelPath] : item;
|
|
437
499
|
}
|
|
438
500
|
|
|
501
|
+
/** @private */
|
|
502
|
+
_getOverflowLabel(length) {
|
|
503
|
+
return length;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/** @private */
|
|
507
|
+
_getOverflowPart(length) {
|
|
508
|
+
let part = `chip overflow`;
|
|
509
|
+
|
|
510
|
+
if (length === 1) {
|
|
511
|
+
part += ' overflow-one';
|
|
512
|
+
} else if (length === 2) {
|
|
513
|
+
part += ' overflow-two';
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
return part;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/** @private */
|
|
520
|
+
_getOverflowTitle(items) {
|
|
521
|
+
return items.map((item) => this._getItemLabel(item, this.itemLabelPath)).join(', ');
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/** @private */
|
|
525
|
+
_isOverflowHidden(length) {
|
|
526
|
+
return length === 0;
|
|
527
|
+
}
|
|
528
|
+
|
|
439
529
|
/** @private */
|
|
440
530
|
_findIndex(item, selectedItems, itemIdPath) {
|
|
441
531
|
if (itemIdPath && item) {
|
|
@@ -452,6 +542,7 @@ class MultiSelectComboBox extends InputControlMixin(ThemableMixin(ElementMixin(P
|
|
|
452
542
|
|
|
453
543
|
/** @private */
|
|
454
544
|
__clearFilter() {
|
|
545
|
+
this.filter = '';
|
|
455
546
|
this.$.comboBox.clear();
|
|
456
547
|
}
|
|
457
548
|
|
|
@@ -501,31 +592,83 @@ class MultiSelectComboBox extends InputControlMixin(ThemableMixin(ElementMixin(P
|
|
|
501
592
|
chip.setAttribute('slot', 'prefix');
|
|
502
593
|
|
|
503
594
|
chip.item = item;
|
|
504
|
-
chip.label = this._getItemLabel(item, this.itemLabelPath);
|
|
505
595
|
chip.toggleAttribute('disabled', this.disabled);
|
|
506
596
|
|
|
597
|
+
const label = this._getItemLabel(item, this.itemLabelPath);
|
|
598
|
+
chip.label = label;
|
|
599
|
+
chip.setAttribute('title', label);
|
|
600
|
+
|
|
507
601
|
chip.addEventListener('item-removed', (e) => this._onItemRemoved(e));
|
|
508
602
|
chip.addEventListener('mousedown', (e) => this._preventBlur(e));
|
|
509
603
|
|
|
510
604
|
return chip;
|
|
511
605
|
}
|
|
512
606
|
|
|
607
|
+
/** @private */
|
|
608
|
+
__getMinWidth(chip) {
|
|
609
|
+
chip.style.visibility = 'hidden';
|
|
610
|
+
chip.style.display = 'block';
|
|
611
|
+
chip.style.minWidth = 'var(--chip-min-width)';
|
|
612
|
+
|
|
613
|
+
const result = parseInt(getComputedStyle(chip).minWidth);
|
|
614
|
+
|
|
615
|
+
chip.style.minWidth = '';
|
|
616
|
+
chip.style.display = '';
|
|
617
|
+
chip.style.visibility = '';
|
|
618
|
+
|
|
619
|
+
return result;
|
|
620
|
+
}
|
|
621
|
+
|
|
513
622
|
/** @private */
|
|
514
623
|
__updateChips() {
|
|
515
624
|
if (!this._inputField) {
|
|
516
625
|
return;
|
|
517
626
|
}
|
|
518
627
|
|
|
519
|
-
|
|
628
|
+
// Clear all chips except the overflow
|
|
629
|
+
const chips = Array.from(this._chips).reverse();
|
|
630
|
+
const overflow = chips.pop();
|
|
631
|
+
|
|
632
|
+
chips.forEach((chip) => {
|
|
520
633
|
chip.remove();
|
|
521
634
|
});
|
|
522
635
|
|
|
523
636
|
const items = [...this.selectedItems];
|
|
524
637
|
|
|
638
|
+
let refNode = overflow.nextElementSibling;
|
|
639
|
+
|
|
640
|
+
// Use overflow chip to measure min-width
|
|
641
|
+
const chipMinWidth = this.__getMinWidth(overflow);
|
|
642
|
+
const inputMinWidth = parseInt(getComputedStyle(this.inputElement).flexBasis);
|
|
643
|
+
const containerStyle = getComputedStyle(this._inputField);
|
|
644
|
+
|
|
645
|
+
// Detect available width for chips
|
|
646
|
+
let totalWidth =
|
|
647
|
+
parseInt(containerStyle.width) -
|
|
648
|
+
parseInt(containerStyle.paddingLeft) -
|
|
649
|
+
parseInt(containerStyle.paddingRight) -
|
|
650
|
+
this.$.toggleButton.clientWidth -
|
|
651
|
+
inputMinWidth;
|
|
652
|
+
|
|
653
|
+
if (this.clearButtonVisible) {
|
|
654
|
+
totalWidth -= this.$.clearButton.clientWidth;
|
|
655
|
+
}
|
|
656
|
+
|
|
525
657
|
for (let i = items.length - 1; i >= 0; i--) {
|
|
526
|
-
|
|
527
|
-
|
|
658
|
+
// Ensure there is enough space for another chip
|
|
659
|
+
if (totalWidth < chipMinWidth) {
|
|
660
|
+
break;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
const item = items.pop();
|
|
664
|
+
const chip = this.__createChip(item);
|
|
665
|
+
this._inputField.insertBefore(chip, refNode);
|
|
666
|
+
|
|
667
|
+
refNode = chip;
|
|
668
|
+
totalWidth -= chipMinWidth;
|
|
528
669
|
}
|
|
670
|
+
|
|
671
|
+
this._overflowItems = items;
|
|
529
672
|
}
|
|
530
673
|
|
|
531
674
|
/**
|
|
@@ -13,27 +13,63 @@ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themab
|
|
|
13
13
|
|
|
14
14
|
const chip = css`
|
|
15
15
|
:host {
|
|
16
|
-
display: inline-flex;
|
|
17
|
-
align-items: center;
|
|
18
|
-
align-self: center;
|
|
19
|
-
font-family: var(--lumo-font-family);
|
|
20
16
|
font-size: var(--lumo-font-size-xxs);
|
|
21
17
|
line-height: 1;
|
|
22
|
-
padding: 0.3125em
|
|
18
|
+
padding: 0.3125em calc(0.5em + var(--lumo-border-radius-s) / 4);
|
|
19
|
+
color: var(--lumo-body-text-color);
|
|
23
20
|
border-radius: var(--lumo-border-radius-s);
|
|
24
|
-
border-radius: var(--lumo-border-radius);
|
|
25
21
|
background-color: var(--lumo-contrast-20pct);
|
|
26
22
|
cursor: var(--lumo-clickable-cursor);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
:host(:not([part~='overflow'])) {
|
|
26
|
+
padding-inline-end: 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
:host([part~='overflow']) {
|
|
30
|
+
position: relative;
|
|
31
|
+
min-width: var(--lumo-size-xxs);
|
|
32
|
+
margin-inline-start: var(--lumo-space-s);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
:host([part~='overflow'])::before,
|
|
36
|
+
:host([part~='overflow'])::after {
|
|
37
|
+
position: absolute;
|
|
38
|
+
content: '';
|
|
39
|
+
width: 3px;
|
|
40
|
+
height: calc(1.875em - 1px);
|
|
41
|
+
border-left: 2px solid;
|
|
42
|
+
border-radius: 4px 0 0 4px;
|
|
43
|
+
border-color: var(--lumo-contrast-30pct);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
:host([part~='overflow'])::before {
|
|
47
|
+
left: -4px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
:host([part~='overflow'])::after {
|
|
51
|
+
left: -8px;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
:host([part~='overflow-two']) {
|
|
55
|
+
margin-inline-start: calc(var(--lumo-space-s) / 2);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
:host([part~='overflow-two'])::after {
|
|
59
|
+
display: none;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
:host([part~='overflow-one']) {
|
|
63
|
+
margin-inline-start: 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
:host([part~='overflow-one'])::before,
|
|
67
|
+
:host([part~='overflow-one'])::after {
|
|
68
|
+
display: none;
|
|
30
69
|
}
|
|
31
70
|
|
|
32
71
|
[part='label'] {
|
|
33
|
-
color: var(--lumo-body-text-color);
|
|
34
72
|
font-weight: 500;
|
|
35
|
-
overflow: hidden;
|
|
36
|
-
text-overflow: ellipsis;
|
|
37
73
|
line-height: 1.25;
|
|
38
74
|
}
|
|
39
75
|
|
|
@@ -43,8 +79,8 @@ const chip = css`
|
|
|
43
79
|
justify-content: center;
|
|
44
80
|
margin-top: -0.3125em;
|
|
45
81
|
margin-bottom: -0.3125em;
|
|
46
|
-
width:
|
|
47
|
-
height:
|
|
82
|
+
width: 1.25em;
|
|
83
|
+
height: 1.25em;
|
|
48
84
|
font-size: 1.5em;
|
|
49
85
|
}
|
|
50
86
|
|
|
@@ -11,20 +11,57 @@ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themab
|
|
|
11
11
|
|
|
12
12
|
const chip = css`
|
|
13
13
|
:host {
|
|
14
|
-
display: flex;
|
|
15
|
-
align-items: center;
|
|
16
|
-
align-self: center;
|
|
17
|
-
box-sizing: border-box;
|
|
18
14
|
height: 1.25rem;
|
|
19
15
|
margin-inline-end: 0.25rem;
|
|
20
16
|
padding-inline-start: 0.5rem;
|
|
21
17
|
border-radius: 4px;
|
|
22
18
|
background-color: hsla(214, 53%, 23%, 0.1);
|
|
23
19
|
cursor: default;
|
|
24
|
-
white-space: nowrap;
|
|
25
20
|
font-family: var(--material-font-family);
|
|
26
21
|
}
|
|
27
22
|
|
|
23
|
+
:host([part~='overflow']) {
|
|
24
|
+
position: relative;
|
|
25
|
+
margin-inline-start: 0.5rem;
|
|
26
|
+
padding-inline-end: 0.5rem;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
:host([part~='overflow'])::before,
|
|
30
|
+
:host([part~='overflow'])::after {
|
|
31
|
+
position: absolute;
|
|
32
|
+
content: '';
|
|
33
|
+
width: 3px;
|
|
34
|
+
height: 20px;
|
|
35
|
+
border-left: 2px solid;
|
|
36
|
+
border-radius: 4px 0 0 4px;
|
|
37
|
+
border-color: hsla(214, 53%, 23%, 0.1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
:host([part~='overflow'])::before {
|
|
41
|
+
left: -4px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
:host([part~='overflow'])::after {
|
|
45
|
+
left: -8px;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
:host([part~='overflow-two']) {
|
|
49
|
+
margin-inline-start: 0.25rem;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
:host([part~='overflow-two'])::after {
|
|
53
|
+
display: none;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
:host([part~='overflow-one']) {
|
|
57
|
+
margin-inline-start: 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
:host([part~='overflow-one'])::before,
|
|
61
|
+
:host([part~='overflow-one'])::after {
|
|
62
|
+
display: none;
|
|
63
|
+
}
|
|
64
|
+
|
|
28
65
|
[part='label'] {
|
|
29
66
|
font-size: var(--material-caption-font-size);
|
|
30
67
|
line-height: 1;
|