@vaadin/combo-box 23.1.2 → 23.2.0-dev.48e5e3967
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 +15 -15
- package/src/vaadin-combo-box-data-provider-mixin.js +38 -38
- package/src/vaadin-combo-box-light.d.ts +3 -1
- package/src/vaadin-combo-box-light.js +14 -13
- package/src/vaadin-combo-box-mixin.d.ts +5 -7
- package/src/vaadin-combo-box-mixin.js +293 -128
- package/src/vaadin-combo-box-overlay.js +1 -3
- package/src/vaadin-combo-box-scroller.js +15 -3
- package/src/vaadin-combo-box.d.ts +1 -0
- package/src/vaadin-combo-box.js +13 -13
- package/src/vaadin-combo-box-dropdown.js +0 -287
|
@@ -52,9 +52,7 @@ export class ComboBoxOverlay extends PositionMixin(OverlayElement) {
|
|
|
52
52
|
connectedCallback() {
|
|
53
53
|
super.connectedCallback();
|
|
54
54
|
|
|
55
|
-
const
|
|
56
|
-
const comboBox = dropdown && dropdown.getRootNode().host;
|
|
57
|
-
this._comboBox = comboBox;
|
|
55
|
+
const comboBox = this._comboBox;
|
|
58
56
|
|
|
59
57
|
const hostDir = comboBox && comboBox.getAttribute('dir');
|
|
60
58
|
if (hostDir) {
|
|
@@ -4,6 +4,7 @@
|
|
|
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';
|
|
7
|
+
import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
|
|
7
8
|
import { Virtualizer } from '@vaadin/component-base/src/virtualizer.js';
|
|
8
9
|
import { ComboBoxPlaceholder } from './vaadin-combo-box-placeholder.js';
|
|
9
10
|
|
|
@@ -90,6 +91,7 @@ export class ComboBoxScroller extends PolymerElement {
|
|
|
90
91
|
*/
|
|
91
92
|
selectedItem: {
|
|
92
93
|
type: Object,
|
|
94
|
+
observer: '__selectedItemChanged',
|
|
93
95
|
},
|
|
94
96
|
|
|
95
97
|
/**
|
|
@@ -145,6 +147,9 @@ export class ComboBoxScroller extends PolymerElement {
|
|
|
145
147
|
ready() {
|
|
146
148
|
super.ready();
|
|
147
149
|
|
|
150
|
+
// Ensure every instance has unique ID
|
|
151
|
+
this.id = `${this.localName}-${generateUniqueId()}`;
|
|
152
|
+
|
|
148
153
|
// Allow extensions to customize tag name for the items
|
|
149
154
|
this.__hostTagName = this.constructor.is.replace('-scroller', '');
|
|
150
155
|
|
|
@@ -218,7 +223,7 @@ export class ComboBoxScroller extends PolymerElement {
|
|
|
218
223
|
|
|
219
224
|
/** @private */
|
|
220
225
|
__isItemFocused(focusedIndex, itemIndex) {
|
|
221
|
-
return focusedIndex === itemIndex;
|
|
226
|
+
return !this.loading && focusedIndex === itemIndex;
|
|
222
227
|
}
|
|
223
228
|
|
|
224
229
|
/** @private */
|
|
@@ -243,12 +248,19 @@ export class ComboBoxScroller extends PolymerElement {
|
|
|
243
248
|
}
|
|
244
249
|
|
|
245
250
|
/** @private */
|
|
246
|
-
__loadingChanged(
|
|
247
|
-
if (this.__virtualizer
|
|
251
|
+
__loadingChanged() {
|
|
252
|
+
if (this.__virtualizer) {
|
|
248
253
|
setTimeout(() => this.requestContentUpdate());
|
|
249
254
|
}
|
|
250
255
|
}
|
|
251
256
|
|
|
257
|
+
/** @private */
|
|
258
|
+
__selectedItemChanged() {
|
|
259
|
+
if (this.__virtualizer) {
|
|
260
|
+
this.requestContentUpdate();
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
252
264
|
/** @private */
|
|
253
265
|
__focusedIndexChanged(index, oldIndex) {
|
|
254
266
|
if (!this.__virtualizer) {
|
|
@@ -165,6 +165,7 @@ export interface ComboBoxEventMap<TItem> extends HTMLElementEventMap {
|
|
|
165
165
|
* Custom property | Description | Default
|
|
166
166
|
* ----------------------------------------|----------------------------|---------
|
|
167
167
|
* `--vaadin-field-default-width` | Default width of the field | `12em`
|
|
168
|
+
* `--vaadin-combo-box-overlay-width` | Width of the overlay | `auto`
|
|
168
169
|
* `--vaadin-combo-box-overlay-max-height` | Max height of the overlay | `65vh`
|
|
169
170
|
*
|
|
170
171
|
* `<vaadin-combo-box>` provides the same set of shadow DOM parts and state attributes as `<vaadin-text-field>`.
|
package/src/vaadin-combo-box.js
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import '@vaadin/input-container/src/vaadin-input-container.js';
|
|
7
|
-
import './vaadin-combo-box-
|
|
7
|
+
import './vaadin-combo-box-item.js';
|
|
8
|
+
import './vaadin-combo-box-overlay.js';
|
|
9
|
+
import './vaadin-combo-box-scroller.js';
|
|
8
10
|
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
9
11
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
10
12
|
import { InputControlMixin } from '@vaadin/field-base/src/input-control-mixin.js';
|
|
@@ -102,6 +104,7 @@ registerStyles('vaadin-combo-box', inputFieldShared, { moduleId: 'vaadin-combo-b
|
|
|
102
104
|
* Custom property | Description | Default
|
|
103
105
|
* ----------------------------------------|----------------------------|---------
|
|
104
106
|
* `--vaadin-field-default-width` | Default width of the field | `12em`
|
|
107
|
+
* `--vaadin-combo-box-overlay-width` | Width of the overlay | `auto`
|
|
105
108
|
* `--vaadin-combo-box-overlay-max-height` | Max height of the overlay | `65vh`
|
|
106
109
|
*
|
|
107
110
|
* `<vaadin-combo-box>` provides the same set of shadow DOM parts and state attributes as `<vaadin-text-field>`.
|
|
@@ -196,19 +199,16 @@ class ComboBox extends ComboBoxDataProviderMixin(
|
|
|
196
199
|
</div>
|
|
197
200
|
</div>
|
|
198
201
|
|
|
199
|
-
<vaadin-combo-box-
|
|
200
|
-
id="
|
|
201
|
-
|
|
202
|
-
|
|
202
|
+
<vaadin-combo-box-overlay
|
|
203
|
+
id="overlay"
|
|
204
|
+
hidden$="[[_isOverlayHidden(filteredItems, loading)]]"
|
|
205
|
+
opened="[[_overlayOpened]]"
|
|
206
|
+
loading$="[[loading]]"
|
|
207
|
+
theme$="[[_theme]]"
|
|
203
208
|
position-target="[[_positionTarget]]"
|
|
204
|
-
|
|
209
|
+
no-vertical-overlap
|
|
205
210
|
restore-focus-node="[[inputElement]]"
|
|
206
|
-
|
|
207
|
-
_item-id-path="[[itemIdPath]]"
|
|
208
|
-
_item-label-path="[[itemLabelPath]]"
|
|
209
|
-
loading="[[loading]]"
|
|
210
|
-
theme="[[_theme]]"
|
|
211
|
-
></vaadin-combo-box-dropdown>
|
|
211
|
+
></vaadin-combo-box-overlay>
|
|
212
212
|
`;
|
|
213
213
|
}
|
|
214
214
|
|
|
@@ -273,7 +273,7 @@ class ComboBox extends ComboBoxDataProviderMixin(
|
|
|
273
273
|
*/
|
|
274
274
|
_shouldRemoveFocus(event) {
|
|
275
275
|
// Do not blur when focus moves to the overlay
|
|
276
|
-
if (event.relatedTarget === this.$.
|
|
276
|
+
if (event.relatedTarget === this.$.overlay) {
|
|
277
277
|
event.composedPath()[0].focus();
|
|
278
278
|
return false;
|
|
279
279
|
}
|
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright (c) 2015 - 2022 Vaadin Ltd.
|
|
4
|
-
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
-
*/
|
|
6
|
-
import './vaadin-combo-box-item.js';
|
|
7
|
-
import './vaadin-combo-box-overlay.js';
|
|
8
|
-
import './vaadin-combo-box-scroller.js';
|
|
9
|
-
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Element for internal use only.
|
|
13
|
-
*
|
|
14
|
-
* @extends HTMLElement
|
|
15
|
-
* @private
|
|
16
|
-
*/
|
|
17
|
-
export class ComboBoxDropdown extends PolymerElement {
|
|
18
|
-
static get is() {
|
|
19
|
-
return 'vaadin-combo-box-dropdown';
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
static get template() {
|
|
23
|
-
return html`
|
|
24
|
-
<vaadin-combo-box-overlay
|
|
25
|
-
id="overlay"
|
|
26
|
-
hidden$="[[_isOverlayHidden(_items.*, loading)]]"
|
|
27
|
-
loading$="[[loading]]"
|
|
28
|
-
opened="{{_overlayOpened}}"
|
|
29
|
-
theme$="[[theme]]"
|
|
30
|
-
position-target="[[positionTarget]]"
|
|
31
|
-
no-vertical-overlap
|
|
32
|
-
restore-focus-on-close="[[restoreFocusOnClose]]"
|
|
33
|
-
restore-focus-node="[[restoreFocusNode]]"
|
|
34
|
-
></vaadin-combo-box-overlay>
|
|
35
|
-
`;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
static get properties() {
|
|
39
|
-
return {
|
|
40
|
-
/**
|
|
41
|
-
* True if the combo-box has been activate by the user.
|
|
42
|
-
* The actual opened state depends on whether the dropdown has items.
|
|
43
|
-
*/
|
|
44
|
-
opened: Boolean,
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* The element to position/align the dropdown by.
|
|
48
|
-
*/
|
|
49
|
-
positionTarget: {
|
|
50
|
-
type: Object,
|
|
51
|
-
},
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Custom function for rendering the content of the `<vaadin-combo-box-item>` propagated from the combo box element.
|
|
55
|
-
*/
|
|
56
|
-
renderer: Function,
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* `true` when new items are being loaded.
|
|
60
|
-
*/
|
|
61
|
-
loading: {
|
|
62
|
-
type: Boolean,
|
|
63
|
-
value: false,
|
|
64
|
-
reflectToAttribute: true,
|
|
65
|
-
},
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Used to propagate the `theme` attribute from the host element.
|
|
69
|
-
*/
|
|
70
|
-
theme: String,
|
|
71
|
-
|
|
72
|
-
_selectedItem: {
|
|
73
|
-
type: Object,
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
_items: {
|
|
77
|
-
type: Array,
|
|
78
|
-
},
|
|
79
|
-
|
|
80
|
-
_focusedIndex: {
|
|
81
|
-
type: Number,
|
|
82
|
-
value: -1,
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
focusedItem: {
|
|
86
|
-
type: String,
|
|
87
|
-
computed: '_getFocusedItem(_focusedIndex)',
|
|
88
|
-
},
|
|
89
|
-
|
|
90
|
-
_itemLabelPath: {
|
|
91
|
-
type: String,
|
|
92
|
-
value: 'label',
|
|
93
|
-
},
|
|
94
|
-
|
|
95
|
-
_itemValuePath: {
|
|
96
|
-
type: String,
|
|
97
|
-
value: 'value',
|
|
98
|
-
},
|
|
99
|
-
|
|
100
|
-
_scroller: Object,
|
|
101
|
-
|
|
102
|
-
_itemIdPath: String,
|
|
103
|
-
|
|
104
|
-
_overlayOpened: {
|
|
105
|
-
type: Boolean,
|
|
106
|
-
observer: '_openedChanged',
|
|
107
|
-
},
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
static get observers() {
|
|
112
|
-
return [
|
|
113
|
-
'_openedOrItemsChanged(opened, _items, loading)',
|
|
114
|
-
'__updateScroller(_scroller, _items, opened, loading, _selectedItem, _itemIdPath, _focusedIndex, renderer, theme)',
|
|
115
|
-
];
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
constructor() {
|
|
119
|
-
super();
|
|
120
|
-
|
|
121
|
-
// Ensure every instance has unique ID
|
|
122
|
-
const uniqueId = (ComboBoxDropdown._uniqueId = 1 + ComboBoxDropdown._uniqueId || 0);
|
|
123
|
-
this.scrollerId = `${this.localName}-scroller-${uniqueId}`;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
ready() {
|
|
127
|
-
super.ready();
|
|
128
|
-
|
|
129
|
-
// Allow extensions to customize tag name for the items
|
|
130
|
-
this.__hostTagName = this.constructor.is.replace('-dropdown', '');
|
|
131
|
-
|
|
132
|
-
const overlay = this.$.overlay;
|
|
133
|
-
const scrollerTag = `${this.__hostTagName}-scroller`;
|
|
134
|
-
|
|
135
|
-
overlay.renderer = (root) => {
|
|
136
|
-
if (!root.firstChild) {
|
|
137
|
-
const scroller = document.createElement(scrollerTag);
|
|
138
|
-
root.appendChild(scroller);
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
// Ensure the scroller is rendered
|
|
143
|
-
overlay.requestContentUpdate();
|
|
144
|
-
|
|
145
|
-
this._scroller = overlay.content.querySelector(scrollerTag);
|
|
146
|
-
this._scroller.id = this.scrollerId;
|
|
147
|
-
|
|
148
|
-
this._scroller.getItemLabel = this.getItemLabel.bind(this);
|
|
149
|
-
this._scroller.comboBox = this.getRootNode().host;
|
|
150
|
-
|
|
151
|
-
this._scroller.addEventListener('selection-changed', (e) => this._forwardScrollerEvent(e));
|
|
152
|
-
this._scroller.addEventListener('index-requested', (e) => this._forwardScrollerEvent(e));
|
|
153
|
-
|
|
154
|
-
overlay.addEventListener('touchend', (e) => this._fireTouchAction(e));
|
|
155
|
-
overlay.addEventListener('touchmove', (e) => this._fireTouchAction(e));
|
|
156
|
-
|
|
157
|
-
// Prevent blurring the input when clicking inside the overlay.
|
|
158
|
-
overlay.addEventListener('mousedown', (e) => e.preventDefault());
|
|
159
|
-
|
|
160
|
-
// Preventing the default modal behaviour of the overlay on input clicking
|
|
161
|
-
overlay.addEventListener('vaadin-overlay-outside-click', (e) => {
|
|
162
|
-
e.preventDefault();
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
disconnectedCallback() {
|
|
167
|
-
super.disconnectedCallback();
|
|
168
|
-
|
|
169
|
-
// Making sure the overlay is closed and removed from DOM after detaching the dropdown.
|
|
170
|
-
this._overlayOpened = false;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
_fireTouchAction(sourceEvent) {
|
|
174
|
-
this.dispatchEvent(
|
|
175
|
-
new CustomEvent('vaadin-overlay-touch-action', {
|
|
176
|
-
detail: { sourceEvent },
|
|
177
|
-
}),
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
_forwardScrollerEvent(event) {
|
|
182
|
-
this.dispatchEvent(new CustomEvent(event.type, { detail: event.detail }));
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
_openedChanged(opened, wasOpened) {
|
|
186
|
-
if (opened) {
|
|
187
|
-
this._scroller.style.maxHeight =
|
|
188
|
-
getComputedStyle(this).getPropertyValue(`--${this.__hostTagName}-overlay-max-height`) || '65vh';
|
|
189
|
-
|
|
190
|
-
this.dispatchEvent(new CustomEvent('vaadin-combo-box-dropdown-opened', { bubbles: true, composed: true }));
|
|
191
|
-
} else if (wasOpened && !this.__emptyItems) {
|
|
192
|
-
this.dispatchEvent(new CustomEvent('vaadin-combo-box-dropdown-closed', { bubbles: true, composed: true }));
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
_openedOrItemsChanged(opened, items, loading) {
|
|
197
|
-
// See https://github.com/vaadin/vaadin-combo-box/pull/964
|
|
198
|
-
const hasItems = items && items.length;
|
|
199
|
-
if (!hasItems) {
|
|
200
|
-
this.__emptyItems = true;
|
|
201
|
-
}
|
|
202
|
-
this._overlayOpened = !!(opened && (loading || hasItems));
|
|
203
|
-
this.__emptyItems = false;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
_getFocusedItem(focusedIndex) {
|
|
207
|
-
if (focusedIndex >= 0) {
|
|
208
|
-
return this._items[focusedIndex];
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Gets the index of the item with the provided label.
|
|
214
|
-
* @return {number}
|
|
215
|
-
*/
|
|
216
|
-
indexOfLabel(label) {
|
|
217
|
-
if (this._items && label) {
|
|
218
|
-
for (let i = 0; i < this._items.length; i++) {
|
|
219
|
-
if (this.getItemLabel(this._items[i]).toString().toLowerCase() === label.toString().toLowerCase()) {
|
|
220
|
-
return i;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
return -1;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Gets the label string for the item based on the `_itemLabelPath`.
|
|
230
|
-
* @return {string}
|
|
231
|
-
*/
|
|
232
|
-
getItemLabel(item, itemLabelPath) {
|
|
233
|
-
itemLabelPath = itemLabelPath || this._itemLabelPath;
|
|
234
|
-
let label = item && itemLabelPath ? this.get(itemLabelPath, item) : undefined;
|
|
235
|
-
if (label === undefined || label === null) {
|
|
236
|
-
label = item ? item.toString() : '';
|
|
237
|
-
}
|
|
238
|
-
return label;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
_scrollIntoView(index) {
|
|
242
|
-
if (!this._scroller) {
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
this._scroller.scrollIntoView(index);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
adjustScrollPosition() {
|
|
249
|
-
if (this.opened && this._items) {
|
|
250
|
-
this._scrollIntoView(this._focusedIndex);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// eslint-disable-next-line max-params
|
|
255
|
-
__updateScroller(scroller, items, opened, loading, selectedItem, itemIdPath, focusedIndex, renderer, theme) {
|
|
256
|
-
if (scroller) {
|
|
257
|
-
scroller.setProperties({
|
|
258
|
-
items: opened ? items : [],
|
|
259
|
-
opened,
|
|
260
|
-
loading,
|
|
261
|
-
selectedItem,
|
|
262
|
-
itemIdPath,
|
|
263
|
-
focusedIndex,
|
|
264
|
-
renderer,
|
|
265
|
-
theme,
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
_isOverlayHidden() {
|
|
271
|
-
return !this.loading && !(this._items && this._items.length);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Fired after the `vaadin-combo-box-dropdown` opens.
|
|
276
|
-
*
|
|
277
|
-
* @event vaadin-combo-box-dropdown-opened
|
|
278
|
-
*/
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Fired after the `vaadin-combo-box-dropdown` closes.
|
|
282
|
-
*
|
|
283
|
-
* @event vaadin-combo-box-dropdown-closed
|
|
284
|
-
*/
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
customElements.define(ComboBoxDropdown.is, ComboBoxDropdown);
|