@vaadin/combo-box 24.4.0-alpha9 → 24.4.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/README.md +0 -1
- package/package.json +16 -14
- package/src/vaadin-combo-box-data-provider-mixin.js +13 -26
- package/src/vaadin-combo-box-item-mixin.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 +2 -7
- package/src/vaadin-combo-box-light.js +3 -127
- package/src/vaadin-combo-box-mixin.js +64 -20
- package/src/vaadin-combo-box-scroller-mixin.js +40 -15
- 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.js +2 -4
- 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/web-types.json +2 -2
- package/web-types.lit.json +2 -2
|
@@ -71,6 +71,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
71
71
|
notify: true,
|
|
72
72
|
value: false,
|
|
73
73
|
reflectToAttribute: true,
|
|
74
|
+
sync: true,
|
|
74
75
|
observer: '_openedChanged',
|
|
75
76
|
},
|
|
76
77
|
|
|
@@ -80,6 +81,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
80
81
|
*/
|
|
81
82
|
autoOpenDisabled: {
|
|
82
83
|
type: Boolean,
|
|
84
|
+
sync: true,
|
|
83
85
|
},
|
|
84
86
|
|
|
85
87
|
/**
|
|
@@ -104,7 +106,10 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
104
106
|
* - `model.item` The item.
|
|
105
107
|
* @type {ComboBoxRenderer | undefined}
|
|
106
108
|
*/
|
|
107
|
-
renderer:
|
|
109
|
+
renderer: {
|
|
110
|
+
type: Object,
|
|
111
|
+
sync: true,
|
|
112
|
+
},
|
|
108
113
|
|
|
109
114
|
/**
|
|
110
115
|
* A full set of items to filter the visible options from.
|
|
@@ -113,6 +118,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
113
118
|
*/
|
|
114
119
|
items: {
|
|
115
120
|
type: Array,
|
|
121
|
+
sync: true,
|
|
116
122
|
observer: '_itemsChanged',
|
|
117
123
|
},
|
|
118
124
|
|
|
@@ -138,6 +144,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
138
144
|
filteredItems: {
|
|
139
145
|
type: Array,
|
|
140
146
|
observer: '_filteredItemsChanged',
|
|
147
|
+
sync: true,
|
|
141
148
|
},
|
|
142
149
|
|
|
143
150
|
/**
|
|
@@ -154,6 +161,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
154
161
|
type: Boolean,
|
|
155
162
|
value: false,
|
|
156
163
|
reflectToAttribute: true,
|
|
164
|
+
sync: true,
|
|
157
165
|
},
|
|
158
166
|
|
|
159
167
|
/**
|
|
@@ -164,6 +172,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
164
172
|
type: Number,
|
|
165
173
|
observer: '_focusedIndexChanged',
|
|
166
174
|
value: -1,
|
|
175
|
+
sync: true,
|
|
167
176
|
},
|
|
168
177
|
|
|
169
178
|
/**
|
|
@@ -174,6 +183,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
174
183
|
type: String,
|
|
175
184
|
value: '',
|
|
176
185
|
notify: true,
|
|
186
|
+
sync: true,
|
|
177
187
|
},
|
|
178
188
|
|
|
179
189
|
/**
|
|
@@ -183,6 +193,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
183
193
|
selectedItem: {
|
|
184
194
|
type: Object,
|
|
185
195
|
notify: true,
|
|
196
|
+
sync: true,
|
|
186
197
|
},
|
|
187
198
|
|
|
188
199
|
/**
|
|
@@ -199,6 +210,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
199
210
|
type: String,
|
|
200
211
|
value: 'label',
|
|
201
212
|
observer: '_itemLabelPathChanged',
|
|
213
|
+
sync: true,
|
|
202
214
|
},
|
|
203
215
|
|
|
204
216
|
/**
|
|
@@ -214,6 +226,7 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
214
226
|
itemValuePath: {
|
|
215
227
|
type: String,
|
|
216
228
|
value: 'value',
|
|
229
|
+
sync: true,
|
|
217
230
|
},
|
|
218
231
|
|
|
219
232
|
/**
|
|
@@ -223,7 +236,10 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
223
236
|
* `dataProvider` callback).
|
|
224
237
|
* @attr {string} item-id-path
|
|
225
238
|
*/
|
|
226
|
-
itemIdPath:
|
|
239
|
+
itemIdPath: {
|
|
240
|
+
type: String,
|
|
241
|
+
sync: true,
|
|
242
|
+
},
|
|
227
243
|
|
|
228
244
|
/**
|
|
229
245
|
* @type {!HTMLElement | undefined}
|
|
@@ -240,27 +256,38 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
240
256
|
*/
|
|
241
257
|
_dropdownItems: {
|
|
242
258
|
type: Array,
|
|
259
|
+
sync: true,
|
|
243
260
|
},
|
|
244
261
|
|
|
245
262
|
/** @private */
|
|
246
263
|
_closeOnBlurIsPrevented: Boolean,
|
|
247
264
|
|
|
248
265
|
/** @private */
|
|
249
|
-
_scroller:
|
|
266
|
+
_scroller: {
|
|
267
|
+
type: Object,
|
|
268
|
+
sync: true,
|
|
269
|
+
},
|
|
250
270
|
|
|
251
271
|
/** @private */
|
|
252
272
|
_overlayOpened: {
|
|
253
273
|
type: Boolean,
|
|
274
|
+
sync: true,
|
|
254
275
|
observer: '_overlayOpenedChanged',
|
|
255
276
|
},
|
|
277
|
+
|
|
278
|
+
/** @private */
|
|
279
|
+
__keepOverlayOpened: {
|
|
280
|
+
type: Boolean,
|
|
281
|
+
sync: true,
|
|
282
|
+
},
|
|
256
283
|
};
|
|
257
284
|
}
|
|
258
285
|
|
|
259
286
|
static get observers() {
|
|
260
287
|
return [
|
|
261
288
|
'_selectedItemChanged(selectedItem, itemValuePath, itemLabelPath)',
|
|
262
|
-
'_openedOrItemsChanged(opened, _dropdownItems, loading)',
|
|
263
|
-
'_updateScroller(_scroller, _dropdownItems, opened, loading, selectedItem, itemIdPath, _focusedIndex, renderer,
|
|
289
|
+
'_openedOrItemsChanged(opened, _dropdownItems, loading, __keepOverlayOpened)',
|
|
290
|
+
'_updateScroller(_scroller, _dropdownItems, opened, loading, selectedItem, itemIdPath, _focusedIndex, renderer, _theme)',
|
|
264
291
|
];
|
|
265
292
|
}
|
|
266
293
|
|
|
@@ -413,6 +440,18 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
413
440
|
}
|
|
414
441
|
}
|
|
415
442
|
|
|
443
|
+
/**
|
|
444
|
+
* Override LitElement lifecycle callback to handle filter property change.
|
|
445
|
+
* @param {Object} props
|
|
446
|
+
*/
|
|
447
|
+
updated(props) {
|
|
448
|
+
super.updated(props);
|
|
449
|
+
|
|
450
|
+
if (props.has('filter')) {
|
|
451
|
+
this._filterChanged(this.filter);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
416
455
|
/** @private */
|
|
417
456
|
_initOverlay() {
|
|
418
457
|
const overlay = this.$.overlay;
|
|
@@ -441,25 +480,23 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
441
480
|
* @protected
|
|
442
481
|
*/
|
|
443
482
|
_initScroller(host) {
|
|
444
|
-
const
|
|
483
|
+
const scroller = document.createElement(`${this._tagNamePrefix}-scroller`);
|
|
484
|
+
|
|
485
|
+
scroller.owner = host || this;
|
|
486
|
+
scroller.getItemLabel = this._getItemLabel.bind(this);
|
|
487
|
+
scroller.addEventListener('selection-changed', this._boundOverlaySelectedItemChanged);
|
|
445
488
|
|
|
446
489
|
const overlay = this._overlayElement;
|
|
447
490
|
|
|
448
491
|
overlay.renderer = (root) => {
|
|
449
|
-
if (!root.
|
|
450
|
-
root.appendChild(
|
|
492
|
+
if (!root.innerHTML) {
|
|
493
|
+
root.appendChild(scroller);
|
|
451
494
|
}
|
|
452
495
|
};
|
|
453
496
|
|
|
454
497
|
// Ensure the scroller is rendered
|
|
455
498
|
overlay.requestContentUpdate();
|
|
456
499
|
|
|
457
|
-
const scroller = overlay.querySelector(scrollerTag);
|
|
458
|
-
|
|
459
|
-
scroller.owner = host || this;
|
|
460
|
-
scroller.getItemLabel = this._getItemLabel.bind(this);
|
|
461
|
-
scroller.addEventListener('selection-changed', this._boundOverlaySelectedItemChanged);
|
|
462
|
-
|
|
463
500
|
// Trigger the observer to set properties
|
|
464
501
|
this._scroller = scroller;
|
|
465
502
|
}
|
|
@@ -483,14 +520,25 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
483
520
|
renderer,
|
|
484
521
|
theme,
|
|
485
522
|
});
|
|
523
|
+
|
|
524
|
+
// NOTE: in PolylitMixin, setProperties() waits for `hasUpdated` to be set.
|
|
525
|
+
// This means for the first opening, properties won't be set synchronously.
|
|
526
|
+
// Call `performUpdate()` in this case to mimic the Polymer version logic.
|
|
527
|
+
if (scroller.performUpdate && !scroller.hasUpdated) {
|
|
528
|
+
try {
|
|
529
|
+
scroller.performUpdate();
|
|
530
|
+
} catch (_) {
|
|
531
|
+
// Suppress errors in synchronous tests for pre-opened combo-box.
|
|
532
|
+
}
|
|
533
|
+
}
|
|
486
534
|
}
|
|
487
535
|
}
|
|
488
536
|
|
|
489
537
|
/** @private */
|
|
490
|
-
_openedOrItemsChanged(opened, items, loading) {
|
|
538
|
+
_openedOrItemsChanged(opened, items, loading, keepOverlayOpened) {
|
|
491
539
|
// Close the overlay if there are no items to display.
|
|
492
540
|
// See https://github.com/vaadin/vaadin-combo-box/pull/964
|
|
493
|
-
this._overlayOpened =
|
|
541
|
+
this._overlayOpened = opened && (keepOverlayOpened || loading || !!(items && items.length));
|
|
494
542
|
}
|
|
495
543
|
|
|
496
544
|
/** @private */
|
|
@@ -542,7 +590,6 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
542
590
|
}
|
|
543
591
|
|
|
544
592
|
if (opened) {
|
|
545
|
-
this._openedWithFocusRing = this.hasAttribute('focus-ring');
|
|
546
593
|
// For touch devices, we don't want to popup virtual keyboard
|
|
547
594
|
// unless input element is explicitly focused by the user.
|
|
548
595
|
if (!this._isInputFocused() && !isTouch) {
|
|
@@ -554,9 +601,6 @@ export const ComboBoxMixin = (subclass) =>
|
|
|
554
601
|
this._overlayElement.restoreFocusOnClose = true;
|
|
555
602
|
} else {
|
|
556
603
|
this._onClosed();
|
|
557
|
-
if (this._openedWithFocusRing && this._isInputFocused()) {
|
|
558
|
-
this.setAttribute('focus-ring', '');
|
|
559
|
-
}
|
|
560
604
|
}
|
|
561
605
|
|
|
562
606
|
const input = this._nativeInput;
|
|
@@ -21,6 +21,7 @@ export const ComboBoxScrollerMixin = (superClass) =>
|
|
|
21
21
|
*/
|
|
22
22
|
items: {
|
|
23
23
|
type: Array,
|
|
24
|
+
sync: true,
|
|
24
25
|
observer: '__itemsChanged',
|
|
25
26
|
},
|
|
26
27
|
|
|
@@ -30,6 +31,7 @@ export const ComboBoxScrollerMixin = (superClass) =>
|
|
|
30
31
|
*/
|
|
31
32
|
focusedIndex: {
|
|
32
33
|
type: Number,
|
|
34
|
+
sync: true,
|
|
33
35
|
observer: '__focusedIndexChanged',
|
|
34
36
|
},
|
|
35
37
|
|
|
@@ -38,6 +40,7 @@ export const ComboBoxScrollerMixin = (superClass) =>
|
|
|
38
40
|
*/
|
|
39
41
|
loading: {
|
|
40
42
|
type: Boolean,
|
|
43
|
+
sync: true,
|
|
41
44
|
observer: '__loadingChanged',
|
|
42
45
|
},
|
|
43
46
|
|
|
@@ -47,6 +50,7 @@ export const ComboBoxScrollerMixin = (superClass) =>
|
|
|
47
50
|
*/
|
|
48
51
|
opened: {
|
|
49
52
|
type: Boolean,
|
|
53
|
+
sync: true,
|
|
50
54
|
observer: '__openedChanged',
|
|
51
55
|
},
|
|
52
56
|
|
|
@@ -55,6 +59,7 @@ export const ComboBoxScrollerMixin = (superClass) =>
|
|
|
55
59
|
*/
|
|
56
60
|
selectedItem: {
|
|
57
61
|
type: Object,
|
|
62
|
+
sync: true,
|
|
58
63
|
observer: '__selectedItemChanged',
|
|
59
64
|
},
|
|
60
65
|
|
|
@@ -84,6 +89,7 @@ export const ComboBoxScrollerMixin = (superClass) =>
|
|
|
84
89
|
*/
|
|
85
90
|
renderer: {
|
|
86
91
|
type: Object,
|
|
92
|
+
sync: true,
|
|
87
93
|
observer: '__rendererChanged',
|
|
88
94
|
},
|
|
89
95
|
|
|
@@ -132,21 +138,21 @@ export const ComboBoxScrollerMixin = (superClass) =>
|
|
|
132
138
|
this.addEventListener('click', (e) => e.stopPropagation());
|
|
133
139
|
|
|
134
140
|
this.__patchWheelOverScrolling();
|
|
135
|
-
|
|
136
|
-
this.__virtualizer = new Virtualizer({
|
|
137
|
-
createElements: this.__createElements.bind(this),
|
|
138
|
-
updateElement: this._updateElement.bind(this),
|
|
139
|
-
elementsContainer: this,
|
|
140
|
-
scrollTarget: this,
|
|
141
|
-
scrollContainer: this.$.selector,
|
|
142
|
-
});
|
|
143
141
|
}
|
|
144
142
|
|
|
145
143
|
/**
|
|
146
|
-
*
|
|
144
|
+
* Updates the virtualizer's size and items.
|
|
147
145
|
*/
|
|
148
146
|
requestContentUpdate() {
|
|
149
|
-
if (this.__virtualizer) {
|
|
147
|
+
if (!this.__virtualizer) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (this.items) {
|
|
152
|
+
this.__virtualizer.size = this.items.length;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (this.opened) {
|
|
150
156
|
this.__virtualizer.update();
|
|
151
157
|
}
|
|
152
158
|
}
|
|
@@ -157,7 +163,7 @@ export const ComboBoxScrollerMixin = (superClass) =>
|
|
|
157
163
|
* @param {number} index
|
|
158
164
|
*/
|
|
159
165
|
scrollIntoView(index) {
|
|
160
|
-
if (!(this.opened && index >= 0)) {
|
|
166
|
+
if (!this.__virtualizer || !(this.opened && index >= 0)) {
|
|
161
167
|
return;
|
|
162
168
|
}
|
|
163
169
|
|
|
@@ -208,11 +214,21 @@ export const ComboBoxScrollerMixin = (superClass) =>
|
|
|
208
214
|
return item === selectedItem;
|
|
209
215
|
}
|
|
210
216
|
|
|
217
|
+
/** @private */
|
|
218
|
+
__initVirtualizer() {
|
|
219
|
+
this.__virtualizer = new Virtualizer({
|
|
220
|
+
createElements: this.__createElements.bind(this),
|
|
221
|
+
updateElement: this._updateElement.bind(this),
|
|
222
|
+
elementsContainer: this,
|
|
223
|
+
scrollTarget: this,
|
|
224
|
+
scrollContainer: this.$.selector,
|
|
225
|
+
reorderElements: true,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
211
229
|
/** @private */
|
|
212
230
|
__itemsChanged(items) {
|
|
213
|
-
if (this.__virtualizer
|
|
214
|
-
this.__virtualizer.size = items.length;
|
|
215
|
-
this.__virtualizer.flush();
|
|
231
|
+
if (items && this.__virtualizer) {
|
|
216
232
|
this.requestContentUpdate();
|
|
217
233
|
}
|
|
218
234
|
}
|
|
@@ -225,6 +241,10 @@ export const ComboBoxScrollerMixin = (superClass) =>
|
|
|
225
241
|
/** @private */
|
|
226
242
|
__openedChanged(opened) {
|
|
227
243
|
if (opened) {
|
|
244
|
+
if (!this.__virtualizer) {
|
|
245
|
+
this.__initVirtualizer();
|
|
246
|
+
}
|
|
247
|
+
|
|
228
248
|
this.requestContentUpdate();
|
|
229
249
|
}
|
|
230
250
|
}
|
|
@@ -285,6 +305,12 @@ export const ComboBoxScrollerMixin = (superClass) =>
|
|
|
285
305
|
focused: !this.loading && focusedIndex === index,
|
|
286
306
|
});
|
|
287
307
|
|
|
308
|
+
// NOTE: in PolylitMixin, setProperties() waits for `hasUpdated` to be set.
|
|
309
|
+
// However, this causes issues with virtualizer. So we enforce sync update.
|
|
310
|
+
if (el.performUpdate && !el.hasUpdated) {
|
|
311
|
+
el.performUpdate();
|
|
312
|
+
}
|
|
313
|
+
|
|
288
314
|
el.id = `${this.__hostTagName}-item-${index}`;
|
|
289
315
|
el.setAttribute('role', index !== undefined ? 'option' : false);
|
|
290
316
|
el.setAttribute('aria-selected', selected.toString());
|
|
@@ -345,7 +371,6 @@ export const ComboBoxScrollerMixin = (superClass) =>
|
|
|
345
371
|
new CustomEvent('index-requested', {
|
|
346
372
|
detail: {
|
|
347
373
|
index,
|
|
348
|
-
currentScrollerPos: this._oldScrollerPosition,
|
|
349
374
|
},
|
|
350
375
|
}),
|
|
351
376
|
);
|
|
@@ -0,0 +1,50 @@
|
|
|
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 { css, html, LitElement } from 'lit';
|
|
7
|
+
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
8
|
+
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
|
|
9
|
+
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
|
|
10
|
+
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
11
|
+
import { ComboBoxItemMixin } from './vaadin-combo-box-item-mixin.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* LitElement based version of `<vaadin-combo-box-item>` web component.
|
|
15
|
+
*
|
|
16
|
+
* ## Disclaimer
|
|
17
|
+
*
|
|
18
|
+
* This component is an experiment not intended for publishing to npm.
|
|
19
|
+
* There is no ETA regarding specific Vaadin version where it'll land.
|
|
20
|
+
* Feel free to try this code in your apps as per Apache 2.0 license.
|
|
21
|
+
*/
|
|
22
|
+
export class ComboBoxItem extends ComboBoxItemMixin(ThemableMixin(DirMixin(PolylitMixin(LitElement)))) {
|
|
23
|
+
static get is() {
|
|
24
|
+
return 'vaadin-combo-box-item';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static get styles() {
|
|
28
|
+
return css`
|
|
29
|
+
:host {
|
|
30
|
+
display: block;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
:host([hidden]) {
|
|
34
|
+
display: none;
|
|
35
|
+
}
|
|
36
|
+
`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** @protected */
|
|
40
|
+
render() {
|
|
41
|
+
return html`
|
|
42
|
+
<span part="checkmark" aria-hidden="true"></span>
|
|
43
|
+
<div part="content">
|
|
44
|
+
<slot></slot>
|
|
45
|
+
</div>
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
defineCustomElement(ComboBoxItem);
|
|
@@ -0,0 +1,58 @@
|
|
|
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 './vaadin-lit-combo-box-item.js';
|
|
7
|
+
import './vaadin-lit-combo-box-overlay.js';
|
|
8
|
+
import './vaadin-lit-combo-box-scroller.js';
|
|
9
|
+
import { css, html, LitElement } from 'lit';
|
|
10
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
11
|
+
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
12
|
+
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
|
|
13
|
+
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
14
|
+
import { ComboBoxLightMixin } from './vaadin-combo-box-light-mixin.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* LitElement based version of `<vaadin-combo-box-light>` web component.
|
|
18
|
+
*
|
|
19
|
+
* ## Disclaimer
|
|
20
|
+
*
|
|
21
|
+
* This component is an experiment not intended for publishing to npm.
|
|
22
|
+
* There is no ETA regarding specific Vaadin version where it'll land.
|
|
23
|
+
* Feel free to try this code in your apps as per Apache 2.0 license.
|
|
24
|
+
*/
|
|
25
|
+
class ComboBoxLight extends ComboBoxLightMixin(ThemableMixin(PolylitMixin(LitElement))) {
|
|
26
|
+
static get is() {
|
|
27
|
+
return 'vaadin-combo-box-light';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static get styles() {
|
|
31
|
+
return css`
|
|
32
|
+
:host([opened]) {
|
|
33
|
+
pointer-events: auto;
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** @protected */
|
|
39
|
+
render() {
|
|
40
|
+
return html`
|
|
41
|
+
<slot></slot>
|
|
42
|
+
|
|
43
|
+
<vaadin-combo-box-overlay
|
|
44
|
+
id="overlay"
|
|
45
|
+
.opened="${this._overlayOpened}"
|
|
46
|
+
?loading="${this.loading}"
|
|
47
|
+
theme="${ifDefined(this._theme)}"
|
|
48
|
+
.positionTarget="${this.inputElement}"
|
|
49
|
+
.restoreFocusNode="${this.inputElement}"
|
|
50
|
+
no-vertical-overlap
|
|
51
|
+
></vaadin-combo-box-overlay>
|
|
52
|
+
`;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
defineCustomElement(ComboBoxLight);
|
|
57
|
+
|
|
58
|
+
export { ComboBoxLight };
|
|
@@ -0,0 +1,76 @@
|
|
|
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 { css, html, LitElement } from 'lit';
|
|
7
|
+
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
8
|
+
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
|
|
9
|
+
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
|
|
10
|
+
import { OverlayMixin } from '@vaadin/overlay/src/vaadin-overlay-mixin.js';
|
|
11
|
+
import { overlayStyles } from '@vaadin/overlay/src/vaadin-overlay-styles.js';
|
|
12
|
+
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
13
|
+
import { ComboBoxOverlayMixin } from './vaadin-combo-box-overlay-mixin.js';
|
|
14
|
+
|
|
15
|
+
const comboBoxOverlayStyles = css`
|
|
16
|
+
#overlay {
|
|
17
|
+
width: var(--vaadin-combo-box-overlay-width, var(--_vaadin-combo-box-overlay-default-width, auto));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
[part='content'] {
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-direction: column;
|
|
23
|
+
height: 100%;
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* An element used internally by `<vaadin-combo-box>`. Not intended to be used separately.
|
|
29
|
+
*
|
|
30
|
+
* @extends HTMLElement
|
|
31
|
+
* @mixes ComboBoxOverlayMixin
|
|
32
|
+
* @mixes DirMixin
|
|
33
|
+
* @mixes OverlayMixin
|
|
34
|
+
* @mixes ThemableMixin
|
|
35
|
+
* @private
|
|
36
|
+
*/
|
|
37
|
+
export class ComboBoxOverlay extends ComboBoxOverlayMixin(
|
|
38
|
+
OverlayMixin(DirMixin(ThemableMixin(PolylitMixin(LitElement)))),
|
|
39
|
+
) {
|
|
40
|
+
static get is() {
|
|
41
|
+
return 'vaadin-combo-box-overlay';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static get styles() {
|
|
45
|
+
return [overlayStyles, comboBoxOverlayStyles, comboBoxOverlayStyles];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static get properties() {
|
|
49
|
+
return {
|
|
50
|
+
/**
|
|
51
|
+
* When true, the overlay is visible and attached to body.
|
|
52
|
+
* This property config is overridden to set `sync: true`.
|
|
53
|
+
*/
|
|
54
|
+
opened: {
|
|
55
|
+
type: Boolean,
|
|
56
|
+
notify: true,
|
|
57
|
+
observer: '_openedChanged',
|
|
58
|
+
reflectToAttribute: true,
|
|
59
|
+
sync: true,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** @protected */
|
|
65
|
+
render() {
|
|
66
|
+
return html`
|
|
67
|
+
<div id="backdrop" part="backdrop" hidden></div>
|
|
68
|
+
<div part="overlay" id="overlay">
|
|
69
|
+
<div part="loader"></div>
|
|
70
|
+
<div part="content" id="content"><slot></slot></div>
|
|
71
|
+
</div>
|
|
72
|
+
`;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
defineCustomElement(ComboBoxOverlay);
|
|
@@ -0,0 +1,59 @@
|
|
|
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 { css, html, LitElement } from 'lit';
|
|
7
|
+
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
8
|
+
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
|
|
9
|
+
import { ComboBoxScrollerMixin } from './vaadin-combo-box-scroller-mixin.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* An element used internally by `<vaadin-combo-box>`. Not intended to be used separately.
|
|
13
|
+
*
|
|
14
|
+
* @extends HTMLElement
|
|
15
|
+
* @mixes ComboBoxScrollerMixin
|
|
16
|
+
* @private
|
|
17
|
+
*/
|
|
18
|
+
export class ComboBoxScroller extends ComboBoxScrollerMixin(PolylitMixin(LitElement)) {
|
|
19
|
+
static get is() {
|
|
20
|
+
return 'vaadin-combo-box-scroller';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static get styles() {
|
|
24
|
+
return css`
|
|
25
|
+
:host {
|
|
26
|
+
display: block;
|
|
27
|
+
min-height: 1px;
|
|
28
|
+
overflow: auto;
|
|
29
|
+
|
|
30
|
+
/* Fixes item background from getting on top of scrollbars on Safari */
|
|
31
|
+
transform: translate3d(0, 0, 0);
|
|
32
|
+
|
|
33
|
+
/* Enable momentum scrolling on iOS */
|
|
34
|
+
-webkit-overflow-scrolling: touch;
|
|
35
|
+
|
|
36
|
+
/* Fixes scrollbar disappearing when 'Show scroll bars: Always' enabled in Safari */
|
|
37
|
+
box-shadow: 0 0 0 white;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
#selector {
|
|
41
|
+
border-width: var(--_vaadin-combo-box-items-container-border-width);
|
|
42
|
+
border-style: var(--_vaadin-combo-box-items-container-border-style);
|
|
43
|
+
border-color: var(--_vaadin-combo-box-items-container-border-color, transparent);
|
|
44
|
+
position: relative;
|
|
45
|
+
}
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** @protected */
|
|
50
|
+
render() {
|
|
51
|
+
return html`
|
|
52
|
+
<div id="selector">
|
|
53
|
+
<slot></slot>
|
|
54
|
+
</div>
|
|
55
|
+
`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
defineCustomElement(ComboBoxScroller);
|