Skip to content

Commit 3524ffc

Browse files
committed
Reimplement VGrid with css grid
1 parent 662ee77 commit 3524ffc

9 files changed

Lines changed: 606 additions & 499 deletions

File tree

src/core/resizer.ts

Lines changed: 10 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
type VirtualStore,
66
} from "./store.js";
77
import { type ItemResize } from "./types.js";
8-
import { max, microtask, NULL } from "./utils.js";
8+
import { microtask, NULL } from "./utils.js";
99

1010
const createResizeObserver = (cb: ResizeObserverCallback) => {
1111
let ro: ResizeObserver | undefined;
@@ -168,16 +168,9 @@ export const createGridResizer = (
168168
[rowIndex: number, colIndex: number]
169169
>();
170170

171-
type CellSize = [height: number, width: number];
172-
const maybeCachedRowIndexes = new Set<number>();
173-
const maybeCachedColIndexes = new Set<number>();
174-
const sizeCache = new Map<string, CellSize>();
175-
const getKey = (rowIndex: number, colIndex: number): string =>
176-
`${rowIndex}-${colIndex}`;
177-
178171
const resizeObserver = createResizeObserver((entries) => {
179-
const resizedRows = new Set<number>();
180-
const resizedCols = new Set<number>();
172+
const resizedRows = new Map<number, number>();
173+
const resizedCols = new Map<number, number>();
181174
for (const {
182175
target,
183176
contentRect: { width, height },
@@ -192,62 +185,24 @@ export const createGridResizer = (
192185
const cell = mountedIndexes.get(target);
193186
if (cell) {
194187
const [rowIndex, colIndex] = cell;
195-
const key = getKey(rowIndex, colIndex);
196-
const prevSize = sizeCache.get(key);
197-
let rowResized: boolean | undefined;
198-
let colResized: boolean | undefined;
199-
if (!prevSize) {
200-
rowResized = colResized = true;
201-
} else {
202-
if (prevSize[0] !== height) {
203-
rowResized = true;
204-
}
205-
if (prevSize[1] !== width) {
206-
colResized = true;
207-
}
208-
}
209-
if (rowResized) {
210-
resizedRows.add(rowIndex);
211-
}
212-
if (colResized) {
213-
resizedCols.add(colIndex);
214-
}
215-
if (rowResized || colResized) {
216-
sizeCache.set(key, [height, width]);
217-
}
188+
189+
resizedRows.set(rowIndex, height);
190+
resizedCols.set(colIndex, width);
218191
}
219192
}
220193
}
221194

222195
if (resizedRows.size) {
223196
const heightResizes: ItemResize[] = [];
224-
resizedRows.forEach((rowIndex) => {
225-
let maxHeight = 0;
226-
maybeCachedColIndexes.forEach((colIndex) => {
227-
const size = sizeCache.get(getKey(rowIndex, colIndex));
228-
if (size) {
229-
maxHeight = max(maxHeight, size[0]);
230-
}
231-
});
232-
if (maxHeight) {
233-
heightResizes.push([rowIndex, maxHeight]);
234-
}
197+
resizedRows.entries().forEach((entry) => {
198+
heightResizes.push(entry);
235199
});
236200
rowStore.$update(ACTION_ITEM_RESIZE, heightResizes);
237201
}
238202
if (resizedCols.size) {
239203
const widthResizes: ItemResize[] = [];
240-
resizedCols.forEach((colIndex) => {
241-
let maxWidth = 0;
242-
maybeCachedRowIndexes.forEach((rowIndex) => {
243-
const size = sizeCache.get(getKey(rowIndex, colIndex));
244-
if (size) {
245-
maxWidth = max(maxWidth, size[1]);
246-
}
247-
});
248-
if (maxWidth) {
249-
widthResizes.push([colIndex, maxWidth]);
250-
}
204+
resizedCols.entries().forEach((entry) => {
205+
widthResizes.push(entry);
251206
});
252207
colStore.$update(ACTION_ITEM_RESIZE, widthResizes);
253208
}
@@ -259,30 +214,12 @@ export const createGridResizer = (
259214
},
260215
$observeItem(el: HTMLElement, rowIndex: number, colIndex: number) {
261216
mountedIndexes.set(el, [rowIndex, colIndex]);
262-
maybeCachedRowIndexes.add(rowIndex);
263-
maybeCachedColIndexes.add(colIndex);
264217
resizeObserver._observe(el);
265218
return () => {
266219
mountedIndexes.delete(el);
267220
resizeObserver._unobserve(el);
268221
};
269222
},
270-
$resizeCols(cols: ItemResize[]) {
271-
for (const [c] of cols) {
272-
for (let r = 0; r < rowStore.$getItemsLength(); r++) {
273-
sizeCache.delete(getKey(r, c));
274-
}
275-
}
276-
colStore.$update(ACTION_ITEM_RESIZE, cols);
277-
},
278-
$resizeRows(rows: ItemResize[]) {
279-
for (const [r] of rows) {
280-
for (let c = 0; c < colStore.$getItemsLength(); c++) {
281-
sizeCache.delete(getKey(r, c));
282-
}
283-
}
284-
rowStore.$update(ACTION_ITEM_RESIZE, rows);
285-
},
286223
$dispose: resizeObserver._dispose,
287224
};
288225
};

src/react/VGrid.spec.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,19 @@ it("should pass attributes to element", async () => {
3838
});
3939

4040
describe("grid", async () => {
41+
it("should render 0 children", async () => {
42+
const { asFragment } = await render(
43+
<VGrid row={0} col={0}>
44+
{({ rowIndex, colIndex }) => (
45+
<div>
46+
{rowIndex} / {colIndex}
47+
</div>
48+
)}
49+
</VGrid>
50+
);
51+
expect(asFragment()).toMatchSnapshot();
52+
});
53+
4154
it("should render 1 children", async () => {
4255
const { asFragment } = await render(
4356
<VGrid row={1} col={1}>

src/react/VGrid.ssr.spec.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ describe("SSR", () => {
1717
const html = renderToString(
1818
<VGrid
1919
id={LIST_ID}
20-
initialRowCount={ROW_COUNT}
21-
initialColCount={COL_COUNT}
20+
ssrRowCount={ROW_COUNT}
21+
ssrColCount={COL_COUNT}
2222
cellHeight={ITEM_SIZE}
2323
cellWidth={ITEM_SIZE}
2424
bufferSize={BUFFER_SIZE}
@@ -48,8 +48,8 @@ describe("SSR", () => {
4848
const html = renderToString(
4949
<VGrid
5050
id={LIST_ID}
51-
initialRowCount={ROW_COUNT}
52-
initialColCount={COL_COUNT}
51+
ssrRowCount={ROW_COUNT}
52+
ssrColCount={COL_COUNT}
5353
cellHeight={ITEM_SIZE}
5454
cellWidth={ITEM_SIZE}
5555
bufferSize={BUFFER_SIZE}
@@ -79,8 +79,8 @@ describe("SSR", () => {
7979
const html = renderToStaticMarkup(
8080
<VGrid
8181
id={LIST_ID}
82-
initialRowCount={ROW_COUNT}
83-
initialColCount={COL_COUNT}
82+
ssrRowCount={ROW_COUNT}
83+
ssrColCount={COL_COUNT}
8484
cellHeight={ITEM_SIZE}
8585
cellWidth={ITEM_SIZE}
8686
bufferSize={BUFFER_SIZE}

0 commit comments

Comments
 (0)