@vaadin/combo-box 25.1.2 → 25.2.0-alpha10

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/combo-box",
3
- "version": "25.1.2",
3
+ "version": "25.2.0-alpha10",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -36,22 +36,22 @@
36
36
  ],
37
37
  "dependencies": {
38
38
  "@open-wc/dedupe-mixin": "^1.3.0",
39
- "@vaadin/a11y-base": "~25.1.2",
40
- "@vaadin/component-base": "~25.1.2",
41
- "@vaadin/field-base": "~25.1.2",
42
- "@vaadin/input-container": "~25.1.2",
43
- "@vaadin/item": "~25.1.2",
44
- "@vaadin/lit-renderer": "~25.1.2",
45
- "@vaadin/overlay": "~25.1.2",
46
- "@vaadin/vaadin-themable-mixin": "~25.1.2",
39
+ "@vaadin/a11y-base": "25.2.0-alpha10",
40
+ "@vaadin/component-base": "25.2.0-alpha10",
41
+ "@vaadin/field-base": "25.2.0-alpha10",
42
+ "@vaadin/input-container": "25.2.0-alpha10",
43
+ "@vaadin/item": "25.2.0-alpha10",
44
+ "@vaadin/lit-renderer": "25.2.0-alpha10",
45
+ "@vaadin/overlay": "25.2.0-alpha10",
46
+ "@vaadin/vaadin-themable-mixin": "25.2.0-alpha10",
47
47
  "lit": "^3.0.0"
48
48
  },
49
49
  "devDependencies": {
50
- "@vaadin/aura": "~25.1.2",
51
- "@vaadin/chai-plugins": "~25.1.2",
52
- "@vaadin/test-runner-commands": "~25.1.2",
50
+ "@vaadin/aura": "25.2.0-alpha10",
51
+ "@vaadin/chai-plugins": "25.2.0-alpha10",
52
+ "@vaadin/test-runner-commands": "25.2.0-alpha10",
53
53
  "@vaadin/testing-helpers": "^2.0.0",
54
- "@vaadin/vaadin-lumo-styles": "~25.1.2",
54
+ "@vaadin/vaadin-lumo-styles": "25.2.0-alpha10",
55
55
  "sinon": "^21.0.2"
56
56
  },
57
57
  "customElements": "custom-elements.json",
@@ -59,5 +59,5 @@
59
59
  "web-types.json",
60
60
  "web-types.lit.json"
61
61
  ],
62
- "gitHead": "48e5dc507ac5eb8d34839be06cac652f1635fe1c"
62
+ "gitHead": "1303b6a3eeecb44a9d26f2b53cb56d9e906febdf"
63
63
  }
@@ -177,7 +177,7 @@ export const ComboBoxMixin = (superClass) =>
177
177
  _openedOrItemsChanged(opened, items, loading, keepOverlayOpened) {
178
178
  // Close the overlay if there are no items to display.
179
179
  // See https://github.com/vaadin/vaadin-combo-box/pull/964
180
- this._overlayOpened = opened && (keepOverlayOpened || loading || !!(items && items.length));
180
+ this._overlayOpened = opened && (keepOverlayOpened || loading || !!items?.length);
181
181
  }
182
182
 
183
183
  /**
@@ -552,43 +552,4 @@ export const ComboBoxMixin = (superClass) =>
552
552
 
553
553
  super._handleFocusOut();
554
554
  }
555
-
556
- /**
557
- * Fired when the value changes.
558
- *
559
- * @event value-changed
560
- * @param {Object} detail
561
- * @param {String} detail.value the combobox value
562
- */
563
-
564
- /**
565
- * Fired when selected item changes.
566
- *
567
- * @event selected-item-changed
568
- * @param {Object} detail
569
- * @param {Object|String} detail.value the selected item. Type is the same as the type of `items`.
570
- */
571
-
572
- /**
573
- * Fired when the user sets a custom value.
574
- * @event custom-value-set
575
- * @param {String} detail the custom value
576
- */
577
-
578
- /**
579
- * Fired when the user commits a value change.
580
- * @event change
581
- */
582
-
583
- /**
584
- * Fired after the `vaadin-combo-box-overlay` opens.
585
- *
586
- * @event vaadin-combo-box-dropdown-opened
587
- */
588
-
589
- /**
590
- * Fired after the `vaadin-combo-box-overlay` closes.
591
- *
592
- * @event vaadin-combo-box-dropdown-closed
593
- */
594
555
  };
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2015 - 2026 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
+
8
+ export declare function ComboBoxScrollToIndexMixin<T extends Constructor<HTMLElement>>(
9
+ base: T,
10
+ ): Constructor<ComboBoxScrollToIndexMixinClass> & T;
11
+
12
+ export declare class ComboBoxScrollToIndexMixinClass {
13
+ /**
14
+ * Scrolls the dropdown to the item at the given index and sets it as the
15
+ * focused (highlighted) item. Safe to call before the dropdown is opened
16
+ * or while the data provider is loading: the call is queued and executed
17
+ * once the overlay is open and not loading.
18
+ *
19
+ * Because this sets the focused item, closing the dropdown without an
20
+ * explicit selection change (e.g. via outside click or blur) will commit
21
+ * the focused item as `selectedItem`. In the typical use case (scroll to
22
+ * the currently selected item) this is a no-op; callers scrolling to a
23
+ * different index should be aware of this behavior.
24
+ *
25
+ * @param index Index of the item to scroll to
26
+ */
27
+ scrollToIndex(index: number): void;
28
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2015 - 2026 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { ComboBoxPlaceholder } from './vaadin-combo-box-placeholder.js';
7
+
8
+ /**
9
+ * @polymerMixin
10
+ */
11
+ export const ComboBoxScrollToIndexMixin = (superClass) =>
12
+ class ScrollToIndexMixin extends superClass {
13
+ static get observers() {
14
+ return ['__clearPendingScrollOnFilter(filter)'];
15
+ }
16
+
17
+ /**
18
+ * Scrolls the dropdown to the item at the given index and sets it as the
19
+ * focused (highlighted) item. Safe to call before the dropdown is opened
20
+ * or while the data provider is loading: the call is queued and executed
21
+ * once the overlay is open and not loading.
22
+ *
23
+ * Because this sets the focused item, closing the dropdown without an
24
+ * explicit selection change (e.g. via outside click or blur) will commit
25
+ * the focused item as `selectedItem`. In the typical use case (scroll to
26
+ * the currently selected item) this is a no-op; callers scrolling to a
27
+ * different index should be aware of this behavior.
28
+ *
29
+ * @param {number} index Index of the item to scroll to
30
+ */
31
+ scrollToIndex(index) {
32
+ if (typeof index !== 'number' || Number.isNaN(index) || index < 0) {
33
+ return;
34
+ }
35
+
36
+ if (!this._overlayOpened || this.loading) {
37
+ this.__scrollToPendingIndex = index;
38
+ return;
39
+ }
40
+
41
+ if (!this._dropdownItems || index >= this._dropdownItems.length) {
42
+ return;
43
+ }
44
+
45
+ if (this._dropdownItems[index] instanceof ComboBoxPlaceholder) {
46
+ // The target item is on a page that has not been loaded yet. Request
47
+ // the page directly and queue the focus-index update for after the
48
+ // page loads (see `__onDataProviderPageLoaded` →
49
+ // `__scrollToPendingIndexIfNeeded`). Relying on `_scrollIntoView` to
50
+ // trigger the page load via the visible-placeholder `index-requested`
51
+ // chain is unreliable on reopen with cached data: the virtualizer
52
+ // has just been torn down by closing the overlay and its scroll API
53
+ // is a no-op while it rebuilds physical items.
54
+ this.__scrollToPendingIndex = index;
55
+ this.__dataProviderController.ensureFlatIndexLoaded(index);
56
+ return;
57
+ }
58
+
59
+ delete this.__scrollToPendingIndex;
60
+ this._focusedIndex = index;
61
+ requestAnimationFrame(() => {
62
+ if (this.isConnected) {
63
+ this._updateActiveDescendant(index);
64
+ }
65
+ });
66
+ }
67
+
68
+ /** @private */
69
+ __scrollToPendingIndexIfNeeded() {
70
+ if (this.__scrollToPendingIndex !== undefined && !this.loading) {
71
+ this.scrollToIndex(this.__scrollToPendingIndex);
72
+ }
73
+ }
74
+
75
+ /** @private */
76
+ __clearPendingScrollOnFilter() {
77
+ delete this.__scrollToPendingIndex;
78
+ }
79
+
80
+ /**
81
+ * Override method from `ComboBoxBaseMixin` to flush any pending
82
+ * `scrollToIndex` call after the overlay opens.
83
+ *
84
+ * @protected
85
+ * @override
86
+ */
87
+ _onOpened() {
88
+ super._onOpened();
89
+ this.__scrollToPendingIndexIfNeeded();
90
+ }
91
+
92
+ /**
93
+ * Override method from `ComboBoxDataProviderMixin` to flush any pending
94
+ * `scrollToIndex` call after a data-provider page lands.
95
+ *
96
+ * @private
97
+ * @override
98
+ */
99
+ __onDataProviderPageLoaded() {
100
+ super.__onDataProviderPageLoaded();
101
+ this.__scrollToPendingIndexIfNeeded();
102
+ }
103
+ };
@@ -262,6 +262,25 @@ export const ComboBoxScrollerMixin = (superClass) =>
262
262
  }
263
263
 
264
264
  this.requestContentUpdate();
265
+ return;
266
+ }
267
+
268
+ // Reset the DOM scrollTop and the virtualizer adapter's
269
+ // `_scrollPosition` cache. Without the cache reset, the adapter's
270
+ // ResizeObserver restores the prior offset when the overlay becomes
271
+ // visible again, leaving the next open stuck at the previous offset
272
+ // (or blank with dataProvider) until the user scrolls. The
273
+ // virtualizer's own `scrollToIndex` can't help — by the time this
274
+ // observer runs, `offsetHeight` is already 0 and its scroll API is
275
+ // a no-op. Guarded on `_scrollPosition > 0` so the reset is skipped
276
+ // when there is nothing to reset (e.g. the initial observer run
277
+ // before the dropdown has ever been opened); unconditionally
278
+ // touching `scrollTop` on connect can affect the outer document's
279
+ // scroll position (see the combo-box re-layout integration test).
280
+ const adapter = this.__virtualizer && this.__virtualizer.__adapter;
281
+ if (adapter && adapter._scrollPosition > 0) {
282
+ this.scrollTop = 0;
283
+ adapter._scrollPosition = 0;
265
284
  }
266
285
  }
267
286
 
@@ -24,6 +24,7 @@ import type { ComboBoxDataProviderMixinClass } from './vaadin-combo-box-data-pro
24
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
+ import type { ComboBoxScrollToIndexMixinClass } from './vaadin-combo-box-scroll-to-index-mixin.js';
27
28
 
28
29
  export {
29
30
  ComboBoxDataProvider,
@@ -225,6 +226,8 @@ export interface ComboBoxEventMap<TItem> extends HTMLElementEventMap {
225
226
  * @fires {CustomEvent} selected-item-changed - Fired when the `selectedItem` property changes.
226
227
  * @fires {CustomEvent} value-changed - Fired when the `value` property changes.
227
228
  * @fires {CustomEvent} validated - Fired whenever the field is validated.
229
+ * @fires {CustomEvent} vaadin-combo-box-dropdown-opened - Fired after the `vaadin-combo-box-overlay` opens.
230
+ * @fires {CustomEvent} vaadin-combo-box-dropdown-closed - Fired after the `vaadin-combo-box-overlay` closes.
228
231
  */
229
232
  declare class ComboBox<TItem = ComboBoxDefaultItem> extends HTMLElement {
230
233
  addEventListener<K extends keyof ComboBoxEventMap<TItem>>(
@@ -245,6 +248,7 @@ interface ComboBox<TItem = ComboBoxDefaultItem>
245
248
  ComboBoxDataProviderMixinClass<TItem>,
246
249
  ComboBoxItemsMixinClass<TItem>,
247
250
  ComboBoxMixinClass<TItem>,
251
+ ComboBoxScrollToIndexMixinClass,
248
252
  ComboBoxBaseMixinClass,
249
253
  ValidateMixinClass,
250
254
  PatternMixinClass,
@@ -23,6 +23,7 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
23
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
+ import { ComboBoxScrollToIndexMixin } from './vaadin-combo-box-scroll-to-index-mixin.js';
26
27
 
27
28
  /**
28
29
  * `<vaadin-combo-box>` is a web component for choosing a value from a filterable list of options
@@ -157,6 +158,8 @@ import { ComboBoxMixin } from './vaadin-combo-box-mixin.js';
157
158
  * @fires {CustomEvent} selected-item-changed - Fired when the `selectedItem` property changes.
158
159
  * @fires {CustomEvent} value-changed - Fired when the `value` property changes.
159
160
  * @fires {CustomEvent} validated - Fired whenever the field is validated.
161
+ * @fires {CustomEvent} vaadin-combo-box-dropdown-opened - Fired after the `vaadin-combo-box-overlay` opens.
162
+ * @fires {CustomEvent} vaadin-combo-box-dropdown-closed - Fired after the `vaadin-combo-box-overlay` closes.
160
163
  *
161
164
  * @customElement vaadin-combo-box
162
165
  * @extends HTMLElement
@@ -166,10 +169,13 @@ import { ComboBoxMixin } from './vaadin-combo-box-mixin.js';
166
169
  * @mixes PatternMixin
167
170
  * @mixes ComboBoxDataProviderMixin
168
171
  * @mixes ComboBoxMixin
172
+ * @mixes ComboBoxScrollToIndexMixin
169
173
  */
170
- class ComboBox extends ComboBoxDataProviderMixin(
171
- ComboBoxMixin(
172
- PatternMixin(InputControlMixin(ThemableMixin(ElementMixin(PolylitMixin(LumoInjectionMixin(LitElement)))))),
174
+ class ComboBox extends ComboBoxScrollToIndexMixin(
175
+ ComboBoxDataProviderMixin(
176
+ ComboBoxMixin(
177
+ PatternMixin(InputControlMixin(ThemableMixin(ElementMixin(PolylitMixin(LumoInjectionMixin(LitElement)))))),
178
+ ),
173
179
  ),
174
180
  ) {
175
181
  static get is() {