@vaadin/combo-box 25.0.0-alpha8 → 25.0.0-beta1
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 +14 -17
- package/src/styles/vaadin-combo-box-base-styles.js +2 -2
- package/src/styles/vaadin-combo-box-overlay-base-styles.js +2 -2
- package/src/vaadin-combo-box-base-mixin.d.ts +0 -2
- package/src/vaadin-combo-box-base-mixin.js +9 -30
- package/src/vaadin-combo-box-data-provider-mixin.js +1 -21
- package/src/vaadin-combo-box-item-mixin.js +1 -1
- package/src/vaadin-combo-box-item.js +1 -1
- package/src/vaadin-combo-box-items-mixin.d.ts +60 -0
- package/src/vaadin-combo-box-items-mixin.js +292 -0
- package/src/vaadin-combo-box-mixin.d.ts +0 -42
- package/src/vaadin-combo-box-mixin.js +4 -236
- package/src/vaadin-combo-box-overlay-mixin.js +1 -25
- package/src/vaadin-combo-box-overlay.js +2 -2
- package/src/vaadin-combo-box-scroller-mixin.d.ts +1 -2
- package/src/vaadin-combo-box-scroller-mixin.js +5 -0
- package/src/vaadin-combo-box-scroller.js +1 -1
- package/src/vaadin-combo-box.d.ts +31 -19
- package/src/vaadin-combo-box.js +62 -21
- package/vaadin-combo-box.js +1 -1
- package/web-types.json +59 -70
- package/web-types.lit.json +20 -20
- package/src/styles/vaadin-combo-box-core-styles.d.ts +0 -8
- package/src/styles/vaadin-combo-box-core-styles.js +0 -12
- package/src/styles/vaadin-combo-box-overlay-core-styles.js +0 -18
- package/src/styles/vaadin-combo-box-scroller-core-styles.js +0 -27
- package/theme/lumo/vaadin-combo-box-item-styles.d.ts +0 -5
- package/theme/lumo/vaadin-combo-box-item-styles.js +0 -25
- package/theme/lumo/vaadin-combo-box-overlay-styles.d.ts +0 -6
- package/theme/lumo/vaadin-combo-box-overlay-styles.js +0 -60
- package/theme/lumo/vaadin-combo-box-styles.d.ts +0 -2
- package/theme/lumo/vaadin-combo-box-styles.js +0 -12
- package/theme/lumo/vaadin-combo-box.d.ts +0 -4
- package/theme/lumo/vaadin-combo-box.js +0 -4
|
@@ -3,10 +3,8 @@
|
|
|
3
3
|
* Copyright (c) 2015 - 2025 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
-
import { get } from '@vaadin/component-base/src/path-utils.js';
|
|
7
6
|
import { ValidateMixin } from '@vaadin/field-base/src/validate-mixin.js';
|
|
8
|
-
import {
|
|
9
|
-
import { ComboBoxPlaceholder } from './vaadin-combo-box-placeholder.js';
|
|
7
|
+
import { ComboBoxItemsMixin } from './vaadin-combo-box-items-mixin.js';
|
|
10
8
|
|
|
11
9
|
/**
|
|
12
10
|
* Checks if the value is supported as an item value in this control.
|
|
@@ -18,32 +16,14 @@ function isValidValue(value) {
|
|
|
18
16
|
return value !== undefined && value !== null;
|
|
19
17
|
}
|
|
20
18
|
|
|
21
|
-
/**
|
|
22
|
-
* Returns the index of the first item that satisfies the provided testing function
|
|
23
|
-
* ignoring placeholder items.
|
|
24
|
-
*
|
|
25
|
-
* @param {Array<ComboBoxItem | string>} items
|
|
26
|
-
* @param {Function} callback
|
|
27
|
-
* @return {number}
|
|
28
|
-
*/
|
|
29
|
-
function findItemIndex(items, callback) {
|
|
30
|
-
return items.findIndex((item) => {
|
|
31
|
-
if (item instanceof ComboBoxPlaceholder) {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return callback(item);
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
|
|
39
19
|
/**
|
|
40
20
|
* @polymerMixin
|
|
41
|
-
* @mixes
|
|
21
|
+
* @mixes ComboBoxItemsMixin
|
|
42
22
|
* @mixes ValidateMixin
|
|
43
23
|
* @param {function(new:HTMLElement)} superClass
|
|
44
24
|
*/
|
|
45
25
|
export const ComboBoxMixin = (superClass) =>
|
|
46
|
-
class ComboBoxMixinClass extends ValidateMixin(
|
|
26
|
+
class ComboBoxMixinClass extends ValidateMixin(ComboBoxItemsMixin(superClass)) {
|
|
47
27
|
static get properties() {
|
|
48
28
|
return {
|
|
49
29
|
/**
|
|
@@ -63,17 +43,6 @@ export const ComboBoxMixin = (superClass) =>
|
|
|
63
43
|
sync: true,
|
|
64
44
|
},
|
|
65
45
|
|
|
66
|
-
/**
|
|
67
|
-
* A full set of items to filter the visible options from.
|
|
68
|
-
* The items can be of either `String` or `Object` type.
|
|
69
|
-
* @type {!Array<!ComboBoxItem | string> | undefined}
|
|
70
|
-
*/
|
|
71
|
-
items: {
|
|
72
|
-
type: Array,
|
|
73
|
-
sync: true,
|
|
74
|
-
observer: '_itemsChanged',
|
|
75
|
-
},
|
|
76
|
-
|
|
77
46
|
/**
|
|
78
47
|
* If `true`, the user can input a value that is not present in the items list.
|
|
79
48
|
* `value` property will be set to the input value in this case.
|
|
@@ -87,18 +56,6 @@ export const ComboBoxMixin = (superClass) =>
|
|
|
87
56
|
value: false,
|
|
88
57
|
},
|
|
89
58
|
|
|
90
|
-
/**
|
|
91
|
-
* A subset of items, filtered based on the user input. Filtered items
|
|
92
|
-
* can be assigned directly to omit the internal filtering functionality.
|
|
93
|
-
* The items can be of either `String` or `Object` type.
|
|
94
|
-
* @type {!Array<!ComboBoxItem | string> | undefined}
|
|
95
|
-
*/
|
|
96
|
-
filteredItems: {
|
|
97
|
-
type: Array,
|
|
98
|
-
observer: '_filteredItemsChanged',
|
|
99
|
-
sync: true,
|
|
100
|
-
},
|
|
101
|
-
|
|
102
59
|
/**
|
|
103
60
|
* When set to `true`, "loading" attribute is added to host and the overlay element.
|
|
104
61
|
* @type {boolean}
|
|
@@ -110,17 +67,6 @@ export const ComboBoxMixin = (superClass) =>
|
|
|
110
67
|
sync: true,
|
|
111
68
|
},
|
|
112
69
|
|
|
113
|
-
/**
|
|
114
|
-
* Filtering string the user has typed into the input field.
|
|
115
|
-
* @type {string}
|
|
116
|
-
*/
|
|
117
|
-
filter: {
|
|
118
|
-
type: String,
|
|
119
|
-
value: '',
|
|
120
|
-
notify: true,
|
|
121
|
-
sync: true,
|
|
122
|
-
},
|
|
123
|
-
|
|
124
70
|
/**
|
|
125
71
|
* The selected item from the `items` array.
|
|
126
72
|
* @type {ComboBoxItem | string | undefined}
|
|
@@ -141,39 +87,6 @@ export const ComboBoxMixin = (superClass) =>
|
|
|
141
87
|
type: Object,
|
|
142
88
|
},
|
|
143
89
|
|
|
144
|
-
/**
|
|
145
|
-
* Path for label of the item. If `items` is an array of objects, the
|
|
146
|
-
* `itemLabelPath` is used to fetch the displayed string label for each
|
|
147
|
-
* item.
|
|
148
|
-
*
|
|
149
|
-
* The item label is also used for matching items when processing user
|
|
150
|
-
* input, i.e., for filtering and selecting items.
|
|
151
|
-
* @attr {string} item-label-path
|
|
152
|
-
* @type {string}
|
|
153
|
-
*/
|
|
154
|
-
itemLabelPath: {
|
|
155
|
-
type: String,
|
|
156
|
-
value: 'label',
|
|
157
|
-
observer: '_itemLabelPathChanged',
|
|
158
|
-
sync: true,
|
|
159
|
-
},
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Path for the value of the item. If `items` is an array of objects, the
|
|
163
|
-
* `itemValuePath:` is used to fetch the string value for the selected
|
|
164
|
-
* item.
|
|
165
|
-
*
|
|
166
|
-
* The item value is used in the `value` property of the combo box,
|
|
167
|
-
* to provide the form value.
|
|
168
|
-
* @attr {string} item-value-path
|
|
169
|
-
* @type {string}
|
|
170
|
-
*/
|
|
171
|
-
itemValuePath: {
|
|
172
|
-
type: String,
|
|
173
|
-
value: 'value',
|
|
174
|
-
sync: true,
|
|
175
|
-
},
|
|
176
|
-
|
|
177
90
|
/**
|
|
178
91
|
* Path for the id of the item. If `items` is an array of objects,
|
|
179
92
|
* the `itemIdPath` is used to compare and identify the same item
|
|
@@ -245,10 +158,6 @@ export const ComboBoxMixin = (superClass) =>
|
|
|
245
158
|
this._scroller[prop] = this[prop];
|
|
246
159
|
}
|
|
247
160
|
});
|
|
248
|
-
|
|
249
|
-
if (props.has('filter')) {
|
|
250
|
-
this._filterChanged(this.filter);
|
|
251
|
-
}
|
|
252
161
|
}
|
|
253
162
|
|
|
254
163
|
/** @private */
|
|
@@ -301,28 +210,6 @@ export const ComboBoxMixin = (superClass) =>
|
|
|
301
210
|
}
|
|
302
211
|
}
|
|
303
212
|
|
|
304
|
-
/**
|
|
305
|
-
* Override method from `ComboBoxBaseMixin` to handle item label path.
|
|
306
|
-
* @protected
|
|
307
|
-
* @override
|
|
308
|
-
*/
|
|
309
|
-
_getItemLabel(item) {
|
|
310
|
-
let label = item && this.itemLabelPath ? get(this.itemLabelPath, item) : undefined;
|
|
311
|
-
if (label === undefined || label === null) {
|
|
312
|
-
label = item ? item.toString() : '';
|
|
313
|
-
}
|
|
314
|
-
return label;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
/** @private */
|
|
318
|
-
_getItemValue(item) {
|
|
319
|
-
let value = item && this.itemValuePath ? get(this.itemValuePath, item) : undefined;
|
|
320
|
-
if (value === undefined) {
|
|
321
|
-
value = item ? item.toString() : '';
|
|
322
|
-
}
|
|
323
|
-
return value;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
213
|
/**
|
|
327
214
|
* Override method from `ComboBoxBaseMixin` to handle loading.
|
|
328
215
|
* @protected
|
|
@@ -488,37 +375,6 @@ export const ComboBoxMixin = (superClass) =>
|
|
|
488
375
|
this._clearFilter();
|
|
489
376
|
}
|
|
490
377
|
|
|
491
|
-
/**
|
|
492
|
-
* Override an event listener from `ComboBoxBaseMixin` to handle
|
|
493
|
-
* batched setting of both `opened` and `filter` properties.
|
|
494
|
-
* @param {!Event} event
|
|
495
|
-
* @protected
|
|
496
|
-
* @override
|
|
497
|
-
*/
|
|
498
|
-
_onInput(event) {
|
|
499
|
-
const filter = this._inputElementValue;
|
|
500
|
-
|
|
501
|
-
// When opening dropdown on user input, both `opened` and `filter` properties are set.
|
|
502
|
-
// Perform a batched property update instead of relying on sync property observers.
|
|
503
|
-
// This is necessary to avoid an extra data-provider request for loading first page.
|
|
504
|
-
const props = {};
|
|
505
|
-
|
|
506
|
-
if (this.filter === filter) {
|
|
507
|
-
// Filter and input value might get out of sync, while keyboard navigating for example.
|
|
508
|
-
// Afterwards, input value might be changed to the same value as used in filtering.
|
|
509
|
-
// In situation like these, we need to make sure all the filter changes handlers are run.
|
|
510
|
-
this._filterChanged(this.filter);
|
|
511
|
-
} else {
|
|
512
|
-
props.filter = filter;
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
if (!this.opened && !this._isClearButton(event) && !this.autoOpenDisabled) {
|
|
516
|
-
props.opened = true;
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
this.setProperties(props);
|
|
520
|
-
}
|
|
521
|
-
|
|
522
378
|
/**
|
|
523
379
|
* Override an event listener from `InputMixin`.
|
|
524
380
|
* @param {!Event} event
|
|
@@ -531,30 +387,6 @@ export const ComboBoxMixin = (superClass) =>
|
|
|
531
387
|
event.stopPropagation();
|
|
532
388
|
}
|
|
533
389
|
|
|
534
|
-
/** @private */
|
|
535
|
-
_itemLabelPathChanged(itemLabelPath) {
|
|
536
|
-
if (typeof itemLabelPath !== 'string') {
|
|
537
|
-
console.error('You should set itemLabelPath to a valid string');
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
/** @private */
|
|
542
|
-
_filterChanged(filter) {
|
|
543
|
-
// Scroll to the top of the list whenever the filter changes.
|
|
544
|
-
this._scrollIntoView(0);
|
|
545
|
-
|
|
546
|
-
this._focusedIndex = -1;
|
|
547
|
-
|
|
548
|
-
if (this.items) {
|
|
549
|
-
this.filteredItems = this._filterItems(this.items, filter);
|
|
550
|
-
} else {
|
|
551
|
-
// With certain use cases (e. g., external filtering), `items` are
|
|
552
|
-
// undefined. Filtering is unnecessary per se, but the filteredItems
|
|
553
|
-
// observer should still be invoked to update focused item.
|
|
554
|
-
this._filteredItemsChanged(this.filteredItems);
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
|
|
558
390
|
/**
|
|
559
391
|
* Override method from `ComboBoxBaseMixin` to handle reverting value.
|
|
560
392
|
* @protected
|
|
@@ -651,40 +483,6 @@ export const ComboBoxMixin = (superClass) =>
|
|
|
651
483
|
}
|
|
652
484
|
}
|
|
653
485
|
|
|
654
|
-
/** @private */
|
|
655
|
-
_itemsChanged(items, oldItems) {
|
|
656
|
-
this._ensureItemsOrDataProvider(() => {
|
|
657
|
-
this.items = oldItems;
|
|
658
|
-
});
|
|
659
|
-
|
|
660
|
-
if (items) {
|
|
661
|
-
this.filteredItems = items.slice(0);
|
|
662
|
-
} else if (oldItems) {
|
|
663
|
-
// Only clear filteredItems if the component had items previously but got cleared
|
|
664
|
-
this.filteredItems = null;
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
/** @private */
|
|
669
|
-
_filteredItemsChanged(filteredItems) {
|
|
670
|
-
this._setDropdownItems(filteredItems);
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
/** @private */
|
|
674
|
-
_filterItems(arr, filter) {
|
|
675
|
-
if (!arr) {
|
|
676
|
-
return arr;
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
const filteredItems = arr.filter((item) => {
|
|
680
|
-
filter = filter ? filter.toString().toLowerCase() : '';
|
|
681
|
-
// Check if item contains input value.
|
|
682
|
-
return this._getItemLabel(item).toString().toLowerCase().indexOf(filter) > -1;
|
|
683
|
-
});
|
|
684
|
-
|
|
685
|
-
return filteredItems;
|
|
686
|
-
}
|
|
687
|
-
|
|
688
486
|
/** @private */
|
|
689
487
|
_selectItemForValue(value) {
|
|
690
488
|
const valueIndex = this.__getItemIndexByValue(this.filteredItems, value);
|
|
@@ -708,6 +506,7 @@ export const ComboBoxMixin = (superClass) =>
|
|
|
708
506
|
* Override this method to show custom items.
|
|
709
507
|
*
|
|
710
508
|
* @protected
|
|
509
|
+
* @override
|
|
711
510
|
*/
|
|
712
511
|
_setDropdownItems(newItems) {
|
|
713
512
|
const oldItems = this._dropdownItems;
|
|
@@ -740,37 +539,6 @@ export const ComboBoxMixin = (superClass) =>
|
|
|
740
539
|
}
|
|
741
540
|
}
|
|
742
541
|
|
|
743
|
-
/**
|
|
744
|
-
* Returns the first item that matches the provided value.
|
|
745
|
-
*
|
|
746
|
-
* @private
|
|
747
|
-
*/
|
|
748
|
-
__getItemIndexByValue(items, value) {
|
|
749
|
-
if (!items || !isValidValue(value)) {
|
|
750
|
-
return -1;
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
return findItemIndex(items, (item) => {
|
|
754
|
-
return this._getItemValue(item) === value;
|
|
755
|
-
});
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
/**
|
|
759
|
-
* Returns the first item that matches the provided label.
|
|
760
|
-
* Labels are matched against each other case insensitively.
|
|
761
|
-
*
|
|
762
|
-
* @private
|
|
763
|
-
*/
|
|
764
|
-
__getItemIndexByLabel(items, label) {
|
|
765
|
-
if (!items || !label) {
|
|
766
|
-
return -1;
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
return findItemIndex(items, (item) => {
|
|
770
|
-
return this._getItemLabel(item).toString().toLowerCase() === label.toString().toLowerCase();
|
|
771
|
-
});
|
|
772
|
-
}
|
|
773
|
-
|
|
774
542
|
/**
|
|
775
543
|
* Override method from `ComboBoxBaseMixin`.
|
|
776
544
|
* @protected
|
|
@@ -22,21 +22,6 @@ export const ComboBoxOverlayMixin = (superClass) =>
|
|
|
22
22
|
this.requiredVerticalSpace = 200;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
/** @protected */
|
|
26
|
-
connectedCallback() {
|
|
27
|
-
super.connectedCallback();
|
|
28
|
-
|
|
29
|
-
const hostDir = this._getHostDir();
|
|
30
|
-
if (hostDir) {
|
|
31
|
-
this.setAttribute('dir', hostDir);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/** @protected */
|
|
36
|
-
_getHostDir() {
|
|
37
|
-
return this.owner && this.owner.getAttribute('dir');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
25
|
/**
|
|
41
26
|
* Override method inherited from `Overlay`
|
|
42
27
|
* to not close on position target click.
|
|
@@ -66,16 +51,7 @@ export const ComboBoxOverlayMixin = (superClass) =>
|
|
|
66
51
|
|
|
67
52
|
/** @protected */
|
|
68
53
|
_updateOverlayWidth() {
|
|
69
|
-
|
|
70
|
-
this.style.setProperty(`--_${propPrefix}-default-width`, `${this.positionTarget.offsetWidth}px`);
|
|
71
|
-
|
|
72
|
-
const customWidth = getComputedStyle(this.owner).getPropertyValue(`--${propPrefix}-width`);
|
|
73
|
-
|
|
74
|
-
if (customWidth === '') {
|
|
75
|
-
this.style.removeProperty(`--${propPrefix}-width`);
|
|
76
|
-
} else {
|
|
77
|
-
this.style.setProperty(`--${propPrefix}-width`, customWidth);
|
|
78
|
-
}
|
|
54
|
+
this.style.setProperty(`--_${this.localName}-default-width`, `${this.positionTarget.offsetWidth}px`);
|
|
79
55
|
}
|
|
80
56
|
|
|
81
57
|
/** @private */
|
|
@@ -7,11 +7,11 @@ import { html, LitElement } from 'lit';
|
|
|
7
7
|
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
8
8
|
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
|
|
9
9
|
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
|
|
10
|
-
import { overlayStyles } from '@vaadin/overlay/src/styles/vaadin-overlay-
|
|
10
|
+
import { overlayStyles } from '@vaadin/overlay/src/styles/vaadin-overlay-base-styles.js';
|
|
11
11
|
import { OverlayMixin } from '@vaadin/overlay/src/vaadin-overlay-mixin.js';
|
|
12
12
|
import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
|
|
13
13
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
14
|
-
import { comboBoxOverlayStyles } from './styles/vaadin-combo-box-overlay-
|
|
14
|
+
import { comboBoxOverlayStyles } from './styles/vaadin-combo-box-overlay-base-styles.js';
|
|
15
15
|
import { ComboBoxOverlayMixin } from './vaadin-combo-box-overlay-mixin.js';
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -45,8 +45,7 @@ export declare class ComboBoxScrollerMixinClass<TItem, TOwner> {
|
|
|
45
45
|
owner: TOwner;
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
|
-
*
|
|
49
|
-
* @attr {boolean} auto-open-disabled
|
|
48
|
+
* Function used to render the content of every combo-box item.
|
|
50
49
|
*/
|
|
51
50
|
renderer: ComboBoxItemRenderer<TItem, TOwner> | null | undefined;
|
|
52
51
|
|
|
@@ -234,6 +234,11 @@ export const ComboBoxScrollerMixin = (superClass) =>
|
|
|
234
234
|
scrollTarget: this,
|
|
235
235
|
scrollContainer: this.$.selector,
|
|
236
236
|
reorderElements: true,
|
|
237
|
+
// Combo-box items have a CSS-defined minimum height, so the virtualizer's
|
|
238
|
+
// height placeholder logic can be disabled. This helps save reflows which
|
|
239
|
+
// might otherwise be triggered by this logic because it reads the row height
|
|
240
|
+
// right after updating the rows' content.
|
|
241
|
+
__disableHeightPlaceholder: true,
|
|
237
242
|
});
|
|
238
243
|
}
|
|
239
244
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { html, LitElement } from 'lit';
|
|
7
7
|
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
8
8
|
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
|
|
9
|
-
import { comboBoxScrollerStyles } from './styles/vaadin-combo-box-scroller-
|
|
9
|
+
import { comboBoxScrollerStyles } from './styles/vaadin-combo-box-scroller-base-styles.js';
|
|
10
10
|
import { ComboBoxScrollerMixin } from './vaadin-combo-box-scroller-mixin.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -9,7 +9,6 @@ import type { FocusMixinClass } from '@vaadin/a11y-base/src/focus-mixin.js';
|
|
|
9
9
|
import type { KeyboardMixinClass } from '@vaadin/a11y-base/src/keyboard-mixin.js';
|
|
10
10
|
import type { DelegateStateMixinClass } from '@vaadin/component-base/src/delegate-state-mixin.js';
|
|
11
11
|
import type { ElementMixinClass } from '@vaadin/component-base/src/element-mixin.js';
|
|
12
|
-
import type { OverlayClassMixinClass } from '@vaadin/component-base/src/overlay-class-mixin.js';
|
|
13
12
|
import type { ClearButtonMixinClass } from '@vaadin/field-base/src/clear-button-mixin.js';
|
|
14
13
|
import type { FieldMixinClass } from '@vaadin/field-base/src/field-mixin.js';
|
|
15
14
|
import type { InputConstraintsMixinClass } from '@vaadin/field-base/src/input-constraints-mixin.js';
|
|
@@ -22,6 +21,7 @@ import type { ThemableMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-th
|
|
|
22
21
|
import type { ThemePropertyMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
|
|
23
22
|
import type { ComboBoxBaseMixinClass } from './vaadin-combo-box-base-mixin.js';
|
|
24
23
|
import type { ComboBoxDataProviderMixinClass } from './vaadin-combo-box-data-provider-mixin.js';
|
|
24
|
+
import type { ComboBoxItemsMixinClass } from './vaadin-combo-box-items-mixin.js';
|
|
25
25
|
import type { ComboBoxMixinClass } from './vaadin-combo-box-mixin.js';
|
|
26
26
|
import type { ComboBoxDefaultItem } from './vaadin-combo-box-mixin.js';
|
|
27
27
|
|
|
@@ -175,33 +175,45 @@ export interface ComboBoxEventMap<TItem> extends HTMLElementEventMap {
|
|
|
175
175
|
* `--vaadin-combo-box-overlay-width` | Width of the overlay | `auto`
|
|
176
176
|
* `--vaadin-combo-box-overlay-max-height` | Max height of the overlay | `65vh`
|
|
177
177
|
*
|
|
178
|
-
*
|
|
179
|
-
* See [`<vaadin-text-field>`](#/elements/vaadin-text-field) for the styling documentation.
|
|
178
|
+
* The following shadow DOM parts are available for styling:
|
|
180
179
|
*
|
|
181
|
-
*
|
|
180
|
+
* Part name | Description
|
|
181
|
+
* ---------------------|----------------
|
|
182
|
+
* `label` | The label element
|
|
183
|
+
* `input-field` | The element that wraps prefix, value and buttons
|
|
184
|
+
* `field-button` | Set on both clear and toggle buttons
|
|
185
|
+
* `clear-button` | The clear button
|
|
186
|
+
* `error-message` | The error message element
|
|
187
|
+
* `helper-text` | The helper text element wrapper
|
|
188
|
+
* `required-indicator` | The `required` state indicator element
|
|
189
|
+
* `toggle-button` | The toggle button
|
|
190
|
+
* `overlay` | The overlay container
|
|
191
|
+
* `content` | The overlay content
|
|
192
|
+
* `loader` | The loading indicator shown while loading items
|
|
182
193
|
*
|
|
183
|
-
*
|
|
184
|
-
* ----------------|----------------
|
|
185
|
-
* `toggle-button` | The toggle button
|
|
194
|
+
* The following state attributes are available for styling:
|
|
186
195
|
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
* `
|
|
192
|
-
* `
|
|
196
|
+
* Attribute | Description
|
|
197
|
+
* ---------------------|---------------------------------
|
|
198
|
+
* `disabled` | Set when the element is disabled
|
|
199
|
+
* `has-value` | Set when the element has a value
|
|
200
|
+
* `has-label` | Set when the element has a label
|
|
201
|
+
* `has-helper` | Set when the element has helper text or slot
|
|
202
|
+
* `has-error-message` | Set when the element has an error message
|
|
203
|
+
* `has-tooltip` | Set when the element has a slotted tooltip
|
|
204
|
+
* `invalid` | Set when the element is invalid
|
|
205
|
+
* `focused` | Set when the element is focused
|
|
206
|
+
* `focus-ring` | Set when the element is keyboard focused
|
|
207
|
+
* `readonly` | Set when the element is readonly
|
|
208
|
+
* `opened` | Set when the overlay is opened
|
|
209
|
+
* `loading` | Set when loading items from the data provider
|
|
193
210
|
*
|
|
194
211
|
* ### Internal components
|
|
195
212
|
*
|
|
196
213
|
* In addition to `<vaadin-combo-box>` itself, the following internal
|
|
197
214
|
* components are themable:
|
|
198
215
|
*
|
|
199
|
-
* - `<vaadin-combo-box-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
|
|
200
216
|
* - `<vaadin-combo-box-item>` - has the same API as [`<vaadin-item>`](#/elements/vaadin-item).
|
|
201
|
-
* - [`<vaadin-input-container>`](#/elements/vaadin-input-container) - an internal element wrapping the input.
|
|
202
|
-
*
|
|
203
|
-
* Note: the `theme` attribute value set on `<vaadin-combo-box>` is
|
|
204
|
-
* propagated to the internal components listed above.
|
|
205
217
|
*
|
|
206
218
|
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
|
|
207
219
|
*
|
|
@@ -230,13 +242,13 @@ declare class ComboBox<TItem = ComboBoxDefaultItem> extends HTMLElement {
|
|
|
230
242
|
|
|
231
243
|
interface ComboBox<TItem = ComboBoxDefaultItem>
|
|
232
244
|
extends ComboBoxDataProviderMixinClass<TItem>,
|
|
245
|
+
ComboBoxItemsMixinClass<TItem>,
|
|
233
246
|
ComboBoxMixinClass<TItem>,
|
|
234
247
|
ComboBoxBaseMixinClass,
|
|
235
248
|
ValidateMixinClass,
|
|
236
249
|
PatternMixinClass,
|
|
237
250
|
LabelMixinClass,
|
|
238
251
|
KeyboardMixinClass,
|
|
239
|
-
OverlayClassMixinClass,
|
|
240
252
|
InputMixinClass,
|
|
241
253
|
ClearButtonMixinClass,
|
|
242
254
|
InputControlMixinClass,
|
package/src/vaadin-combo-box.js
CHANGED
|
@@ -20,7 +20,7 @@ import { PatternMixin } from '@vaadin/field-base/src/pattern-mixin.js';
|
|
|
20
20
|
import { inputFieldShared } from '@vaadin/field-base/src/styles/input-field-shared-styles.js';
|
|
21
21
|
import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
|
|
22
22
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
23
|
-
import { comboBoxStyles } from './styles/vaadin-combo-box-
|
|
23
|
+
import { comboBoxStyles } from './styles/vaadin-combo-box-base-styles.js';
|
|
24
24
|
import { ComboBoxDataProviderMixin } from './vaadin-combo-box-data-provider-mixin.js';
|
|
25
25
|
import { ComboBoxMixin } from './vaadin-combo-box-mixin.js';
|
|
26
26
|
|
|
@@ -107,33 +107,45 @@ import { ComboBoxMixin } from './vaadin-combo-box-mixin.js';
|
|
|
107
107
|
* `--vaadin-combo-box-overlay-width` | Width of the overlay | `auto`
|
|
108
108
|
* `--vaadin-combo-box-overlay-max-height` | Max height of the overlay | `65vh`
|
|
109
109
|
*
|
|
110
|
-
*
|
|
111
|
-
* See [`<vaadin-text-field>`](#/elements/vaadin-text-field) for the styling documentation.
|
|
110
|
+
* The following shadow DOM parts are available for styling:
|
|
112
111
|
*
|
|
113
|
-
*
|
|
112
|
+
* Part name | Description
|
|
113
|
+
* ---------------------|----------------
|
|
114
|
+
* `label` | The label element
|
|
115
|
+
* `input-field` | The element that wraps prefix, value and buttons
|
|
116
|
+
* `field-button` | Set on both clear and toggle buttons
|
|
117
|
+
* `clear-button` | The clear button
|
|
118
|
+
* `error-message` | The error message element
|
|
119
|
+
* `helper-text` | The helper text element wrapper
|
|
120
|
+
* `required-indicator` | The `required` state indicator element
|
|
121
|
+
* `toggle-button` | The toggle button
|
|
122
|
+
* `overlay` | The overlay container
|
|
123
|
+
* `content` | The overlay content
|
|
124
|
+
* `loader` | The loading indicator shown while loading items
|
|
114
125
|
*
|
|
115
|
-
*
|
|
116
|
-
* ----------------|----------------
|
|
117
|
-
* `toggle-button` | The toggle button
|
|
126
|
+
* The following state attributes are available for styling:
|
|
118
127
|
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* `
|
|
124
|
-
* `
|
|
128
|
+
* Attribute | Description
|
|
129
|
+
* ---------------------|---------------------------------
|
|
130
|
+
* `disabled` | Set when the element is disabled
|
|
131
|
+
* `has-value` | Set when the element has a value
|
|
132
|
+
* `has-label` | Set when the element has a label
|
|
133
|
+
* `has-helper` | Set when the element has helper text or slot
|
|
134
|
+
* `has-error-message` | Set when the element has an error message
|
|
135
|
+
* `has-tooltip` | Set when the element has a slotted tooltip
|
|
136
|
+
* `invalid` | Set when the element is invalid
|
|
137
|
+
* `focused` | Set when the element is focused
|
|
138
|
+
* `focus-ring` | Set when the element is keyboard focused
|
|
139
|
+
* `readonly` | Set when the element is readonly
|
|
140
|
+
* `opened` | Set when the overlay is opened
|
|
141
|
+
* `loading` | Set when loading items from the data provider
|
|
125
142
|
*
|
|
126
143
|
* ### Internal components
|
|
127
144
|
*
|
|
128
145
|
* In addition to `<vaadin-combo-box>` itself, the following internal
|
|
129
146
|
* components are themable:
|
|
130
147
|
*
|
|
131
|
-
* - `<vaadin-combo-box-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
|
|
132
148
|
* - `<vaadin-combo-box-item>` - has the same API as [`<vaadin-item>`](#/elements/vaadin-item).
|
|
133
|
-
* - [`<vaadin-input-container>`](#/elements/vaadin-input-container) - an internal element wrapping the input.
|
|
134
|
-
*
|
|
135
|
-
* Note: the `theme` attribute value set on `<vaadin-combo-box>` is
|
|
136
|
-
* propagated to the internal components listed above.
|
|
137
149
|
*
|
|
138
150
|
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
|
|
139
151
|
*
|
|
@@ -206,8 +218,8 @@ class ComboBox extends ComboBoxDataProviderMixin(
|
|
|
206
218
|
>
|
|
207
219
|
<slot name="prefix" slot="prefix"></slot>
|
|
208
220
|
<slot name="input"></slot>
|
|
209
|
-
<div id="clearButton" part="clear-button" slot="suffix" aria-hidden="true"></div>
|
|
210
|
-
<div id="toggleButton" part="toggle-button" slot="suffix" aria-hidden="true"></div>
|
|
221
|
+
<div id="clearButton" part="field-button clear-button" slot="suffix" aria-hidden="true"></div>
|
|
222
|
+
<div id="toggleButton" part="field-button toggle-button" slot="suffix" aria-hidden="true"></div>
|
|
211
223
|
</vaadin-input-container>
|
|
212
224
|
|
|
213
225
|
<div part="helper-text">
|
|
@@ -221,13 +233,17 @@ class ComboBox extends ComboBoxDataProviderMixin(
|
|
|
221
233
|
|
|
222
234
|
<vaadin-combo-box-overlay
|
|
223
235
|
id="overlay"
|
|
236
|
+
exportparts="overlay, content, loader"
|
|
224
237
|
.owner="${this}"
|
|
238
|
+
.dir="${this.dir}"
|
|
225
239
|
.opened="${this._overlayOpened}"
|
|
226
240
|
?loading="${this.loading}"
|
|
227
241
|
theme="${ifDefined(this._theme)}"
|
|
228
242
|
.positionTarget="${this._positionTarget}"
|
|
229
243
|
no-vertical-overlap
|
|
230
|
-
|
|
244
|
+
>
|
|
245
|
+
<slot name="overlay"></slot>
|
|
246
|
+
</vaadin-combo-box-overlay>
|
|
231
247
|
|
|
232
248
|
<slot name="tooltip"></slot>
|
|
233
249
|
`;
|
|
@@ -257,6 +273,15 @@ class ComboBox extends ComboBoxDataProviderMixin(
|
|
|
257
273
|
this._toggleElement = this.$.toggleButton;
|
|
258
274
|
}
|
|
259
275
|
|
|
276
|
+
/** @protected */
|
|
277
|
+
updated(props) {
|
|
278
|
+
super.updated(props);
|
|
279
|
+
|
|
280
|
+
if (props.has('dataProvider') || props.has('value')) {
|
|
281
|
+
this._warnDataProviderValue(this.dataProvider, this.value);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
260
285
|
/**
|
|
261
286
|
* Override the method from `InputControlMixin`
|
|
262
287
|
* to stop event propagation to prevent `ComboBoxMixin`
|
|
@@ -283,6 +308,22 @@ class ComboBox extends ComboBoxDataProviderMixin(
|
|
|
283
308
|
super._onHostClick(event);
|
|
284
309
|
}
|
|
285
310
|
}
|
|
311
|
+
|
|
312
|
+
/** @private */
|
|
313
|
+
_warnDataProviderValue(dataProvider, value) {
|
|
314
|
+
if (dataProvider && value !== '' && (this.selectedItem === undefined || this.selectedItem === null)) {
|
|
315
|
+
const valueIndex = this.__getItemIndexByValue(this.filteredItems, value);
|
|
316
|
+
if (valueIndex < 0 || !this._getItemLabel(this.filteredItems[valueIndex])) {
|
|
317
|
+
console.warn(
|
|
318
|
+
'Warning: unable to determine the label for the provided `value`. ' +
|
|
319
|
+
'Nothing to display in the text field. This usually happens when ' +
|
|
320
|
+
'setting an initial `value` before any items are returned from ' +
|
|
321
|
+
'the `dataProvider` callback. Consider setting `selectedItem` ' +
|
|
322
|
+
'instead of `value`',
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
286
327
|
}
|
|
287
328
|
|
|
288
329
|
defineCustomElement(ComboBox);
|
package/vaadin-combo-box.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import './
|
|
1
|
+
import './src/vaadin-combo-box.js';
|
|
2
2
|
export * from './src/vaadin-combo-box.js';
|