Skip to content

Commit

Permalink
add onRenderRangeChange and release version patch
Browse files Browse the repository at this point in the history
  • Loading branch information
radubrehar committed Jul 25, 2024
1 parent a587aa8 commit 6a00d4c
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import * as React from 'react';

import {
InfiniteTable,
InfiniteTablePropColumns,
DataSourceData,
ScrollStopInfo,
debounce,
} from '@infinite-table/infinite-react';
import { DataSource } from '@infinite-table/infinite-react';
import { TableRenderRange } from '@src/components/VirtualBrain/MatrixBrain';

type Developer = {
id: number;
firstName: string;
lastName: string;
country: string;
city: string;
currency: string;

email: string;
preferredLanguage: string;
stack: string;
canDesign: 'yes' | 'no';
hobby: string;
salary: number;
age: number;
};

const columns: InfiniteTablePropColumns<Developer> = {
index: {
renderValue: ({ rowInfo }) => {
return `${rowInfo.indexInAll}`;
},
},
preferredLanguage: {
field: 'preferredLanguage',
},
salary: {
field: 'salary',
type: 'number',
},
age: { field: 'age' },
city: { field: 'city' },
email: { field: 'email' },
canDesign: { field: 'canDesign' },
stack: { field: 'stack' },
};

const dataSource: DataSourceData<Developer> = ({}) => {
return fetch(process.env.NEXT_PUBLIC_BASE_URL + `/developers10k-sql`)
.then((r) => r.json())
.then((data: Developer[]) => data);
};

const sinon = require('sinon');

const onRenderRangeChange = sinon.spy((_scrollInfo: ScrollStopInfo) => {});

(globalThis as any).onRenderRangeChange = onRenderRangeChange;

export default () => {
const fn = React.useMemo(() => {
return debounce(
(range: TableRenderRange) => {
console.log(range);
onRenderRangeChange(range);
},
{ wait: 10 },
);
}, []);
return (
<React.StrictMode>
<>
<DataSource<Developer> data={dataSource} primaryKey="id">
<InfiniteTable<Developer>
domProps={{
style: {
margin: '5px',
height: '60vh',
width: '80vw',
border: '1px solid gray',
position: 'relative',
},
}}
columnMinWidth={50}
columnDefaultWidth={350}
onRenderRangeChange={fn}
columns={columns}
/>
</DataSource>
</>
</React.StrictMode>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { getFnCalls } from '../../../testUtils/getFnCalls';
import { test, expect } from '@testing';

export default test.describe.parallel('onRenderRangeChange', () => {
test('should correctly be called', async ({ page, apiModel }) => {
await page.waitForInfinite();

let calls = await getFnCalls('onRenderRangeChange', { page });
expect(calls.length).toEqual(1);

await apiModel.evaluate((api) => {
return api.scrollRowIntoView(100);
});
await page.waitForTimeout(50);

calls = await getFnCalls('onRenderRangeChange', { page });
expect(calls.length).toEqual(2);

await page.setViewportSize({
width: 500,
height: 500,
});

await page.waitForTimeout(100);

calls = await getFnCalls('onRenderRangeChange', { page });
expect(calls.length).toEqual(3);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ export function useCellRendering<T>(
});
}, [brain]);

useEffect(() => {
return brain.onRenderRangeChange((range) => {
getState().onRenderRangeChange?.(range);
});
}, [brain]);

useEffect(() => {
return brain.onScrollStop((scrollPosition) => {
const { scrollTop, scrollLeft } = scrollPosition;
Expand Down
2 changes: 2 additions & 0 deletions source/src/components/InfiniteTable/state/getInitialState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ export const forwardProps = <T>(
onContextMenu: 1,
onCellContextMenu: 1,

onRenderRangeChange: 1,

onScrollToTop: 1,
onScrollToBottom: 1,
onScrollStop: 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,8 @@ export interface InfiniteTableProps<T> {
onScrollStop?: (param: ScrollStopInfo) => void;
scrollToBottomOffset?: number;

onRenderRangeChange?: (range: TableRenderRange) => void;

defaultColumnOrder?: InfiniteTablePropColumnOrder;
columnOrder?: InfiniteTablePropColumnOrder;
onColumnOrderChange?: (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ export interface InfiniteTableMappedState<T> {

activeRowIndex: InfiniteTableProps<T>['activeRowIndex'];
activeCellIndex: InfiniteTableProps<T>['activeCellIndex'];

onRenderRangeChange: InfiniteTableProps<T>['onRenderRangeChange'];

scrollStopDelay: NonUndefined<InfiniteTableProps<T>['scrollStopDelay']>;
onScrollToTop: InfiniteTableProps<T>['onScrollToTop'];
onScrollToBottom: InfiniteTableProps<T>['onScrollToBottom'];
Expand Down
50 changes: 49 additions & 1 deletion www/content/docs/reference/infinite-table-props.page.md
Original file line number Diff line number Diff line change
Expand Up @@ -2903,6 +2903,54 @@ It will never be called again after the component is ready.
</Prop>
<Prop name="onRenderRangeChange" type="(range)=>void">
> Called whenever the render range changes, that is, additional rows or columns come into view.
The first (and only) argument is an object with `{start, end}` where both `start` and `end` are arrays of `[rowIndex, colIndex]` pairs.
So if you want to get the start and end indexes, you can do
```ts
const [startRow, startCol] = renderRange.start;
const [endRow, endCol] = renderRange.end;
```
<Note>
This callback is not debounced or throttled, so it can be called multiple times in a short period of time, especially while scrolling. Make sure your function is fast, or attach a debounced function, in order to avoid performance issues.
```tsx
import {
debounce,
InfiniteTable,
DataSource
} from '@infinite-table/infinite-react';

function App() {
const onRenderRangeChange = useMemo(() => {
return debounce((range) => {
console.log(range.start, range.end);
}, {wait: 100});
}, []);

return <DataSource<Developer>
primaryKey="id"
data={/*data*/}
>
<InfiniteTable<Developer>
onRenderRangeChange={onRenderRangeChange}
columns={/*columns*/}
/>
</DataSource>
}
```
</Note>
Unlike <PropLink name="onScrollStop" />, this function is also called when the DataGrid is resized and also when initially rendered.
</Prop>
<Prop name="onScrollStop" type="({renderRange, viewportSize, scrollTop, scrollLeft})=>void">
> Triggered when the user has stopped scrolling (after <PropLink name="scrollStopDelay" /> milliseconds).
Expand All @@ -2922,7 +2970,7 @@ The function is called with an object that has the following properties:
- `scrollLeft` - the scrollLeft position of the viewport - `number`
Also see <PropLink name="onScrollToTop" /> and <PropLink name="onScrollToBottom" />.
Also see <PropLink name="onScrollToTop" />, <PropLink name="onScrollToBottom" /> and <PropLink name="onRenderRangeChange" />.
<Sandpack title="onScrollStop is called with viewport info - scroll the grid and see the console" >
Expand Down

0 comments on commit 6a00d4c

Please sign in to comment.