Skip to content

Commit 13e550f

Browse files
authored
fix: scrollLeft should keep in sync when width changed (#230)
* fix: resize should trigger scrollLeft * fix: resize not handle scroll
1 parent ed01307 commit 13e550f

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

src/List.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ export function RawList<T>(props: ListProps<T>, ref: React.Ref<ListRef>) {
255255

256256
// ================================= Size =================================
257257
const [size, setSize] = React.useState({ width: 0, height });
258+
258259
const onHolderResize: ResizeObserverProps['onResize'] = (sizeInfo) => {
259260
setSize(sizeInfo);
260261
};
@@ -409,6 +410,15 @@ export function RawList<T>(props: ListProps<T>, ref: React.Ref<ListRef>) {
409410
};
410411
}, [useVirtual]);
411412

413+
// Sync scroll left
414+
useLayoutEffect(() => {
415+
if (scrollWidth) {
416+
setOffsetLeft((left) => {
417+
return keepInHorizontalRange(left);
418+
});
419+
}
420+
}, [size.width, scrollWidth]);
421+
412422
// ================================= Ref ==================================
413423
const delayHideScrollBar = () => {
414424
verticalScrollBarRef.current?.delayHidden();

tests/scrollWidth.test.tsx

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React from 'react';
22
import { act, fireEvent, render } from '@testing-library/react';
33
import { spyElementPrototypes } from 'rc-util/lib/test/domHook';
4-
import {} from 'rc-resize-observer';
54
import type { ListRef } from '../src';
65
import List, { type ListProps } from '../src';
76
import { _rs as onLibResize } from 'rc-resize-observer/lib/utils/observerUtil';
@@ -18,16 +17,18 @@ describe('List.scrollWidth', () => {
1817
let mockMouseEvent;
1918
let pageX: number;
2019

20+
let holderWidth = 100;
21+
2122
beforeAll(() => {
2223
mockElement = spyElementPrototypes(HTMLElement, {
2324
offsetHeight: {
2425
get: () => ITEM_HEIGHT,
2526
},
2627
clientHeight: {
27-
get: () => 100,
28+
get: () => holderWidth,
2829
},
2930
getBoundingClientRect: () => ({
30-
width: 100,
31+
width: holderWidth,
3132
height: 100,
3233
}),
3334
});
@@ -45,6 +46,7 @@ describe('List.scrollWidth', () => {
4546
});
4647

4748
beforeEach(() => {
49+
holderWidth = 100;
4850
jest.useFakeTimers();
4951
});
5052

@@ -229,4 +231,34 @@ describe('List.scrollWidth', () => {
229231
`${ITEM_HEIGHT}/${4 * ITEM_HEIGHT}`,
230232
);
231233
});
234+
235+
it('resize should back of scrollLeft', async () => {
236+
const { container } = await genList({
237+
itemHeight: ITEM_HEIGHT,
238+
height: 100,
239+
data: genData(100),
240+
scrollWidth: 1000,
241+
});
242+
243+
// Wheel
244+
fireEvent.wheel(container.querySelector('.rc-virtual-list-holder')!, {
245+
deltaX: 9999999,
246+
});
247+
248+
holderWidth = 200;
249+
250+
await act(async () => {
251+
onLibResize([
252+
{
253+
target: container.querySelector('.rc-virtual-list-holder')!,
254+
} as ResizeObserverEntry,
255+
]);
256+
257+
await Promise.resolve();
258+
});
259+
260+
expect(container.querySelector('.rc-virtual-list-holder-inner')).toHaveStyle({
261+
marginLeft: '-800px',
262+
});
263+
});
232264
});

0 commit comments

Comments
 (0)