Skip to content

Commit

Permalink
feat: support render get size (#217)
Browse files Browse the repository at this point in the history
* feat: support render get size

* feat: get from key range

* test: update snapshot
  • Loading branch information
zombieJ committed Aug 17, 2023
1 parent 8c3ee61 commit 35d31f5
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 19 deletions.
8 changes: 5 additions & 3 deletions examples/horizontal-scroll.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';
import List from '../src/List';

interface Item {
id: number;
id: string;
height: number;
}

Expand Down Expand Up @@ -72,7 +72,7 @@ const ForwardMyItem = React.forwardRef(MyItem);
const data: Item[] = [];
for (let i = 0; i < 1000; i += 1) {
data.push({
id: i,
id: `id_${i}`,
height: 30 + Math.random() * 10,
});
}
Expand Down Expand Up @@ -105,12 +105,14 @@ const Demo = () => {
}}
extraRender={(info) => {
const { offsetX, rtl: isRTL } = info;
const sizeInfo = info.getSize('id_3', 'id_5');

return (
<div
style={{
position: 'absolute',
top: 100,
top: sizeInfo.top,
height: sizeInfo.bottom - sizeInfo.top,
[isRTL ? 'right' : 'left']: 100 - offsetX,
background: 'rgba(255,0,0,0.1)',
}}
Expand Down
44 changes: 36 additions & 8 deletions src/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,42 @@ export function RawList<T>(props: ListProps<T>, ref: React.Ref<ListRef>) {
}
}, [start, end, mergedData]);

// ================================ Extra =================================
const getSize = (startKey: React.Key, endKey = startKey) => {
let top = 0;
let bottom = 0;
let total = 0;

const dataLen = mergedData.length;
for (let i = 0; i < dataLen; i += 1) {
const item = mergedData[i];
const key = getKey(item);

const cacheHeight = heights.get(key) ?? itemHeight;
bottom = total + cacheHeight;

if (key === startKey) {
top = total;
}
if (key === endKey) {
break;
}

total = bottom;
}

return { top, bottom };
};

const extraContent = extraRender?.({
start,
end,
virtual: inVirtual,
offsetX: offsetLeft,
rtl: isRTL,
getSize,
});

// ================================ Render ================================
const listChildren = useChildren(
mergedData,
Expand All @@ -460,14 +496,6 @@ export function RawList<T>(props: ListProps<T>, ref: React.Ref<ListRef>) {
sharedConfig,
);

const extraContent = extraRender?.({
start,
end,
virtual: inVirtual,
offsetX: offsetLeft,
rtl: isRTL,
});

let componentStyle: React.CSSProperties = null;
if (height) {
componentStyle = { [fullHeight ? 'height' : 'maxHeight']: height, ...ScrollStyle };
Expand Down
2 changes: 2 additions & 0 deletions src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ export interface ExtraRenderInfo {
offsetX: number;

rtl: boolean;

getSize: (startKey: React.Key, endKey?: React.Key) => { top: number; bottom: number };
}
27 changes: 19 additions & 8 deletions tests/scrollWidth.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import List, { type ListProps } from '../src';
import { _rs as onLibResize } from 'rc-resize-observer/lib/utils/observerUtil';
import '@testing-library/jest-dom';

const ITEM_HEIGHT = 20;

function genData(count) {
return new Array(count).fill(null).map((_, index) => ({ id: String(index) }));
}
Expand All @@ -19,7 +21,7 @@ describe('List.scrollWidth', () => {
beforeAll(() => {
mockElement = spyElementPrototypes(HTMLElement, {
offsetHeight: {
get: () => 20,
get: () => ITEM_HEIGHT,
},
clientHeight: {
get: () => 100,
Expand Down Expand Up @@ -73,7 +75,7 @@ describe('List.scrollWidth', () => {

it('work', async () => {
const { container } = await genList({
itemHeight: 20,
itemHeight: ITEM_HEIGHT,
height: 100,
data: genData(100),
scrollWidth: 1000,
Expand All @@ -88,7 +90,7 @@ describe('List.scrollWidth', () => {
const listRef = React.createRef<ListRef>();

const { container } = await genList({
itemHeight: 20,
itemHeight: ITEM_HEIGHT,
height: 100,
data: genData(100),
scrollWidth: 1000,
Expand Down Expand Up @@ -136,7 +138,7 @@ describe('List.scrollWidth', () => {
const onVirtualScroll = jest.fn();

const { container } = await genList({
itemHeight: 20,
itemHeight: ITEM_HEIGHT,
height: 100,
data: genData(100),
scrollWidth: 1000,
Expand All @@ -155,7 +157,7 @@ describe('List.scrollWidth', () => {
const listRef = React.createRef<ListRef>();

await genList({
itemHeight: 20,
itemHeight: ITEM_HEIGHT,
height: 100,
data: genData(100),
scrollWidth: 1000,
Expand All @@ -171,13 +173,22 @@ describe('List.scrollWidth', () => {

it('support extraRender', async () => {
const { container } = await genList({
itemHeight: 20,
itemHeight: ITEM_HEIGHT,
height: 100,
data: genData(100),
scrollWidth: 1000,
extraRender: () => <div className="bamboo" />,
extraRender: ({ getSize }) => {
const size = getSize('1', '3');
return (
<div className="bamboo">
{size.top}/{size.bottom}
</div>
);
},
});

expect(container.querySelector('.bamboo')).toBeTruthy();
expect(container.querySelector('.bamboo').textContent).toEqual(
`${ITEM_HEIGHT}/${4 * ITEM_HEIGHT}`,
);
});
});

0 comments on commit 35d31f5

Please sign in to comment.