Skip to content

Commit

Permalink
feat: add shouldAdjustScrollPositionOnItemSizeChange method (#702)
Browse files Browse the repository at this point in the history
  • Loading branch information
piecyk committed Apr 15, 2024
1 parent f053758 commit 9715328
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
6 changes: 6 additions & 0 deletions docs/api/virtualizer.md
Original file line number Diff line number Diff line change
Expand Up @@ -319,3 +319,9 @@ scrollRect: Rect
```
Current `Rect` of the scroll element.
```tsx
shouldAdjustScrollPositionOnItemSizeChange: undefined | ((item: VirtualItem, delta: number, instance: Virtualizer<TScrollElement, TItemElement>) => boolean)
```
The shouldAdjustScrollPositionOnItemSizeChange method enables fine-grained control over the adjustment of scroll position when the size of dynamically rendered items differs from the estimated size. When jumping in the middle of the list and scrolling backward new elements may have a different size than the initially estimated size. This discrepancy can cause subsequent items to shift, potentially disrupting the user's scrolling experience, particularly when navigating backward through the list.
13 changes: 12 additions & 1 deletion packages/virtual-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,13 @@ export class Virtualizer<
scrollOffset: number
scrollDirection: ScrollDirection | null = null
private scrollAdjustments: number = 0
shouldAdjustScrollPositionOnItemSizeChange:
| undefined
| ((
item: VirtualItem,
delta: number,
instance: Virtualizer<TScrollElement, TItemElement>,
) => boolean)
measureElementCache = new Map<Key, TItemElement>()
private observer = (() => {
let _ro: ResizeObserver | null = null
Expand Down Expand Up @@ -666,7 +673,11 @@ export class Virtualizer<
const delta = size - itemSize

if (delta !== 0) {
if (item.start < this.scrollOffset + this.scrollAdjustments) {
if (
this.shouldAdjustScrollPositionOnItemSizeChange !== undefined
? this.shouldAdjustScrollPositionOnItemSizeChange(item, delta, this)
: item.start < this.scrollOffset + this.scrollAdjustments
) {
if (process.env.NODE_ENV !== 'production' && this.options.debug) {
console.info('correction', delta)
}
Expand Down

0 comments on commit 9715328

Please sign in to comment.