@vaadin/component-base 23.2.11 → 23.2.12

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/component-base",
3
- "version": "23.2.11",
3
+ "version": "23.2.12",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -42,5 +42,5 @@
42
42
  "@vaadin/testing-helpers": "^0.3.2",
43
43
  "sinon": "^13.0.2"
44
44
  },
45
- "gitHead": "1f5ad874238211488c43bb1bd302975170d06b23"
45
+ "gitHead": "ab3cb30a6af93cb7ea2891ba1f688cb68d4cf928"
46
46
  }
@@ -39,7 +39,7 @@ const registered = new Set();
39
39
  export const ElementMixin = (superClass) =>
40
40
  class VaadinElementMixin extends DirMixin(superClass) {
41
41
  static get version() {
42
- return '23.2.11';
42
+ return '23.2.12';
43
43
  }
44
44
 
45
45
  /** @protected */
@@ -15,7 +15,17 @@ const IOS_TOUCH_SCROLLING = IOS && IOS[1] >= 8;
15
15
  const DEFAULT_PHYSICAL_COUNT = 3;
16
16
 
17
17
  /**
18
- * @private
18
+ * DO NOT EDIT THIS FILE!
19
+ *
20
+ * This file includes the iron-list scrolling engine copied from
21
+ * https://github.com/PolymerElements/iron-list/blob/master/iron-list.js
22
+ *
23
+ * If something in the scrolling engine needs to be changed
24
+ * for the virtualizer's purposes, override a function
25
+ * in virtualizer-iron-list-adapter.js instead of changing it here.
26
+ *
27
+ * This will allow us to keep the iron-list code here as close to
28
+ * the original as possible.
19
29
  */
20
30
  export const ironList = {
21
31
  /**
@@ -34,6 +34,7 @@ export class IronListAdapter {
34
34
  this.timeouts = {
35
35
  SCROLL_REORDER: 500,
36
36
  IGNORE_WHEEL: 500,
37
+ FIX_INVALID_ITEM_POSITIONING: 100,
37
38
  };
38
39
 
39
40
  this.__resizeObserver = new ResizeObserver(() => this._resizeHandler());
@@ -121,6 +122,9 @@ export class IronListAdapter {
121
122
  this._resizeHandler();
122
123
  flush();
123
124
  this._scrollHandler();
125
+ if (this.__fixInvalidItemPositioningDebouncer) {
126
+ this.__fixInvalidItemPositioningDebouncer.flush();
127
+ }
124
128
  if (this.__scrollReorderDebouncer) {
125
129
  this.__scrollReorderDebouncer.flush();
126
130
  }
@@ -184,6 +188,14 @@ export class IronListAdapter {
184
188
  if (size === this.size) {
185
189
  return;
186
190
  }
191
+ // Cancel active debouncers
192
+ if (this.__fixInvalidItemPositioningDebouncer) {
193
+ this.__fixInvalidItemPositioningDebouncer.cancel();
194
+ }
195
+ if (this._debouncers && this._debouncers._increasePoolIfNeeded) {
196
+ // Avoid creating unnecessary elements on the following flush()
197
+ this._debouncers._increasePoolIfNeeded.cancel();
198
+ }
187
199
 
188
200
  // Prevent element update while the scroll position is being restored
189
201
  this.__preventElementUpdates = true;
@@ -199,10 +211,6 @@ export class IronListAdapter {
199
211
  // Change the size
200
212
  this.__size = size;
201
213
 
202
- // Flush before invoking items change to avoid
203
- // creating excess elements on the following flush()
204
- flush();
205
-
206
214
  this._itemsChanged({
207
215
  path: 'items',
208
216
  });
@@ -344,6 +352,15 @@ export class IronListAdapter {
344
352
  }
345
353
  }
346
354
 
355
+ if (delta) {
356
+ // There was a change in scroll top. Schedule a check for invalid item positioning.
357
+ this.__fixInvalidItemPositioningDebouncer = Debouncer.debounce(
358
+ this.__fixInvalidItemPositioningDebouncer,
359
+ timeOut.after(this.timeouts.FIX_INVALID_ITEM_POSITIONING),
360
+ () => this.__fixInvalidItemPositioning(),
361
+ );
362
+ }
363
+
347
364
  if (this.reorderElements) {
348
365
  this.__scrollReorderDebouncer = Debouncer.debounce(
349
366
  this.__scrollReorderDebouncer,
@@ -355,9 +372,46 @@ export class IronListAdapter {
355
372
  this.__previousScrollTop = this._scrollTop;
356
373
 
357
374
  // If the first visible index is not 0 when scrolled to the top,
358
- // add some scroll offset to enable the user to continue scrolling.
359
- if (this._scrollTop === 0 && this.firstVisibleIndex !== 0) {
360
- this._scrollTop = 1;
375
+ // scroll to index 0 to fix the issue.
376
+ if (this._scrollTop === 0 && this.firstVisibleIndex !== 0 && Math.abs(delta) > 0) {
377
+ this.scrollToIndex(0);
378
+ }
379
+ }
380
+
381
+ /**
382
+ * Work around an iron-list issue with invalid item positioning.
383
+ * See https://github.com/vaadin/flow-components/issues/4306
384
+ * @private
385
+ */
386
+ __fixInvalidItemPositioning() {
387
+ if (!this.scrollTarget.isConnected) {
388
+ return;
389
+ }
390
+
391
+ // Check if the first physical item element is below the top of the viewport
392
+ const physicalTopBelowTop = this._physicalTop > this._scrollTop;
393
+ // Check if the last physical item element is above the bottom of the viewport
394
+ const physicalBottomAboveBottom = this._physicalBottom < this._scrollBottom;
395
+
396
+ // Check if the first index is visible
397
+ const firstIndexVisible = this.adjustedFirstVisibleIndex === 0;
398
+ // Check if the last index is visible
399
+ const lastIndexVisible = this.adjustedLastVisibleIndex === this.size - 1;
400
+
401
+ if ((physicalTopBelowTop && !firstIndexVisible) || (physicalBottomAboveBottom && !lastIndexVisible)) {
402
+ // Invalid state! Try to recover.
403
+
404
+ const isScrollingDown = physicalBottomAboveBottom;
405
+ // Set the "_ratio" property temporarily to 0 to make iron-list's _getReusables
406
+ // place all the free physical items on one side of the viewport.
407
+ const originalRatio = this._ratio;
408
+ this._ratio = 0;
409
+ // Fake a scroll change to make _scrollHandler place the physical items
410
+ // on the desired side.
411
+ this._scrollPosition = this._scrollTop + (isScrollingDown ? -1 : 1);
412
+ this._scrollHandler();
413
+ // Restore the original "_ratio" value.
414
+ this._ratio = originalRatio;
361
415
  }
362
416
  }
363
417