@vaadin/component-base 24.0.0-alpha7 → 24.0.0-alpha9

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 (60) hide show
  1. package/package.json +2 -2
  2. package/src/a11y-announcer.d.ts +1 -1
  3. package/src/a11y-announcer.js +1 -1
  4. package/src/active-mixin.d.ts +1 -1
  5. package/src/active-mixin.js +1 -1
  6. package/src/browser-utils.js +7 -7
  7. package/src/controller-mixin.d.ts +1 -1
  8. package/src/controller-mixin.js +1 -1
  9. package/src/delegate-focus-mixin.d.ts +48 -0
  10. package/src/delegate-focus-mixin.js +228 -0
  11. package/src/delegate-state-mixin.d.ts +20 -0
  12. package/src/delegate-state-mixin.js +125 -0
  13. package/src/dir-mixin.d.ts +1 -5
  14. package/src/dir-mixin.js +1 -31
  15. package/src/dir-utils.d.ts +19 -0
  16. package/src/dir-utils.js +36 -0
  17. package/src/disabled-mixin.d.ts +1 -1
  18. package/src/disabled-mixin.js +1 -1
  19. package/src/dom-utils.d.ts +1 -1
  20. package/src/dom-utils.js +1 -1
  21. package/src/element-mixin.d.ts +1 -1
  22. package/src/element-mixin.js +11 -5
  23. package/src/focus-mixin.d.ts +1 -1
  24. package/src/focus-mixin.js +1 -1
  25. package/src/focus-trap-controller.d.ts +1 -1
  26. package/src/focus-trap-controller.js +1 -1
  27. package/src/focus-utils.d.ts +1 -1
  28. package/src/focus-utils.js +1 -1
  29. package/src/gestures.js +1 -1
  30. package/src/iron-list-core.js +32 -12
  31. package/src/keyboard-direction-mixin.d.ts +1 -1
  32. package/src/keyboard-direction-mixin.js +1 -1
  33. package/src/keyboard-mixin.d.ts +1 -1
  34. package/src/keyboard-mixin.js +1 -1
  35. package/src/list-mixin.d.ts +1 -1
  36. package/src/list-mixin.js +5 -6
  37. package/src/media-query-controller.d.ts +1 -1
  38. package/src/media-query-controller.js +1 -1
  39. package/src/overflow-controller.d.ts +1 -1
  40. package/src/overflow-controller.js +1 -1
  41. package/src/overlay-class-mixin.d.ts +33 -0
  42. package/src/overlay-class-mixin.js +79 -0
  43. package/src/polylit-mixin.d.ts +1 -1
  44. package/src/polylit-mixin.js +9 -4
  45. package/src/resize-mixin.d.ts +1 -1
  46. package/src/resize-mixin.js +1 -1
  47. package/src/{slot-observe-controller.d.ts → slot-child-observe-controller.d.ts} +2 -2
  48. package/src/{slot-observe-controller.js → slot-child-observe-controller.js} +2 -2
  49. package/src/slot-controller.d.ts +1 -1
  50. package/src/slot-controller.js +1 -1
  51. package/src/tabindex-mixin.d.ts +1 -1
  52. package/src/tabindex-mixin.js +1 -1
  53. package/src/templates.js +1 -1
  54. package/src/tooltip-controller.d.ts +1 -1
  55. package/src/tooltip-controller.js +1 -1
  56. package/src/unique-id-utils.d.ts +1 -1
  57. package/src/unique-id-utils.js +1 -1
  58. package/src/virtualizer-iron-list-adapter.js +65 -9
  59. package/src/dir-helper.d.ts +0 -42
  60. package/src/dir-helper.js +0 -93
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { animationFrame, timeOut } from './async.js';
@@ -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
 
@@ -376,7 +430,9 @@ export class IronListAdapter {
376
430
  deltaY *= this._scrollPageHeight;
377
431
  }
378
432
 
379
- this._deltaYAcc ||= 0;
433
+ if (!this._deltaYAcc) {
434
+ this._deltaYAcc = 0;
435
+ }
380
436
 
381
437
  if (this._wheelAnimationFrame) {
382
438
  // Accumulate wheel delta while a frame is being processed
@@ -1,42 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
-
7
- /**
8
- * Helper that provides a set of functions for RTL.
9
- */
10
- declare class DirHelper {
11
- /**
12
- * Get the scroll type in the current browser view.
13
- *
14
- * @returns the scroll type. Possible values are `default|reverse|negative`
15
- */
16
- static detectScrollType(): string;
17
-
18
- /**
19
- * Get the scrollLeft value of the element relative to the direction
20
- *
21
- * @param scrollType type of the scroll detected with `detectScrollType`
22
- * @param direction current direction of the element
23
- * @returns the scrollLeft value.
24
- */
25
- static getNormalizedScrollLeft(scrollType: string, direction: string, element: Element | null): number;
26
-
27
- /**
28
- * Set the scrollLeft value of the element relative to the direction
29
- *
30
- * @param scrollType type of the scroll detected with `detectScrollType`
31
- * @param direction current direction of the element
32
- * @param scrollLeft the scrollLeft value to be set
33
- */
34
- static setNormalizedScrollLeft(
35
- scrollType: string,
36
- direction: string,
37
- element: Element | null,
38
- scrollLeft: number,
39
- ): void;
40
- }
41
-
42
- export { DirHelper };
package/src/dir-helper.js DELETED
@@ -1,93 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
-
7
- /**
8
- * Helper that provides a set of functions for RTL.
9
- */
10
- class DirHelper {
11
- /**
12
- * Get the scroll type in the current browser view.
13
- *
14
- * @return {string} the scroll type. Possible values are `default|reverse|negative`
15
- */
16
- static detectScrollType() {
17
- const dummy = document.createElement('div');
18
- dummy.textContent = 'ABCD';
19
- dummy.dir = 'rtl';
20
- dummy.style.fontSize = '14px';
21
- dummy.style.width = '4px';
22
- dummy.style.height = '1px';
23
- dummy.style.position = 'absolute';
24
- dummy.style.top = '-1000px';
25
- dummy.style.overflow = 'scroll';
26
- document.body.appendChild(dummy);
27
-
28
- let cachedType = 'reverse';
29
- if (dummy.scrollLeft > 0) {
30
- cachedType = 'default';
31
- } else {
32
- dummy.scrollLeft = 2;
33
- if (dummy.scrollLeft < 2) {
34
- cachedType = 'negative';
35
- }
36
- }
37
- document.body.removeChild(dummy);
38
- return cachedType;
39
- }
40
-
41
- /**
42
- * Get the scrollLeft value of the element relative to the direction
43
- *
44
- * @param {string} scrollType type of the scroll detected with `detectScrollType`
45
- * @param {string} direction current direction of the element
46
- * @param {Element} element
47
- * @return {number} the scrollLeft value.
48
- */
49
- static getNormalizedScrollLeft(scrollType, direction, element) {
50
- const { scrollLeft } = element;
51
- if (direction !== 'rtl' || !scrollType) {
52
- return scrollLeft;
53
- }
54
-
55
- switch (scrollType) {
56
- case 'negative':
57
- return element.scrollWidth - element.clientWidth + scrollLeft;
58
- case 'reverse':
59
- return element.scrollWidth - element.clientWidth - scrollLeft;
60
- default:
61
- return scrollLeft;
62
- }
63
- }
64
-
65
- /**
66
- * Set the scrollLeft value of the element relative to the direction
67
- *
68
- * @param {string} scrollType type of the scroll detected with `detectScrollType`
69
- * @param {string} direction current direction of the element
70
- * @param {Element} element
71
- * @param {number} scrollLeft the scrollLeft value to be set
72
- */
73
- static setNormalizedScrollLeft(scrollType, direction, element, scrollLeft) {
74
- if (direction !== 'rtl' || !scrollType) {
75
- element.scrollLeft = scrollLeft;
76
- return;
77
- }
78
-
79
- switch (scrollType) {
80
- case 'negative':
81
- element.scrollLeft = element.clientWidth - element.scrollWidth + scrollLeft;
82
- break;
83
- case 'reverse':
84
- element.scrollLeft = element.scrollWidth - element.clientWidth - scrollLeft;
85
- break;
86
- default:
87
- element.scrollLeft = scrollLeft;
88
- break;
89
- }
90
- }
91
- }
92
-
93
- export { DirHelper };