react-virtual-renderer 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -122
- package/dist/components/VirtualGrid.d.ts +2 -6
- package/dist/components/VirtualGrid.d.ts.map +1 -1
- package/dist/components/VirtualGrid.js +131 -143
- package/dist/components/VirtualGrid.js.map +1 -1
- package/dist/components/VirtualList.d.ts.map +1 -1
- package/dist/components/VirtualList.js +51 -29
- package/dist/components/VirtualList.js.map +1 -1
- package/dist/core/MeasurementSystem.d.ts +18 -24
- package/dist/core/MeasurementSystem.d.ts.map +1 -1
- package/dist/core/MeasurementSystem.js +100 -71
- package/dist/core/MeasurementSystem.js.map +1 -1
- package/dist/core/VirtualizationEngine.d.ts +9 -54
- package/dist/core/VirtualizationEngine.d.ts.map +1 -1
- package/dist/core/VirtualizationEngine.js +70 -153
- package/dist/core/VirtualizationEngine.js.map +1 -1
- package/dist/hooks/useInfiniteScroll.d.ts +28 -10
- package/dist/hooks/useInfiniteScroll.d.ts.map +1 -1
- package/dist/hooks/useInfiniteScroll.js +31 -14
- package/dist/hooks/useInfiniteScroll.js.map +1 -1
- package/dist/hooks/useLazyLoad.d.ts +32 -11
- package/dist/hooks/useLazyLoad.d.ts.map +1 -1
- package/dist/hooks/useLazyLoad.js +44 -21
- package/dist/hooks/useLazyLoad.js.map +1 -1
- package/dist/hooks/useScrollRestoration.d.ts +46 -5
- package/dist/hooks/useScrollRestoration.d.ts.map +1 -1
- package/dist/hooks/useScrollRestoration.js +138 -41
- package/dist/hooks/useScrollRestoration.js.map +1 -1
- package/dist/hooks/useVirtualList.js +1 -1
- package/dist/hooks/useVirtualList.js.map +1 -1
- package/dist/hooks/useVirtualizedSearch.d.ts +29 -29
- package/dist/hooks/useVirtualizedSearch.d.ts.map +1 -1
- package/dist/hooks/useVirtualizedSearch.js +63 -149
- package/dist/hooks/useVirtualizedSearch.js.map +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/types.d.ts +28 -11
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# React Virtual Renderer
|
|
1
|
+
# 🚀 React Virtual Renderer
|
|
2
2
|
|
|
3
|
-
High-performance React virtualization library for **large lists, grids, tables, infinite scrolling, dynamic heights, and masonry layouts**.
|
|
3
|
+
High-performance React virtualization library for **large lists, grids, tables, infinite scrolling, chat apps, dynamic heights, and masonry layouts**.
|
|
4
4
|
|
|
5
|
-
A modern alternative to react-window and react-virtualized with
|
|
5
|
+
A modern alternative to `react-window` and `react-virtualized` with **better layout flexibility, TypeScript-first API, and advanced rendering control**.
|
|
6
6
|
|
|
7
7
|

|
|
8
8
|

|
|
@@ -11,82 +11,80 @@ A modern alternative to react-window and react-virtualized with built-in accessi
|
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
-
## Why React Virtual Renderer?
|
|
14
|
+
## ✨ Why React Virtual Renderer?
|
|
15
15
|
|
|
16
|
-
Rendering thousands of DOM nodes can severely
|
|
16
|
+
Rendering thousands of DOM nodes can severely degrade performance in React apps.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
This library solves it by rendering **only visible items + overscan buffer**, enabling smooth performance at scale.
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
- Infinite scrolling
|
|
22
|
-
- Dynamic item heights
|
|
23
|
-
- Large tables
|
|
24
|
-
- Chat applications
|
|
25
|
-
- Product catalogs
|
|
26
|
-
- Masonry layouts
|
|
20
|
+
### Built for:
|
|
27
21
|
|
|
28
|
-
|
|
22
|
+
- Chat applications (WhatsApp-style, reverse scroll)
|
|
23
|
+
- Large data tables (10k+ rows)
|
|
24
|
+
- Infinite feeds
|
|
25
|
+
- E-commerce product catalogs
|
|
26
|
+
- Masonry / Pinterest layouts
|
|
27
|
+
- Real-time dashboards
|
|
28
|
+
- Search-heavy UIs
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
32
|
-
## Features
|
|
32
|
+
## ⚡ Features
|
|
33
33
|
|
|
34
|
-
### Performance
|
|
34
|
+
### 🚀 Performance
|
|
35
35
|
|
|
36
|
-
- Virtualized
|
|
37
|
-
- Virtualized
|
|
38
|
-
- Infinite
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
36
|
+
- Virtualized List rendering
|
|
37
|
+
- Virtualized Grid system
|
|
38
|
+
- Infinite scroll support
|
|
39
|
+
- Reverse scrolling (chat apps)
|
|
40
|
+
- Overscan buffering
|
|
41
|
+
- Dynamic height measurement
|
|
42
|
+
- Measurement caching engine
|
|
43
|
+
- Stable scroll handling
|
|
43
44
|
|
|
44
|
-
###
|
|
45
|
+
### 🧠 Layout Engine
|
|
45
46
|
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
47
|
+
- Fixed grid layout
|
|
48
|
+
- Masonry layout (Pinterest-style)
|
|
49
|
+
- Variable row heights
|
|
50
|
+
- Auto column calculation
|
|
51
|
+
- Sticky rows support
|
|
52
|
+
- Adaptive overscan based on scroll speed
|
|
51
53
|
|
|
52
|
-
###
|
|
54
|
+
### 🧑💻 Developer Experience
|
|
53
55
|
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
56
|
+
- Full TypeScript support
|
|
57
|
+
- Hook-based API (`useVirtualList`)
|
|
58
|
+
- Imperative scroll control
|
|
59
|
+
- Ref forwarding support
|
|
60
|
+
- Zero dependencies
|
|
61
|
+
- React 18+ compatible
|
|
58
62
|
|
|
59
|
-
###
|
|
63
|
+
### ♿ Accessibility
|
|
60
64
|
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
- Feed Layout
|
|
65
|
+
- Minimal DOM updates
|
|
66
|
+
- Screen-reader safe structure
|
|
67
|
+
- Keyboard-friendly scrolling
|
|
65
68
|
|
|
66
69
|
---
|
|
67
70
|
|
|
68
|
-
## Installation
|
|
71
|
+
## 📦 Installation
|
|
69
72
|
|
|
70
|
-
|
|
73
|
+
````bash
|
|
71
74
|
npm install react-virtual-renderer
|
|
72
|
-
```
|
|
73
75
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
yarn add react-virtual-renderer
|
|
78
|
-
```
|
|
76
|
+
## 🚀 Quick Start Examples
|
|
79
77
|
|
|
80
78
|
---
|
|
81
79
|
|
|
82
|
-
|
|
80
|
+
### 📋 Basic Virtual List
|
|
83
81
|
|
|
84
82
|
```tsx
|
|
85
83
|
import { VirtualList } from "react-virtual-renderer";
|
|
86
84
|
|
|
87
|
-
const items = Array.from({ length: 10000 }, (_,
|
|
88
|
-
id:
|
|
89
|
-
name: `Item ${
|
|
85
|
+
const items = Array.from({ length: 10000 }, (_, i) => ({
|
|
86
|
+
id: i,
|
|
87
|
+
name: `Item ${i}`,
|
|
90
88
|
}));
|
|
91
89
|
|
|
92
90
|
export default function App() {
|
|
@@ -94,77 +92,13 @@ export default function App() {
|
|
|
94
92
|
<VirtualList
|
|
95
93
|
items={items}
|
|
96
94
|
height={600}
|
|
97
|
-
|
|
95
|
+
estimatedItemSize={40}
|
|
96
|
+
renderItem={({ item }) => (
|
|
97
|
+
<div style={{ padding: 12 }}>
|
|
98
|
+
{item.name}
|
|
99
|
+
</div>
|
|
100
|
+
)}
|
|
98
101
|
/>
|
|
99
102
|
);
|
|
100
103
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
## Common Use Cases
|
|
106
|
-
|
|
107
|
-
- Chat Applications
|
|
108
|
-
- Messaging Systems
|
|
109
|
-
- Activity Feeds
|
|
110
|
-
- Social Networks
|
|
111
|
-
- Infinite Scroll Lists
|
|
112
|
-
- Data Tables
|
|
113
|
-
- Admin Dashboards
|
|
114
|
-
- Product Catalogs
|
|
115
|
-
- E-commerce Grids
|
|
116
|
-
- Analytics Dashboards
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
## Comparison
|
|
121
|
-
|
|
122
|
-
| Feature | React Virtual Renderer | react-window | react-virtualized |
|
|
123
|
-
| --------------- | ---------------------- | ------------ | ----------------- |
|
|
124
|
-
| Dynamic Heights | ✅ | ⚠️ | ⚠️ |
|
|
125
|
-
| Infinite Scroll | ✅ | ❌ | ⚠️ |
|
|
126
|
-
| Masonry Layout | ✅ | ❌ | ⚠️ |
|
|
127
|
-
| Accessibility | ✅ | ❌ | ⚠️ |
|
|
128
|
-
| TypeScript | ✅ | ⚠️ | ⚠️ |
|
|
129
|
-
| Lightweight | ✅ | ✅ | ❌ |
|
|
130
|
-
| React 19 Ready | ✅ | ⚠️ | ⚠️ |
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
## Roadmap
|
|
135
|
-
|
|
136
|
-
### v1.x
|
|
137
|
-
|
|
138
|
-
- Virtual Lists
|
|
139
|
-
- Virtual Grids
|
|
140
|
-
- Infinite Scroll
|
|
141
|
-
- Dynamic Heights
|
|
142
|
-
- Accessibility
|
|
143
|
-
|
|
144
|
-
### v2.x
|
|
145
|
-
|
|
146
|
-
- Masonry Layouts
|
|
147
|
-
- Waterfall Layouts
|
|
148
|
-
- Advanced Grid System
|
|
149
|
-
|
|
150
|
-
### v3.x
|
|
151
|
-
|
|
152
|
-
- Visual Debugger
|
|
153
|
-
- Performance Inspector
|
|
154
|
-
- Analytics Dashboard
|
|
155
|
-
|
|
156
|
-
---
|
|
157
|
-
|
|
158
|
-
## Documentation
|
|
159
|
-
|
|
160
|
-
- Getting Started
|
|
161
|
-
- API Reference
|
|
162
|
-
- Accessibility Guide
|
|
163
|
-
- Performance Guide
|
|
164
|
-
- Examples
|
|
165
|
-
|
|
166
|
-
---
|
|
167
|
-
|
|
168
|
-
## License
|
|
169
|
-
|
|
170
|
-
MIT
|
|
104
|
+
````
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { VirtualGridProps } from
|
|
3
|
-
/**
|
|
4
|
-
* VirtualGrid Component
|
|
5
|
-
* Efficient rendering for grid and masonry layouts
|
|
6
|
-
*/
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { VirtualGridProps } from "../types";
|
|
7
3
|
export declare const VirtualGrid: React.ForwardRefExoticComponent<VirtualGridProps<any> & React.RefAttributes<HTMLDivElement>>;
|
|
8
4
|
//# sourceMappingURL=VirtualGrid.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualGrid.d.ts","sourceRoot":"","sources":["../../src/components/VirtualGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"VirtualGrid.d.ts","sourceRoot":"","sources":["../../src/components/VirtualGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAS5C,eAAO,MAAM,WAAW,8FAyQvB,CAAC"}
|
|
@@ -1,187 +1,175 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef, useMemo, useState, useRef, useImperativeHandle, } from
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export const VirtualGrid = forwardRef(({ items, renderItem, itemKey, height, width, columnCount = 3, rowHeight = 200, columnWidth, layout = 'grid', overscan = 3, gap = 16, onScroll, className = '', style = {}, }, containerRef) => {
|
|
8
|
-
const [scrollOffset, setScrollOffset] = useState(0);
|
|
2
|
+
import { forwardRef, useMemo, useState, useRef, useEffect, useImperativeHandle, } from "react";
|
|
3
|
+
export const VirtualGrid = forwardRef(({ items, renderItem, itemKey, height = 600, width = "100%", columnCount = 3, rowHeight = 200, columnWidth, layout = "grid", overscan = 5, gap = 16, onScroll, innerClassName, innerStyle, }, ref) => {
|
|
4
|
+
const containerRef = useRef(null);
|
|
5
|
+
useImperativeHandle(ref, () => containerRef.current);
|
|
6
|
+
const [scrollTop, setScrollTop] = useState(0);
|
|
9
7
|
const [isScrolling, setIsScrolling] = useState(false);
|
|
10
|
-
const
|
|
11
|
-
const scrollTimeoutRef = useRef(null);
|
|
12
|
-
const columnHeightsRef = useRef([]);
|
|
8
|
+
const scrollTimeout = useRef(null);
|
|
13
9
|
/**
|
|
14
|
-
*
|
|
10
|
+
* ✅ FIX 1: Safe container width (supports %, number, fallback)
|
|
15
11
|
*/
|
|
16
|
-
|
|
12
|
+
const containerWidth = useMemo(() => {
|
|
13
|
+
if (typeof width === "number")
|
|
14
|
+
return width;
|
|
15
|
+
if (typeof width === "string") {
|
|
16
|
+
if (width.endsWith("%")) {
|
|
17
|
+
const parentWidth = containerRef.current?.offsetWidth ||
|
|
18
|
+
window.innerWidth;
|
|
19
|
+
return (parseFloat(width) / 100) * parentWidth;
|
|
20
|
+
}
|
|
21
|
+
const parsed = Number(width);
|
|
22
|
+
return Number.isFinite(parsed) ? parsed : 800;
|
|
23
|
+
}
|
|
24
|
+
return 800;
|
|
25
|
+
}, [width]);
|
|
17
26
|
/**
|
|
18
|
-
*
|
|
27
|
+
* Columns
|
|
19
28
|
*/
|
|
20
|
-
const cols =
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
const cols = useMemo(() => {
|
|
30
|
+
if (columnCount === "auto") {
|
|
31
|
+
const containerWidth = typeof width === "number"
|
|
32
|
+
? width
|
|
33
|
+
: containerRef.current?.offsetWidth || 800;
|
|
34
|
+
const minColWidth = 250; // you can tune this
|
|
35
|
+
return Math.max(1, Math.floor(containerWidth / minColWidth));
|
|
36
|
+
}
|
|
37
|
+
return Math.max(1, columnCount);
|
|
38
|
+
}, [columnCount, width]);
|
|
26
39
|
/**
|
|
27
|
-
*
|
|
40
|
+
* ✅ FIX 2: Safe column width (NO NaN ever)
|
|
28
41
|
*/
|
|
29
|
-
const colWidth =
|
|
30
|
-
|
|
31
|
-
|
|
42
|
+
const colWidth = useMemo(() => {
|
|
43
|
+
if (typeof columnWidth === "number")
|
|
44
|
+
return columnWidth;
|
|
45
|
+
const safeWidth = Number.isFinite(containerWidth)
|
|
46
|
+
? containerWidth
|
|
47
|
+
: 800;
|
|
48
|
+
return (safeWidth - gap * (cols - 1)) / cols;
|
|
49
|
+
}, [columnWidth, containerWidth, cols, gap]);
|
|
32
50
|
/**
|
|
33
|
-
*
|
|
51
|
+
* Precompute positions
|
|
34
52
|
*/
|
|
35
53
|
const positions = useMemo(() => {
|
|
36
|
-
const
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
54
|
+
const pos = [];
|
|
55
|
+
if (!Number.isFinite(colWidth))
|
|
56
|
+
return pos;
|
|
57
|
+
if (layout === "masonry") {
|
|
58
|
+
const colHeights = Array(cols).fill(0);
|
|
59
|
+
for (let i = 0; i < items.length; i++) {
|
|
60
|
+
const minCol = colHeights.indexOf(Math.min(...colHeights));
|
|
61
|
+
const h = typeof rowHeight === "function"
|
|
62
|
+
? rowHeight(i)
|
|
43
63
|
: rowHeight;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
x: shortestColIndex *
|
|
48
|
-
(colWidth + gap),
|
|
49
|
-
y: columnHeights[shortestColIndex],
|
|
64
|
+
pos.push({
|
|
65
|
+
x: minCol * (colWidth + gap),
|
|
66
|
+
y: colHeights[minCol],
|
|
50
67
|
width: colWidth,
|
|
51
|
-
height:
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
itemHeight + gap;
|
|
56
|
-
});
|
|
57
|
-
columnHeightsRef.current = columnHeights;
|
|
68
|
+
height: h,
|
|
69
|
+
});
|
|
70
|
+
colHeights[minCol] += h + gap;
|
|
71
|
+
}
|
|
58
72
|
}
|
|
59
73
|
else {
|
|
60
|
-
items.
|
|
61
|
-
const row = Math.floor(
|
|
62
|
-
const col =
|
|
63
|
-
const
|
|
64
|
-
? rowHeight(
|
|
74
|
+
for (let i = 0; i < items.length; i++) {
|
|
75
|
+
const row = Math.floor(i / cols);
|
|
76
|
+
const col = i % cols;
|
|
77
|
+
const h = typeof rowHeight === "function"
|
|
78
|
+
? rowHeight(i)
|
|
65
79
|
: rowHeight;
|
|
66
|
-
|
|
67
|
-
row,
|
|
68
|
-
col,
|
|
80
|
+
pos.push({
|
|
69
81
|
x: col * (colWidth + gap),
|
|
70
|
-
y: row * (
|
|
82
|
+
y: row * (h + gap),
|
|
71
83
|
width: colWidth,
|
|
72
|
-
height:
|
|
84
|
+
height: h,
|
|
73
85
|
});
|
|
74
|
-
}
|
|
86
|
+
}
|
|
75
87
|
}
|
|
76
|
-
return
|
|
77
|
-
}, [
|
|
78
|
-
items,
|
|
79
|
-
cols,
|
|
80
|
-
colWidth,
|
|
81
|
-
gap,
|
|
82
|
-
layout,
|
|
83
|
-
rowHeight,
|
|
84
|
-
]);
|
|
88
|
+
return pos;
|
|
89
|
+
}, [items, cols, colWidth, gap, layout, rowHeight]);
|
|
85
90
|
/**
|
|
86
|
-
* Visible range
|
|
91
|
+
* Visible range (safe + stable)
|
|
87
92
|
*/
|
|
88
93
|
const visibleRange = useMemo(() => {
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
const start = Math.max(0,
|
|
92
|
-
const end =
|
|
93
|
-
? items.length
|
|
94
|
-
: Math.min(items.length,
|
|
94
|
+
const startIndex = positions.findIndex((p) => p.y + p.height >= scrollTop);
|
|
95
|
+
const endIndex = positions.findIndex((p) => p.y > scrollTop + (typeof height === "number" ? height : 600));
|
|
96
|
+
const start = Math.max(0, startIndex - overscan);
|
|
97
|
+
const end = endIndex === -1
|
|
98
|
+
? items.length - 1
|
|
99
|
+
: Math.min(items.length - 1, endIndex + overscan);
|
|
95
100
|
return { start, end };
|
|
96
|
-
}, [
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
}, [positions, scrollTop, height, overscan, items.length]);
|
|
102
|
+
/**
|
|
103
|
+
* Total height (safe)
|
|
104
|
+
*/
|
|
105
|
+
const totalHeight = useMemo(() => {
|
|
106
|
+
if (!positions.length)
|
|
107
|
+
return 0;
|
|
108
|
+
if (layout === "masonry") {
|
|
109
|
+
return Math.max(...positions.map((p) => p.y + p.height));
|
|
110
|
+
}
|
|
111
|
+
const rows = Math.ceil(items.length / cols);
|
|
112
|
+
const avgHeight = typeof rowHeight === "function" ? 200 : rowHeight;
|
|
113
|
+
return rows * (avgHeight + gap);
|
|
114
|
+
}, [positions, layout, items.length, cols, rowHeight, gap]);
|
|
103
115
|
/**
|
|
104
116
|
* Scroll handler
|
|
105
117
|
*/
|
|
106
118
|
const handleScroll = (e) => {
|
|
107
|
-
const
|
|
108
|
-
|
|
119
|
+
const top = e.currentTarget.scrollTop;
|
|
120
|
+
setScrollTop(top);
|
|
109
121
|
setIsScrolling(true);
|
|
110
|
-
|
|
111
|
-
|
|
122
|
+
onScroll?.(top, e.currentTarget.scrollLeft);
|
|
123
|
+
if (scrollTimeout.current) {
|
|
124
|
+
clearTimeout(scrollTimeout.current);
|
|
112
125
|
}
|
|
113
|
-
|
|
114
|
-
clearTimeout(scrollTimeoutRef.current);
|
|
115
|
-
}
|
|
116
|
-
scrollTimeoutRef.current = setTimeout(() => {
|
|
126
|
+
scrollTimeout.current = setTimeout(() => {
|
|
117
127
|
setIsScrolling(false);
|
|
118
|
-
},
|
|
128
|
+
}, 120);
|
|
119
129
|
};
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
: [0]));
|
|
128
|
-
}
|
|
129
|
-
const totalRows = Math.ceil(items.length / cols);
|
|
130
|
-
const maxItemHeight = Math.max(...Array.from({ length: items.length || 1 }, (_, i) => typeof rowHeight === 'function'
|
|
131
|
-
? rowHeight(i)
|
|
132
|
-
: rowHeight));
|
|
133
|
-
return totalRows * (maxItemHeight + gap);
|
|
134
|
-
}, [
|
|
135
|
-
items.length,
|
|
136
|
-
cols,
|
|
137
|
-
gap,
|
|
138
|
-
layout,
|
|
139
|
-
rowHeight,
|
|
140
|
-
]);
|
|
141
|
-
/**
|
|
142
|
-
* Container style
|
|
143
|
-
*/
|
|
130
|
+
useEffect(() => {
|
|
131
|
+
return () => {
|
|
132
|
+
if (scrollTimeout.current) {
|
|
133
|
+
clearTimeout(scrollTimeout.current);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
}, []);
|
|
144
137
|
const containerStyle = {
|
|
145
138
|
height,
|
|
146
139
|
width,
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
140
|
+
overflowY: "auto",
|
|
141
|
+
overflowX: "hidden",
|
|
142
|
+
position: "relative",
|
|
143
|
+
...innerStyle,
|
|
150
144
|
};
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const gridStyle = {
|
|
155
|
-
position: 'relative',
|
|
145
|
+
const safeColWidth = Number.isFinite(colWidth) ? colWidth : 200;
|
|
146
|
+
const innerStyleComputed = {
|
|
147
|
+
position: "relative",
|
|
156
148
|
height: totalHeight,
|
|
157
|
-
width:
|
|
149
|
+
width: cols * safeColWidth + gap * (cols - 1),
|
|
158
150
|
};
|
|
159
|
-
return (_jsx("div", { ref:
|
|
160
|
-
|
|
161
|
-
|
|
151
|
+
return (_jsx("div", { ref: containerRef, className: innerClassName, style: containerStyle, onScroll: handleScroll, children: _jsx("div", { style: innerStyleComputed, children: Array.from({ length: visibleRange.end - visibleRange.start + 1 }, (_, i) => {
|
|
152
|
+
const index = visibleRange.start + i;
|
|
153
|
+
const item = items[index];
|
|
154
|
+
const pos = positions[index];
|
|
155
|
+
if (!item || !pos)
|
|
162
156
|
return null;
|
|
163
|
-
|
|
164
|
-
const position = positions[index];
|
|
165
|
-
if (!position) {
|
|
157
|
+
if (!Number.isFinite(pos.width))
|
|
166
158
|
return null;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
left: position.x,
|
|
174
|
-
top: position.y,
|
|
175
|
-
width: position.width,
|
|
176
|
-
height: position.height,
|
|
177
|
-
},
|
|
178
|
-
isScrolling,
|
|
159
|
+
const style = {
|
|
160
|
+
position: "absolute",
|
|
161
|
+
top: pos.y,
|
|
162
|
+
left: pos.x,
|
|
163
|
+
width: pos.width,
|
|
164
|
+
height: pos.height,
|
|
179
165
|
};
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
166
|
+
return (_jsx("div", { style: style, children: renderItem({
|
|
167
|
+
item,
|
|
168
|
+
index,
|
|
169
|
+
isScrolling,
|
|
170
|
+
style,
|
|
171
|
+
}) }, itemKey?.(index, item) ?? index));
|
|
184
172
|
}) }) }));
|
|
185
173
|
});
|
|
186
|
-
VirtualGrid.displayName =
|
|
174
|
+
VirtualGrid.displayName = "VirtualGrid";
|
|
187
175
|
//# sourceMappingURL=VirtualGrid.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualGrid.js","sourceRoot":"","sources":["../../src/components/VirtualGrid.tsx"],"names":[],"mappings":";AAAA,OAAc,EACV,UAAU,EACV,OAAO,EACP,QAAQ,EACR,MAAM,EACN,mBAAmB,GACtB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"VirtualGrid.js","sourceRoot":"","sources":["../../src/components/VirtualGrid.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualList.d.ts","sourceRoot":"","sources":["../../src/components/VirtualList.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"VirtualList.d.ts","sourceRoot":"","sources":["../../src/components/VirtualList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAKN,MAAM,OAAO,CAAC;AAGf,OAAO,EACH,gBAAgB,EAEnB,MAAM,UAAU,CAAC;AAElB;;;GAGG;AACH,eAAO,MAAM,WAAW,8FAoPvB,CAAC"}
|