Skip to content

Commit 535e68d

Browse files
committed
Implement gap prop
1 parent 29b66a0 commit 535e68d

22 files changed

Lines changed: 232 additions & 71 deletions

src/core/cache.spec.ts

Lines changed: 86 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const initCacheWithComputedOffsets = (
3838
return acc;
3939
}, [] as number[]),
4040
_defaultItemSize: defaultSize,
41+
_gap: 0,
4142
};
4243
};
4344

@@ -51,6 +52,7 @@ const initCacheWithEmptyOffsets = (
5152
_computedOffsetIndex: -1,
5253
_offsets: range(sizes.length, () => -1),
5354
_defaultItemSize: defaultSize,
55+
_gap: 0,
5456
};
5557
};
5658

@@ -68,6 +70,7 @@ const initCacheWithOffsets = (
6870
_computedOffsetIndex: offsets.findIndex((o) => o === -1) - 1,
6971
_offsets: [...offsets],
7072
_defaultItemSize: defaultSize,
73+
_gap: 0,
7174
};
7275
};
7376

@@ -306,6 +309,7 @@ describe(computeTotalSize.name, () => {
306309
_computedOffsetIndex: 2,
307310
_offsets: offsets,
308311
_defaultItemSize: 30,
312+
_gap: 0,
309313
};
310314
expect(computeTotalSize(cache)).toBe(sum(range(8, () => 20)) + 22);
311315
expect(cache._offsets).toEqual([
@@ -322,6 +326,7 @@ describe(computeTotalSize.name, () => {
322326
_computedOffsetIndex: 9,
323327
_offsets: offsets,
324328
_defaultItemSize: 30,
329+
_gap: 0,
325330
};
326331
expect(computeTotalSize(cache)).toBe(99 + 20);
327332
expect(cache._offsets).toEqual([0, 11, 22, 33, 44, 55, 66, 77, 88, 99]);
@@ -740,11 +745,12 @@ describe(estimateDefaultItemSize.name, () => {
740745
describe(initCache.name, () => {
741746
it("should create cache", () => {
742747
const itemLength = 10;
743-
const cache = initCache(itemLength, 23);
748+
const cache = initCache(itemLength, 23, 0);
744749
expect(cache).toMatchInlineSnapshot(`
745750
{
746751
"_computedOffsetIndex": -1,
747752
"_defaultItemSize": 23,
753+
"_gap": 0,
748754
"_length": 10,
749755
"_offsets": [
750756
-1,
@@ -779,53 +785,55 @@ describe(initCache.name, () => {
779785

780786
it("should restore cache from snapshot", () => {
781787
const itemLength = 10;
782-
const cache = initCache(itemLength, 23, [
788+
const cache = initCache(itemLength, 23, 0, [
783789
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
784790
123,
785791
]);
786792
expect(cache).toMatchInlineSnapshot(`
787-
{
788-
"_computedOffsetIndex": -1,
789-
"_defaultItemSize": 123,
790-
"_length": 10,
791-
"_offsets": [
792-
-1,
793-
-1,
794-
-1,
795-
-1,
796-
-1,
797-
-1,
798-
-1,
799-
-1,
800-
-1,
801-
-1,
802-
],
803-
"_sizes": [
804-
0,
805-
1,
806-
2,
807-
3,
808-
4,
809-
5,
810-
6,
811-
7,
812-
8,
813-
9,
814-
],
815-
}
816-
`);
793+
{
794+
"_computedOffsetIndex": -1,
795+
"_defaultItemSize": 123,
796+
"_gap": 0,
797+
"_length": 10,
798+
"_offsets": [
799+
-1,
800+
-1,
801+
-1,
802+
-1,
803+
-1,
804+
-1,
805+
-1,
806+
-1,
807+
-1,
808+
-1,
809+
],
810+
"_sizes": [
811+
0,
812+
1,
813+
2,
814+
3,
815+
4,
816+
5,
817+
6,
818+
7,
819+
8,
820+
9,
821+
],
822+
}
823+
`);
817824
expect(cache._length).toBe(itemLength);
818825
expect(cache._sizes.length).toBe(itemLength);
819826
expect(cache._offsets.length).toBe(itemLength);
820827
});
821828

822829
it("should restore cache from snapshot which has shorter length", () => {
823830
const itemLength = 10;
824-
const cache = initCache(itemLength, 23, [[0, 1, 2, 3, 4], 123]);
831+
const cache = initCache(itemLength, 23, 0, [[0, 1, 2, 3, 4], 123]);
825832
expect(cache).toMatchInlineSnapshot(`
826833
{
827834
"_computedOffsetIndex": -1,
828835
"_defaultItemSize": 123,
836+
"_gap": 0,
829837
"_length": 10,
830838
"_offsets": [
831839
-1,
@@ -860,41 +868,42 @@ describe(initCache.name, () => {
860868

861869
it("should restore cache from snapshot which has longer length", () => {
862870
const itemLength = 10;
863-
const cache = initCache(itemLength, 23, [
871+
const cache = initCache(itemLength, 23, 0, [
864872
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
865873
123,
866874
]);
867875
expect(cache).toMatchInlineSnapshot(`
868-
{
869-
"_computedOffsetIndex": -1,
870-
"_defaultItemSize": 123,
871-
"_length": 10,
872-
"_offsets": [
873-
-1,
874-
-1,
875-
-1,
876-
-1,
877-
-1,
878-
-1,
879-
-1,
880-
-1,
881-
-1,
882-
-1,
883-
],
884-
"_sizes": [
885-
0,
886-
1,
887-
2,
888-
3,
889-
4,
890-
5,
891-
6,
892-
7,
893-
8,
894-
9,
895-
],
896-
}
897-
`);
876+
{
877+
"_computedOffsetIndex": -1,
878+
"_defaultItemSize": 123,
879+
"_gap": 0,
880+
"_length": 10,
881+
"_offsets": [
882+
-1,
883+
-1,
884+
-1,
885+
-1,
886+
-1,
887+
-1,
888+
-1,
889+
-1,
890+
-1,
891+
-1,
892+
],
893+
"_sizes": [
894+
0,
895+
1,
896+
2,
897+
3,
898+
4,
899+
5,
900+
6,
901+
7,
902+
8,
903+
9,
904+
],
905+
}
906+
`);
898907
expect(cache._length).toBe(itemLength);
899908
expect(cache._sizes.length).toBe(itemLength);
900909
expect(cache._offsets.length).toBe(itemLength);
@@ -937,21 +946,22 @@ describe(takeCacheSnapshot.name, () => {
937946

938947
describe(updateCacheLength.name, () => {
939948
it("should recover cache length from 0", () => {
940-
const cache = initCache(10, 40);
949+
const cache = initCache(10, 40, 0);
941950
const initialCache = structuredClone(cache);
942951
updateCacheLength(cache, 0);
943952
updateCacheLength(cache, 10);
944953
expect(cache).toEqual(initialCache);
945954
});
946955

947956
it("should increase cache length", () => {
948-
const cache = initCache(10, 40);
957+
const cache = initCache(10, 40, 0);
949958
const res = updateCacheLength(cache, 15, undefined);
950959
expect(res).toEqual(40 * 5);
951960
expect(cache).toMatchInlineSnapshot(`
952961
{
953962
"_computedOffsetIndex": -1,
954963
"_defaultItemSize": 40,
964+
"_gap": 0,
955965
"_length": 15,
956966
"_offsets": [
957967
-1,
@@ -1000,6 +1010,7 @@ describe(updateCacheLength.name, () => {
10001010
{
10011011
"_computedOffsetIndex": 9,
10021012
"_defaultItemSize": 40,
1013+
"_gap": 0,
10031014
"_length": 15,
10041015
"_offsets": [
10051016
0,
@@ -1040,13 +1051,14 @@ describe(updateCacheLength.name, () => {
10401051
});
10411052

10421053
it("should decrease cache length", () => {
1043-
const cache = initCache(10, 40);
1054+
const cache = initCache(10, 40, 0);
10441055
const res = updateCacheLength(cache, 5, undefined);
10451056
expect(res).toEqual(-(40 * 5));
10461057
expect(cache).toMatchInlineSnapshot(`
10471058
{
10481059
"_computedOffsetIndex": -1,
10491060
"_defaultItemSize": 40,
1061+
"_gap": 0,
10501062
"_length": 5,
10511063
"_offsets": [
10521064
-1,
@@ -1075,6 +1087,7 @@ describe(updateCacheLength.name, () => {
10751087
{
10761088
"_computedOffsetIndex": 4,
10771089
"_defaultItemSize": 40,
1090+
"_gap": 0,
10781091
"_length": 5,
10791092
"_offsets": [
10801093
0,
@@ -1095,13 +1108,14 @@ describe(updateCacheLength.name, () => {
10951108
});
10961109

10971110
it("should increase cache length with shifting", () => {
1098-
const cache = initCache(10, 40);
1111+
const cache = initCache(10, 40, 0);
10991112
const res = updateCacheLength(cache, 15, true);
11001113
expect(res).toEqual(40 * 5);
11011114
expect(cache).toMatchInlineSnapshot(`
11021115
{
11031116
"_computedOffsetIndex": -1,
11041117
"_defaultItemSize": 40,
1118+
"_gap": 0,
11051119
"_length": 15,
11061120
"_offsets": [
11071121
-1,
@@ -1150,6 +1164,7 @@ describe(updateCacheLength.name, () => {
11501164
{
11511165
"_computedOffsetIndex": -1,
11521166
"_defaultItemSize": 40,
1167+
"_gap": 0,
11531168
"_length": 15,
11541169
"_offsets": [
11551170
0,
@@ -1190,13 +1205,14 @@ describe(updateCacheLength.name, () => {
11901205
});
11911206

11921207
it("should decrease cache length with shifting", () => {
1193-
const cache = initCache(10, 40);
1208+
const cache = initCache(10, 40, 0);
11941209
const res = updateCacheLength(cache, 5, true);
11951210
expect(res).toEqual(-(40 * 5));
11961211
expect(cache).toMatchInlineSnapshot(`
11971212
{
11981213
"_computedOffsetIndex": -1,
11991214
"_defaultItemSize": 40,
1215+
"_gap": 0,
12001216
"_length": 5,
12011217
"_offsets": [
12021218
-1,
@@ -1225,6 +1241,7 @@ describe(updateCacheLength.name, () => {
12251241
{
12261242
"_computedOffsetIndex": -1,
12271243
"_defaultItemSize": 40,
1244+
"_gap": 0,
12281245
"_length": 5,
12291246
"_offsets": [
12301247
0,

src/core/cache.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export type Cache = {
1919
// offsets
2020
readonly _computedOffsetIndex: number;
2121
readonly _offsets: number[];
22+
readonly _gap: number;
2223
};
2324

2425
const fill = (array: number[], length: number, prepend?: boolean): number[] => {
@@ -73,7 +74,7 @@ export const computeOffset = (
7374
let i = cache._computedOffsetIndex;
7475
let top = cache._offsets[i]!;
7576
while (i < index) {
76-
top += getItemSize(cache, i);
77+
top += getItemSize(cache, i) + cache._gap;
7778
cache._offsets[++i] = top;
7879
}
7980
// mark as measured
@@ -188,6 +189,7 @@ export const estimateDefaultItemSize = (
188189
export const initCache = (
189190
length: number,
190191
itemSize: number,
192+
gap: number,
191193
snapshot?: InternalCacheSnapshot
192194
): Cache => {
193195
return {
@@ -203,6 +205,7 @@ export const initCache = (
203205
_length: length,
204206
_computedOffsetIndex: -1,
205207
_offsets: fill([], length),
208+
_gap: gap,
206209
};
207210
};
208211

src/core/store.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ export type VirtualStore = {
120120
export const createVirtualStore = (
121121
elementsCount: number,
122122
itemSize: number = 40,
123+
gap: number = 0,
123124
ssrCount: number = 0,
124125
cacheSnapshot?: CacheSnapshot | undefined,
125126
shouldAutoEstimateItemSize: boolean = false
@@ -141,6 +142,7 @@ export const createVirtualStore = (
141142
const cache = initCache(
142143
elementsCount,
143144
itemSize,
145+
gap,
144146
cacheSnapshot as unknown as InternalCacheSnapshot | undefined
145147
);
146148
const subscribers = new Set<[number, Subscriber]>();

src/react/VGrid.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,11 +277,13 @@ export const VGrid = forwardRef<VGridHandle, VGridProps>(
277277
const _rowStore = createVirtualStore(
278278
rowCount,
279279
cellHeight,
280+
undefined, // TODO
280281
initialRowCount
281282
);
282283
const _colStore = createVirtualStore(
283284
colCount,
284285
cellWidth,
286+
undefined, // TODO
285287
initialColCount
286288
);
287289
return [

0 commit comments

Comments
 (0)