-
Notifications
You must be signed in to change notification settings - Fork 86
fix: adjust virtualizer indexes when scrolling at the end #9142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
55d57ee
5269198
1d3a2bf
6d6e26a
ffc6ee4
f4aa239
da4316b
81577f4
7749ae0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change seems to introduce a new issue when resizing a grid. It keeps adjusting the indexes in a loop, decreasing the scrollable area until the scroll position snaps back to the start. It looks like this happens when there is still some empty space at the top that could be filled with another item. This is likely cause by Some other observations:
Bildschirmaufnahme.2025-06-17.um.11.08.13.movReproduction<script type="module">
// PolymerElement based imports
import '@vaadin/grid/all-imports';
import '@vaadin/dialog';
const grid = document.querySelector('vaadin-grid');
grid.items = [...Array(1000)].map((_, i) => ({
name: `Item ${i}`,
}));
const scrollButton = document.getElementById('scroll');
scrollButton.addEventListener('click', () => {
// Scroll to the end of the grid
grid.scrollToIndex(1000);
});
const dialog = document.querySelector('vaadin-dialog');
const dialogContent = document.getElementById('dialog-content');
dialog.renderer = (root) => {
root.innerHTML = '';
root.appendChild(dialogContent);
}
dialog.opened = true;
</script>
<vaadin-dialog resizable draggable></vaadin-dialog>
<div id="dialog-content" style="height: 100%; display: flex; flex-direction: column; gap: 10px;">
<vaadin-grid item-id-path="name" style="flex: 1">
<vaadin-grid-column path="name" width="200px" flex-shrink="0"></vaadin-grid-column>
<vaadin-grid-column path="name" width="200px" flex-shrink="0"></vaadin-grid-column>
<vaadin-grid-column path="name" width="200px" flex-shrink="0"></vaadin-grid-column>
</vaadin-grid>
<button id="scroll" style="flex: 0">Scroll to end</button>
</div> There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This endless loop around There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated the fix based on the suggestions and tried it with multiple setups. I cannot reproduce a loop anymore. The fix resides in an overridden |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -599,6 +599,24 @@ export class IronListAdapter { | |
} | ||
} | ||
|
||
/** @override */ | ||
_resizeHandler() { | ||
super._resizeHandler(); | ||
|
||
// Fixes an issue where the new items are not created on scroll target resize when the scroll position is around the end. | ||
// See https://github.com/vaadin/flow-components/issues/7307 | ||
const lastIndexVisible = this.adjustedLastVisibleIndex === this.size - 1; | ||
const emptySpace = this._physicalTop - this._scrollPosition; | ||
if (lastIndexVisible && emptySpace > 0) { | ||
const idxAdjustment = Math.ceil(emptySpace / this._physicalAverage); | ||
this._virtualStart = Math.max(0, this._virtualStart - idxAdjustment); | ||
this._physicalStart = Math.max(0, this._physicalStart - idxAdjustment); | ||
// Scroll to end for smoother resize | ||
super.scrollToIndex(this._virtualCount - 1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While this works well for virtualizer generally: Kapture.2025-06-19.at.09.15.07.mp4Resizing grid still looks strange Kapture.2025-06-19.at.09.20.59.mp4This could possibly be fixed by calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, it seems to make the scrolling smoother. Updated the PR. |
||
this.scrollTarget.scrollTop = this.scrollTarget.scrollHeight - this.scrollTarget.clientHeight; | ||
} | ||
} | ||
|
||
/** | ||
* Work around an iron-list issue with invalid item positioning. | ||
* See https://github.com/vaadin/flow-components/issues/4306 | ||
|
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the issue occurs on resize, I wonder if this should rather be fixed by overriding iron-list's
_resizeHandler
:EDIT: Since
_resizeHandler
also invokes on item resize, could also consider adding a dedicatedResizeObserver
toscrollTarget
for this purpose (maybe it's overoptimizing).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a pretty clean fix. Updated the PR to use this approach. However, separating the resize handling to apply the fix only for the scroll target still reproduces the issue under some cases. Therefore, I left the resize observer a single one that applies the fix to both.