@vaadin/multi-select-combo-box 23.1.0-alpha3 → 23.1.0-beta2
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 +17 -8
- package/src/vaadin-multi-select-combo-box-container.js +4 -5
- package/src/vaadin-multi-select-combo-box-internal.js +93 -5
- package/src/vaadin-multi-select-combo-box-overlay.js +1 -1
- package/src/vaadin-multi-select-combo-box-scroller.js +24 -0
- package/src/vaadin-multi-select-combo-box.d.ts +47 -8
- package/src/vaadin-multi-select-combo-box.js +331 -71
- package/theme/lumo/vaadin-multi-select-combo-box-chip-styles.js +20 -9
- package/theme/lumo/vaadin-multi-select-combo-box-styles.js +27 -3
- package/theme/material/vaadin-multi-select-combo-box-chip-styles.js +20 -21
- package/theme/material/vaadin-multi-select-combo-box-styles.js +22 -3
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-beta2",
|
|
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-beta2",
|
|
37
|
+
"@vaadin/component-base": "23.1.0-beta2",
|
|
38
|
+
"@vaadin/field-base": "23.1.0-beta2",
|
|
39
|
+
"@vaadin/input-container": "23.1.0-beta2",
|
|
40
|
+
"@vaadin/vaadin-lumo-styles": "23.1.0-beta2",
|
|
41
|
+
"@vaadin/vaadin-material-styles": "23.1.0-beta2",
|
|
42
|
+
"@vaadin/vaadin-themable-mixin": "23.1.0-beta2"
|
|
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": "f11f9245a0b5e6bf912725a501c27c24b74e7c8d"
|
|
50
50
|
}
|
|
@@ -30,13 +30,23 @@ 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
|
-
type: String
|
|
44
|
+
type: String,
|
|
35
45
|
},
|
|
36
46
|
|
|
37
47
|
item: {
|
|
38
|
-
type: Object
|
|
39
|
-
}
|
|
48
|
+
type: Object,
|
|
49
|
+
},
|
|
40
50
|
};
|
|
41
51
|
}
|
|
42
52
|
|
|
@@ -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>
|
|
@@ -73,11 +82,11 @@ class MultiSelectComboBoxChip extends ThemableMixin(PolymerElement) {
|
|
|
73
82
|
this.dispatchEvent(
|
|
74
83
|
new CustomEvent('item-removed', {
|
|
75
84
|
detail: {
|
|
76
|
-
item: this.item
|
|
85
|
+
item: this.item,
|
|
77
86
|
},
|
|
78
87
|
bubbles: true,
|
|
79
|
-
composed: true
|
|
80
|
-
})
|
|
88
|
+
composed: true,
|
|
89
|
+
}),
|
|
81
90
|
);
|
|
82
91
|
}
|
|
83
92
|
}
|
|
@@ -9,15 +9,14 @@ 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
|
{
|
|
19
|
-
moduleId: 'vaadin-multi-select-combo-box-container-styles'
|
|
20
|
-
}
|
|
18
|
+
moduleId: 'vaadin-multi-select-combo-box-container-styles',
|
|
19
|
+
},
|
|
21
20
|
);
|
|
22
21
|
|
|
23
22
|
let memoizedTemplate;
|
|
@@ -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]);
|
|
@@ -51,8 +51,8 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
|
|
|
51
51
|
static get properties() {
|
|
52
52
|
return {
|
|
53
53
|
_target: {
|
|
54
|
-
type: Object
|
|
55
|
-
}
|
|
54
|
+
type: Object,
|
|
55
|
+
},
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -65,6 +65,17 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
|
|
|
65
65
|
return this.querySelector('[part="clear-button"]');
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Override method inherited from the combo-box
|
|
70
|
+
* to allow opening dropdown when readonly.
|
|
71
|
+
* @override
|
|
72
|
+
*/
|
|
73
|
+
open() {
|
|
74
|
+
if (!this.disabled && !(this.readonly && this._getOverlayItems().length === 0)) {
|
|
75
|
+
this.opened = true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
68
79
|
/**
|
|
69
80
|
* @protected
|
|
70
81
|
* @override
|
|
@@ -113,6 +124,11 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
|
|
|
113
124
|
* @override
|
|
114
125
|
*/
|
|
115
126
|
_closeOrCommit() {
|
|
127
|
+
if (this.readonly) {
|
|
128
|
+
this.close();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
116
132
|
if (this.__enterPressed) {
|
|
117
133
|
this.__enterPressed = null;
|
|
118
134
|
|
|
@@ -127,6 +143,73 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
|
|
|
127
143
|
super._closeOrCommit();
|
|
128
144
|
}
|
|
129
145
|
|
|
146
|
+
/**
|
|
147
|
+
* Override method inherited from the combo-box
|
|
148
|
+
* to not update focused item when readonly.
|
|
149
|
+
* @protected
|
|
150
|
+
* @override
|
|
151
|
+
*/
|
|
152
|
+
_onArrowDown() {
|
|
153
|
+
if (!this.readonly) {
|
|
154
|
+
super._onArrowDown();
|
|
155
|
+
} else if (!this.opened) {
|
|
156
|
+
this.open();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Override method inherited from the combo-box
|
|
162
|
+
* to not update focused item when readonly.
|
|
163
|
+
* @protected
|
|
164
|
+
* @override
|
|
165
|
+
*/
|
|
166
|
+
_onArrowUp() {
|
|
167
|
+
if (!this.readonly) {
|
|
168
|
+
super._onArrowUp();
|
|
169
|
+
} else if (!this.opened) {
|
|
170
|
+
this.open();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Override method inherited from the combo-box
|
|
176
|
+
* to close dropdown on blur when readonly.
|
|
177
|
+
* @param {FocusEvent} event
|
|
178
|
+
* @protected
|
|
179
|
+
* @override
|
|
180
|
+
*/
|
|
181
|
+
_onFocusout(event) {
|
|
182
|
+
// Disable combo-box logic that updates selectedItem
|
|
183
|
+
// based on the overlay focused index on input blur
|
|
184
|
+
this._ignoreCommitValue = true;
|
|
185
|
+
|
|
186
|
+
super._onFocusout(event);
|
|
187
|
+
|
|
188
|
+
if (this.readonly && !this._closeOnBlurIsPrevented) {
|
|
189
|
+
this.close();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Override method inherited from the combo-box
|
|
195
|
+
* to not commit an already selected item again
|
|
196
|
+
* on blur, which would result in un-selecting.
|
|
197
|
+
* @protected
|
|
198
|
+
* @override
|
|
199
|
+
*/
|
|
200
|
+
_detectAndDispatchChange() {
|
|
201
|
+
if (this._ignoreCommitValue) {
|
|
202
|
+
this._ignoreCommitValue = false;
|
|
203
|
+
|
|
204
|
+
// Reset internal combo-box state
|
|
205
|
+
this.selectedItem = null;
|
|
206
|
+
this._inputElementValue = '';
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
super._detectAndDispatchChange();
|
|
211
|
+
}
|
|
212
|
+
|
|
130
213
|
/**
|
|
131
214
|
* @param {CustomEvent} event
|
|
132
215
|
* @protected
|
|
@@ -135,6 +218,11 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
|
|
|
135
218
|
_overlaySelectedItemChanged(event) {
|
|
136
219
|
event.stopPropagation();
|
|
137
220
|
|
|
221
|
+
// Do not un-select on click when readonly
|
|
222
|
+
if (this.readonly) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
138
226
|
if (event.detail.item instanceof ComboBoxPlaceholder) {
|
|
139
227
|
return;
|
|
140
228
|
}
|
|
@@ -143,9 +231,9 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
|
|
|
143
231
|
this.dispatchEvent(
|
|
144
232
|
new CustomEvent('combo-box-item-selected', {
|
|
145
233
|
detail: {
|
|
146
|
-
item: event.detail.item
|
|
147
|
-
}
|
|
148
|
-
})
|
|
234
|
+
item: event.detail.item,
|
|
235
|
+
},
|
|
236
|
+
}),
|
|
149
237
|
);
|
|
150
238
|
}
|
|
151
239
|
}
|
|
@@ -17,15 +17,39 @@ 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) {
|
|
23
36
|
return false;
|
|
24
37
|
}
|
|
25
38
|
|
|
39
|
+
if (this.comboBox.readonly) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
|
|
26
43
|
const host = this.comboBox.getRootNode().host;
|
|
27
44
|
return host._findIndex(item, host.selectedItems, itemIdPath) > -1;
|
|
28
45
|
}
|
|
46
|
+
|
|
47
|
+
/** @private */
|
|
48
|
+
__updateElement(el, index) {
|
|
49
|
+
super.__updateElement(el, index);
|
|
50
|
+
|
|
51
|
+
el.toggleAttribute('readonly', this.comboBox.readonly);
|
|
52
|
+
}
|
|
29
53
|
}
|
|
30
54
|
|
|
31
55
|
customElements.define(MultiSelectComboBoxScroller.is, MultiSelectComboBoxScroller);
|
|
@@ -20,6 +20,14 @@ 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
|
+
focused: string;
|
|
26
|
+
selected: string;
|
|
27
|
+
deselected: string;
|
|
28
|
+
total: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
/**
|
|
24
32
|
* Fired when the user commits a value change.
|
|
25
33
|
*/
|
|
@@ -30,7 +38,7 @@ export type MultiSelectComboBoxChangeEvent<TItem> = Event & {
|
|
|
30
38
|
/**
|
|
31
39
|
* Fired when the user sets a custom value.
|
|
32
40
|
*/
|
|
33
|
-
export type
|
|
41
|
+
export type MultiSelectComboBoxCustomValueSetEvent = CustomEvent<string>;
|
|
34
42
|
|
|
35
43
|
/**
|
|
36
44
|
* Fired when the `filter` property changes.
|
|
@@ -50,7 +58,7 @@ export type MultiSelectComboBoxSelectedItemsChangedEvent<TItem> = CustomEvent<{
|
|
|
50
58
|
export interface MultiSelectComboBoxEventMap<TItem> extends HTMLElementEventMap {
|
|
51
59
|
change: MultiSelectComboBoxChangeEvent<TItem>;
|
|
52
60
|
|
|
53
|
-
'custom-
|
|
61
|
+
'custom-value-set': MultiSelectComboBoxCustomValueSetEvent;
|
|
54
62
|
|
|
55
63
|
'filter-changed': MultiSelectComboBoxFilterChangedEvent;
|
|
56
64
|
|
|
@@ -79,6 +87,7 @@ export interface MultiSelectComboBoxEventMap<TItem> extends HTMLElementEventMap
|
|
|
79
87
|
*
|
|
80
88
|
* Part name | Description
|
|
81
89
|
* -----------------------|----------------
|
|
90
|
+
* `chips` | The element that wraps chips for selected items
|
|
82
91
|
* `chip` | Chip shown for every selected item
|
|
83
92
|
* `label` | The label element
|
|
84
93
|
* `input-field` | The element that wraps prefix, value and suffix
|
|
@@ -112,7 +121,6 @@ export interface MultiSelectComboBoxEventMap<TItem> extends HTMLElementEventMap
|
|
|
112
121
|
* -----------------------------------------------------|----------------------------|--------
|
|
113
122
|
* `--vaadin-field-default-width` | Default width of the field | `12em`
|
|
114
123
|
* `--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
124
|
* `--vaadin-multi-select-combo-box-input-min-width` | Min width of the input | `4em`
|
|
117
125
|
*
|
|
118
126
|
* ### Internal components
|
|
@@ -130,7 +138,7 @@ export interface MultiSelectComboBoxEventMap<TItem> extends HTMLElementEventMap
|
|
|
130
138
|
* See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
|
|
131
139
|
*
|
|
132
140
|
* @fires {Event} change - Fired when the user commits a value change.
|
|
133
|
-
* @fires {CustomEvent} custom-
|
|
141
|
+
* @fires {CustomEvent} custom-value-set - Fired when the user sets a custom value.
|
|
134
142
|
* @fires {CustomEvent} filter-changed - Fired when the `filter` property changes.
|
|
135
143
|
* @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
|
|
136
144
|
* @fires {CustomEvent} selected-items-changed - Fired when the `selectedItems` property changes.
|
|
@@ -138,9 +146,9 @@ export interface MultiSelectComboBoxEventMap<TItem> extends HTMLElementEventMap
|
|
|
138
146
|
declare class MultiSelectComboBox<TItem = ComboBoxDefaultItem> extends HTMLElement {
|
|
139
147
|
/**
|
|
140
148
|
* When true, the user can input a value that is not present in the items list.
|
|
141
|
-
* @attr {boolean} allow-custom-
|
|
149
|
+
* @attr {boolean} allow-custom-value
|
|
142
150
|
*/
|
|
143
|
-
|
|
151
|
+
allowCustomValue: boolean;
|
|
144
152
|
|
|
145
153
|
/**
|
|
146
154
|
* Set true to prevent the overlay from opening automatically.
|
|
@@ -199,6 +207,30 @@ declare class MultiSelectComboBox<TItem = ComboBoxDefaultItem> extends HTMLEleme
|
|
|
199
207
|
*/
|
|
200
208
|
itemValuePath: string;
|
|
201
209
|
|
|
210
|
+
/**
|
|
211
|
+
* The object used to localize this component.
|
|
212
|
+
* To change the default localization, replace the entire
|
|
213
|
+
* _i18n_ object or just the property you want to modify.
|
|
214
|
+
*
|
|
215
|
+
* The object has the following JSON structure and default values:
|
|
216
|
+
* ```
|
|
217
|
+
* {
|
|
218
|
+
* // Screen reader announcement on clear button click.
|
|
219
|
+
* cleared: 'Selection cleared',
|
|
220
|
+
* // Screen reader announcement when a chip is focused.
|
|
221
|
+
* focused: ' focused. Press Backspace to remove',
|
|
222
|
+
* // Screen reader announcement when item is selected.
|
|
223
|
+
* selected: 'added to selection',
|
|
224
|
+
* // Screen reader announcement when item is deselected.
|
|
225
|
+
* deselected: 'removed from selection',
|
|
226
|
+
* // Screen reader announcement of the selected items count.
|
|
227
|
+
* // {count} is replaced with the actual count of items.
|
|
228
|
+
* total: '{count} items selected',
|
|
229
|
+
* }
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
i18n: MultiSelectComboBoxI18n;
|
|
233
|
+
|
|
202
234
|
/**
|
|
203
235
|
* True if the dropdown is open, false otherwise.
|
|
204
236
|
*/
|
|
@@ -210,6 +242,13 @@ declare class MultiSelectComboBox<TItem = ComboBoxDefaultItem> extends HTMLEleme
|
|
|
210
242
|
*/
|
|
211
243
|
pageSize: number;
|
|
212
244
|
|
|
245
|
+
/**
|
|
246
|
+
* A hint to the user of what can be entered in the control.
|
|
247
|
+
* The placeholder will be only displayed in the case when
|
|
248
|
+
* there is no item selected.
|
|
249
|
+
*/
|
|
250
|
+
placeholder: string;
|
|
251
|
+
|
|
213
252
|
/**
|
|
214
253
|
* Custom function for rendering the content of every item.
|
|
215
254
|
* Receives three arguments:
|
|
@@ -232,13 +271,13 @@ declare class MultiSelectComboBox<TItem = ComboBoxDefaultItem> extends HTMLEleme
|
|
|
232
271
|
addEventListener<K extends keyof MultiSelectComboBoxEventMap<TItem>>(
|
|
233
272
|
type: K,
|
|
234
273
|
listener: (this: MultiSelectComboBox<TItem>, ev: MultiSelectComboBoxEventMap<TItem>[K]) => void,
|
|
235
|
-
options?: boolean | AddEventListenerOptions
|
|
274
|
+
options?: boolean | AddEventListenerOptions,
|
|
236
275
|
): void;
|
|
237
276
|
|
|
238
277
|
removeEventListener<K extends keyof MultiSelectComboBoxEventMap<TItem>>(
|
|
239
278
|
type: K,
|
|
240
279
|
listener: (this: MultiSelectComboBox<TItem>, ev: MultiSelectComboBoxEventMap<TItem>[K]) => void,
|
|
241
|
-
options?: boolean | EventListenerOptions
|
|
280
|
+
options?: boolean | EventListenerOptions,
|
|
242
281
|
): void;
|
|
243
282
|
}
|
|
244
283
|
|