Skip to content

Commit 35d31f5

Browse files
authored
feat: support render get size (#217)
* feat: support render get size * feat: get from key range * test: update snapshot
1 parent 8c3ee61 commit 35d31f5

File tree

4 files changed

+62
-19
lines changed

4 files changed

+62
-19
lines changed

examples/horizontal-scroll.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as React from 'react';
22
import List from '../src/List';
33

44
interface Item {
5-
id: number;
5+
id: string;
66
height: number;
77
}
88

@@ -72,7 +72,7 @@ const ForwardMyItem = React.forwardRef(MyItem);
7272
const data: Item[] = [];
7373
for (let i = 0; i < 1000; i += 1) {
7474
data.push({
75-
id: i,
75+
id: `id_${i}`,
7676
height: 30 + Math.random() * 10,
7777
});
7878
}
@@ -105,12 +105,14 @@ const Demo = () => {
105105
}}
106106
extraRender={(info) => {
107107
const { offsetX, rtl: isRTL } = info;
108+
const sizeInfo = info.getSize('id_3', 'id_5');
108109

109110
return (
110111
<div
111112
style={{
112113
position: 'absolute',
113-
top: 100,
114+
top: sizeInfo.top,
115+
height: sizeInfo.bottom - sizeInfo.top,
114116
[isRTL ? 'right' : 'left']: 100 - offsetX,
115117
background: 'rgba(255,0,0,0.1)',
116118
}}

src/List.tsx

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,42 @@ export function RawList<T>(props: ListProps<T>, ref: React.Ref<ListRef>) {
449449
}
450450
}, [start, end, mergedData]);
451451

452+
// ================================ Extra =================================
453+
const getSize = (startKey: React.Key, endKey = startKey) => {
454+
let top = 0;
455+
let bottom = 0;
456+
let total = 0;
457+
458+
const dataLen = mergedData.length;
459+
for (let i = 0; i < dataLen; i += 1) {
460+
const item = mergedData[i];
461+
const key = getKey(item);
462+
463+
const cacheHeight = heights.get(key) ?? itemHeight;
464+
bottom = total + cacheHeight;
465+
466+
if (key === startKey) {
467+
top = total;
468+
}
469+
if (key === endKey) {
470+
break;
471+
}
472+
473+
total = bottom;
474+
}
475+
476+
return { top, bottom };
477+
};
478+
479+
const extraContent = extraRender?.({
480+
start,
481+
end,
482+
virtual: inVirtual,
483+
offsetX: offsetLeft,
484+
rtl: isRTL,
485+
getSize,
486+
});
487+
452488
// ================================ Render ================================
453489
const listChildren = useChildren(
454490
mergedData,
@@ -460,14 +496,6 @@ export function RawList<T>(props: ListProps<T>, ref: React.Ref<ListRef>) {
460496
sharedConfig,
461497
);
462498

463-
const extraContent = extraRender?.({
464-
start,
465-
end,
466-
virtual: inVirtual,
467-
offsetX: offsetLeft,
468-
rtl: isRTL,
469-
});
470-
471499
let componentStyle: React.CSSProperties = null;
472500
if (height) {
473501
componentStyle = { [fullHeight ? 'height' : 'maxHeight']: height, ...ScrollStyle };

src/interface.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,6 @@ export interface ExtraRenderInfo {
2121
offsetX: number;
2222

2323
rtl: boolean;
24+
25+
getSize: (startKey: React.Key, endKey?: React.Key) => { top: number; bottom: number };
2426
}

tests/scrollWidth.test.tsx

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import List, { type ListProps } from '../src';
77
import { _rs as onLibResize } from 'rc-resize-observer/lib/utils/observerUtil';
88
import '@testing-library/jest-dom';
99

10+
const ITEM_HEIGHT = 20;
11+
1012
function genData(count) {
1113
return new Array(count).fill(null).map((_, index) => ({ id: String(index) }));
1214
}
@@ -19,7 +21,7 @@ describe('List.scrollWidth', () => {
1921
beforeAll(() => {
2022
mockElement = spyElementPrototypes(HTMLElement, {
2123
offsetHeight: {
22-
get: () => 20,
24+
get: () => ITEM_HEIGHT,
2325
},
2426
clientHeight: {
2527
get: () => 100,
@@ -73,7 +75,7 @@ describe('List.scrollWidth', () => {
7375

7476
it('work', async () => {
7577
const { container } = await genList({
76-
itemHeight: 20,
78+
itemHeight: ITEM_HEIGHT,
7779
height: 100,
7880
data: genData(100),
7981
scrollWidth: 1000,
@@ -88,7 +90,7 @@ describe('List.scrollWidth', () => {
8890
const listRef = React.createRef<ListRef>();
8991

9092
const { container } = await genList({
91-
itemHeight: 20,
93+
itemHeight: ITEM_HEIGHT,
9294
height: 100,
9395
data: genData(100),
9496
scrollWidth: 1000,
@@ -136,7 +138,7 @@ describe('List.scrollWidth', () => {
136138
const onVirtualScroll = jest.fn();
137139

138140
const { container } = await genList({
139-
itemHeight: 20,
141+
itemHeight: ITEM_HEIGHT,
140142
height: 100,
141143
data: genData(100),
142144
scrollWidth: 1000,
@@ -155,7 +157,7 @@ describe('List.scrollWidth', () => {
155157
const listRef = React.createRef<ListRef>();
156158

157159
await genList({
158-
itemHeight: 20,
160+
itemHeight: ITEM_HEIGHT,
159161
height: 100,
160162
data: genData(100),
161163
scrollWidth: 1000,
@@ -171,13 +173,22 @@ describe('List.scrollWidth', () => {
171173

172174
it('support extraRender', async () => {
173175
const { container } = await genList({
174-
itemHeight: 20,
176+
itemHeight: ITEM_HEIGHT,
175177
height: 100,
176178
data: genData(100),
177179
scrollWidth: 1000,
178-
extraRender: () => <div className="bamboo" />,
180+
extraRender: ({ getSize }) => {
181+
const size = getSize('1', '3');
182+
return (
183+
<div className="bamboo">
184+
{size.top}/{size.bottom}
185+
</div>
186+
);
187+
},
179188
});
180189

181-
expect(container.querySelector('.bamboo')).toBeTruthy();
190+
expect(container.querySelector('.bamboo').textContent).toEqual(
191+
`${ITEM_HEIGHT}/${4 * ITEM_HEIGHT}`,
192+
);
182193
});
183194
});

0 commit comments

Comments
 (0)