@cleverbamboo/react-virtual-masonry 1.0.0
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/LICENSE +21 -0
- package/README.md +343 -0
- package/README.zh-CN.md +490 -0
- package/dist/DynamicMasonryView.d.ts +97 -0
- package/dist/DynamicMasonryView.d.ts.map +1 -0
- package/dist/FullWidthEqualHeightMasonry.d.ts +51 -0
- package/dist/FullWidthEqualHeightMasonry.d.ts.map +1 -0
- package/dist/VirtualMasonry.d.ts +35 -0
- package/dist/VirtualMasonry.d.ts.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.esm.js +674 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +680 -0
- package/dist/index.js.map +1 -0
- package/package.json +68 -0
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
# React Virtual Masonry (中文文档)
|
|
2
|
+
|
|
3
|
+
[English](./README.md) | 简体中文
|
|
4
|
+
|
|
5
|
+
一个高性能的 React 虚拟滚动瀑布流布局库,支持瀑布流和等高布局两种模式。
|
|
6
|
+
|
|
7
|
+
## ✨ 特性
|
|
8
|
+
|
|
9
|
+
- 🚀 **高性能虚拟滚动** - 只渲染可视区域内的元素,支持海量数据展示
|
|
10
|
+
- 📐 **多种布局模式**
|
|
11
|
+
- 瀑布流布局(Pinterest 风格) - 不等宽不等高,自动找到最短列放置
|
|
12
|
+
- 等高布局(Google Photos 风格) - 每行高度相同,宽度按原始比例自适应填满整行
|
|
13
|
+
- 动态布局 - 支持根据接口返回的数据动态切换布局类型
|
|
14
|
+
- 🎯 **智能预加载** - 基于 IntersectionObserver 实现的无限滚动,支持自定义预加载距离
|
|
15
|
+
- 🎨 **完全可定制** - 支持自定义渲染函数、加载状态、"没有更多"提示、间距等
|
|
16
|
+
- 📱 **响应式设计** - 使用 ResizeObserver 自动适配容器宽度变化
|
|
17
|
+
- ⚡ **RAF 优化** - 使用 requestAnimationFrame 优化滚动性能,避免卡顿
|
|
18
|
+
- 🔧 **TypeScript 支持** - 完整的 TypeScript 类型定义
|
|
19
|
+
- 🪶 **零外部依赖** - 除了 React 不依赖任何第三方库
|
|
20
|
+
|
|
21
|
+
## 📦 安装
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install react-virtual-masonry
|
|
25
|
+
# 或者
|
|
26
|
+
yarn add react-virtual-masonry
|
|
27
|
+
# 或者
|
|
28
|
+
pnpm add react-virtual-masonry
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 🎯 快速开始
|
|
32
|
+
|
|
33
|
+
### 1. 瀑布流布局 (Pinterest 风格)
|
|
34
|
+
|
|
35
|
+
适用于图片墙、商品列表等场景。
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import { VirtualMasonry } from 'react-virtual-masonry';
|
|
39
|
+
|
|
40
|
+
function ImageGallery() {
|
|
41
|
+
// 数据加载函数
|
|
42
|
+
const loadData = async (page: number, pageSize: number) => {
|
|
43
|
+
const response = await fetch(`/api/images?page=${page}&size=${pageSize}`);
|
|
44
|
+
const data = await response.json();
|
|
45
|
+
return {
|
|
46
|
+
data: data.items, // 数据数组
|
|
47
|
+
hasMore: data.hasMore, // 是否还有更多数据
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<VirtualMasonry
|
|
53
|
+
loadData={loadData}
|
|
54
|
+
pageSize={30}
|
|
55
|
+
minColumnWidth={200} // 最小列宽
|
|
56
|
+
maxColumnWidth={350} // 最大列宽(可选)
|
|
57
|
+
gap={16} // 间距
|
|
58
|
+
renderItem={(item) => (
|
|
59
|
+
<div
|
|
60
|
+
style={{
|
|
61
|
+
position: 'absolute',
|
|
62
|
+
left: item.x, // 组件会自动计算位置
|
|
63
|
+
top: item.y,
|
|
64
|
+
width: item.width,
|
|
65
|
+
height: item.height,
|
|
66
|
+
}}
|
|
67
|
+
>
|
|
68
|
+
<img src={item.url} alt={item.title} />
|
|
69
|
+
</div>
|
|
70
|
+
)}
|
|
71
|
+
/>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 2. 等高布局 (Google Photos 风格)
|
|
77
|
+
|
|
78
|
+
适用于相册、时间线等需要整齐对齐的场景。
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
import { FullWidthEqualHeightMasonry } from 'react-virtual-masonry';
|
|
82
|
+
|
|
83
|
+
function PhotoAlbum() {
|
|
84
|
+
const loadData = async (page: number, pageSize: number) => {
|
|
85
|
+
const response = await fetch(`/api/photos?page=${page}&size=${pageSize}`);
|
|
86
|
+
const data = await response.json();
|
|
87
|
+
return {
|
|
88
|
+
data: data.items,
|
|
89
|
+
hasMore: data.hasMore,
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<FullWidthEqualHeightMasonry
|
|
95
|
+
loadData={loadData}
|
|
96
|
+
pageSize={30}
|
|
97
|
+
targetRowHeight={245} // 目标行高
|
|
98
|
+
sizeRange={[230, 260]} // 行高范围[最小, 最大]
|
|
99
|
+
maxItemWidth={975} // 单个项目最大宽度
|
|
100
|
+
gap={8}
|
|
101
|
+
renderItem={(item) => (
|
|
102
|
+
<div
|
|
103
|
+
style={{
|
|
104
|
+
position: 'absolute',
|
|
105
|
+
left: item.x,
|
|
106
|
+
top: item.y,
|
|
107
|
+
width: item.width,
|
|
108
|
+
height: item.height,
|
|
109
|
+
}}
|
|
110
|
+
>
|
|
111
|
+
<img src={item.url} alt={item.title} />
|
|
112
|
+
</div>
|
|
113
|
+
)}
|
|
114
|
+
/>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### 3. 动态布局
|
|
120
|
+
|
|
121
|
+
根据接口返回的数据动态切换布局类型。
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
import { DynamicMasonryView } from 'react-virtual-masonry';
|
|
125
|
+
|
|
126
|
+
function DynamicGallery() {
|
|
127
|
+
const loadData = async (page: number, pageSize: number) => {
|
|
128
|
+
const response = await fetch(`/api/content?page=${page}&size=${pageSize}`);
|
|
129
|
+
const data = await response.json();
|
|
130
|
+
|
|
131
|
+
// 第一次加载时返回布局类型
|
|
132
|
+
if (page === 1) {
|
|
133
|
+
return {
|
|
134
|
+
data: data.items,
|
|
135
|
+
hasMore: data.hasMore,
|
|
136
|
+
isMasonry: data.layoutType === 'waterfall', // true=瀑布流, false=等高
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// 后续加载不需要返回布局类型
|
|
141
|
+
return {
|
|
142
|
+
data: data.items,
|
|
143
|
+
hasMore: data.hasMore,
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<DynamicMasonryView
|
|
149
|
+
loadData={loadData}
|
|
150
|
+
pageSize={30}
|
|
151
|
+
// 瀑布流配置
|
|
152
|
+
waterfallConfig={{
|
|
153
|
+
minColumnWidth: 200,
|
|
154
|
+
maxColumnWidth: 350,
|
|
155
|
+
gap: 16,
|
|
156
|
+
}}
|
|
157
|
+
// 等高布局配置
|
|
158
|
+
equalHeightConfig={{
|
|
159
|
+
targetRowHeight: 245,
|
|
160
|
+
sizeRange: [230, 260],
|
|
161
|
+
gap: 8,
|
|
162
|
+
}}
|
|
163
|
+
renderItem={(item, isMasonry) => (
|
|
164
|
+
<div
|
|
165
|
+
style={{
|
|
166
|
+
position: 'absolute',
|
|
167
|
+
left: item.x,
|
|
168
|
+
top: item.y,
|
|
169
|
+
width: item.width,
|
|
170
|
+
height: item.height,
|
|
171
|
+
borderRadius: isMasonry ? '8px' : '4px', // 可以根据布局类型调整样式
|
|
172
|
+
}}
|
|
173
|
+
>
|
|
174
|
+
<img src={item.url} alt={item.title} />
|
|
175
|
+
</div>
|
|
176
|
+
)}
|
|
177
|
+
/>
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## 📖 API 文档
|
|
183
|
+
|
|
184
|
+
### VirtualMasonry
|
|
185
|
+
|
|
186
|
+
瀑布流布局组件,适合不等宽不等高的内容。
|
|
187
|
+
|
|
188
|
+
#### Props
|
|
189
|
+
|
|
190
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
191
|
+
|------|------|--------|------|
|
|
192
|
+
| `loadData` | `(page: number, pageSize: number) => Promise<{data: any[], hasMore: boolean}>` | **必填** | 数据加载函数,返回 Promise |
|
|
193
|
+
| `renderItem` | `(item: any, index: number) => React.ReactNode` | **必填** | 渲染每个项目的函数 |
|
|
194
|
+
| `pageSize` | `number` | `50` | 每页加载的数据量 |
|
|
195
|
+
| `minColumnWidth` | `number` | `200` | 最小列宽(px) |
|
|
196
|
+
| `maxColumnWidth` | `number` | - | 最大列宽(px),不设置则不限制 |
|
|
197
|
+
| `gap` | `number` | `16` | 项目间距(px) |
|
|
198
|
+
| `buffer` | `number` | `1500` | 可视区域外的缓冲区大小(px),越大渲染的内容越多 |
|
|
199
|
+
| `loadMoreThreshold` | `number` | `800` | 预加载阈值(px),距离底部多远时触发加载 |
|
|
200
|
+
| `mapSize` | `(raw: any) => {width: number, height: number}` | - | 映射数据的宽高字段 |
|
|
201
|
+
| `renderLoader` | `(totalHeight: number) => React.ReactNode` | - | 自定义加载状态组件 |
|
|
202
|
+
| `renderNoMore` | `(totalHeight: number) => React.ReactNode` | - | 自定义"没有更多"提示组件 |
|
|
203
|
+
|
|
204
|
+
### FullWidthEqualHeightMasonry
|
|
205
|
+
|
|
206
|
+
等高布局组件,每行高度相同,宽度自适应。
|
|
207
|
+
|
|
208
|
+
#### Props
|
|
209
|
+
|
|
210
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
211
|
+
|------|------|--------|------|
|
|
212
|
+
| `loadData` | `(page: number, pageSize: number) => Promise<{data: any[], hasMore: boolean}>` | **必填** | 数据加载函数 |
|
|
213
|
+
| `renderItem` | `(item: any) => React.ReactNode` | **必填** | 渲染函数,item 包含 x, y, width, height |
|
|
214
|
+
| `pageSize` | `number` | `50` | 每页数据量 |
|
|
215
|
+
| `targetRowHeight` | `number` | `245` | 目标行高,实际会在 sizeRange 范围内调整 |
|
|
216
|
+
| `sizeRange` | `[number, number]` | `[230, 260]` | 行高范围 [最小高度, 最大高度] |
|
|
217
|
+
| `maxItemWidth` | `number` | `975` | 单个项目的最大宽度,避免图片过宽 |
|
|
218
|
+
| `maxStretchRatio` | `number` | `1.5` | 最大拉伸比例,避免图片过度变形 |
|
|
219
|
+
| `gap` | `number` | `8` | 项目间距(px) |
|
|
220
|
+
| `buffer` | `number` | `1500` | 缓冲区大小(px) |
|
|
221
|
+
| `loadMoreThreshold` | `number` | `500` | 预加载阈值(px) |
|
|
222
|
+
| `mapSize` | `(raw: any) => {width: number, height: number}` | - | 映射数据的宽高字段 |
|
|
223
|
+
| `renderLoader` | `(totalHeight: number) => React.ReactNode` | - | 自定义加载状态 |
|
|
224
|
+
| `renderNoMore` | `(totalHeight: number) => React.ReactNode` | - | 自定义"没有更多"提示 |
|
|
225
|
+
|
|
226
|
+
### DynamicMasonryView
|
|
227
|
+
|
|
228
|
+
动态布局组件,可以根据数据动态切换瀑布流和等高布局。
|
|
229
|
+
|
|
230
|
+
#### Props
|
|
231
|
+
|
|
232
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
233
|
+
|------|------|--------|------|
|
|
234
|
+
| `isMasonry` | `boolean` | - | 受控模式:是否使用瀑布流布局 |
|
|
235
|
+
| `defaultIsMasonry` | `boolean` | `true` | 非受控模式:默认布局类型 |
|
|
236
|
+
| `loadData` | `LoadDataFn` | **必填** | 数据加载函数,第一次可返回 isMasonry |
|
|
237
|
+
| `renderItem` | `(item: any, isMasonry: boolean) => React.ReactNode` | **必填** | 渲染函数,第二个参数表示当前布局类型 |
|
|
238
|
+
| `waterfallConfig` | `WaterfallConfig` | `{}` | 瀑布流配置对象 |
|
|
239
|
+
| `equalHeightConfig` | `EqualHeightConfig` | `{}` | 等高布局配置对象 |
|
|
240
|
+
| `pageSize` | `number` | `50` | 每页数据量 |
|
|
241
|
+
| `mapSize` | `(raw: any) => {width: number, height: number}` | - | 映射宽高字段 |
|
|
242
|
+
| `renderInitialLoader` | `() => React.ReactNode` | - | 初始加载状态(获取布局类型时) |
|
|
243
|
+
| `onLayoutTypeLoaded` | `(isMasonry: boolean) => void` | - | 布局类型加载完成回调 |
|
|
244
|
+
| `onError` | `(error: Error) => void` | - | 错误回调 |
|
|
245
|
+
|
|
246
|
+
#### LoadDataFn 类型
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
type LoadDataFn<T = any> = (
|
|
250
|
+
page: number,
|
|
251
|
+
pageSize: number,
|
|
252
|
+
) => Promise<{
|
|
253
|
+
data: T[];
|
|
254
|
+
hasMore: boolean;
|
|
255
|
+
isMasonry?: boolean; // 仅第一次调用时返回
|
|
256
|
+
}>;
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## 🎨 自定义样式
|
|
260
|
+
|
|
261
|
+
### 自定义加载状态和"没有更多"提示
|
|
262
|
+
|
|
263
|
+
```tsx
|
|
264
|
+
<VirtualMasonry
|
|
265
|
+
loadData={loadData}
|
|
266
|
+
renderItem={renderItem}
|
|
267
|
+
renderLoader={(totalHeight) => (
|
|
268
|
+
<div
|
|
269
|
+
style={{
|
|
270
|
+
position: 'absolute',
|
|
271
|
+
top: totalHeight,
|
|
272
|
+
left: 0,
|
|
273
|
+
right: 0,
|
|
274
|
+
height: 100,
|
|
275
|
+
display: 'flex',
|
|
276
|
+
justifyContent: 'center',
|
|
277
|
+
alignItems: 'center',
|
|
278
|
+
}}
|
|
279
|
+
>
|
|
280
|
+
<div className="custom-loader">加载中...</div>
|
|
281
|
+
</div>
|
|
282
|
+
)}
|
|
283
|
+
renderNoMore={(totalHeight) => (
|
|
284
|
+
<div
|
|
285
|
+
style={{
|
|
286
|
+
position: 'absolute',
|
|
287
|
+
top: totalHeight,
|
|
288
|
+
left: 0,
|
|
289
|
+
right: 0,
|
|
290
|
+
height: 50,
|
|
291
|
+
textAlign: 'center',
|
|
292
|
+
color: '#999',
|
|
293
|
+
paddingTop: '20px',
|
|
294
|
+
}}
|
|
295
|
+
>
|
|
296
|
+
- 没有更多数据了 -
|
|
297
|
+
</div>
|
|
298
|
+
)}
|
|
299
|
+
/>
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### 自定义项目样式
|
|
303
|
+
|
|
304
|
+
```tsx
|
|
305
|
+
<VirtualMasonry
|
|
306
|
+
loadData={loadData}
|
|
307
|
+
renderItem={(item) => (
|
|
308
|
+
<div
|
|
309
|
+
className="gallery-item"
|
|
310
|
+
style={{
|
|
311
|
+
position: 'absolute',
|
|
312
|
+
left: item.x,
|
|
313
|
+
top: item.y,
|
|
314
|
+
width: item.width,
|
|
315
|
+
height: item.height,
|
|
316
|
+
borderRadius: '8px',
|
|
317
|
+
overflow: 'hidden',
|
|
318
|
+
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
|
|
319
|
+
transition: 'transform 0.2s, box-shadow 0.2s',
|
|
320
|
+
}}
|
|
321
|
+
onMouseEnter={(e) => {
|
|
322
|
+
e.currentTarget.style.transform = 'scale(1.05)';
|
|
323
|
+
e.currentTarget.style.boxShadow = '0 8px 16px rgba(0,0,0,0.2)';
|
|
324
|
+
}}
|
|
325
|
+
onMouseLeave={(e) => {
|
|
326
|
+
e.currentTarget.style.transform = 'scale(1)';
|
|
327
|
+
e.currentTarget.style.boxShadow = '0 2px 8px rgba(0,0,0,0.1)';
|
|
328
|
+
}}
|
|
329
|
+
>
|
|
330
|
+
<img
|
|
331
|
+
src={item.url}
|
|
332
|
+
alt={item.title}
|
|
333
|
+
style={{
|
|
334
|
+
width: '100%',
|
|
335
|
+
height: '100%',
|
|
336
|
+
objectFit: 'cover',
|
|
337
|
+
}}
|
|
338
|
+
/>
|
|
339
|
+
<div className="overlay">
|
|
340
|
+
<h3>{item.title}</h3>
|
|
341
|
+
<p>{item.description}</p>
|
|
342
|
+
</div>
|
|
343
|
+
</div>
|
|
344
|
+
)}
|
|
345
|
+
/>
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## 🔧 高级用法
|
|
349
|
+
|
|
350
|
+
### 映射数据格式
|
|
351
|
+
|
|
352
|
+
如果你的数据格式与默认不同,可以使用 `mapSize` 来映射宽高字段:
|
|
353
|
+
|
|
354
|
+
```tsx
|
|
355
|
+
<VirtualMasonry
|
|
356
|
+
loadData={loadData}
|
|
357
|
+
mapSize={(item) => ({
|
|
358
|
+
width: item.imageWidth, // 自定义宽度字段名
|
|
359
|
+
height: item.imageHeight, // 自定义高度字段名
|
|
360
|
+
})}
|
|
361
|
+
renderItem={renderItem}
|
|
362
|
+
/>
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
**默认支持的字段名:**
|
|
366
|
+
- 宽度: `width` / `w` / `imgW`
|
|
367
|
+
- 高度: `height` / `h` / `imgH`
|
|
368
|
+
|
|
369
|
+
### 性能优化建议
|
|
370
|
+
|
|
371
|
+
#### 1. 调整缓冲区大小
|
|
372
|
+
|
|
373
|
+
`buffer` 属性控制可视区域外渲染多少内容。值越大,滚动时越流畅,但内存占用越高。
|
|
374
|
+
|
|
375
|
+
```tsx
|
|
376
|
+
<VirtualMasonry
|
|
377
|
+
buffer={1500} // 默认值,可根据实际情况调整
|
|
378
|
+
// ...
|
|
379
|
+
/>
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
#### 2. 调整预加载阈值
|
|
383
|
+
|
|
384
|
+
`loadMoreThreshold` 控制距离底部多远时开始加载下一页。
|
|
385
|
+
|
|
386
|
+
```tsx
|
|
387
|
+
<VirtualMasonry
|
|
388
|
+
loadMoreThreshold={800} // 距离底部 800px 时开始加载
|
|
389
|
+
// ...
|
|
390
|
+
/>
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
#### 3. 使用 React.memo 优化渲染
|
|
394
|
+
|
|
395
|
+
```tsx
|
|
396
|
+
const GalleryItem = React.memo(({ item }) => (
|
|
397
|
+
<div
|
|
398
|
+
style={{
|
|
399
|
+
position: 'absolute',
|
|
400
|
+
left: item.x,
|
|
401
|
+
top: item.y,
|
|
402
|
+
width: item.width,
|
|
403
|
+
height: item.height,
|
|
404
|
+
}}
|
|
405
|
+
>
|
|
406
|
+
<img src={item.url} alt={item.title} />
|
|
407
|
+
</div>
|
|
408
|
+
));
|
|
409
|
+
|
|
410
|
+
<VirtualMasonry
|
|
411
|
+
renderItem={(item) => <GalleryItem item={item} />}
|
|
412
|
+
/>
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
#### 4. 图片懒加载
|
|
416
|
+
|
|
417
|
+
配合浏览器原生懒加载或第三方库:
|
|
418
|
+
|
|
419
|
+
```tsx
|
|
420
|
+
<VirtualMasonry
|
|
421
|
+
renderItem={(item) => (
|
|
422
|
+
<div style={{...}}>
|
|
423
|
+
<img
|
|
424
|
+
src={item.url}
|
|
425
|
+
alt={item.title}
|
|
426
|
+
loading="lazy" // 浏览器原生懒加载
|
|
427
|
+
/>
|
|
428
|
+
</div>
|
|
429
|
+
)}
|
|
430
|
+
/>
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
## 🏃 运行 Demo
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
# 克隆仓库
|
|
437
|
+
git clone https://github.com/yourusername/react-virtual-masonry.git
|
|
438
|
+
cd react-virtual-masonry
|
|
439
|
+
|
|
440
|
+
# 安装依赖
|
|
441
|
+
npm install
|
|
442
|
+
|
|
443
|
+
# 启动开发服务器
|
|
444
|
+
npm run dev
|
|
445
|
+
|
|
446
|
+
# 构建库
|
|
447
|
+
npm run build
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
访问 `http://localhost:3000` 查看完整的 demo 示例。
|
|
451
|
+
|
|
452
|
+
## 📝 更新日志
|
|
453
|
+
|
|
454
|
+
### v1.0.0 (2025-01-XX)
|
|
455
|
+
|
|
456
|
+
- 🎉 首次发布
|
|
457
|
+
- ✨ 支持瀑布流布局
|
|
458
|
+
- ✨ 支持等高布局
|
|
459
|
+
- ✨ 支持动态布局切换
|
|
460
|
+
- 🚀 虚拟滚动优化
|
|
461
|
+
- 📖 完整的 TypeScript 类型
|
|
462
|
+
|
|
463
|
+
## 🤝 贡献指南
|
|
464
|
+
|
|
465
|
+
我们欢迎所有形式的贡献!
|
|
466
|
+
|
|
467
|
+
1. Fork 本仓库
|
|
468
|
+
2. 创建你的特性分支 (`git checkout -b feature/AmazingFeature`)
|
|
469
|
+
3. 提交你的改动 (`git commit -m 'Add some AmazingFeature'`)
|
|
470
|
+
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
|
471
|
+
5. 开启一个 Pull Request
|
|
472
|
+
|
|
473
|
+
## 📄 许可证
|
|
474
|
+
|
|
475
|
+
本项目采用 [MIT](./LICENSE) 许可证。
|
|
476
|
+
|
|
477
|
+
## 📮 联系方式
|
|
478
|
+
|
|
479
|
+
如果你有任何问题或建议:
|
|
480
|
+
|
|
481
|
+
- 提交 Issue: [GitHub Issues](https://github.com/yourusername/react-virtual-masonry/issues)
|
|
482
|
+
- 发送邮件: your.email@example.com
|
|
483
|
+
|
|
484
|
+
## 🙏 致谢
|
|
485
|
+
|
|
486
|
+
感谢所有为这个项目做出贡献的开发者!
|
|
487
|
+
|
|
488
|
+
---
|
|
489
|
+
|
|
490
|
+
如果这个项目对你有帮助,欢迎给个 ⭐️ Star!
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* 视图类型枚举
|
|
4
|
+
* 1 - 瀑布流(不等宽不等高)
|
|
5
|
+
* 2 - 等高不等宽
|
|
6
|
+
*/
|
|
7
|
+
export declare enum ViewType {
|
|
8
|
+
WATERFALL = 1,
|
|
9
|
+
EQUAL_HEIGHT = 2
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 数据加载函数
|
|
13
|
+
* 第一次调用时(page === 1)会返回布局类型
|
|
14
|
+
* 后续调用不返回布局类型
|
|
15
|
+
*/
|
|
16
|
+
export type LoadDataFn<T = any> = (page: number, pageSize: number) => Promise<{
|
|
17
|
+
data: T[];
|
|
18
|
+
hasMore: boolean;
|
|
19
|
+
isMasonry?: boolean;
|
|
20
|
+
}>;
|
|
21
|
+
/**
|
|
22
|
+
* 组件 Props
|
|
23
|
+
*/
|
|
24
|
+
export interface DynamicMasonryViewProps<T = any> {
|
|
25
|
+
/**
|
|
26
|
+
* 是否使用瀑布流布局(受控模式)
|
|
27
|
+
*/
|
|
28
|
+
isMasonry?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* 默认是否使用瀑布流布局(非受控模式)
|
|
31
|
+
*/
|
|
32
|
+
defaultIsMasonry?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* 是否启用动画
|
|
35
|
+
*/
|
|
36
|
+
enableAnimation?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* 映射宽高
|
|
39
|
+
*/
|
|
40
|
+
mapSize?: (raw: any) => {
|
|
41
|
+
width: number;
|
|
42
|
+
height: number;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* 瀑布流配置
|
|
46
|
+
*/
|
|
47
|
+
waterfallConfig?: {
|
|
48
|
+
minColumnWidth?: number;
|
|
49
|
+
maxColumnWidth?: number;
|
|
50
|
+
gap?: number;
|
|
51
|
+
buffer?: number;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* 等高不等宽配置
|
|
55
|
+
*/
|
|
56
|
+
equalHeightConfig?: {
|
|
57
|
+
targetRowHeight?: number;
|
|
58
|
+
sizeRange?: [number, number];
|
|
59
|
+
maxItemWidth?: number;
|
|
60
|
+
maxStretchRatio?: number;
|
|
61
|
+
gap?: number;
|
|
62
|
+
buffer?: number;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* 自定义初始加载状态
|
|
66
|
+
*/
|
|
67
|
+
renderInitialLoader?: () => React.ReactNode;
|
|
68
|
+
/**
|
|
69
|
+
* 自定义数据加载函数
|
|
70
|
+
*/
|
|
71
|
+
loadData?: LoadDataFn<T>;
|
|
72
|
+
/**
|
|
73
|
+
* 每页数据条数
|
|
74
|
+
*/
|
|
75
|
+
pageSize?: number;
|
|
76
|
+
/**
|
|
77
|
+
* 自定义渲染项
|
|
78
|
+
*/
|
|
79
|
+
renderItem: (item: any, index: number, isMasonry: boolean) => React.ReactNode;
|
|
80
|
+
/**
|
|
81
|
+
* 布局类型加载完成回调
|
|
82
|
+
*/
|
|
83
|
+
onLayoutTypeLoaded?: (isMasonry: boolean) => void;
|
|
84
|
+
/**
|
|
85
|
+
* 数据加载错误回调
|
|
86
|
+
*/
|
|
87
|
+
onError?: (error: Error) => void;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 动态瀑布流视图组件
|
|
91
|
+
*
|
|
92
|
+
* 支持两种视图模式:
|
|
93
|
+
* 1. 瀑布流(不等宽不等高) - Pinterest 风格
|
|
94
|
+
* 2. 等高不等宽 - Google Photos 风格
|
|
95
|
+
*/
|
|
96
|
+
export default function DynamicMasonryView<T = any>({ isMasonry: controlledIsMasonry, defaultIsMasonry, enableAnimation, waterfallConfig, equalHeightConfig, loadData, pageSize, renderItem, mapSize, renderInitialLoader, onLayoutTypeLoaded, onError, }: DynamicMasonryViewProps<T>): React.JSX.Element;
|
|
97
|
+
//# sourceMappingURL=DynamicMasonryView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DynamicMasonryView.d.ts","sourceRoot":"","sources":["../src/DynamicMasonryView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAMhE;;;;GAIG;AACH,oBAAY,QAAQ;IAClB,SAAS,IAAI;IACb,YAAY,IAAI;CACjB;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,GAAG,GAAG,IAAI,CAChC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC;IACX,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,WAAW,uBAAuB,CAAC,CAAC,GAAG,GAAG;IAC9C;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAE1D;;OAEG;IACH,eAAe,CAAC,EAAE;QAChB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IAEF;;OAEG;IACH,iBAAiB,CAAC,EAAE;QAClB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IAEF;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;IAE5C;;OAEG;IACH,QAAQ,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,KAAK,KAAK,CAAC,SAAS,CAAC;IAE9E;;OAEG;IACH,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IAElD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAID;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,CAAC,GAAG,GAAG,EAAE,EAClD,SAAS,EAAE,mBAAmB,EAC9B,gBAAuB,EACvB,eAAsB,EACtB,eAAoB,EACpB,iBAAsB,EACtB,QAAQ,EACR,QAAa,EACb,UAAU,EACV,OAAO,EACP,mBAAmB,EACnB,kBAAkB,EAClB,OAAO,GACR,EAAE,uBAAuB,CAAC,CAAC,CAAC,qBAgK5B"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
type FullWidthEqualHeightMasonryCoreProps = {
|
|
3
|
+
items: any[];
|
|
4
|
+
renderItem: (item: {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
[key: string]: any;
|
|
10
|
+
}, index: number) => React.ReactNode;
|
|
11
|
+
onLoadMore?: () => void;
|
|
12
|
+
targetRowHeight?: number;
|
|
13
|
+
gap?: number;
|
|
14
|
+
buffer?: number;
|
|
15
|
+
hasMore?: boolean;
|
|
16
|
+
loading?: boolean;
|
|
17
|
+
sizeRange?: [number, number];
|
|
18
|
+
maxItemWidth?: number;
|
|
19
|
+
maxStretchRatio?: number;
|
|
20
|
+
loadMoreThreshold?: number;
|
|
21
|
+
};
|
|
22
|
+
export declare function FullWidthEqualHeightMasonryCore({ items, renderItem, onLoadMore, targetRowHeight, gap, buffer, hasMore, loading, sizeRange, maxItemWidth, maxStretchRatio, loadMoreThreshold, }: FullWidthEqualHeightMasonryCoreProps): React.JSX.Element;
|
|
23
|
+
type FullWidthEqualHeightMasonryProps = {
|
|
24
|
+
mapSize?: (raw: any) => {
|
|
25
|
+
width: number;
|
|
26
|
+
height: number;
|
|
27
|
+
};
|
|
28
|
+
renderItem: (item: {
|
|
29
|
+
x: number;
|
|
30
|
+
y: number;
|
|
31
|
+
width: number;
|
|
32
|
+
height: number;
|
|
33
|
+
[key: string]: any;
|
|
34
|
+
}, index: number) => React.ReactNode;
|
|
35
|
+
enableAnimation?: boolean;
|
|
36
|
+
loadData?: (page: number, pageSize: number) => Promise<{
|
|
37
|
+
data: any[];
|
|
38
|
+
hasMore: boolean;
|
|
39
|
+
}>;
|
|
40
|
+
pageSize?: number;
|
|
41
|
+
targetRowHeight?: number;
|
|
42
|
+
sizeRange?: [number, number];
|
|
43
|
+
maxItemWidth?: number;
|
|
44
|
+
maxStretchRatio?: number;
|
|
45
|
+
gap?: number;
|
|
46
|
+
buffer?: number;
|
|
47
|
+
loadMoreThreshold?: number;
|
|
48
|
+
};
|
|
49
|
+
export default function FullWidthEqualHeightMasonry({ mapSize, renderItem, enableAnimation: _enableAnimation, loadData, pageSize, targetRowHeight, sizeRange, maxItemWidth, maxStretchRatio, gap, buffer, loadMoreThreshold, }: FullWidthEqualHeightMasonryProps): React.JSX.Element;
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=FullWidthEqualHeightMasonry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FullWidthEqualHeightMasonry.d.ts","sourceRoot":"","sources":["../src/FullWidthEqualHeightMasonry.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,KAAK,oCAAoC,GAAG;IAC1C,KAAK,EAAE,GAAG,EAAE,CAAC;IACb,UAAU,EAAE,CACV,IAAI,EAAE;QACJ,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,EACD,KAAK,EAAE,MAAM,KACV,KAAK,CAAC,SAAS,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AA8QF,wBAAgB,+BAA+B,CAAC,EAC9C,KAAK,EACL,UAAU,EACV,UAAU,EACV,eAAqB,EACrB,GAAS,EACT,MAAa,EACb,OAAc,EACd,OAAe,EACf,SAAsB,EACtB,YAAkB,EAClB,eAAqB,EACrB,iBAAuB,GACxB,EAAE,oCAAoC,qBAyGtC;AAGD,KAAK,gCAAgC,GAAG;IACtC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,UAAU,EAAE,CACV,IAAI,EAAE;QACJ,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,EACD,KAAK,EAAE,MAAM,KACV,KAAK,CAAC,SAAS,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,CACT,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC;QACX,IAAI,EAAE,GAAG,EAAE,CAAC;QACZ,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC,CAAC;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,2BAA2B,CAAC,EAClD,OAAO,EACP,UAAU,EACV,eAAe,EAAE,gBAAuB,EACxC,QAAQ,EACR,QAAa,EACb,eAAqB,EACrB,SAAsB,EACtB,YAAkB,EAClB,eAAqB,EACrB,GAAS,EACT,MAAa,EACb,iBAAuB,GACxB,EAAE,gCAAgC,qBAsFlC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
type VirtualMasonryCoreProps = {
|
|
3
|
+
items: any[];
|
|
4
|
+
renderItem: (item: any, index: number) => React.ReactNode;
|
|
5
|
+
onLoadMore?: () => void;
|
|
6
|
+
minColumnWidth?: number;
|
|
7
|
+
maxColumnWidth?: number;
|
|
8
|
+
gap?: number;
|
|
9
|
+
buffer?: number;
|
|
10
|
+
hasMore?: boolean;
|
|
11
|
+
loading?: boolean;
|
|
12
|
+
loadMoreThreshold?: number;
|
|
13
|
+
};
|
|
14
|
+
export declare function VirtualMasonryCore({ items, renderItem, onLoadMore, minColumnWidth, maxColumnWidth, gap, buffer, hasMore, loading, loadMoreThreshold, }: VirtualMasonryCoreProps): React.JSX.Element;
|
|
15
|
+
export type VirtualMasonryProps = {
|
|
16
|
+
mapSize?: (raw: any) => {
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
};
|
|
20
|
+
renderItem: (item: any, index: number) => React.ReactNode;
|
|
21
|
+
enableAnimation?: boolean;
|
|
22
|
+
loadData?: (page: number, pageSize: number) => Promise<{
|
|
23
|
+
data: any[];
|
|
24
|
+
hasMore: boolean;
|
|
25
|
+
}>;
|
|
26
|
+
pageSize?: number;
|
|
27
|
+
minColumnWidth?: number;
|
|
28
|
+
maxColumnWidth?: number;
|
|
29
|
+
gap?: number;
|
|
30
|
+
buffer?: number;
|
|
31
|
+
loadMoreThreshold?: number;
|
|
32
|
+
};
|
|
33
|
+
export default function VirtualMasonry({ mapSize, renderItem, loadData, pageSize, minColumnWidth, maxColumnWidth, gap, buffer, loadMoreThreshold, }: VirtualMasonryProps): React.JSX.Element;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=VirtualMasonry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VirtualMasonry.d.ts","sourceRoot":"","sources":["../src/VirtualMasonry.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,KAAK,uBAAuB,GAAG;IAC7B,KAAK,EAAE,GAAG,EAAE,CAAC;IACb,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IAC1D,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAuGF,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,UAAU,EACV,UAAU,EACV,cAAoB,EACpB,cAAc,EACd,GAAQ,EACR,MAAY,EACZ,OAAc,EACd,OAAe,EACf,iBAAuB,GACxB,EAAE,uBAAuB,qBAgGzB;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IAC1D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,CACT,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC;QACX,IAAI,EAAE,GAAG,EAAE,CAAC;QACZ,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC,CAAC;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EACrC,OAAO,EACP,UAAU,EACV,QAAQ,EACR,QAAa,EACb,cAAoB,EACpB,cAAc,EACd,GAAQ,EACR,MAAa,EACb,iBAAuB,GACxB,EAAE,mBAAmB,qBAoFrB"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { default as VirtualMasonry, VirtualMasonryCore } from "./VirtualMasonry";
|
|
2
|
+
export type { VirtualMasonryProps } from "./VirtualMasonry";
|
|
3
|
+
export { default as FullWidthEqualHeightMasonry, FullWidthEqualHeightMasonryCore, } from "./FullWidthEqualHeightMasonry";
|
|
4
|
+
export { default as DynamicMasonryView, ViewType } from "./DynamicMasonryView";
|
|
5
|
+
export type { DynamicMasonryViewProps, LoadDataFn, } from "./DynamicMasonryView";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACjF,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,OAAO,EACL,OAAO,IAAI,2BAA2B,EACtC,+BAA+B,GAChC,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC/E,YAAY,EACV,uBAAuB,EACvB,UAAU,GACX,MAAM,sBAAsB,CAAC"}
|