smart-masonry-grid 0.2.0 → 0.2.1
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 +143 -36
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,19 +1,59 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<h1 align="center">smart-masonry-grid</h1>
|
|
3
|
+
<p align="center">
|
|
4
|
+
A zero-dependency, virtualized masonry grid layout library for vanilla JS and React.
|
|
5
|
+
</p>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
<p align="center">
|
|
9
|
+
<a href="https://www.npmjs.com/package/smart-masonry-grid"><img src="https://img.shields.io/npm/v/smart-masonry-grid?color=blue&label=npm" alt="npm version" /></a>
|
|
10
|
+
<a href="https://bundlephobia.com/package/smart-masonry-grid"><img src="https://img.shields.io/bundlephobia/minzip/smart-masonry-grid?color=green&label=size" alt="bundle size" /></a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/smart-masonry-grid"><img src="https://img.shields.io/npm/dm/smart-masonry-grid?color=orange" alt="downloads" /></a>
|
|
12
|
+
<a href="https://github.com/LittleBoy9/smart-masonry-grid/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/smart-masonry-grid" alt="license" /></a>
|
|
13
|
+
<a href="https://github.com/LittleBoy9/smart-masonry-grid"><img src="https://img.shields.io/github/stars/LittleBoy9/smart-masonry-grid?style=social" alt="GitHub stars" /></a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
<p align="center">
|
|
17
|
+
<a href="https://littleboy9.github.io/smart-masonry-grid/"><b>Landing Page</b></a> ·
|
|
18
|
+
<a href="https://smart-masonry-grid-demo-1dkf4r5bx-iamsounak01s-projects.vercel.app/"><b>Live Demo</b></a> ·
|
|
19
|
+
<a href="https://github.com/LittleBoy9/smart-masonry-grid"><b>GitHub</b></a>
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Highlights
|
|
8
25
|
|
|
9
26
|
- **Zero dependencies** — uses native `ResizeObserver` and `IntersectionObserver`
|
|
10
|
-
- **Virtualization** — renders only visible items, handles 10,000+ items smoothly
|
|
11
|
-
- **Responsive** — auto columns, fixed count, or
|
|
12
|
-
- **SSR-compatible** — CSS columns fallback with hydration support
|
|
27
|
+
- **Virtualization** — renders only visible items, handles **10,000+ items** smoothly
|
|
28
|
+
- **Responsive** — auto columns, fixed count, named breakpoints, or custom pixel breakpoints
|
|
29
|
+
- **SSR-compatible** — CSS columns fallback with hydration support for Next.js
|
|
13
30
|
- **TypeScript-first** — full type definitions included
|
|
14
|
-
- **Dual API** — vanilla `MasonryGrid` class + React components
|
|
31
|
+
- **Dual API** — vanilla `MasonryGrid` class + React components (`<Masonry>`, `<VirtualMasonry>`, `useMasonryGrid`)
|
|
32
|
+
- **Animations** — built-in entry animations with configurable duration, easing, and offset
|
|
33
|
+
- **Infinite scroll** — built-in `onReachEnd` callback
|
|
34
|
+
- **Tree-shakeable** — ESM + CommonJS, `sideEffects: false`
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Why smart-masonry-grid?
|
|
39
|
+
|
|
40
|
+
Most masonry libraries are **abandoned**, **React-only**, or **missing critical features**. Here's how `smart-masonry-grid` compares:
|
|
41
|
+
|
|
42
|
+
| Feature | smart-masonry-grid | masonry-layout | react-masonry-css | masonic | @mui/lab Masonry |
|
|
43
|
+
|---|:---:|:---:|:---:|:---:|:---:|
|
|
44
|
+
| Zero dependencies | **Yes** | No | Yes | No | No (heavy) |
|
|
45
|
+
| Virtualization (10K+ items) | **Yes** | No | No | Yes | No |
|
|
46
|
+
| SSR / Next.js support | **Yes** | No | No | Partial | Buggy |
|
|
47
|
+
| Vanilla JS + React | **Yes** | Vanilla only | React only | React only | React only |
|
|
48
|
+
| Built-in animations | **Yes** | No | No | No | No |
|
|
49
|
+
| Built-in infinite scroll | **Yes** | No | No | Yes | No |
|
|
50
|
+
| TypeScript (built-in) | **Yes** | No (@types) | Partial | Yes | Yes |
|
|
51
|
+
| Responsive breakpoints | **4 modes** | No | Basic | No | Basic |
|
|
52
|
+
| Actively maintained | **Yes** | Barely | No (4yr+) | Partial | Yes |
|
|
53
|
+
|
|
54
|
+
> **No other library** combines zero-dependency virtualization, SSR support, and multi-framework support in one package.
|
|
15
55
|
|
|
16
|
-
|
|
56
|
+
---
|
|
17
57
|
|
|
18
58
|
## Install
|
|
19
59
|
|
|
@@ -21,9 +61,20 @@ A zero-dependency, virtualized masonry grid layout library for vanilla JS and Re
|
|
|
21
61
|
npm install smart-masonry-grid
|
|
22
62
|
```
|
|
23
63
|
|
|
24
|
-
|
|
64
|
+
```bash
|
|
65
|
+
# or
|
|
66
|
+
yarn add smart-masonry-grid
|
|
67
|
+
# or
|
|
68
|
+
pnpm add smart-masonry-grid
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
25
72
|
|
|
26
|
-
|
|
73
|
+
## Quick Start
|
|
74
|
+
|
|
75
|
+
### React
|
|
76
|
+
|
|
77
|
+
#### `<Masonry>` — renders all children
|
|
27
78
|
|
|
28
79
|
```tsx
|
|
29
80
|
import { Masonry } from 'smart-masonry-grid/react';
|
|
@@ -39,7 +90,7 @@ function Gallery({ photos }) {
|
|
|
39
90
|
}
|
|
40
91
|
```
|
|
41
92
|
|
|
42
|
-
|
|
93
|
+
#### `<VirtualMasonry>` — for large datasets (1,000+ items)
|
|
43
94
|
|
|
44
95
|
```tsx
|
|
45
96
|
import { VirtualMasonry } from 'smart-masonry-grid/react';
|
|
@@ -60,7 +111,7 @@ function Gallery({ photos }) {
|
|
|
60
111
|
}
|
|
61
112
|
```
|
|
62
113
|
|
|
63
|
-
|
|
114
|
+
#### `useMasonryGrid` hook — full control
|
|
64
115
|
|
|
65
116
|
```tsx
|
|
66
117
|
import { useMasonryGrid } from 'smart-masonry-grid/react';
|
|
@@ -83,7 +134,7 @@ function CustomGrid({ items }) {
|
|
|
83
134
|
}
|
|
84
135
|
```
|
|
85
136
|
|
|
86
|
-
|
|
137
|
+
### Vanilla JS
|
|
87
138
|
|
|
88
139
|
```js
|
|
89
140
|
import { MasonryGrid } from 'smart-masonry-grid';
|
|
@@ -107,7 +158,7 @@ grid.on('resize', (width, cols) => console.log(width, cols));
|
|
|
107
158
|
grid.destroy();
|
|
108
159
|
```
|
|
109
160
|
|
|
110
|
-
|
|
161
|
+
#### Virtualized (vanilla)
|
|
111
162
|
|
|
112
163
|
```js
|
|
113
164
|
const grid = new MasonryGrid(container, {
|
|
@@ -120,48 +171,87 @@ const grid = new MasonryGrid(container, {
|
|
|
120
171
|
});
|
|
121
172
|
```
|
|
122
173
|
|
|
123
|
-
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Column Strategies
|
|
177
|
+
|
|
178
|
+
4 flexible ways to configure columns:
|
|
124
179
|
|
|
125
180
|
```tsx
|
|
126
|
-
// Fixed column count
|
|
181
|
+
// 1. Fixed column count
|
|
127
182
|
<Masonry columns={4} />
|
|
128
183
|
|
|
129
|
-
// Auto
|
|
184
|
+
// 2. Auto — fill based on minimum column width
|
|
130
185
|
<Masonry columns={{ type: 'auto', minColumnWidth: 250 }} />
|
|
131
186
|
|
|
132
|
-
// Named breakpoints (sm=640, md=768, lg=1024, xl=1280)
|
|
187
|
+
// 3. Named breakpoints (sm=640, md=768, lg=1024, xl=1280)
|
|
133
188
|
<Masonry columns={{ sm: 2, md: 3, lg: 4, xl: 5 }} />
|
|
134
189
|
|
|
135
|
-
// Custom pixel breakpoints
|
|
190
|
+
// 4. Custom pixel breakpoints
|
|
136
191
|
<Masonry columns={{ 480: 2, 768: 3, 1200: 4 }} />
|
|
137
192
|
```
|
|
138
193
|
|
|
139
|
-
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## API Reference
|
|
140
197
|
|
|
141
|
-
### `<Masonry>`
|
|
198
|
+
### `<Masonry>` Props
|
|
142
199
|
|
|
143
200
|
| Prop | Type | Default | Description |
|
|
144
|
-
|
|
201
|
+
|---|---|---|---|
|
|
145
202
|
| `children` | `ReactNode` | — | Items to lay out |
|
|
146
203
|
| `columns` | `number \| ColumnStrategy \| NamedBreakpoints` | `auto, 250px` | Column configuration |
|
|
147
|
-
| `gap` | `number` | `16` | Gap between items
|
|
204
|
+
| `gap` | `number` | `16` | Gap between items in pixels |
|
|
148
205
|
| `animate` | `boolean \| AnimationConfig` | `false` | Entry animations |
|
|
149
|
-
| `onLayout` | `(output: LayoutOutput) => void` | — |
|
|
150
|
-
| `onReachEnd` | `() => void` | — |
|
|
206
|
+
| `onLayout` | `(output: LayoutOutput) => void` | — | Called after each layout computation |
|
|
207
|
+
| `onReachEnd` | `() => void` | — | Called when scrolled near the bottom (infinite scroll) |
|
|
151
208
|
| `reachEndThreshold` | `number` | `200` | Pixels from bottom to trigger `onReachEnd` |
|
|
152
209
|
|
|
153
|
-
### `<VirtualMasonry>`
|
|
210
|
+
### `<VirtualMasonry>` Props
|
|
154
211
|
|
|
155
212
|
All `<Masonry>` props except `children`, plus:
|
|
156
213
|
|
|
157
214
|
| Prop | Type | Default | Description |
|
|
158
|
-
|
|
159
|
-
| `totalItems` | `number` | — | Total
|
|
160
|
-
| `renderItem` | `(index: number) => ReactElement` | — | Render function
|
|
161
|
-
| `height` | `number` | — | Scroll container height
|
|
162
|
-
| `overscan` | `number` | `600` | Pre-render buffer
|
|
215
|
+
|---|---|---|---|
|
|
216
|
+
| `totalItems` | `number` | — | Total number of items |
|
|
217
|
+
| `renderItem` | `(index: number) => ReactElement` | — | Render function for each item |
|
|
218
|
+
| `height` | `number` | — | Scroll container height in pixels |
|
|
219
|
+
| `overscan` | `number` | `600` | Pre-render buffer in pixels |
|
|
163
220
|
| `estimatedItemHeight` | `number` | `300` | Height estimate for unmeasured items |
|
|
164
|
-
| `placeholder` | `ReactElement` | — | Shown while item is
|
|
221
|
+
| `placeholder` | `ReactElement` | — | Shown while an item is being measured |
|
|
222
|
+
|
|
223
|
+
### `MasonryGrid` (Vanilla JS)
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
const grid = new MasonryGrid(container: HTMLElement, options?: MasonryGridOptions);
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
| Option | Type | Default | Description |
|
|
230
|
+
|---|---|---|---|
|
|
231
|
+
| `columns` | `number \| ColumnStrategy` | `auto, 250px` | Column configuration |
|
|
232
|
+
| `gap` | `number` | `16` | Gap between items in pixels |
|
|
233
|
+
| `virtualize` | `boolean` | `true` | Enable virtualization |
|
|
234
|
+
| `totalItems` | `number` | — | Total items (virtualized mode) |
|
|
235
|
+
| `renderItem` | `(index: number) => HTMLElement` | — | Item renderer (virtualized mode) |
|
|
236
|
+
| `ssrFallback` | `boolean` | `false` | Use CSS columns for SSR |
|
|
237
|
+
| `resizeDebounceMs` | `number` | `100` | Debounce delay for resize events |
|
|
238
|
+
|
|
239
|
+
**Methods:**
|
|
240
|
+
|
|
241
|
+
| Method | Description |
|
|
242
|
+
|---|---|
|
|
243
|
+
| `append(elements)` | Add elements to the end |
|
|
244
|
+
| `prepend(elements)` | Add elements to the beginning |
|
|
245
|
+
| `remove(id)` | Remove an item by ID |
|
|
246
|
+
| `refresh()` | Force a full relayout |
|
|
247
|
+
| `getLayout()` | Returns current `LayoutOutput` |
|
|
248
|
+
| `getColumnCount()` | Returns current column count |
|
|
249
|
+
| `on(event, callback)` | Subscribe to events |
|
|
250
|
+
| `destroy()` | Clean up observers and DOM |
|
|
251
|
+
|
|
252
|
+
**Events:** `layout`, `resize`, `scroll`, `itemResize`, `destroy`
|
|
253
|
+
|
|
254
|
+
---
|
|
165
255
|
|
|
166
256
|
## SSR
|
|
167
257
|
|
|
@@ -172,6 +262,23 @@ import { getSSRStyles } from 'smart-masonry-grid';
|
|
|
172
262
|
const css = getSSRStyles();
|
|
173
263
|
```
|
|
174
264
|
|
|
265
|
+
The library provides a CSS columns fallback for the initial server render, then smoothly transitions to the JS-powered masonry layout after hydration.
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Browser Support
|
|
270
|
+
|
|
271
|
+
Uses native browser APIs with excellent coverage:
|
|
272
|
+
|
|
273
|
+
| API | Support |
|
|
274
|
+
|---|---|
|
|
275
|
+
| `ResizeObserver` | 99%+ |
|
|
276
|
+
| `IntersectionObserver` | 98%+ |
|
|
277
|
+
|
|
278
|
+
No polyfills needed for modern browsers.
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
175
282
|
## License
|
|
176
283
|
|
|
177
284
|
[MIT](LICENSE) — Built by [Sounak Das](https://sounakdas.in)
|