masonry-snap-grid-layout 1.0.7 → 1.0.10
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 +116 -80
- package/dist/esm/react.js +9 -10
- package/dist/esm/react.js.map +1 -1
- package/dist/react.d.cts +5 -2
- package/dist/react.d.ts +5 -2
- package/dist/react.js +8 -8
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
|
+
|
|
1
2
|
# masonry-snap-grid-layout
|
|
2
3
|
|
|
3
4
|
[](https://www.npmjs.com/package/masonry-snap-grid-layout)
|
|
4
5
|
[](https://github.com/khachatryan-dev/masonry-snap-grid-layout/actions)
|
|
6
|
+
[](https://codesandbox.io/p/sandbox/l9xl7s)
|
|
7
|
+
[](https://codesandbox.io/p/sandbox/rgxsxp)
|
|
5
8
|
|
|
6
9
|
A performant masonry grid layout library with smooth animations, customizable gutter, columns, and dynamic item content.
|
|
7
10
|
|
|
11
|
+

|
|
12
|
+
|
|
8
13
|
---
|
|
9
14
|
|
|
10
15
|
## 🚀 Features
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
- **Dynamic Columns & Gutter**: Automatically adapts to container width
|
|
18
|
+
- **Smooth Animations**: CSS-powered transitions when layout changes
|
|
19
|
+
- **Customizable Items**: Render any content with gradient backgrounds and emojis
|
|
20
|
+
- **Lightweight**: Zero dependencies, pure TypeScript
|
|
21
|
+
- **React & Vanilla JS**: Works with both React and plain JavaScript
|
|
22
|
+
- **Responsive**: Perfect for galleries, dashboards, and card layouts
|
|
17
23
|
|
|
18
24
|
---
|
|
19
25
|
|
|
@@ -23,138 +29,168 @@ A performant masonry grid layout library with smooth animations, customizable gu
|
|
|
23
29
|
npm install masonry-snap-grid-layout
|
|
24
30
|
# or
|
|
25
31
|
yarn add masonry-snap-grid-layout
|
|
26
|
-
|
|
32
|
+
# or
|
|
33
|
+
pnpm add masonry-snap-grid-layout
|
|
34
|
+
```
|
|
27
35
|
|
|
28
36
|
---
|
|
29
37
|
|
|
30
|
-
## 💡 Usage
|
|
38
|
+
## 💡 Usage Examples
|
|
39
|
+
|
|
40
|
+
### Vanilla JavaScript (Live Demo)
|
|
31
41
|
|
|
32
|
-
```
|
|
42
|
+
```javascript
|
|
33
43
|
import MasonrySnapGridLayout from 'masonry-snap-grid-layout';
|
|
34
|
-
import 'masonry-snap-grid-layout/dist/index.css';
|
|
44
|
+
import 'masonry-snap-grid-layout/dist/index.css';
|
|
45
|
+
|
|
46
|
+
const container = document.getElementById('masonry-container');
|
|
47
|
+
const items = [
|
|
48
|
+
{ id: 1, title: "Sunset", emoji: "🌅", color: "#FF9A9E" },
|
|
49
|
+
{ id: 2, title: "Ocean", emoji: "🌊", color: "#A1C4FD" },
|
|
50
|
+
// ... more items
|
|
51
|
+
];
|
|
35
52
|
|
|
36
|
-
const container = document.getElementById('masonry-container')!;
|
|
37
53
|
const masonry = new MasonrySnapGridLayout(container, {
|
|
38
|
-
gutter:
|
|
54
|
+
gutter: 16,
|
|
39
55
|
minColWidth: 200,
|
|
40
|
-
initialItems: 20,
|
|
41
56
|
animate: true,
|
|
42
|
-
transitionDuration:
|
|
43
|
-
|
|
57
|
+
transitionDuration: 300,
|
|
58
|
+
items: items,
|
|
59
|
+
renderItem: (item) => {
|
|
44
60
|
const div = document.createElement('div');
|
|
45
|
-
div.
|
|
61
|
+
div.style.height = `${120 + Math.random() * 200}px`;
|
|
62
|
+
div.style.background = `linear-gradient(135deg, ${item.color} 0%, #FFFFFF 100%)`;
|
|
63
|
+
div.style.borderRadius = '12px';
|
|
64
|
+
div.style.padding = '16px';
|
|
65
|
+
div.style.color = '#333';
|
|
66
|
+
div.innerHTML = `
|
|
67
|
+
<div style="font-size: 2rem">${item.emoji}</div>
|
|
68
|
+
<h3 style="margin: 8px 0">${item.title}</h3>
|
|
69
|
+
`;
|
|
46
70
|
return div;
|
|
47
|
-
}
|
|
71
|
+
}
|
|
48
72
|
});
|
|
49
73
|
```
|
|
50
74
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
```html
|
|
54
|
-
<div id="masonry-container" style="position: relative; width: 100%;"></div>
|
|
55
|
-
```
|
|
75
|
+
[](https://codesandbox.io/p/sandbox/l9xl7s)
|
|
56
76
|
|
|
57
77
|
---
|
|
58
78
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
```tsx
|
|
62
|
-
'use client';
|
|
79
|
+
### React (Live Demo)
|
|
63
80
|
|
|
64
|
-
|
|
81
|
+
```jsx
|
|
65
82
|
import MasonrySnapGrid from 'masonry-snap-grid-layout/react';
|
|
66
|
-
import 'masonry-snap-grid-layout/dist/index.css';
|
|
83
|
+
import 'masonry-snap-grid-layout/dist/index.css';
|
|
67
84
|
|
|
68
|
-
|
|
69
|
-
|
|
85
|
+
const items = Array.from({ length: 20 }, (_, i) => ({
|
|
86
|
+
id: i,
|
|
87
|
+
title: `Item ${i + 1}`,
|
|
88
|
+
emoji: ['🌻', '🌈', '🍕', '🎸', '🚀'][Math.floor(Math.random() * 5)],
|
|
89
|
+
height: 120 + Math.random() * 200
|
|
90
|
+
}));
|
|
70
91
|
|
|
92
|
+
export default function Gallery() {
|
|
71
93
|
return (
|
|
72
94
|
<MasonrySnapGrid
|
|
73
95
|
items={items}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
96
|
+
gutter={16}
|
|
97
|
+
minColWidth={220}
|
|
98
|
+
animate
|
|
99
|
+
transitionDuration={400}
|
|
100
|
+
renderItem={(item) => (
|
|
101
|
+
<div style={{
|
|
102
|
+
height: `${item.height}px`,
|
|
103
|
+
background: `linear-gradient(135deg,
|
|
104
|
+
hsl(${Math.random() * 360}, 70%, 70%) 0%,
|
|
105
|
+
hsl(${Math.random() * 360}, 70%, 80%) 100%)`,
|
|
106
|
+
borderRadius: '12px',
|
|
107
|
+
padding: '16px',
|
|
108
|
+
color: 'white'
|
|
109
|
+
}}>
|
|
110
|
+
<div style={{ fontSize: '2rem' }}>{item.emoji}</div>
|
|
111
|
+
<h3 style={{ margin: '8px 0' }}>{item.title}</h3>
|
|
112
|
+
<small>Height: {Math.round(item.height)}px</small>
|
|
83
113
|
</div>
|
|
84
114
|
)}
|
|
85
|
-
className="my-masonry-container"
|
|
86
|
-
style={{ position: 'relative', width: '100%' }}
|
|
87
115
|
/>
|
|
88
116
|
);
|
|
89
117
|
}
|
|
90
118
|
```
|
|
91
119
|
|
|
92
|
-
|
|
120
|
+
[](https://codesandbox.io/p/sandbox/rgxsxp)
|
|
93
121
|
|
|
94
|
-
|
|
122
|
+
---
|
|
95
123
|
|
|
96
|
-
|
|
124
|
+
## 🛠️ API Reference
|
|
97
125
|
|
|
98
|
-
|
|
99
|
-
new MasonrySnapGridLayout(container: HTMLElement, options?: MasonrySnapGridLayoutOptions)
|
|
100
|
-
```
|
|
126
|
+
### Configuration Options
|
|
101
127
|
|
|
102
|
-
|
|
103
|
-
|
|
128
|
+
| Option | Type | Default | Description |
|
|
129
|
+
|----------------------|---------------------------|---------|--------------------------------------|
|
|
130
|
+
| `gutter` | `number` | `16` | Spacing between items (px) |
|
|
131
|
+
| `minColWidth` | `number` | `250` | Minimum column width (px) |
|
|
132
|
+
| `animate` | `boolean` | `true` | Enable/disable animations |
|
|
133
|
+
| `transitionDuration` | `number` | `400` | Animation duration (ms) |
|
|
134
|
+
| `items` | `Array<T>` | `[]` | Your data items |
|
|
135
|
+
| `renderItem` | `(item: T) => HTMLElement`| - | Function to render each item |
|
|
136
|
+
| `classNames` | `Object` | - | Custom CSS class names |
|
|
104
137
|
|
|
105
138
|
### Methods
|
|
106
139
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
140
|
+
- `updateItems(newItems: T[])`: Refresh with new items
|
|
141
|
+
- `shuffleItems()`: Randomize item positions
|
|
142
|
+
- `destroy()`: Clean up the instance
|
|
110
143
|
|
|
111
144
|
---
|
|
112
145
|
|
|
113
|
-
##
|
|
146
|
+
## 🎨 Customization Tips
|
|
114
147
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
| `gutter` | `number` | `16` | Spacing between items in pixels. |
|
|
118
|
-
| `minColWidth` | `number` | `250` | Minimum column width in pixels. |
|
|
119
|
-
| `animate` | `boolean` | `true` | Enable/disable animations. |
|
|
120
|
-
| `transitionDuration` | `number` | `400` | Animation duration in milliseconds. |
|
|
121
|
-
| `initialItems` | `number` | `30` | Number of items generated initially. |
|
|
122
|
-
| `classNames` | `Partial<MasonrySnapGridLayoutClassNames>` | Default CSS classes | Override CSS class names for styling. |
|
|
123
|
-
| `itemContent` | `string` \| `HTMLElement` \| `(index: number) => HTMLElement \| string` | `null` | Content or content generator callback for items. |
|
|
148
|
+
**1. Gradient Backgrounds**
|
|
149
|
+
Use CSS gradients for beautiful card backgrounds:
|
|
124
150
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
151
|
+
```css
|
|
152
|
+
background: linear-gradient(135deg, #ff9a9e 0%, #fad0c4 100%);
|
|
153
|
+
```
|
|
128
154
|
|
|
129
|
-
|
|
155
|
+
**2. Random Emojis**
|
|
156
|
+
Add personality with emojis:
|
|
130
157
|
|
|
131
|
-
|
|
158
|
+
```javascript
|
|
159
|
+
const emojis = ['🌻', '🌈', '🍕', '🎸', '🚀'];
|
|
160
|
+
const randomEmoji = emojis[Math.floor(Math.random() * emojis.length)];
|
|
161
|
+
```
|
|
132
162
|
|
|
133
|
-
|
|
163
|
+
**3. Responsive Breakpoints**
|
|
164
|
+
Adjust columns based on screen size:
|
|
134
165
|
|
|
135
|
-
|
|
166
|
+
```javascript
|
|
167
|
+
minColWidth: window.innerWidth < 768 ? 150 : 250
|
|
168
|
+
```
|
|
136
169
|
|
|
137
|
-
|
|
170
|
+
---
|
|
138
171
|
|
|
139
|
-
|
|
172
|
+
## 📦 Package Structure
|
|
140
173
|
|
|
141
|
-
```bash
|
|
142
|
-
npm version patch
|
|
143
|
-
git push origin main --tags
|
|
144
174
|
```
|
|
145
|
-
|
|
146
|
-
|
|
175
|
+
dist/
|
|
176
|
+
├── index.js # Vanilla JS bundle
|
|
177
|
+
├── react.js # React component
|
|
178
|
+
├── index.d.ts # TypeScript types
|
|
179
|
+
└── index.css # Base styles
|
|
180
|
+
```
|
|
147
181
|
|
|
148
182
|
---
|
|
149
183
|
|
|
150
|
-
##
|
|
184
|
+
## 🤝 Contributing
|
|
151
185
|
|
|
152
|
-
|
|
186
|
+
1. Fork the repository
|
|
187
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
188
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
189
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
190
|
+
5. Open a Pull Request
|
|
153
191
|
|
|
154
192
|
---
|
|
155
193
|
|
|
156
194
|
## 📄 License
|
|
157
195
|
|
|
158
|
-
MIT © [Aram Khachatryan](https://github.com/khachatryan-dev)
|
|
159
|
-
|
|
160
|
-
---
|
|
196
|
+
MIT © [Aram Khachatryan](https://github.com/khachatryan-dev)
|
package/dist/esm/react.js
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
useEffect,
|
|
4
4
|
useRef,
|
|
5
|
-
forwardRef
|
|
6
|
-
useImperativeHandle
|
|
5
|
+
forwardRef
|
|
7
6
|
} from "react";
|
|
8
7
|
import ReactDOM from "react-dom/client";
|
|
9
8
|
|
|
@@ -86,13 +85,13 @@ var MasonrySnapGridLayout = class {
|
|
|
86
85
|
|
|
87
86
|
// src/react.tsx
|
|
88
87
|
import { jsx } from "react/jsx-runtime";
|
|
89
|
-
|
|
88
|
+
var MasonrySnapGridInner = ({
|
|
90
89
|
items,
|
|
91
90
|
renderItem,
|
|
92
91
|
className,
|
|
93
92
|
style,
|
|
94
93
|
...options
|
|
95
|
-
}, ref) {
|
|
94
|
+
}, ref) => {
|
|
96
95
|
const containerRef = useRef(null);
|
|
97
96
|
const masonryRef = useRef(null);
|
|
98
97
|
const rootsRef = useRef(/* @__PURE__ */ new Map());
|
|
@@ -110,7 +109,10 @@ function MasonrySnapGridInner({
|
|
|
110
109
|
}
|
|
111
110
|
});
|
|
112
111
|
return () => {
|
|
113
|
-
rootsRef.current.forEach((root) =>
|
|
112
|
+
rootsRef.current.forEach((root, div) => {
|
|
113
|
+
root.unmount();
|
|
114
|
+
div.remove();
|
|
115
|
+
});
|
|
114
116
|
rootsRef.current.clear();
|
|
115
117
|
masonryRef.current?.destroy();
|
|
116
118
|
masonryRef.current = null;
|
|
@@ -121,9 +123,6 @@ function MasonrySnapGridInner({
|
|
|
121
123
|
masonryRef.current.updateItems(items);
|
|
122
124
|
}
|
|
123
125
|
}, [items]);
|
|
124
|
-
useImperativeHandle(ref, () => ({
|
|
125
|
-
layout: masonryRef.current
|
|
126
|
-
}));
|
|
127
126
|
return /* @__PURE__ */ jsx(
|
|
128
127
|
"div",
|
|
129
128
|
{
|
|
@@ -132,9 +131,9 @@ function MasonrySnapGridInner({
|
|
|
132
131
|
style: { position: "relative", width: "100%", ...style }
|
|
133
132
|
}
|
|
134
133
|
);
|
|
135
|
-
}
|
|
134
|
+
};
|
|
136
135
|
var MasonrySnapGrid = forwardRef(MasonrySnapGridInner);
|
|
137
|
-
var react_default =
|
|
136
|
+
var react_default = MasonrySnapGrid;
|
|
138
137
|
export {
|
|
139
138
|
react_default as default
|
|
140
139
|
};
|
package/dist/esm/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react.tsx","../../src/MasonrySnapGridLayout.ts"],"sourcesContent":["import React, {\r\n useEffect,\r\n useRef,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from 'react';\r\nimport ReactDOM from 'react-dom/client';\r\nimport MasonrySnapGridLayout from './MasonrySnapGridLayout';\r\nimport {\r\n MasonrySnapGridLayoutOptions,\r\n MasonrySnapGridRef,\r\n} from './types';\r\n\r\ninterface MasonrySnapGridProps<T>\r\n extends Omit<MasonrySnapGridLayoutOptions<T>, 'items' | 'renderItem'> {\r\n items: T[];\r\n renderItem: (item: T) => React.ReactNode;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n}\r\n\r\nfunction MasonrySnapGridInner<T>(\r\n {\r\n items,\r\n renderItem,\r\n className,\r\n style,\r\n ...options\r\n }: MasonrySnapGridProps<T>,\r\n ref: React.Ref<MasonrySnapGridRef>\r\n) {\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const masonryRef = useRef<MasonrySnapGridLayout<T> | null>(null);\r\n\r\n // React roots storage to prevent memory leaks\r\n const rootsRef = useRef<Map<HTMLElement, ReactDOM.Root>>(new Map());\r\n\r\n // Initialize masonry layout\r\n useEffect(() => {\r\n if (!containerRef.current) return;\r\n\r\n masonryRef.current = new MasonrySnapGridLayout(containerRef.current, {\r\n ...options,\r\n items,\r\n renderItem: (item) => {\r\n const div = document.createElement('div');\r\n const root = ReactDOM.createRoot(div);\r\n root.render(renderItem(item));\r\n rootsRef.current.set(div, root);\r\n return div;\r\n },\r\n });\r\n\r\n return () => {\r\n // Unmount all React roots to avoid memory leaks\r\n rootsRef.current.forEach((root) => root.unmount());\r\n rootsRef.current.clear();\r\n\r\n masonryRef.current?.destroy();\r\n masonryRef.current = null;\r\n };\r\n }, [options, renderItem]); // include renderItem if it's not memoized\r\n\r\n // Update items on change\r\n useEffect(() => {\r\n if (masonryRef.current) {\r\n masonryRef.current.updateItems(items);\r\n }\r\n }, [items]);\r\n\r\n // Expose layout instance through ref\r\n useImperativeHandle(ref, () => ({\r\n layout: masonryRef.current!,\r\n }));\r\n\r\n return (\r\n <div\r\n ref={containerRef}\r\n className={className}\r\n style={{ position: 'relative', width: '100%', ...style }}\r\n />\r\n );\r\n}\r\n\r\n// Apply generic type correctly to forwardRef\r\nconst MasonrySnapGrid = forwardRef(MasonrySnapGridInner) as <T>(\r\n props: MasonrySnapGridProps<T> & { ref?: React.Ref<MasonrySnapGridRef> }\r\n) => ReturnType<typeof MasonrySnapGridInner>;\r\n\r\nexport default MasonrySnapGridInner\r\n","import { MasonrySnapGridLayoutOptions } from './types';\r\n\r\nexport default class MasonrySnapGridLayout<T = any> {\r\n private readonly container: HTMLElement;\r\n private readonly options: Required<MasonrySnapGridLayoutOptions<T>>;\r\n private items: HTMLElement[] = [];\r\n private columnHeights: number[] = [];\r\n private resizeObserver: ResizeObserver | undefined;\r\n private rafId: number | null = null;\r\n\r\n constructor(container: HTMLElement, options: MasonrySnapGridLayoutOptions<T>) {\r\n this.container = container;\r\n this.options = {\r\n gutter: 16,\r\n minColWidth: 250,\r\n animate: true,\r\n transitionDuration: 400,\r\n classNames: {\r\n container: 'masonry-snap-grid-container',\r\n item: 'masonry-snap-grid-item',\r\n },\r\n ...options,\r\n };\r\n\r\n // Apply container class\r\n this.container.classList.add(this.options.classNames.container || \"\");\r\n\r\n // Initialize\r\n this.renderItems();\r\n this.setupResizeObserver();\r\n }\r\n\r\n private renderItems() {\r\n // Clear existing items\r\n this.items.forEach(item => item.remove());\r\n this.items = [];\r\n\r\n // Create fragment for batch DOM insertion\r\n const fragment = document.createDocumentFragment();\r\n\r\n // Create and append items\r\n this.options.items.forEach(itemData => {\r\n const itemElement = this.options.renderItem(itemData);\r\n itemElement.classList.add(this.options.classNames.item|| \"\");\r\n fragment.appendChild(itemElement);\r\n this.items.push(itemElement);\r\n });\r\n\r\n this.container.appendChild(fragment);\r\n this.updateLayout();\r\n }\r\n\r\n private setupResizeObserver() {\r\n this.resizeObserver = new ResizeObserver(() => {\r\n if (this.rafId) cancelAnimationFrame(this.rafId);\r\n this.rafId = requestAnimationFrame(() => this.updateLayout());\r\n });\r\n this.resizeObserver.observe(this.container);\r\n }\r\n\r\n private updateLayout() {\r\n const { gutter, minColWidth, animate, transitionDuration } = this.options;\r\n const containerWidth = this.container.clientWidth;\r\n\r\n // Calculate columns\r\n const columns = Math.max(1, Math.floor((containerWidth + gutter) / (minColWidth + gutter)));\r\n const colWidth = (containerWidth - (columns - 1) * gutter) / columns;\r\n\r\n // Reset column heights\r\n this.columnHeights = new Array(columns).fill(0);\r\n\r\n // Position items\r\n this.items.forEach((item) => {\r\n const height = item.offsetHeight;\r\n const minCol = this.findShortestColumn();\r\n const x = minCol * (colWidth + gutter);\r\n const y = this.columnHeights[minCol];\r\n\r\n // Apply position and size\r\n item.style.width = `${colWidth}px`;\r\n item.style.transform = `translate3d(${x}px, ${y}px, 0)`;\r\n item.style.transition = animate\r\n ? `transform ${transitionDuration}ms ease`\r\n : 'none';\r\n\r\n // Update column height\r\n this.columnHeights[minCol] += height + gutter;\r\n });\r\n\r\n // Set container height\r\n const maxHeight = Math.max(...this.columnHeights);\r\n this.container.style.height = `${maxHeight}px`;\r\n }\r\n\r\n private findShortestColumn(): number {\r\n return this.columnHeights.indexOf(Math.min(...this.columnHeights));\r\n }\r\n\r\n public updateItems(newItems: T[]) {\r\n this.options.items = newItems;\r\n this.renderItems();\r\n }\r\n\r\n public destroy() {\r\n this.resizeObserver?.disconnect();\r\n if (this.rafId) cancelAnimationFrame(this.rafId);\r\n this.container.innerHTML = '';\r\n this.container.removeAttribute('style');\r\n this.container.classList.remove(this.options.classNames.container || \"\");\r\n }\r\n}"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/react.tsx","../../src/MasonrySnapGridLayout.ts"],"sourcesContent":["import React, {\r\n useEffect,\r\n useRef,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from 'react';\r\nimport ReactDOM from 'react-dom/client';\r\nimport MasonrySnapGridLayout from './MasonrySnapGridLayout';\r\nimport {\r\n MasonrySnapGridLayoutOptions,\r\n MasonrySnapGridRef,\r\n} from './types';\r\n\r\ninterface MasonrySnapGridProps<T>\r\n extends Omit<MasonrySnapGridLayoutOptions<T>, 'items' | 'renderItem'> {\r\n items: T[];\r\n renderItem: (item: T) => React.ReactNode;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n}\r\n\r\nconst MasonrySnapGridInner = <T,>(\r\n {\r\n items,\r\n renderItem,\r\n className,\r\n style,\r\n ...options\r\n }: MasonrySnapGridProps<T>,\r\n ref: React.ForwardedRef<MasonrySnapGridRef>\r\n) => {\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const masonryRef = useRef<MasonrySnapGridLayout<T> | null>(null);\r\n const rootsRef = useRef<Map<HTMLElement, ReactDOM.Root>>(new Map());\r\n\r\n // Initialize masonry layout\r\n useEffect(() => {\r\n if (!containerRef.current) return;\r\n\r\n masonryRef.current = new MasonrySnapGridLayout(containerRef.current, {\r\n ...options,\r\n items,\r\n renderItem: (item) => {\r\n const div = document.createElement('div');\r\n const root = ReactDOM.createRoot(div);\r\n root.render(renderItem(item));\r\n rootsRef.current.set(div, root);\r\n return div;\r\n },\r\n });\r\n\r\n return () => {\r\n // Proper cleanup\r\n rootsRef.current.forEach((root, div) => {\r\n root.unmount();\r\n div.remove();\r\n });\r\n rootsRef.current.clear();\r\n masonryRef.current?.destroy();\r\n masonryRef.current = null;\r\n };\r\n }, [options, renderItem]);\r\n\r\n // Update items on change\r\n useEffect(() => {\r\n if (masonryRef.current) {\r\n masonryRef.current.updateItems(items);\r\n }\r\n }, [items]);\r\n\r\n\r\n return (\r\n <div\r\n ref={containerRef}\r\n className={className}\r\n style={{ position: 'relative', width: '100%', ...style }}\r\n />\r\n );\r\n};\r\n\r\n// Properly typed forwardRef component\r\nconst MasonrySnapGrid = forwardRef(MasonrySnapGridInner) as <T>(\r\n props: MasonrySnapGridProps<T> & { ref?: React.ForwardedRef<MasonrySnapGridRef> }\r\n) => ReturnType<typeof MasonrySnapGridInner>;\r\n\r\nexport default MasonrySnapGrid;","import { MasonrySnapGridLayoutOptions } from './types';\r\n\r\nexport default class MasonrySnapGridLayout<T = any> {\r\n private readonly container: HTMLElement;\r\n private readonly options: Required<MasonrySnapGridLayoutOptions<T>>;\r\n private items: HTMLElement[] = [];\r\n private columnHeights: number[] = [];\r\n private resizeObserver: ResizeObserver | undefined;\r\n private rafId: number | null = null;\r\n\r\n constructor(container: HTMLElement, options: MasonrySnapGridLayoutOptions<T>) {\r\n this.container = container;\r\n this.options = {\r\n gutter: 16,\r\n minColWidth: 250,\r\n animate: true,\r\n transitionDuration: 400,\r\n classNames: {\r\n container: 'masonry-snap-grid-container',\r\n item: 'masonry-snap-grid-item',\r\n },\r\n ...options,\r\n };\r\n\r\n // Apply container class\r\n this.container.classList.add(this.options.classNames.container || \"\");\r\n\r\n // Initialize\r\n this.renderItems();\r\n this.setupResizeObserver();\r\n }\r\n\r\n private renderItems() {\r\n // Clear existing items\r\n this.items.forEach(item => item.remove());\r\n this.items = [];\r\n\r\n // Create fragment for batch DOM insertion\r\n const fragment = document.createDocumentFragment();\r\n\r\n // Create and append items\r\n this.options.items.forEach(itemData => {\r\n const itemElement = this.options.renderItem(itemData);\r\n itemElement.classList.add(this.options.classNames.item|| \"\");\r\n fragment.appendChild(itemElement);\r\n this.items.push(itemElement);\r\n });\r\n\r\n this.container.appendChild(fragment);\r\n this.updateLayout();\r\n }\r\n\r\n private setupResizeObserver() {\r\n this.resizeObserver = new ResizeObserver(() => {\r\n if (this.rafId) cancelAnimationFrame(this.rafId);\r\n this.rafId = requestAnimationFrame(() => this.updateLayout());\r\n });\r\n this.resizeObserver.observe(this.container);\r\n }\r\n\r\n private updateLayout() {\r\n const { gutter, minColWidth, animate, transitionDuration } = this.options;\r\n const containerWidth = this.container.clientWidth;\r\n\r\n // Calculate columns\r\n const columns = Math.max(1, Math.floor((containerWidth + gutter) / (minColWidth + gutter)));\r\n const colWidth = (containerWidth - (columns - 1) * gutter) / columns;\r\n\r\n // Reset column heights\r\n this.columnHeights = new Array(columns).fill(0);\r\n\r\n // Position items\r\n this.items.forEach((item) => {\r\n const height = item.offsetHeight;\r\n const minCol = this.findShortestColumn();\r\n const x = minCol * (colWidth + gutter);\r\n const y = this.columnHeights[minCol];\r\n\r\n // Apply position and size\r\n item.style.width = `${colWidth}px`;\r\n item.style.transform = `translate3d(${x}px, ${y}px, 0)`;\r\n item.style.transition = animate\r\n ? `transform ${transitionDuration}ms ease`\r\n : 'none';\r\n\r\n // Update column height\r\n this.columnHeights[minCol] += height + gutter;\r\n });\r\n\r\n // Set container height\r\n const maxHeight = Math.max(...this.columnHeights);\r\n this.container.style.height = `${maxHeight}px`;\r\n }\r\n\r\n private findShortestColumn(): number {\r\n return this.columnHeights.indexOf(Math.min(...this.columnHeights));\r\n }\r\n\r\n public updateItems(newItems: T[]) {\r\n this.options.items = newItems;\r\n this.renderItems();\r\n }\r\n\r\n public destroy() {\r\n this.resizeObserver?.disconnect();\r\n if (this.rafId) cancelAnimationFrame(this.rafId);\r\n this.container.innerHTML = '';\r\n this.container.removeAttribute('style');\r\n this.container.classList.remove(this.options.classNames.container || \"\");\r\n }\r\n}"],"mappings":";AAAA;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,OAEG;AACP,OAAO,cAAc;;;ACJrB,IAAqB,wBAArB,MAAoD;AAAA,EAQhD,YAAY,WAAwB,SAA0C;AAL9E,SAAQ,QAAuB,CAAC;AAChC,SAAQ,gBAA0B,CAAC;AAEnC,SAAQ,QAAuB;AAG3B,SAAK,YAAY;AACjB,SAAK,UAAU;AAAA,MACX,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,SAAS;AAAA,MACT,oBAAoB;AAAA,MACpB,YAAY;AAAA,QACR,WAAW;AAAA,QACX,MAAM;AAAA,MACV;AAAA,MACA,GAAG;AAAA,IACP;AAGA,SAAK,UAAU,UAAU,IAAI,KAAK,QAAQ,WAAW,aAAa,EAAE;AAGpE,SAAK,YAAY;AACjB,SAAK,oBAAoB;AAAA,EAC7B;AAAA,EAEQ,cAAc;AAElB,SAAK,MAAM,QAAQ,UAAQ,KAAK,OAAO,CAAC;AACxC,SAAK,QAAQ,CAAC;AAGd,UAAM,WAAW,SAAS,uBAAuB;AAGjD,SAAK,QAAQ,MAAM,QAAQ,cAAY;AACnC,YAAM,cAAc,KAAK,QAAQ,WAAW,QAAQ;AACpD,kBAAY,UAAU,IAAI,KAAK,QAAQ,WAAW,QAAO,EAAE;AAC3D,eAAS,YAAY,WAAW;AAChC,WAAK,MAAM,KAAK,WAAW;AAAA,IAC/B,CAAC;AAED,SAAK,UAAU,YAAY,QAAQ;AACnC,SAAK,aAAa;AAAA,EACtB;AAAA,EAEQ,sBAAsB;AAC1B,SAAK,iBAAiB,IAAI,eAAe,MAAM;AAC3C,UAAI,KAAK,MAAO,sBAAqB,KAAK,KAAK;AAC/C,WAAK,QAAQ,sBAAsB,MAAM,KAAK,aAAa,CAAC;AAAA,IAChE,CAAC;AACD,SAAK,eAAe,QAAQ,KAAK,SAAS;AAAA,EAC9C;AAAA,EAEQ,eAAe;AACnB,UAAM,EAAE,QAAQ,aAAa,SAAS,mBAAmB,IAAI,KAAK;AAClE,UAAM,iBAAiB,KAAK,UAAU;AAGtC,UAAM,UAAU,KAAK,IAAI,GAAG,KAAK,OAAO,iBAAiB,WAAW,cAAc,OAAO,CAAC;AAC1F,UAAM,YAAY,kBAAkB,UAAU,KAAK,UAAU;AAG7D,SAAK,gBAAgB,IAAI,MAAM,OAAO,EAAE,KAAK,CAAC;AAG9C,SAAK,MAAM,QAAQ,CAAC,SAAS;AACzB,YAAM,SAAS,KAAK;AACpB,YAAM,SAAS,KAAK,mBAAmB;AACvC,YAAM,IAAI,UAAU,WAAW;AAC/B,YAAM,IAAI,KAAK,cAAc,MAAM;AAGnC,WAAK,MAAM,QAAQ,GAAG,QAAQ;AAC9B,WAAK,MAAM,YAAY,eAAe,CAAC,OAAO,CAAC;AAC/C,WAAK,MAAM,aAAa,UAClB,aAAa,kBAAkB,YAC/B;AAGN,WAAK,cAAc,MAAM,KAAK,SAAS;AAAA,IAC3C,CAAC;AAGD,UAAM,YAAY,KAAK,IAAI,GAAG,KAAK,aAAa;AAChD,SAAK,UAAU,MAAM,SAAS,GAAG,SAAS;AAAA,EAC9C;AAAA,EAEQ,qBAA6B;AACjC,WAAO,KAAK,cAAc,QAAQ,KAAK,IAAI,GAAG,KAAK,aAAa,CAAC;AAAA,EACrE;AAAA,EAEO,YAAY,UAAe;AAC9B,SAAK,QAAQ,QAAQ;AACrB,SAAK,YAAY;AAAA,EACrB;AAAA,EAEO,UAAU;AACb,SAAK,gBAAgB,WAAW;AAChC,QAAI,KAAK,MAAO,sBAAqB,KAAK,KAAK;AAC/C,SAAK,UAAU,YAAY;AAC3B,SAAK,UAAU,gBAAgB,OAAO;AACtC,SAAK,UAAU,UAAU,OAAO,KAAK,QAAQ,WAAW,aAAa,EAAE;AAAA,EAC3E;AACJ;;;ADtCQ;AAnDR,IAAM,uBAAuB,CACzB;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACP,GACA,QACC;AACD,QAAM,eAAe,OAAuB,IAAI;AAChD,QAAM,aAAa,OAAwC,IAAI;AAC/D,QAAM,WAAW,OAAwC,oBAAI,IAAI,CAAC;AAGlE,YAAU,MAAM;AACZ,QAAI,CAAC,aAAa,QAAS;AAE3B,eAAW,UAAU,IAAI,sBAAsB,aAAa,SAAS;AAAA,MACjE,GAAG;AAAA,MACH;AAAA,MACA,YAAY,CAAC,SAAS;AAClB,cAAM,MAAM,SAAS,cAAc,KAAK;AACxC,cAAM,OAAO,SAAS,WAAW,GAAG;AACpC,aAAK,OAAO,WAAW,IAAI,CAAC;AAC5B,iBAAS,QAAQ,IAAI,KAAK,IAAI;AAC9B,eAAO;AAAA,MACX;AAAA,IACJ,CAAC;AAED,WAAO,MAAM;AAET,eAAS,QAAQ,QAAQ,CAAC,MAAM,QAAQ;AACpC,aAAK,QAAQ;AACb,YAAI,OAAO;AAAA,MACf,CAAC;AACD,eAAS,QAAQ,MAAM;AACvB,iBAAW,SAAS,QAAQ;AAC5B,iBAAW,UAAU;AAAA,IACzB;AAAA,EACJ,GAAG,CAAC,SAAS,UAAU,CAAC;AAGxB,YAAU,MAAM;AACZ,QAAI,WAAW,SAAS;AACpB,iBAAW,QAAQ,YAAY,KAAK;AAAA,IACxC;AAAA,EACJ,GAAG,CAAC,KAAK,CAAC;AAGV,SACI;AAAA,IAAC;AAAA;AAAA,MACG,KAAK;AAAA,MACL;AAAA,MACA,OAAO,EAAE,UAAU,YAAY,OAAO,QAAQ,GAAG,MAAM;AAAA;AAAA,EAC3D;AAER;AAGA,IAAM,kBAAkB,WAAW,oBAAoB;AAIvD,IAAO,gBAAQ;","names":[]}
|
package/dist/react.d.cts
CHANGED
|
@@ -8,6 +8,9 @@ interface MasonrySnapGridProps<T> extends Omit<MasonrySnapGridLayoutOptions<T>,
|
|
|
8
8
|
className?: string;
|
|
9
9
|
style?: React.CSSProperties;
|
|
10
10
|
}
|
|
11
|
-
declare
|
|
11
|
+
declare const MasonrySnapGridInner: <T>({ items, renderItem, className, style, ...options }: MasonrySnapGridProps<T>, ref: React.ForwardedRef<MasonrySnapGridRef>) => react_jsx_runtime.JSX.Element;
|
|
12
|
+
declare const MasonrySnapGrid: <T>(props: MasonrySnapGridProps<T> & {
|
|
13
|
+
ref?: React.ForwardedRef<MasonrySnapGridRef>;
|
|
14
|
+
}) => ReturnType<typeof MasonrySnapGridInner>;
|
|
12
15
|
|
|
13
|
-
export {
|
|
16
|
+
export { MasonrySnapGrid as default };
|
package/dist/react.d.ts
CHANGED
|
@@ -8,6 +8,9 @@ interface MasonrySnapGridProps<T> extends Omit<MasonrySnapGridLayoutOptions<T>,
|
|
|
8
8
|
className?: string;
|
|
9
9
|
style?: React.CSSProperties;
|
|
10
10
|
}
|
|
11
|
-
declare
|
|
11
|
+
declare const MasonrySnapGridInner: <T>({ items, renderItem, className, style, ...options }: MasonrySnapGridProps<T>, ref: React.ForwardedRef<MasonrySnapGridRef>) => react_jsx_runtime.JSX.Element;
|
|
12
|
+
declare const MasonrySnapGrid: <T>(props: MasonrySnapGridProps<T> & {
|
|
13
|
+
ref?: React.ForwardedRef<MasonrySnapGridRef>;
|
|
14
|
+
}) => ReturnType<typeof MasonrySnapGridInner>;
|
|
12
15
|
|
|
13
|
-
export {
|
|
16
|
+
export { MasonrySnapGrid as default };
|
package/dist/react.js
CHANGED
|
@@ -115,13 +115,13 @@ var MasonrySnapGridLayout = class {
|
|
|
115
115
|
|
|
116
116
|
// src/react.tsx
|
|
117
117
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
118
|
-
|
|
118
|
+
var MasonrySnapGridInner = ({
|
|
119
119
|
items,
|
|
120
120
|
renderItem,
|
|
121
121
|
className,
|
|
122
122
|
style,
|
|
123
123
|
...options
|
|
124
|
-
}, ref) {
|
|
124
|
+
}, ref) => {
|
|
125
125
|
const containerRef = (0, import_react.useRef)(null);
|
|
126
126
|
const masonryRef = (0, import_react.useRef)(null);
|
|
127
127
|
const rootsRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
|
|
@@ -139,7 +139,10 @@ function MasonrySnapGridInner({
|
|
|
139
139
|
}
|
|
140
140
|
});
|
|
141
141
|
return () => {
|
|
142
|
-
rootsRef.current.forEach((root) =>
|
|
142
|
+
rootsRef.current.forEach((root, div) => {
|
|
143
|
+
root.unmount();
|
|
144
|
+
div.remove();
|
|
145
|
+
});
|
|
143
146
|
rootsRef.current.clear();
|
|
144
147
|
masonryRef.current?.destroy();
|
|
145
148
|
masonryRef.current = null;
|
|
@@ -150,9 +153,6 @@ function MasonrySnapGridInner({
|
|
|
150
153
|
masonryRef.current.updateItems(items);
|
|
151
154
|
}
|
|
152
155
|
}, [items]);
|
|
153
|
-
(0, import_react.useImperativeHandle)(ref, () => ({
|
|
154
|
-
layout: masonryRef.current
|
|
155
|
-
}));
|
|
156
156
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
157
157
|
"div",
|
|
158
158
|
{
|
|
@@ -161,7 +161,7 @@ function MasonrySnapGridInner({
|
|
|
161
161
|
style: { position: "relative", width: "100%", ...style }
|
|
162
162
|
}
|
|
163
163
|
);
|
|
164
|
-
}
|
|
164
|
+
};
|
|
165
165
|
var MasonrySnapGrid = (0, import_react.forwardRef)(MasonrySnapGridInner);
|
|
166
|
-
var react_default =
|
|
166
|
+
var react_default = MasonrySnapGrid;
|
|
167
167
|
//# sourceMappingURL=react.js.map
|
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react.tsx","../src/MasonrySnapGridLayout.ts"],"sourcesContent":["import React, {\r\n useEffect,\r\n useRef,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from 'react';\r\nimport ReactDOM from 'react-dom/client';\r\nimport MasonrySnapGridLayout from './MasonrySnapGridLayout';\r\nimport {\r\n MasonrySnapGridLayoutOptions,\r\n MasonrySnapGridRef,\r\n} from './types';\r\n\r\ninterface MasonrySnapGridProps<T>\r\n extends Omit<MasonrySnapGridLayoutOptions<T>, 'items' | 'renderItem'> {\r\n items: T[];\r\n renderItem: (item: T) => React.ReactNode;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n}\r\n\r\nfunction MasonrySnapGridInner<T>(\r\n {\r\n items,\r\n renderItem,\r\n className,\r\n style,\r\n ...options\r\n }: MasonrySnapGridProps<T>,\r\n ref: React.Ref<MasonrySnapGridRef>\r\n) {\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const masonryRef = useRef<MasonrySnapGridLayout<T> | null>(null);\r\n\r\n // React roots storage to prevent memory leaks\r\n const rootsRef = useRef<Map<HTMLElement, ReactDOM.Root>>(new Map());\r\n\r\n // Initialize masonry layout\r\n useEffect(() => {\r\n if (!containerRef.current) return;\r\n\r\n masonryRef.current = new MasonrySnapGridLayout(containerRef.current, {\r\n ...options,\r\n items,\r\n renderItem: (item) => {\r\n const div = document.createElement('div');\r\n const root = ReactDOM.createRoot(div);\r\n root.render(renderItem(item));\r\n rootsRef.current.set(div, root);\r\n return div;\r\n },\r\n });\r\n\r\n return () => {\r\n // Unmount all React roots to avoid memory leaks\r\n rootsRef.current.forEach((root) => root.unmount());\r\n rootsRef.current.clear();\r\n\r\n masonryRef.current?.destroy();\r\n masonryRef.current = null;\r\n };\r\n }, [options, renderItem]); // include renderItem if it's not memoized\r\n\r\n // Update items on change\r\n useEffect(() => {\r\n if (masonryRef.current) {\r\n masonryRef.current.updateItems(items);\r\n }\r\n }, [items]);\r\n\r\n // Expose layout instance through ref\r\n useImperativeHandle(ref, () => ({\r\n layout: masonryRef.current!,\r\n }));\r\n\r\n return (\r\n <div\r\n ref={containerRef}\r\n className={className}\r\n style={{ position: 'relative', width: '100%', ...style }}\r\n />\r\n );\r\n}\r\n\r\n// Apply generic type correctly to forwardRef\r\nconst MasonrySnapGrid = forwardRef(MasonrySnapGridInner) as <T>(\r\n props: MasonrySnapGridProps<T> & { ref?: React.Ref<MasonrySnapGridRef> }\r\n) => ReturnType<typeof MasonrySnapGridInner>;\r\n\r\nexport default MasonrySnapGridInner\r\n","import { MasonrySnapGridLayoutOptions } from './types';\r\n\r\nexport default class MasonrySnapGridLayout<T = any> {\r\n private readonly container: HTMLElement;\r\n private readonly options: Required<MasonrySnapGridLayoutOptions<T>>;\r\n private items: HTMLElement[] = [];\r\n private columnHeights: number[] = [];\r\n private resizeObserver: ResizeObserver | undefined;\r\n private rafId: number | null = null;\r\n\r\n constructor(container: HTMLElement, options: MasonrySnapGridLayoutOptions<T>) {\r\n this.container = container;\r\n this.options = {\r\n gutter: 16,\r\n minColWidth: 250,\r\n animate: true,\r\n transitionDuration: 400,\r\n classNames: {\r\n container: 'masonry-snap-grid-container',\r\n item: 'masonry-snap-grid-item',\r\n },\r\n ...options,\r\n };\r\n\r\n // Apply container class\r\n this.container.classList.add(this.options.classNames.container || \"\");\r\n\r\n // Initialize\r\n this.renderItems();\r\n this.setupResizeObserver();\r\n }\r\n\r\n private renderItems() {\r\n // Clear existing items\r\n this.items.forEach(item => item.remove());\r\n this.items = [];\r\n\r\n // Create fragment for batch DOM insertion\r\n const fragment = document.createDocumentFragment();\r\n\r\n // Create and append items\r\n this.options.items.forEach(itemData => {\r\n const itemElement = this.options.renderItem(itemData);\r\n itemElement.classList.add(this.options.classNames.item|| \"\");\r\n fragment.appendChild(itemElement);\r\n this.items.push(itemElement);\r\n });\r\n\r\n this.container.appendChild(fragment);\r\n this.updateLayout();\r\n }\r\n\r\n private setupResizeObserver() {\r\n this.resizeObserver = new ResizeObserver(() => {\r\n if (this.rafId) cancelAnimationFrame(this.rafId);\r\n this.rafId = requestAnimationFrame(() => this.updateLayout());\r\n });\r\n this.resizeObserver.observe(this.container);\r\n }\r\n\r\n private updateLayout() {\r\n const { gutter, minColWidth, animate, transitionDuration } = this.options;\r\n const containerWidth = this.container.clientWidth;\r\n\r\n // Calculate columns\r\n const columns = Math.max(1, Math.floor((containerWidth + gutter) / (minColWidth + gutter)));\r\n const colWidth = (containerWidth - (columns - 1) * gutter) / columns;\r\n\r\n // Reset column heights\r\n this.columnHeights = new Array(columns).fill(0);\r\n\r\n // Position items\r\n this.items.forEach((item) => {\r\n const height = item.offsetHeight;\r\n const minCol = this.findShortestColumn();\r\n const x = minCol * (colWidth + gutter);\r\n const y = this.columnHeights[minCol];\r\n\r\n // Apply position and size\r\n item.style.width = `${colWidth}px`;\r\n item.style.transform = `translate3d(${x}px, ${y}px, 0)`;\r\n item.style.transition = animate\r\n ? `transform ${transitionDuration}ms ease`\r\n : 'none';\r\n\r\n // Update column height\r\n this.columnHeights[minCol] += height + gutter;\r\n });\r\n\r\n // Set container height\r\n const maxHeight = Math.max(...this.columnHeights);\r\n this.container.style.height = `${maxHeight}px`;\r\n }\r\n\r\n private findShortestColumn(): number {\r\n return this.columnHeights.indexOf(Math.min(...this.columnHeights));\r\n }\r\n\r\n public updateItems(newItems: T[]) {\r\n this.options.items = newItems;\r\n this.renderItems();\r\n }\r\n\r\n public destroy() {\r\n this.resizeObserver?.disconnect();\r\n if (this.rafId) cancelAnimationFrame(this.rafId);\r\n this.container.innerHTML = '';\r\n this.container.removeAttribute('style');\r\n this.container.classList.remove(this.options.classNames.container || \"\");\r\n }\r\n}"],"mappings":"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","names":["ReactDOM"]}
|
|
1
|
+
{"version":3,"sources":["../src/react.tsx","../src/MasonrySnapGridLayout.ts"],"sourcesContent":["import React, {\r\n useEffect,\r\n useRef,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from 'react';\r\nimport ReactDOM from 'react-dom/client';\r\nimport MasonrySnapGridLayout from './MasonrySnapGridLayout';\r\nimport {\r\n MasonrySnapGridLayoutOptions,\r\n MasonrySnapGridRef,\r\n} from './types';\r\n\r\ninterface MasonrySnapGridProps<T>\r\n extends Omit<MasonrySnapGridLayoutOptions<T>, 'items' | 'renderItem'> {\r\n items: T[];\r\n renderItem: (item: T) => React.ReactNode;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n}\r\n\r\nconst MasonrySnapGridInner = <T,>(\r\n {\r\n items,\r\n renderItem,\r\n className,\r\n style,\r\n ...options\r\n }: MasonrySnapGridProps<T>,\r\n ref: React.ForwardedRef<MasonrySnapGridRef>\r\n) => {\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const masonryRef = useRef<MasonrySnapGridLayout<T> | null>(null);\r\n const rootsRef = useRef<Map<HTMLElement, ReactDOM.Root>>(new Map());\r\n\r\n // Initialize masonry layout\r\n useEffect(() => {\r\n if (!containerRef.current) return;\r\n\r\n masonryRef.current = new MasonrySnapGridLayout(containerRef.current, {\r\n ...options,\r\n items,\r\n renderItem: (item) => {\r\n const div = document.createElement('div');\r\n const root = ReactDOM.createRoot(div);\r\n root.render(renderItem(item));\r\n rootsRef.current.set(div, root);\r\n return div;\r\n },\r\n });\r\n\r\n return () => {\r\n // Proper cleanup\r\n rootsRef.current.forEach((root, div) => {\r\n root.unmount();\r\n div.remove();\r\n });\r\n rootsRef.current.clear();\r\n masonryRef.current?.destroy();\r\n masonryRef.current = null;\r\n };\r\n }, [options, renderItem]);\r\n\r\n // Update items on change\r\n useEffect(() => {\r\n if (masonryRef.current) {\r\n masonryRef.current.updateItems(items);\r\n }\r\n }, [items]);\r\n\r\n\r\n return (\r\n <div\r\n ref={containerRef}\r\n className={className}\r\n style={{ position: 'relative', width: '100%', ...style }}\r\n />\r\n );\r\n};\r\n\r\n// Properly typed forwardRef component\r\nconst MasonrySnapGrid = forwardRef(MasonrySnapGridInner) as <T>(\r\n props: MasonrySnapGridProps<T> & { ref?: React.ForwardedRef<MasonrySnapGridRef> }\r\n) => ReturnType<typeof MasonrySnapGridInner>;\r\n\r\nexport default MasonrySnapGrid;","import { MasonrySnapGridLayoutOptions } from './types';\r\n\r\nexport default class MasonrySnapGridLayout<T = any> {\r\n private readonly container: HTMLElement;\r\n private readonly options: Required<MasonrySnapGridLayoutOptions<T>>;\r\n private items: HTMLElement[] = [];\r\n private columnHeights: number[] = [];\r\n private resizeObserver: ResizeObserver | undefined;\r\n private rafId: number | null = null;\r\n\r\n constructor(container: HTMLElement, options: MasonrySnapGridLayoutOptions<T>) {\r\n this.container = container;\r\n this.options = {\r\n gutter: 16,\r\n minColWidth: 250,\r\n animate: true,\r\n transitionDuration: 400,\r\n classNames: {\r\n container: 'masonry-snap-grid-container',\r\n item: 'masonry-snap-grid-item',\r\n },\r\n ...options,\r\n };\r\n\r\n // Apply container class\r\n this.container.classList.add(this.options.classNames.container || \"\");\r\n\r\n // Initialize\r\n this.renderItems();\r\n this.setupResizeObserver();\r\n }\r\n\r\n private renderItems() {\r\n // Clear existing items\r\n this.items.forEach(item => item.remove());\r\n this.items = [];\r\n\r\n // Create fragment for batch DOM insertion\r\n const fragment = document.createDocumentFragment();\r\n\r\n // Create and append items\r\n this.options.items.forEach(itemData => {\r\n const itemElement = this.options.renderItem(itemData);\r\n itemElement.classList.add(this.options.classNames.item|| \"\");\r\n fragment.appendChild(itemElement);\r\n this.items.push(itemElement);\r\n });\r\n\r\n this.container.appendChild(fragment);\r\n this.updateLayout();\r\n }\r\n\r\n private setupResizeObserver() {\r\n this.resizeObserver = new ResizeObserver(() => {\r\n if (this.rafId) cancelAnimationFrame(this.rafId);\r\n this.rafId = requestAnimationFrame(() => this.updateLayout());\r\n });\r\n this.resizeObserver.observe(this.container);\r\n }\r\n\r\n private updateLayout() {\r\n const { gutter, minColWidth, animate, transitionDuration } = this.options;\r\n const containerWidth = this.container.clientWidth;\r\n\r\n // Calculate columns\r\n const columns = Math.max(1, Math.floor((containerWidth + gutter) / (minColWidth + gutter)));\r\n const colWidth = (containerWidth - (columns - 1) * gutter) / columns;\r\n\r\n // Reset column heights\r\n this.columnHeights = new Array(columns).fill(0);\r\n\r\n // Position items\r\n this.items.forEach((item) => {\r\n const height = item.offsetHeight;\r\n const minCol = this.findShortestColumn();\r\n const x = minCol * (colWidth + gutter);\r\n const y = this.columnHeights[minCol];\r\n\r\n // Apply position and size\r\n item.style.width = `${colWidth}px`;\r\n item.style.transform = `translate3d(${x}px, ${y}px, 0)`;\r\n item.style.transition = animate\r\n ? `transform ${transitionDuration}ms ease`\r\n : 'none';\r\n\r\n // Update column height\r\n this.columnHeights[minCol] += height + gutter;\r\n });\r\n\r\n // Set container height\r\n const maxHeight = Math.max(...this.columnHeights);\r\n this.container.style.height = `${maxHeight}px`;\r\n }\r\n\r\n private findShortestColumn(): number {\r\n return this.columnHeights.indexOf(Math.min(...this.columnHeights));\r\n }\r\n\r\n public updateItems(newItems: T[]) {\r\n this.options.items = newItems;\r\n this.renderItems();\r\n }\r\n\r\n public destroy() {\r\n this.resizeObserver?.disconnect();\r\n if (this.rafId) cancelAnimationFrame(this.rafId);\r\n this.container.innerHTML = '';\r\n this.container.removeAttribute('style');\r\n this.container.classList.remove(this.options.classNames.container || \"\");\r\n }\r\n}"],"mappings":"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","names":["ReactDOM"]}
|
package/package.json
CHANGED