@vaadin/combo-box 24.4.0-dev.b3e1d14600 → 24.5.0-alpha1
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/README.md +0 -1
- package/package.json +16 -14
- package/src/lit/renderer-directives.d.ts +1 -1
- package/src/lit/renderer-directives.js +1 -1
- package/src/vaadin-combo-box-data-provider-mixin.d.ts +1 -1
- package/src/vaadin-combo-box-data-provider-mixin.js +116 -120
- package/src/vaadin-combo-box-item-mixin.d.ts +1 -1
- package/src/vaadin-combo-box-item-mixin.js +2 -2
- package/src/vaadin-combo-box-item.d.ts +1 -1
- package/src/vaadin-combo-box-item.js +1 -1
- package/src/vaadin-combo-box-light-mixin.d.ts +26 -0
- package/src/vaadin-combo-box-light-mixin.js +140 -0
- package/src/vaadin-combo-box-light.d.ts +3 -8
- package/src/vaadin-combo-box-light.js +4 -128
- package/src/vaadin-combo-box-mixin.d.ts +9 -1
- package/src/vaadin-combo-box-mixin.js +112 -33
- package/src/vaadin-combo-box-overlay-mixin.d.ts +1 -1
- package/src/vaadin-combo-box-overlay-mixin.js +1 -1
- package/src/vaadin-combo-box-overlay.d.ts +1 -1
- package/src/vaadin-combo-box-overlay.js +1 -1
- package/src/vaadin-combo-box-placeholder.js +1 -1
- package/src/vaadin-combo-box-scroller-mixin.d.ts +1 -1
- package/src/vaadin-combo-box-scroller-mixin.js +65 -16
- package/src/vaadin-combo-box-scroller.d.ts +1 -1
- package/src/vaadin-combo-box-scroller.js +1 -1
- package/src/vaadin-combo-box.d.ts +1 -1
- package/src/vaadin-combo-box.js +1 -1
- package/src/vaadin-lit-combo-box-item.js +50 -0
- package/src/vaadin-lit-combo-box-light.js +58 -0
- package/src/vaadin-lit-combo-box-overlay.js +76 -0
- package/src/vaadin-lit-combo-box-scroller.js +59 -0
- package/src/vaadin-lit-combo-box.js +170 -0
- package/theme/lumo/vaadin-combo-box-item-styles.d.ts +5 -0
- package/theme/lumo/vaadin-combo-box-item-styles.js +2 -4
- package/theme/lumo/vaadin-combo-box-light.d.ts +3 -0
- package/theme/lumo/vaadin-combo-box-overlay-styles.d.ts +6 -0
- package/theme/lumo/vaadin-combo-box-styles.d.ts +2 -0
- package/theme/lumo/vaadin-combo-box.d.ts +4 -0
- package/theme/lumo/vaadin-lit-combo-box-light.d.ts +3 -0
- package/theme/lumo/vaadin-lit-combo-box-light.js +3 -0
- package/theme/lumo/vaadin-lit-combo-box.d.ts +4 -0
- package/theme/lumo/vaadin-lit-combo-box.js +4 -0
- package/theme/material/vaadin-combo-box-item-styles.d.ts +5 -0
- package/theme/material/vaadin-combo-box-light.d.ts +3 -0
- package/theme/material/vaadin-combo-box-overlay-styles.d.ts +4 -0
- package/theme/material/vaadin-combo-box-styles.d.ts +3 -0
- package/theme/material/vaadin-combo-box.d.ts +4 -0
- package/web-types.json +1210 -0
- package/web-types.lit.json +587 -0
package/README.md
CHANGED
|
@@ -5,7 +5,6 @@ A web component for choosing a value from a filterable list of options presented
|
|
|
5
5
|
[Documentation + Live Demo ↗](https://vaadin.com/docs/latest/components/combo-box)
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/@vaadin/combo-box)
|
|
8
|
-
[](https://discord.gg/PHmkCKC)
|
|
9
8
|
|
|
10
9
|
```html
|
|
11
10
|
<vaadin-combo-box
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/combo-box",
|
|
3
|
-
"version": "24.
|
|
3
|
+
"version": "24.5.0-alpha1",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -26,7 +26,9 @@
|
|
|
26
26
|
"vaadin-*.d.ts",
|
|
27
27
|
"vaadin-*.js",
|
|
28
28
|
"web-types.json",
|
|
29
|
-
"web-types.lit.json"
|
|
29
|
+
"web-types.lit.json",
|
|
30
|
+
"!vaadin-lit-*.d.ts",
|
|
31
|
+
"!vaadin-lit-*.js"
|
|
30
32
|
],
|
|
31
33
|
"keywords": [
|
|
32
34
|
"Vaadin",
|
|
@@ -38,21 +40,21 @@
|
|
|
38
40
|
"dependencies": {
|
|
39
41
|
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
40
42
|
"@polymer/polymer": "^3.0.0",
|
|
41
|
-
"@vaadin/a11y-base": "24.
|
|
42
|
-
"@vaadin/component-base": "24.
|
|
43
|
-
"@vaadin/field-base": "24.
|
|
44
|
-
"@vaadin/input-container": "24.
|
|
45
|
-
"@vaadin/item": "24.
|
|
46
|
-
"@vaadin/lit-renderer": "24.
|
|
47
|
-
"@vaadin/overlay": "24.
|
|
48
|
-
"@vaadin/vaadin-lumo-styles": "24.
|
|
49
|
-
"@vaadin/vaadin-material-styles": "24.
|
|
50
|
-
"@vaadin/vaadin-themable-mixin": "24.
|
|
43
|
+
"@vaadin/a11y-base": "24.5.0-alpha1",
|
|
44
|
+
"@vaadin/component-base": "24.5.0-alpha1",
|
|
45
|
+
"@vaadin/field-base": "24.5.0-alpha1",
|
|
46
|
+
"@vaadin/input-container": "24.5.0-alpha1",
|
|
47
|
+
"@vaadin/item": "24.5.0-alpha1",
|
|
48
|
+
"@vaadin/lit-renderer": "24.5.0-alpha1",
|
|
49
|
+
"@vaadin/overlay": "24.5.0-alpha1",
|
|
50
|
+
"@vaadin/vaadin-lumo-styles": "24.5.0-alpha1",
|
|
51
|
+
"@vaadin/vaadin-material-styles": "24.5.0-alpha1",
|
|
52
|
+
"@vaadin/vaadin-themable-mixin": "24.5.0-alpha1"
|
|
51
53
|
},
|
|
52
54
|
"devDependencies": {
|
|
53
55
|
"@esm-bundle/chai": "^4.3.4",
|
|
54
56
|
"@vaadin/testing-helpers": "^0.6.0",
|
|
55
|
-
"@vaadin/text-field": "24.
|
|
57
|
+
"@vaadin/text-field": "24.5.0-alpha1",
|
|
56
58
|
"lit": "^3.0.0",
|
|
57
59
|
"sinon": "^13.0.2"
|
|
58
60
|
},
|
|
@@ -60,5 +62,5 @@
|
|
|
60
62
|
"web-types.json",
|
|
61
63
|
"web-types.lit.json"
|
|
62
64
|
],
|
|
63
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "57806caac5468532a3b4e3dbdda730cd0fca193a"
|
|
64
66
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2017 -
|
|
3
|
+
* Copyright (c) 2017 - 2024 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import type { DirectiveResult } from 'lit/directive.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2015 -
|
|
3
|
+
* Copyright (c) 2015 - 2024 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import type { Constructor } from '@open-wc/dedupe-mixin';
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2015 -
|
|
3
|
+
* Copyright (c) 2015 - 2024 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
-
import { DataProviderController } from '@vaadin/component-base/src/data-provider-controller/data-provider-controller.js';
|
|
7
|
-
import { get } from '@vaadin/component-base/src/path-utils.js';
|
|
8
6
|
import { ComboBoxPlaceholder } from './vaadin-combo-box-placeholder.js';
|
|
9
7
|
|
|
10
8
|
/**
|
|
@@ -23,6 +21,7 @@ export const ComboBoxDataProviderMixin = (superClass) =>
|
|
|
23
21
|
type: Number,
|
|
24
22
|
value: 50,
|
|
25
23
|
observer: '_pageSizeChanged',
|
|
24
|
+
sync: true,
|
|
26
25
|
},
|
|
27
26
|
|
|
28
27
|
/**
|
|
@@ -32,6 +31,7 @@ export const ComboBoxDataProviderMixin = (superClass) =>
|
|
|
32
31
|
size: {
|
|
33
32
|
type: Number,
|
|
34
33
|
observer: '_sizeChanged',
|
|
34
|
+
sync: true,
|
|
35
35
|
},
|
|
36
36
|
|
|
37
37
|
/**
|
|
@@ -51,6 +51,14 @@ export const ComboBoxDataProviderMixin = (superClass) =>
|
|
|
51
51
|
dataProvider: {
|
|
52
52
|
type: Object,
|
|
53
53
|
observer: '_dataProviderChanged',
|
|
54
|
+
sync: true,
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
/** @private */
|
|
58
|
+
_pendingRequests: {
|
|
59
|
+
value: () => {
|
|
60
|
+
return {};
|
|
61
|
+
},
|
|
54
62
|
},
|
|
55
63
|
|
|
56
64
|
/** @private */
|
|
@@ -73,47 +81,20 @@ export const ComboBoxDataProviderMixin = (superClass) =>
|
|
|
73
81
|
];
|
|
74
82
|
}
|
|
75
83
|
|
|
76
|
-
constructor() {
|
|
77
|
-
super();
|
|
78
|
-
|
|
79
|
-
/** @type {DataProviderController} */
|
|
80
|
-
this._dataProviderController = new DataProviderController(this, {
|
|
81
|
-
size: this.size,
|
|
82
|
-
pageSize: this.pageSize,
|
|
83
|
-
getItemId: (item) => get(this.itemIdPath, item),
|
|
84
|
-
placeholder: this.__placeHolder,
|
|
85
|
-
dataProvider: this.dataProvider ? this.dataProvider.bind(this) : null,
|
|
86
|
-
dataProviderParams: () => ({ filter: this.filter }),
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
|
|
90
84
|
/** @protected */
|
|
91
85
|
ready() {
|
|
92
86
|
super.ready();
|
|
93
|
-
|
|
94
|
-
this._dataProviderController.addEventListener('page-requested', this.__onDataProviderPageRequested.bind(this));
|
|
95
|
-
this._dataProviderController.addEventListener('page-received', this.__onDataProviderPageReceived.bind(this));
|
|
96
|
-
this._dataProviderController.addEventListener('page-loaded', this.__onDataProviderPageLoaded.bind(this));
|
|
97
|
-
|
|
98
87
|
this._scroller.addEventListener('index-requested', (e) => {
|
|
99
88
|
if (!this._shouldFetchData()) {
|
|
100
89
|
return;
|
|
101
90
|
}
|
|
102
91
|
|
|
103
92
|
const index = e.detail.index;
|
|
104
|
-
const currentScrollerPos = e.detail.currentScrollerPos;
|
|
105
|
-
const allowedIndexRange = Math.floor(this.pageSize * 1.5);
|
|
106
|
-
|
|
107
|
-
// Ignores the indexes, which are being re-sent during scrolling reset,
|
|
108
|
-
// if the corresponding page is around the current scroller position.
|
|
109
|
-
// Otherwise, there might be a last pages duplicates, which cause the
|
|
110
|
-
// loading indicator hanging and blank items
|
|
111
|
-
if (this._shouldSkipIndex(index, allowedIndexRange, currentScrollerPos)) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
93
|
if (index !== undefined) {
|
|
116
|
-
this.
|
|
94
|
+
const page = this._getPageForIndex(index);
|
|
95
|
+
if (this._shouldLoadPage(page)) {
|
|
96
|
+
this._loadPage(page);
|
|
97
|
+
}
|
|
117
98
|
}
|
|
118
99
|
});
|
|
119
100
|
}
|
|
@@ -128,10 +109,11 @@ export const ComboBoxDataProviderMixin = (superClass) =>
|
|
|
128
109
|
if (this.__previousDataProviderFilter !== filter) {
|
|
129
110
|
this.__previousDataProviderFilter = filter;
|
|
130
111
|
|
|
131
|
-
this.
|
|
112
|
+
this.__keepOverlayOpened = true;
|
|
113
|
+
this._pendingRequests = {};
|
|
132
114
|
this.size = undefined;
|
|
133
115
|
this.clearCache();
|
|
134
|
-
this.
|
|
116
|
+
this.__keepOverlayOpened = false;
|
|
135
117
|
}
|
|
136
118
|
}
|
|
137
119
|
|
|
@@ -150,39 +132,74 @@ export const ComboBoxDataProviderMixin = (superClass) =>
|
|
|
150
132
|
return;
|
|
151
133
|
}
|
|
152
134
|
|
|
153
|
-
if (opened &&
|
|
154
|
-
this.
|
|
135
|
+
if (opened && this._shouldLoadPage(0)) {
|
|
136
|
+
this._loadPage(0);
|
|
155
137
|
}
|
|
156
138
|
}
|
|
157
139
|
|
|
158
140
|
/** @private */
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
);
|
|
165
|
-
}
|
|
141
|
+
_shouldLoadPage(page) {
|
|
142
|
+
if (this._forceNextRequest) {
|
|
143
|
+
this._forceNextRequest = false;
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
166
146
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
147
|
+
const loadedItem = this.filteredItems[page * this.pageSize];
|
|
148
|
+
if (loadedItem !== undefined) {
|
|
149
|
+
return loadedItem instanceof ComboBoxPlaceholder;
|
|
150
|
+
}
|
|
151
|
+
return this.size === undefined;
|
|
170
152
|
}
|
|
171
153
|
|
|
172
154
|
/** @private */
|
|
173
|
-
|
|
174
|
-
|
|
155
|
+
_loadPage(page) {
|
|
156
|
+
// Make sure same page isn't requested multiple times.
|
|
157
|
+
if (this._pendingRequests[page] || !this.dataProvider) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const params = {
|
|
162
|
+
page,
|
|
163
|
+
pageSize: this.pageSize,
|
|
164
|
+
filter: this.filter,
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const callback = (items, size) => {
|
|
168
|
+
if (this._pendingRequests[page] !== callback) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const filteredItems = this.filteredItems ? [...this.filteredItems] : [];
|
|
173
|
+
filteredItems.splice(params.page * params.pageSize, items.length, ...items);
|
|
174
|
+
this.filteredItems = filteredItems;
|
|
175
|
+
|
|
176
|
+
if (!this.opened && !this._isInputFocused()) {
|
|
177
|
+
this._commitValue();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (size !== undefined) {
|
|
181
|
+
this.size = size;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
delete this._pendingRequests[page];
|
|
185
|
+
|
|
186
|
+
if (Object.keys(this._pendingRequests).length === 0) {
|
|
187
|
+
this.loading = false;
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
this._pendingRequests[page] = callback;
|
|
192
|
+
// Set the `loading` flag only after marking the request as pending
|
|
193
|
+
// to prevent the same page from getting requested multiple times
|
|
194
|
+
// as a result of `__loadingChanged` in the scroller which requests
|
|
195
|
+
// a virtualizer update which in turn may trigger a data provider page request.
|
|
196
|
+
this.loading = true;
|
|
197
|
+
this.dataProvider(params, callback);
|
|
175
198
|
}
|
|
176
199
|
|
|
177
200
|
/** @private */
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
this._commitValue();
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
if (!this._dataProviderController.isLoading()) {
|
|
184
|
-
this.loading = false;
|
|
185
|
-
}
|
|
201
|
+
_getPageForIndex(index) {
|
|
202
|
+
return Math.floor(index / this.pageSize);
|
|
186
203
|
}
|
|
187
204
|
|
|
188
205
|
/**
|
|
@@ -193,74 +210,32 @@ export const ComboBoxDataProviderMixin = (superClass) =>
|
|
|
193
210
|
return;
|
|
194
211
|
}
|
|
195
212
|
|
|
196
|
-
this.
|
|
197
|
-
|
|
198
|
-
this.
|
|
213
|
+
this._pendingRequests = {};
|
|
214
|
+
const filteredItems = [];
|
|
215
|
+
for (let i = 0; i < (this.size || 0); i++) {
|
|
216
|
+
filteredItems.push(this.__placeHolder);
|
|
217
|
+
}
|
|
218
|
+
this.filteredItems = filteredItems;
|
|
199
219
|
|
|
200
220
|
if (this._shouldFetchData()) {
|
|
201
|
-
this.
|
|
221
|
+
this._forceNextRequest = false;
|
|
222
|
+
this._loadPage(0);
|
|
223
|
+
} else {
|
|
224
|
+
this._forceNextRequest = true;
|
|
202
225
|
}
|
|
203
226
|
}
|
|
204
227
|
|
|
205
228
|
/** @private */
|
|
206
229
|
_sizeChanged(size = 0) {
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
// a content update to re-render the scroller.
|
|
211
|
-
if (rootCache.size !== size) {
|
|
212
|
-
rootCache.size = size;
|
|
213
|
-
this.requestContentUpdate();
|
|
230
|
+
const filteredItems = (this.filteredItems || []).slice(0, size);
|
|
231
|
+
for (let i = 0; i < size; i++) {
|
|
232
|
+
filteredItems[i] = filteredItems[i] !== undefined ? filteredItems[i] : this.__placeHolder;
|
|
214
233
|
}
|
|
215
|
-
|
|
234
|
+
this.filteredItems = filteredItems;
|
|
216
235
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
*/
|
|
221
|
-
_filteredItemsChanged(items) {
|
|
222
|
-
if (!this.dataProvider) {
|
|
223
|
-
return super._filteredItemsChanged(items);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const { rootCache } = this._dataProviderController;
|
|
227
|
-
// When the items update originates from the developer,
|
|
228
|
-
// sync the new items with the controller and trigger
|
|
229
|
-
// a content update to re-render the scroller.
|
|
230
|
-
if (rootCache.items !== items) {
|
|
231
|
-
rootCache.items = items;
|
|
232
|
-
this.requestContentUpdate();
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/** @override */
|
|
237
|
-
requestContentUpdate() {
|
|
238
|
-
if (this.dataProvider) {
|
|
239
|
-
const { rootCache } = this._dataProviderController;
|
|
240
|
-
|
|
241
|
-
// Sync the controller's size with the component.
|
|
242
|
-
// They can be out of sync after, for example,
|
|
243
|
-
// the controller received new data.
|
|
244
|
-
if ((this.size || 0) !== rootCache.size) {
|
|
245
|
-
this.size = rootCache.size;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// Sync the controller's items with the component.
|
|
249
|
-
// They can be out of sync after, for example,
|
|
250
|
-
// the controller received new data.
|
|
251
|
-
if (this.filteredItems !== rootCache.items) {
|
|
252
|
-
this.filteredItems = rootCache.items;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// Sync the controller's loading state with the component.
|
|
256
|
-
this.loading = this._dataProviderController.isLoading();
|
|
257
|
-
|
|
258
|
-
// Set a copy of the controller's items as the dropdown items
|
|
259
|
-
// to trigger an update of the focused index in _setDropdownItems.
|
|
260
|
-
this._setDropdownItems([...this.filteredItems]);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
super.requestContentUpdate();
|
|
236
|
+
// Cleans up the redundant pending requests for pages > size
|
|
237
|
+
// Refers to https://github.com/vaadin/vaadin-flow-components/issues/229
|
|
238
|
+
this._flushPendingRequests(size);
|
|
264
239
|
}
|
|
265
240
|
|
|
266
241
|
/** @private */
|
|
@@ -269,8 +244,6 @@ export const ComboBoxDataProviderMixin = (superClass) =>
|
|
|
269
244
|
this.pageSize = oldPageSize;
|
|
270
245
|
throw new Error('`pageSize` value must be an integer > 0');
|
|
271
246
|
}
|
|
272
|
-
|
|
273
|
-
this._dataProviderController.setPageSize(pageSize);
|
|
274
247
|
this.clearCache();
|
|
275
248
|
}
|
|
276
249
|
|
|
@@ -280,7 +253,6 @@ export const ComboBoxDataProviderMixin = (superClass) =>
|
|
|
280
253
|
this.dataProvider = oldDataProvider;
|
|
281
254
|
});
|
|
282
255
|
|
|
283
|
-
this._dataProviderController.setDataProvider(dataProvider);
|
|
284
256
|
this.clearCache();
|
|
285
257
|
}
|
|
286
258
|
|
|
@@ -307,4 +279,28 @@ export const ComboBoxDataProviderMixin = (superClass) =>
|
|
|
307
279
|
}
|
|
308
280
|
}
|
|
309
281
|
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* This method cleans up the page callbacks which refers to the
|
|
285
|
+
* non-existing pages, i.e. which item indexes are greater than the
|
|
286
|
+
* changed size.
|
|
287
|
+
* This case is basically happens when:
|
|
288
|
+
* 1. Users scroll fast to the bottom and combo box generates the
|
|
289
|
+
* redundant page request/callback
|
|
290
|
+
* 2. Server side uses undefined size lazy loading and suddenly reaches
|
|
291
|
+
* the exact size which is on the range edge
|
|
292
|
+
* (for default page size = 50, it will be 100, 200, 300, ...).
|
|
293
|
+
* @param size the new size of items
|
|
294
|
+
* @private
|
|
295
|
+
*/
|
|
296
|
+
_flushPendingRequests(size) {
|
|
297
|
+
if (this._pendingRequests) {
|
|
298
|
+
const lastPage = Math.ceil(size / this.pageSize);
|
|
299
|
+
Object.entries(this._pendingRequests).forEach(([page, callback]) => {
|
|
300
|
+
if (parseInt(page) >= lastPage) {
|
|
301
|
+
callback([], size);
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
}
|
|
310
306
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2015 -
|
|
3
|
+
* Copyright (c) 2015 - 2024 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import type { Constructor } from '@open-wc/dedupe-mixin';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2015 -
|
|
3
|
+
* Copyright (c) 2015 - 2024 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -60,7 +60,7 @@ export const ComboBoxItemMixin = (superClass) =>
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
static get observers() {
|
|
63
|
-
return ['__rendererOrItemChanged(renderer, index, item
|
|
63
|
+
return ['__rendererOrItemChanged(renderer, index, item, selected, focused)', '__updateLabel(label, renderer)'];
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
static get observedAttributes() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2015 -
|
|
3
|
+
* Copyright (c) 2015 - 2024 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import type { DirMixinClass } from '@vaadin/component-base/src/dir-mixin.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2015 -
|
|
3
|
+
* Copyright (c) 2015 - 2024 Vaadin Ltd.
|
|
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';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2015 - 2024 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import type { Constructor } from '@open-wc/dedupe-mixin';
|
|
7
|
+
import type { ValidateMixinClass } from '@vaadin/field-base/src/validate-mixin.js';
|
|
8
|
+
import type { ComboBoxDataProviderMixinClass } from './vaadin-combo-box-data-provider-mixin.js';
|
|
9
|
+
import type { ComboBoxMixinClass } from './vaadin-combo-box-mixin.js';
|
|
10
|
+
|
|
11
|
+
export declare function ComboBoxLightMixin<TItem, T extends Constructor<HTMLElement>>(
|
|
12
|
+
base: T,
|
|
13
|
+
): Constructor<ComboBoxDataProviderMixinClass<TItem>> &
|
|
14
|
+
Constructor<ComboBoxLightMixinClass> &
|
|
15
|
+
Constructor<ComboBoxMixinClass<TItem>> &
|
|
16
|
+
Constructor<ValidateMixinClass> &
|
|
17
|
+
T;
|
|
18
|
+
|
|
19
|
+
export declare class ComboBoxLightMixinClass {
|
|
20
|
+
/**
|
|
21
|
+
* Name of the two-way data-bindable property representing the
|
|
22
|
+
* value of the custom input field.
|
|
23
|
+
* @attr {string} attr-for-value
|
|
24
|
+
*/
|
|
25
|
+
attrForValue: string;
|
|
26
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2015 - 2024 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { dashToCamelCase } from '@polymer/polymer/lib/utils/case-map.js';
|
|
7
|
+
import { afterNextRender } from '@polymer/polymer/lib/utils/render-status.js';
|
|
8
|
+
import { ValidateMixin } from '@vaadin/field-base/src/validate-mixin.js';
|
|
9
|
+
import { ComboBoxDataProviderMixin } from './vaadin-combo-box-data-provider-mixin.js';
|
|
10
|
+
import { ComboBoxMixin } from './vaadin-combo-box-mixin.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @polymerMixin
|
|
14
|
+
* @mixes ComboBoxDataProviderMixin
|
|
15
|
+
* @mixes ComboBoxMixin
|
|
16
|
+
* @mixes ValidateMixin
|
|
17
|
+
*/
|
|
18
|
+
export const ComboBoxLightMixin = (superClass) =>
|
|
19
|
+
class ComboBoxLightMixinClass extends ComboBoxDataProviderMixin(ComboBoxMixin(ValidateMixin(superClass))) {
|
|
20
|
+
static get properties() {
|
|
21
|
+
return {
|
|
22
|
+
/**
|
|
23
|
+
* Name of the two-way data-bindable property representing the
|
|
24
|
+
* value of the custom input field.
|
|
25
|
+
* @attr {string} attr-for-value
|
|
26
|
+
* @type {string}
|
|
27
|
+
*/
|
|
28
|
+
attrForValue: {
|
|
29
|
+
type: String,
|
|
30
|
+
value: 'value',
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Used by `InputControlMixin` as a reference to the clear button element.
|
|
37
|
+
* @protected
|
|
38
|
+
* @return {!HTMLElement}
|
|
39
|
+
*/
|
|
40
|
+
get clearElement() {
|
|
41
|
+
return this.querySelector('.clear-button');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Override this getter from `InputMixin` to allow using
|
|
46
|
+
* an arbitrary property name instead of `value`
|
|
47
|
+
* for accessing the input element's value.
|
|
48
|
+
*
|
|
49
|
+
* @protected
|
|
50
|
+
* @override
|
|
51
|
+
* @return {string}
|
|
52
|
+
*/
|
|
53
|
+
get _inputElementValueProperty() {
|
|
54
|
+
return dashToCamelCase(this.attrForValue);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @protected
|
|
59
|
+
* @override
|
|
60
|
+
* @return {HTMLInputElement | undefined}
|
|
61
|
+
*/
|
|
62
|
+
get _nativeInput() {
|
|
63
|
+
const input = this.inputElement;
|
|
64
|
+
|
|
65
|
+
if (input) {
|
|
66
|
+
// Support `<input class="input">`
|
|
67
|
+
if (input instanceof HTMLInputElement) {
|
|
68
|
+
return input;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Support `<input>` in light DOM (e.g. `vaadin-text-field`)
|
|
72
|
+
const slottedInput = input.querySelector('input');
|
|
73
|
+
if (slottedInput) {
|
|
74
|
+
return slottedInput;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (input.shadowRoot) {
|
|
78
|
+
// Support `<input>` in Shadow DOM (e.g. `mwc-textfield`)
|
|
79
|
+
const shadowInput = input.shadowRoot.querySelector('input');
|
|
80
|
+
if (shadowInput) {
|
|
81
|
+
return shadowInput;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** @protected */
|
|
90
|
+
ready() {
|
|
91
|
+
super.ready();
|
|
92
|
+
|
|
93
|
+
this._toggleElement = this.querySelector('.toggle-button');
|
|
94
|
+
|
|
95
|
+
// Wait until the slotted input DOM is ready
|
|
96
|
+
afterNextRender(this, () => {
|
|
97
|
+
this._setInputElement(this.querySelector('vaadin-text-field,.input'));
|
|
98
|
+
this._revertInputValue();
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Returns true if the current input value satisfies all constraints (if any).
|
|
104
|
+
* @return {boolean}
|
|
105
|
+
*/
|
|
106
|
+
checkValidity() {
|
|
107
|
+
if (this.inputElement && this.inputElement.validate) {
|
|
108
|
+
return this.inputElement.validate();
|
|
109
|
+
}
|
|
110
|
+
return super.checkValidity();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @protected
|
|
115
|
+
* @override
|
|
116
|
+
*/
|
|
117
|
+
_isClearButton(event) {
|
|
118
|
+
return (
|
|
119
|
+
super._isClearButton(event) ||
|
|
120
|
+
(event.type === 'input' && !event.isTrusted) || // Fake input event dispatched by clear button
|
|
121
|
+
event.composedPath()[0].getAttribute('part') === 'clear-button'
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @protected
|
|
127
|
+
* @override
|
|
128
|
+
*/
|
|
129
|
+
_shouldRemoveFocus(event) {
|
|
130
|
+
const isBlurringControlButtons = event.target === this._toggleElement || event.target === this.clearElement;
|
|
131
|
+
const isFocusingInputElement = event.relatedTarget && event.relatedTarget === this._nativeInput;
|
|
132
|
+
|
|
133
|
+
// prevent closing the overlay when moving focus from clear or toggle buttons to the internal input
|
|
134
|
+
if (isBlurringControlButtons && isFocusingInputElement) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return super._shouldRemoveFocus(event);
|
|
139
|
+
}
|
|
140
|
+
};
|