Skip to content

Commit 186b124

Browse files
committed
first working virtualization for both rows and columns
1 parent 6c6d0bb commit 186b124

20 files changed

+200
-297
lines changed

examples/src/pages/demos/new-perf-approach.page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export default function App() {
4040
</b>
4141
);
4242
};
43-
const [brain] = React.useState(() => new MatrixBrain());
43+
const [brain] = React.useState(() => new MatrixBrain('test'));
4444

4545
(globalThis as any).brain = brain;
4646

examples/src/pages/demos/new-perf-approach2.page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export default function App() {
3939
</b>
4040
);
4141
};
42-
const [brain] = React.useState(() => new MatrixBrain());
42+
const [brain] = React.useState(() => new MatrixBrain('test'));
4343

4444
(globalThis as any).brain = brain;
4545

examples/src/pages/tests/horizontal-layout/default.page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ export function getRandomInt(min: number, max: number) {
2727
return Math.floor(Math.random() * (max - min + 1) + min);
2828
}
2929

30-
const domProps = { style: { height: '30vh', width: 900 } };
30+
const domProps = { style: { height: '30vh', width: '90vw' } };
31+
// const domProps = { style: { height: '30vh', width: 300 } };
3132

3233
// dataSource.length = 12;
3334

examples/src/pages/tests/horizontal-layout/test.page.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const columns: InfiniteTablePropColumns<Developer> = {
2525

2626
const domProps = {
2727
// style: { height: 420 /*30px header, 420 body*/, width: 230 },
28-
style: { height: '50vh' /*30px header, 420 body*/, width: '50vw' },
28+
style: { height: '50vh' /*30px header, 420 body*/, width: '30vw' },
2929
};
3030

3131
const data = Array.from({ length: 10 }, (_, i) => ({
@@ -55,10 +55,10 @@ export default function App() {
5555
wrapRowsHorizontally={wrapRowsHorizontally}
5656
rowHeight={50}
5757
domProps={domProps}
58-
header={false}
58+
header={true}
5959
columnHeaderHeight={30}
6060
columns={columns}
61-
columnDefaultWidth={100}
61+
columnDefaultWidth={200}
6262
onCellClick={({ rowIndex, colIndex }) => {
6363
console.log('clicked', rowIndex, colIndex);
6464
}}

examples/src/pages/tests/matrix-brain.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export default test.describe.parallel('MatrixBrain', () => {
2626
const ROWS = 20;
2727
const COLS = 7;
2828

29-
const brain = new MatrixBrain();
29+
const brain = new MatrixBrain('test');
3030

3131
brain.update({
3232
colWidth: COL_SIZE,
@@ -86,7 +86,7 @@ export default test.describe.parallel('MatrixBrain', () => {
8686
const ROWS = 20;
8787
const COLS = 7;
8888

89-
const brain = new MatrixBrain();
89+
const brain = new MatrixBrain('test');
9090

9191
brain.update({
9292
colWidth: COL_SIZE,
@@ -118,7 +118,7 @@ export default test.describe.parallel('MatrixBrain', () => {
118118
const ROWS = 20;
119119
const COLS = 7;
120120

121-
const brain = new MatrixBrain();
121+
const brain = new MatrixBrain('test');
122122

123123
brain.update({
124124
colWidth: COL_SIZE,
@@ -200,7 +200,7 @@ export default test.describe.parallel('MatrixBrain', () => {
200200
const ROWS = 20;
201201
const COLS = 7;
202202

203-
const brain = new MatrixBrain();
203+
const brain = new MatrixBrain('test');
204204

205205
brain.update({
206206
colWidth: COL_SIZE,

source/src/components/HeadlessTable/HorizontalLayoutTableRenderer.tsx

Lines changed: 10 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,29 @@
1-
import { TableRenderRange } from '../InfiniteTable';
2-
import { Renderable } from '../types/Renderable';
31
import { HorizontalLayoutMatrixBrain } from '../VirtualBrain/HorizontalLayoutMatrixBrain';
42
import {
53
columnOffsetAtIndex,
64
columnOffsetAtIndexWhileReordering,
75
currentTransformY,
86
ReactHeadlessTableRenderer,
9-
TableRenderCellFn,
10-
TableRenderDetailRowFn,
117
} from './ReactHeadlessTableRenderer';
128

139
export class HorizontalLayoutTableRenderer extends ReactHeadlessTableRenderer {
1410
protected brain: HorizontalLayoutMatrixBrain;
15-
constructor(brain: HorizontalLayoutMatrixBrain) {
16-
super(brain);
11+
constructor(brain: HorizontalLayoutMatrixBrain, debugId?: string) {
12+
super(brain, debugId);
1713
this.brain = brain;
1814
}
1915

2016
protected getCellRealCoordinates(rowIndex: number, colIndex: number) {
17+
// return {
18+
// rowIndex,
19+
// colIndex,
20+
// };
2121
return this.brain.getHorizontalLayoutPositionFromMatrixCoordinates({
2222
rowIndex,
2323
colIndex,
2424
});
2525
}
2626

27-
renderRange(
28-
range: TableRenderRange,
29-
30-
{
31-
renderCell,
32-
renderDetailRow,
33-
force,
34-
onRender,
35-
}: {
36-
force?: boolean;
37-
renderCell: TableRenderCellFn;
38-
renderDetailRow?: TableRenderDetailRowFn;
39-
onRender: (items: Renderable[]) => void;
40-
},
41-
): Renderable[] {
42-
return super.renderRange(range, {
43-
renderCell,
44-
renderDetailRow,
45-
force,
46-
onRender,
47-
});
48-
}
49-
5027
setTransform = (
5128
element: HTMLElement,
5229
rowIndex: number,
@@ -58,7 +35,7 @@ export class HorizontalLayoutTableRenderer extends ReactHeadlessTableRenderer {
5835
scrollLeft?: boolean;
5936
scrollTop?: boolean;
6037
},
61-
zIndex: number | 'auto' | undefined | null,
38+
_zIndex: number | 'auto' | undefined | null,
6239
) => {
6340
const horizontalLayoutCoords = this.getCellRealCoordinates(
6441
rowIndex,
@@ -69,7 +46,8 @@ export class HorizontalLayoutTableRenderer extends ReactHeadlessTableRenderer {
6946
const pageIndex = Math.floor(
7047
horizontalLayoutCoords.rowIndex / this.brain.rowsPerPage,
7148
);
72-
const pageOffset = pageIndex ? pageIndex * this.brain.pageWidth : 0;
49+
const pageWidth = `${this.brain.pageWidth}px`;
50+
const pageOffset = pageIndex ? `calc(${pageIndex} * ${pageWidth})` : '0px';
7351

7452
const columnOffsetX = `${columnOffsetAtIndex}-${horizontalLayoutCoords.colIndex}`;
7553
const columnOffsetXWhileReordering = `${columnOffsetAtIndexWhileReordering}-${horizontalLayoutCoords.colIndex}`;
@@ -83,7 +61,7 @@ export class HorizontalLayoutTableRenderer extends ReactHeadlessTableRenderer {
8361
element.style.setProperty(currentTransformY, currentTransformYValue);
8462
}
8563

86-
const xOffset = `calc(var(${columnOffsetX}) + ${pageOffset}px)`;
64+
const xOffset = `calc(var(${columnOffsetX}) + ${pageOffset})`;
8765
const transformX = `var(${columnOffsetXWhileReordering}, ${xOffset})`;
8866
const transformY = `var(${currentTransformY})`;
8967

source/src/components/HeadlessTable/RawTable.tsx

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { useEffect, useLayoutEffect, useMemo } from 'react';
44
import { AvoidReactDiff } from '../RawList/AvoidReactDiff';
55
import { Renderable } from '../types/Renderable';
66
import { SubscriptionCallback } from '../types/SubscriptionCallback';
7-
import { buildSubscriptionCallback } from '../utils/buildSubscriptionCallback';
87
import { MatrixBrain } from '../VirtualBrain/MatrixBrain';
8+
import { createRenderer } from './createRenderer';
99

1010
import {
1111
ReactHeadlessTableRenderer,
@@ -23,20 +23,6 @@ export type RawTableProps = {
2323
onRenderUpdater?: SubscriptionCallback<Renderable>;
2424
};
2525

26-
function createRenderer(brain: MatrixBrain) {
27-
const renderer = new ReactHeadlessTableRenderer(brain);
28-
const onRenderUpdater = buildSubscriptionCallback<Renderable>();
29-
30-
brain.onDestroy(() => {
31-
renderer.destroy();
32-
onRenderUpdater.destroy();
33-
});
34-
35-
return {
36-
renderer,
37-
onRenderUpdater,
38-
};
39-
}
4026
export function RawTableFn(props: RawTableProps) {
4127
const { brain, renderCell, renderDetailRow } = props;
4228

source/src/components/HeadlessTable/ReactHeadlessTableRenderer.tsx

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,11 @@ export class ReactHeadlessTableRenderer extends Logger {
193193
}
194194
};
195195

196-
constructor(brain: MatrixBrain) {
197-
super('ReactHeadlessTableRenderer');
196+
constructor(brain: MatrixBrain, debugId?: string) {
197+
debugId = debugId || 'ReactHeadlessTableRenderer';
198+
super(debugId);
198199
this.brain = brain;
199-
this.debugId = brain.name;
200+
this.debugId = debugId;
200201

201202
this.mappedCells = new MappedCells();
202203
this.mappedDetailRows = new MappedVirtualRows();
@@ -1306,13 +1307,6 @@ export class ReactHeadlessTableRenderer extends Logger {
13061307
renderedNode,
13071308
);
13081309

1309-
if (__DEV__) {
1310-
this.debug(
1311-
`Render cell ${rowIndex},${colIndex} at element ${elementIndex}`,
1312-
);
1313-
}
1314-
1315-
// console.log('update', rowIndex, colIndex, renderedNode);
13161310
itemUpdater(renderedNode);
13171311

13181312
this.updateElementPosition(elementIndex, { hidden, rowspan, colspan });
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { Renderable } from '../types/Renderable';
2+
import { buildSubscriptionCallback } from '../utils/buildSubscriptionCallback';
3+
import { HorizontalLayoutMatrixBrain } from '../VirtualBrain/HorizontalLayoutMatrixBrain';
4+
import { MatrixBrain } from '../VirtualBrain/MatrixBrain';
5+
import { HorizontalLayoutTableRenderer } from './HorizontalLayoutTableRenderer';
6+
import { ReactHeadlessTableRenderer } from './ReactHeadlessTableRenderer';
7+
8+
export function createRenderer(brain: MatrixBrain) {
9+
const renderer = !brain.isHorizontalLayoutBrain
10+
? new ReactHeadlessTableRenderer(
11+
brain,
12+
`ReactHeadlessTableRenderer:${brain.name}`,
13+
)
14+
: new HorizontalLayoutTableRenderer(
15+
brain as HorizontalLayoutMatrixBrain,
16+
`HorizontalLayoutTableRenderer:${brain.name}`,
17+
);
18+
19+
const onRenderUpdater = buildSubscriptionCallback<Renderable>();
20+
21+
brain.onDestroy(() => {
22+
renderer.destroy();
23+
onRenderUpdater.destroy();
24+
});
25+
26+
if (__DEV__) {
27+
(brain as any).renderer = renderer;
28+
}
29+
30+
return {
31+
renderer,
32+
onRenderUpdater,
33+
};
34+
}

source/src/components/InfiniteTable/components/HScrollSyncContent.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,17 @@ export function HScrollSyncContent(
2828
const style = { ...domProps.style };
2929

3030
if (width === 'column') {
31-
style.width = ThemeVars.runtime.totalVisibleColumnsWidth;
31+
style.width = ThemeVars.runtime.totalVisibleColumnsWidthValue;
3232
} else if (width === 'viewport') {
3333
style.width = ThemeVars.runtime.bodyWidth;
3434
}
3535
if (minWidth === 'column') {
36-
style.minWidth = ThemeVars.runtime.totalVisibleColumnsWidth;
36+
style.minWidth = ThemeVars.runtime.totalVisibleColumnsWidthValue;
3737
} else if (minWidth === 'viewport') {
3838
style.minWidth = ThemeVars.runtime.bodyWidth;
3939
}
4040
if (maxWidth === 'column') {
41-
style.maxWidth = ThemeVars.runtime.totalVisibleColumnsWidth;
41+
style.maxWidth = ThemeVars.runtime.totalVisibleColumnsWidthValue;
4242
} else if (maxWidth === 'viewport') {
4343
style.maxWidth = ThemeVars.runtime.bodyWidth;
4444
}

0 commit comments

Comments
 (0)