@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.
Files changed (34) hide show
  1. package/package.json +14 -17
  2. package/src/styles/vaadin-combo-box-base-styles.js +2 -2
  3. package/src/styles/vaadin-combo-box-overlay-base-styles.js +2 -2
  4. package/src/vaadin-combo-box-base-mixin.d.ts +0 -2
  5. package/src/vaadin-combo-box-base-mixin.js +9 -30
  6. package/src/vaadin-combo-box-data-provider-mixin.js +1 -21
  7. package/src/vaadin-combo-box-item-mixin.js +1 -1
  8. package/src/vaadin-combo-box-item.js +1 -1
  9. package/src/vaadin-combo-box-items-mixin.d.ts +60 -0
  10. package/src/vaadin-combo-box-items-mixin.js +292 -0
  11. package/src/vaadin-combo-box-mixin.d.ts +0 -42
  12. package/src/vaadin-combo-box-mixin.js +4 -236
  13. package/src/vaadin-combo-box-overlay-mixin.js +1 -25
  14. package/src/vaadin-combo-box-overlay.js +2 -2
  15. package/src/vaadin-combo-box-scroller-mixin.d.ts +1 -2
  16. package/src/vaadin-combo-box-scroller-mixin.js +5 -0
  17. package/src/vaadin-combo-box-scroller.js +1 -1
  18. package/src/vaadin-combo-box.d.ts +31 -19
  19. package/src/vaadin-combo-box.js +62 -21
  20. package/vaadin-combo-box.js +1 -1
  21. package/web-types.json +59 -70
  22. package/web-types.lit.json +20 -20
  23. package/src/styles/vaadin-combo-box-core-styles.d.ts +0 -8
  24. package/src/styles/vaadin-combo-box-core-styles.js +0 -12
  25. package/src/styles/vaadin-combo-box-overlay-core-styles.js +0 -18
  26. package/src/styles/vaadin-combo-box-scroller-core-styles.js +0 -27
  27. package/theme/lumo/vaadin-combo-box-item-styles.d.ts +0 -5
  28. package/theme/lumo/vaadin-combo-box-item-styles.js +0 -25
  29. package/theme/lumo/vaadin-combo-box-overlay-styles.d.ts +0 -6
  30. package/theme/lumo/vaadin-combo-box-overlay-styles.js +0 -60
  31. package/theme/lumo/vaadin-combo-box-styles.d.ts +0 -2
  32. package/theme/lumo/vaadin-combo-box-styles.js +0 -12
  33. package/theme/lumo/vaadin-combo-box.d.ts +0 -4
  34. package/theme/lumo/vaadin-combo-box.js +0 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/combo-box",
3
- "version": "25.0.0-alpha8",
3
+ "version": "25.0.0-beta1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -22,9 +22,6 @@
22
22
  "lit.d.ts",
23
23
  "lit.js",
24
24
  "src",
25
- "!src/styles/*-base-styles.d.ts",
26
- "!src/styles/*-base-styles.js",
27
- "theme",
28
25
  "vaadin-*.d.ts",
29
26
  "vaadin-*.js",
30
27
  "web-types.json",
@@ -38,26 +35,26 @@
38
35
  ],
39
36
  "dependencies": {
40
37
  "@open-wc/dedupe-mixin": "^1.3.0",
41
- "@vaadin/a11y-base": "25.0.0-alpha8",
42
- "@vaadin/component-base": "25.0.0-alpha8",
43
- "@vaadin/field-base": "25.0.0-alpha8",
44
- "@vaadin/input-container": "25.0.0-alpha8",
45
- "@vaadin/item": "25.0.0-alpha8",
46
- "@vaadin/lit-renderer": "25.0.0-alpha8",
47
- "@vaadin/overlay": "25.0.0-alpha8",
48
- "@vaadin/vaadin-lumo-styles": "25.0.0-alpha8",
49
- "@vaadin/vaadin-themable-mixin": "25.0.0-alpha8",
38
+ "@vaadin/a11y-base": "25.0.0-beta1",
39
+ "@vaadin/component-base": "25.0.0-beta1",
40
+ "@vaadin/field-base": "25.0.0-beta1",
41
+ "@vaadin/input-container": "25.0.0-beta1",
42
+ "@vaadin/item": "25.0.0-beta1",
43
+ "@vaadin/lit-renderer": "25.0.0-beta1",
44
+ "@vaadin/overlay": "25.0.0-beta1",
45
+ "@vaadin/vaadin-themable-mixin": "25.0.0-beta1",
50
46
  "lit": "^3.0.0"
51
47
  },
52
48
  "devDependencies": {
53
- "@vaadin/chai-plugins": "25.0.0-alpha8",
54
- "@vaadin/test-runner-commands": "25.0.0-alpha8",
49
+ "@vaadin/chai-plugins": "25.0.0-beta1",
50
+ "@vaadin/test-runner-commands": "25.0.0-beta1",
55
51
  "@vaadin/testing-helpers": "^2.0.0",
56
- "sinon": "^18.0.0"
52
+ "@vaadin/vaadin-lumo-styles": "25.0.0-beta1",
53
+ "sinon": "^21.0.0"
57
54
  },
58
55
  "web-types": [
59
56
  "web-types.json",
60
57
  "web-types.lit.json"
61
58
  ],
62
- "gitHead": "ebf53673d5f639d2b1b6f2b31f640f530643ee2f"
59
+ "gitHead": "1d20cf54e582d1f2e209126d4586f8b4c01c50e0"
63
60
  }
@@ -3,7 +3,7 @@
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 '@vaadin/component-base/src/style-props.js';
6
+ import '@vaadin/component-base/src/styles/style-props.js';
7
7
  import { css } from 'lit';
8
8
 
9
9
  export const comboBoxStyles = css`
@@ -11,7 +11,7 @@ export const comboBoxStyles = css`
11
11
  pointer-events: auto;
12
12
  }
13
13
 
14
- [part='toggle-button']::before {
14
+ [part~='toggle-button']::before {
15
15
  mask-image: var(--_vaadin-icon-chevron-down);
16
16
  }
17
17
  `;
@@ -3,9 +3,9 @@
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 '@vaadin/component-base/src/style-props.js';
6
+ import '@vaadin/component-base/src/styles/style-props.js';
7
7
  import { css } from 'lit';
8
- import { loaderStyles } from '@vaadin/component-base/src/loader-styles.js';
8
+ import { loaderStyles } from '@vaadin/component-base/src/styles/loader-styles.js';
9
9
 
10
10
  export const comboBoxOverlayStyles = [
11
11
  loaderStyles,
@@ -7,7 +7,6 @@ import type { Constructor } from '@open-wc/dedupe-mixin';
7
7
  import type { DisabledMixinClass } from '@vaadin/a11y-base/src/disabled-mixin.js';
8
8
  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
- import type { OverlayClassMixinClass } from '@vaadin/component-base/src/overlay-class-mixin.js';
11
10
  import type { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js';
12
11
  import type { ValidateMixinClass } from '@vaadin/field-base/src/validate-mixin.js';
13
12
 
@@ -18,7 +17,6 @@ export declare function ComboBoxBaseMixin<T extends Constructor<HTMLElement>>(
18
17
  Constructor<FocusMixinClass> &
19
18
  Constructor<InputMixinClass> &
20
19
  Constructor<KeyboardMixinClass> &
21
- Constructor<OverlayClassMixinClass> &
22
20
  Constructor<ValidateMixinClass> &
23
21
  T;
24
22
 
@@ -8,7 +8,6 @@ import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
8
8
  import { isElementFocused, isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
9
9
  import { KeyboardMixin } from '@vaadin/a11y-base/src/keyboard-mixin.js';
10
10
  import { isTouch } from '@vaadin/component-base/src/browser-utils.js';
11
- import { OverlayClassMixin } from '@vaadin/component-base/src/overlay-class-mixin.js';
12
11
  import { InputMixin } from '@vaadin/field-base/src/input-mixin.js';
13
12
  import { VirtualKeyboardController } from '@vaadin/field-base/src/virtual-keyboard-controller.js';
14
13
  import { ComboBoxPlaceholder } from './vaadin-combo-box-placeholder.js';
@@ -19,13 +18,10 @@ import { ComboBoxPlaceholder } from './vaadin-combo-box-placeholder.js';
19
18
  * @mixes FocusMixin
20
19
  * @mixes InputMixin
21
20
  * @mixes KeyboardMixin
22
- * @mixes OverlayClassMixin
23
21
  * @param {function(new:HTMLElement)} superClass
24
22
  */
25
23
  export const ComboBoxBaseMixin = (superClass) =>
26
- class ComboBoxMixinBaseClass extends OverlayClassMixin(
27
- KeyboardMixin(InputMixin(DisabledMixin(FocusMixin(superClass)))),
28
- ) {
24
+ class ComboBoxMixinBaseClass extends KeyboardMixin(InputMixin(DisabledMixin(FocusMixin(superClass)))) {
29
25
  static get properties() {
30
26
  return {
31
27
  /**
@@ -184,15 +180,6 @@ export const ComboBoxBaseMixin = (superClass) =>
184
180
  this.clearElement.addEventListener('mousedown', this._boundOnClearButtonMouseDown);
185
181
  }
186
182
 
187
- const bringToFrontListener = () => {
188
- requestAnimationFrame(() => {
189
- this._overlayElement.bringToFront();
190
- });
191
- };
192
-
193
- this.addEventListener('mousedown', bringToFrontListener);
194
- this.addEventListener('touchstart', bringToFrontListener);
195
-
196
183
  this.addController(new VirtualKeyboardController(this));
197
184
  }
198
185
 
@@ -241,14 +228,13 @@ export const ComboBoxBaseMixin = (superClass) =>
241
228
 
242
229
  /**
243
230
  * Create and initialize the scroller element.
244
- * Override to provide custom host reference.
245
231
  *
246
- * @protected
232
+ * @private
247
233
  */
248
- _initScroller(host) {
234
+ _initScroller() {
249
235
  const scroller = document.createElement(`${this._tagNamePrefix}-scroller`);
250
236
 
251
- scroller.owner = host || this;
237
+ scroller.owner = this;
252
238
  scroller.getItemLabel = this._getItemLabel.bind(this);
253
239
  scroller.addEventListener('selection-changed', this._boundOverlaySelectedItemChanged);
254
240
 
@@ -259,21 +245,14 @@ export const ComboBoxBaseMixin = (superClass) =>
259
245
 
260
246
  /**
261
247
  * Render the scroller element to the overlay.
262
- * Override to provide custom logic (e.g. setting "slot").
263
248
  *
264
- * @protected
249
+ * @private
265
250
  */
266
251
  _renderScroller(scroller) {
267
- const overlay = this.$.overlay;
268
-
269
- overlay.renderer = (root) => {
270
- if (!root.innerHTML) {
271
- root.appendChild(scroller);
272
- }
273
- };
274
-
275
- // Ensure the scroller is rendered
276
- overlay.requestContentUpdate();
252
+ scroller.setAttribute('slot', 'overlay');
253
+ // Prevent focusing scroller on input Tab
254
+ scroller.setAttribute('tabindex', '-1');
255
+ this.appendChild(scroller);
277
256
  }
278
257
 
279
258
  /**
@@ -58,11 +58,7 @@ export const ComboBoxDataProviderMixin = (superClass) =>
58
58
  }
59
59
 
60
60
  static get observers() {
61
- return [
62
- '_dataProviderFilterChanged(filter)',
63
- '_warnDataProviderValue(dataProvider, value)',
64
- '_ensureFirstPage(opened)',
65
- ];
61
+ return ['_dataProviderFilterChanged(filter)', '_ensureFirstPage(opened)'];
66
62
  }
67
63
 
68
64
  constructor() {
@@ -283,20 +279,4 @@ export const ComboBoxDataProviderMixin = (superClass) =>
283
279
  throw new Error('Using `items` and `dataProvider` together is not supported');
284
280
  }
285
281
  }
286
-
287
- /** @private */
288
- _warnDataProviderValue(dataProvider, value) {
289
- if (dataProvider && value !== '' && (this.selectedItem === undefined || this.selectedItem === null)) {
290
- const valueIndex = this.__getItemIndexByValue(this.filteredItems, value);
291
- if (valueIndex < 0 || !this._getItemLabel(this.filteredItems[valueIndex])) {
292
- console.warn(
293
- 'Warning: unable to determine the label for the provided `value`. ' +
294
- 'Nothing to display in the text field. This usually happens when ' +
295
- 'setting an initial `value` before any items are returned from ' +
296
- 'the `dataProvider` callback. Consider setting `selectedItem` ' +
297
- 'instead of `value`',
298
- );
299
- }
300
- }
301
- }
302
282
  };
@@ -92,7 +92,7 @@ export const ComboBoxItemMixin = (superClass) =>
92
92
 
93
93
  /** @protected */
94
94
  _getHostDir() {
95
- return this._owner && this._owner.getAttribute('dir');
95
+ return this._owner && this._owner.$.overlay.getAttribute('dir');
96
96
  }
97
97
 
98
98
  /**
@@ -7,7 +7,7 @@ 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 { itemStyles } from '@vaadin/item/src/styles/vaadin-item-core-styles.js';
10
+ import { itemStyles } from '@vaadin/item/src/styles/vaadin-item-base-styles.js';
11
11
  import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
12
12
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
13
13
  import { ComboBoxItemMixin } from './vaadin-combo-box-item-mixin.js';
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2015 - 2025 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 { ComboBoxBaseMixinClass } from './vaadin-combo-box-base-mixin.js';
8
+
9
+ export declare function ComboBoxItemsMixin<TItem, T extends Constructor<HTMLElement>>(
10
+ base: T,
11
+ ): Constructor<ComboBoxBaseMixinClass> & Constructor<ComboBoxItemsMixinClass<TItem>> & T;
12
+
13
+ export declare class ComboBoxItemsMixinClass<TItem> {
14
+ /**
15
+ * A full set of items to filter the visible options from.
16
+ * The items can be of either `String` or `Object` type.
17
+ */
18
+ items: TItem[] | undefined;
19
+
20
+ /**
21
+ * A subset of items, filtered based on the user input. Filtered items
22
+ * can be assigned directly to omit the internal filtering functionality.
23
+ * The items can be of either `String` or `Object` type.
24
+ */
25
+ filteredItems: TItem[] | undefined;
26
+
27
+ /**
28
+ * Filtering string the user has typed into the input field.
29
+ */
30
+ filter: string;
31
+
32
+ /**
33
+ * A function that is used to generate the label for dropdown
34
+ * items based on the item. Receives one argument:
35
+ * - `item` The item to generate the label for.
36
+ */
37
+ itemLabelGenerator: ((item: TItem) => string) | undefined;
38
+
39
+ /**
40
+ * Path for label of the item. If `items` is an array of objects, the
41
+ * `itemLabelPath` is used to fetch the displayed string label for each
42
+ * item.
43
+ *
44
+ * The item label is also used for matching items when processing user
45
+ * input, i.e., for filtering and selecting items.
46
+ * @attr {string} item-label-path
47
+ */
48
+ itemLabelPath: string;
49
+
50
+ /**
51
+ * Path for the value of the item. If `items` is an array of objects, the
52
+ * `itemValuePath:` is used to fetch the string value for the selected
53
+ * item.
54
+ *
55
+ * The item value is used in the `value` property of the combo box,
56
+ * to provide the form value.
57
+ * @attr {string} item-value-path
58
+ */
59
+ itemValuePath: string;
60
+ }
@@ -0,0 +1,292 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2015 - 2025 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { get } from '@vaadin/component-base/src/path-utils.js';
7
+ import { ComboBoxBaseMixin } from './vaadin-combo-box-base-mixin.js';
8
+ import { ComboBoxPlaceholder } from './vaadin-combo-box-placeholder.js';
9
+
10
+ /**
11
+ * Checks if the value is supported as an item value in this control.
12
+ *
13
+ * @param {unknown} value
14
+ * @return {boolean}
15
+ */
16
+ function isValidValue(value) {
17
+ return value !== undefined && value !== null;
18
+ }
19
+
20
+ /**
21
+ * Returns the index of the first item that satisfies the provided testing function
22
+ * ignoring placeholder items.
23
+ *
24
+ * @param {Array<ComboBoxItem | string>} items
25
+ * @param {Function} callback
26
+ * @return {number}
27
+ */
28
+ function findItemIndex(items, callback) {
29
+ return items.findIndex((item) => {
30
+ if (item instanceof ComboBoxPlaceholder) {
31
+ return false;
32
+ }
33
+
34
+ return callback(item);
35
+ });
36
+ }
37
+
38
+ /**
39
+ * @polymerMixin
40
+ * @mixes ComboBoxBaseMixin
41
+ */
42
+ export const ComboBoxItemsMixin = (superClass) =>
43
+ class ComboBoxItemsMixinClass extends ComboBoxBaseMixin(superClass) {
44
+ static get properties() {
45
+ return {
46
+ /**
47
+ * A full set of items to filter the visible options from.
48
+ * The items can be of either `String` or `Object` type.
49
+ * @type {!Array<!ComboBoxItem | string> | undefined}
50
+ */
51
+ items: {
52
+ type: Array,
53
+ sync: true,
54
+ observer: '_itemsChanged',
55
+ },
56
+
57
+ /**
58
+ * A subset of items, filtered based on the user input. Filtered items
59
+ * can be assigned directly to omit the internal filtering functionality.
60
+ * The items can be of either `String` or `Object` type.
61
+ * @type {!Array<!ComboBoxItem | string> | undefined}
62
+ */
63
+ filteredItems: {
64
+ type: Array,
65
+ observer: '_filteredItemsChanged',
66
+ sync: true,
67
+ },
68
+
69
+ /**
70
+ * Filtering string the user has typed into the input field.
71
+ * @type {string}
72
+ */
73
+ filter: {
74
+ type: String,
75
+ value: '',
76
+ notify: true,
77
+ sync: true,
78
+ },
79
+
80
+ /**
81
+ * A function that is used to generate the label for dropdown
82
+ * items based on the item. Receives one argument:
83
+ * - `item` The item to generate the label for.
84
+ */
85
+ itemLabelGenerator: {
86
+ type: Object,
87
+ },
88
+
89
+ /**
90
+ * Path for label of the item. If `items` is an array of objects, the
91
+ * `itemLabelPath` is used to fetch the displayed string label for each
92
+ * item.
93
+ *
94
+ * The item label is also used for matching items when processing user
95
+ * input, i.e., for filtering and selecting items.
96
+ * @attr {string} item-label-path
97
+ * @type {string}
98
+ */
99
+ itemLabelPath: {
100
+ type: String,
101
+ value: 'label',
102
+ observer: '_itemLabelPathChanged',
103
+ sync: true,
104
+ },
105
+
106
+ /**
107
+ * Path for the value of the item. If `items` is an array of objects, the
108
+ * `itemValuePath:` is used to fetch the string value for the selected
109
+ * item.
110
+ *
111
+ * The item value is used in the `value` property of the combo box,
112
+ * to provide the form value.
113
+ * @attr {string} item-value-path
114
+ * @type {string}
115
+ */
116
+ itemValuePath: {
117
+ type: String,
118
+ value: 'value',
119
+ sync: true,
120
+ },
121
+ };
122
+ }
123
+
124
+ /**
125
+ * @param {Object} props
126
+ * @protected
127
+ */
128
+ updated(props) {
129
+ super.updated(props);
130
+
131
+ if (props.has('filter')) {
132
+ this._filterChanged(this.filter);
133
+ }
134
+
135
+ if (props.has('itemLabelGenerator')) {
136
+ this.requestContentUpdate();
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Override an event listener from `ComboBoxBaseMixin` to handle
142
+ * batched setting of both `opened` and `filter` properties.
143
+ * @param {!Event} event
144
+ * @protected
145
+ * @override
146
+ */
147
+ _onInput(event) {
148
+ const filter = this._inputElementValue;
149
+
150
+ // When opening dropdown on user input, both `opened` and `filter` properties are set.
151
+ // Perform a batched property update instead of relying on sync property observers.
152
+ // This is necessary to avoid an extra data-provider request for loading first page.
153
+ const props = {};
154
+
155
+ if (this.filter === filter) {
156
+ // Filter and input value might get out of sync, while keyboard navigating for example.
157
+ // Afterwards, input value might be changed to the same value as used in filtering.
158
+ // In situation like these, we need to make sure all the filter changes handlers are run.
159
+ this._filterChanged(this.filter);
160
+ } else {
161
+ props.filter = filter;
162
+ }
163
+
164
+ if (!this.opened && !this._isClearButton(event) && !this.autoOpenDisabled) {
165
+ props.opened = true;
166
+ }
167
+
168
+ this.setProperties(props);
169
+ }
170
+
171
+ /**
172
+ * Override method from `ComboBoxBaseMixin` to handle item label path.
173
+ * @protected
174
+ * @override
175
+ */
176
+ _getItemLabel(item) {
177
+ if (typeof this.itemLabelGenerator === 'function' && item) {
178
+ return this.itemLabelGenerator(item) || '';
179
+ }
180
+
181
+ let label = item && this.itemLabelPath ? get(this.itemLabelPath, item) : undefined;
182
+ if (label === undefined || label === null) {
183
+ label = item ? item.toString() : '';
184
+ }
185
+ return label;
186
+ }
187
+
188
+ /** @protected */
189
+ _getItemValue(item) {
190
+ let value = item && this.itemValuePath ? get(this.itemValuePath, item) : undefined;
191
+ if (value === undefined) {
192
+ value = item ? item.toString() : '';
193
+ }
194
+ return value;
195
+ }
196
+
197
+ /** @private */
198
+ _itemLabelPathChanged(itemLabelPath) {
199
+ if (typeof itemLabelPath !== 'string') {
200
+ console.error('You should set itemLabelPath to a valid string');
201
+ }
202
+ }
203
+
204
+ /** @private */
205
+ _filterChanged(filter) {
206
+ // Scroll to the top of the list whenever the filter changes.
207
+ this._scrollIntoView(0);
208
+
209
+ this._focusedIndex = -1;
210
+
211
+ if (this.items) {
212
+ this.filteredItems = this._filterItems(this.items, filter);
213
+ } else {
214
+ // With certain use cases (e. g., external filtering), `items` are
215
+ // undefined. Filtering is unnecessary per se, but the filteredItems
216
+ // observer should still be invoked to update focused item.
217
+ this._filteredItemsChanged(this.filteredItems);
218
+ }
219
+ }
220
+
221
+ /** @private */
222
+ _itemsChanged(items, oldItems) {
223
+ this._ensureItemsOrDataProvider(() => {
224
+ this.items = oldItems;
225
+ });
226
+
227
+ if (items) {
228
+ this.filteredItems = items.slice(0);
229
+ } else if (oldItems) {
230
+ // Only clear filteredItems if the component had items previously but got cleared
231
+ this.filteredItems = null;
232
+ }
233
+ }
234
+
235
+ /** @private */
236
+ _filteredItemsChanged(filteredItems) {
237
+ this._setDropdownItems(filteredItems);
238
+ }
239
+
240
+ /**
241
+ * Provide items to be rendered in the dropdown.
242
+ * Override to provide actual implementation.
243
+ * @protected
244
+ */
245
+ _setDropdownItems() {
246
+ // To be implemented
247
+ }
248
+
249
+ /** @private */
250
+ _filterItems(arr, filter) {
251
+ if (!arr) {
252
+ return arr;
253
+ }
254
+
255
+ const filteredItems = arr.filter((item) => {
256
+ filter = filter ? filter.toString().toLowerCase() : '';
257
+ // Check if item contains input value.
258
+ return this._getItemLabel(item).toString().toLowerCase().indexOf(filter) > -1;
259
+ });
260
+
261
+ return filteredItems;
262
+ }
263
+
264
+ /**
265
+ * Returns the first item that matches the provided value.
266
+ * @protected
267
+ */
268
+ __getItemIndexByValue(items, value) {
269
+ if (!items || !isValidValue(value)) {
270
+ return -1;
271
+ }
272
+
273
+ return findItemIndex(items, (item) => {
274
+ return this._getItemValue(item) === value;
275
+ });
276
+ }
277
+
278
+ /**
279
+ * Returns the first item that matches the provided label.
280
+ * Labels are matched against each other case insensitively.
281
+ * @protected
282
+ */
283
+ __getItemIndexByLabel(items, label) {
284
+ if (!items || !label) {
285
+ return -1;
286
+ }
287
+
288
+ return findItemIndex(items, (item) => {
289
+ return this._getItemLabel(item).toString().toLowerCase() === label.toString().toLowerCase();
290
+ });
291
+ }
292
+ };
@@ -7,7 +7,6 @@ import type { Constructor } from '@open-wc/dedupe-mixin';
7
7
  import type { DisabledMixinClass } from '@vaadin/a11y-base/src/disabled-mixin.js';
8
8
  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
- import type { OverlayClassMixinClass } from '@vaadin/component-base/src/overlay-class-mixin.js';
11
10
  import type { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js';
12
11
  import type { ValidateMixinClass } from '@vaadin/field-base/src/validate-mixin.js';
13
12
  import type { ComboBox } from './vaadin-combo-box.js';
@@ -26,7 +25,6 @@ export declare function ComboBoxMixin<TItem, T extends Constructor<HTMLElement>>
26
25
  Constructor<FocusMixinClass> &
27
26
  Constructor<InputMixinClass> &
28
27
  Constructor<KeyboardMixinClass> &
29
- Constructor<OverlayClassMixinClass> &
30
28
  Constructor<ValidateMixinClass> &
31
29
  T;
32
30
 
@@ -44,12 +42,6 @@ export declare class ComboBoxMixinClass<TItem> {
44
42
  */
45
43
  renderer: ComboBoxRenderer<TItem> | null | undefined;
46
44
 
47
- /**
48
- * A full set of items to filter the visible options from.
49
- * The items can be of either `String` or `Object` type.
50
- */
51
- items: TItem[] | undefined;
52
-
53
45
  /**
54
46
  * A function used to generate CSS class names for dropdown
55
47
  * items based on the item. The return value should be the
@@ -67,13 +59,6 @@ export declare class ComboBoxMixinClass<TItem> {
67
59
  */
68
60
  allowCustomValue: boolean;
69
61
 
70
- /**
71
- * A subset of items, filtered based on the user input. Filtered items
72
- * can be assigned directly to omit the internal filtering functionality.
73
- * The items can be of either `String` or `Object` type.
74
- */
75
- filteredItems: TItem[] | undefined;
76
-
77
62
  /**
78
63
  * The `String` value for the selected item of the combo box.
79
64
  *
@@ -89,38 +74,11 @@ export declare class ComboBoxMixinClass<TItem> {
89
74
  */
90
75
  loading: boolean;
91
76
 
92
- /**
93
- * Filtering string the user has typed into the input field.
94
- */
95
- filter: string;
96
-
97
77
  /**
98
78
  * The selected item from the `items` array.
99
79
  */
100
80
  selectedItem: TItem | null | undefined;
101
81
 
102
- /**
103
- * Path for label of the item. If `items` is an array of objects, the
104
- * `itemLabelPath` is used to fetch the displayed string label for each
105
- * item.
106
- *
107
- * The item label is also used for matching items when processing user
108
- * input, i.e., for filtering and selecting items.
109
- * @attr {string} item-label-path
110
- */
111
- itemLabelPath: string;
112
-
113
- /**
114
- * Path for the value of the item. If `items` is an array of objects, the
115
- * `itemValuePath:` is used to fetch the string value for the selected
116
- * item.
117
- *
118
- * The item value is used in the `value` property of the combo box,
119
- * to provide the form value.
120
- * @attr {string} item-value-path
121
- */
122
- itemValuePath: string;
123
-
124
82
  /**
125
83
  * Path for the id of the item. If `items` is an array of objects,
126
84
  * the `itemIdPath` is used to compare and identify the same item