Skip to content

Commit 951f259

Browse files
fix(virtual-core): observe scrollbar viewport changes
1 parent bce82b1 commit 951f259

2 files changed

Lines changed: 45 additions & 1 deletion

File tree

‎packages/virtual-core/src/index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ export const observeElementRect = <T extends Element>(
185185
: run()
186186
})
187187

188-
observer.observe(element, { box: 'border-box' })
188+
observer.observe(element, { box: 'content-box' })
189189

190190
return () => {
191191
observer.unobserve(element)

‎packages/virtual-core/tests/index.test.ts‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7021,3 +7021,47 @@ test.each([false, true])(
70217021
virtualizer._didMount()()
70227022
},
70237023
)
7024+
7025+
test('refreshes horizontal end alignment when a scrollbar toggles', () => {
7026+
const { el } = createOwnWindow()
7027+
let deliverResize: ResizeObserverCallback
7028+
let observedBox: ResizeObserverBoxOptions | undefined
7029+
el.ownerDocument.defaultView!.ResizeObserver = vi.fn(function (cb) {
7030+
deliverResize = cb
7031+
return {
7032+
observe: (_target: Element, options?: ResizeObserverOptions) => {
7033+
observedBox = options?.box
7034+
},
7035+
unobserve: vi.fn(),
7036+
disconnect: vi.fn(),
7037+
}
7038+
}) as unknown as typeof ResizeObserver
7039+
Object.assign(el, { scrollWidth: 5000 })
7040+
const virtualizer = new Virtualizer({
7041+
count: 100,
7042+
horizontal: true,
7043+
estimateSize: () => 50,
7044+
getScrollElement: () => el,
7045+
scrollToFn: vi.fn(),
7046+
observeElementRect,
7047+
observeElementOffset: (_instance, cb) => {
7048+
cb(0, false)
7049+
},
7050+
})
7051+
virtualizer._willUpdate()
7052+
expect(virtualizer.getOffsetForIndex(10, 'end')?.[0]).toBe(150)
7053+
for (const width of [385, 400]) {
7054+
// A classic scrollbar changes the content box, leaving the border box fixed.
7055+
Object.assign(el, { clientWidth: width })
7056+
if (observedBox !== 'border-box') {
7057+
deliverResize!(
7058+
[{ target: el } as ResizeObserverEntry],
7059+
{} as ResizeObserver,
7060+
)
7061+
}
7062+
expect(el.offsetWidth).toBe(400)
7063+
expect(virtualizer.scrollRect?.width).toBe(width)
7064+
expect(virtualizer.getOffsetForIndex(10, 'end')?.[0]).toBe(550 - width)
7065+
}
7066+
virtualizer._didMount()()
7067+
})

0 commit comments

Comments
 (0)