react-gallery-layouts
v0.3.0
Published
React gallery layouts library with masonry, stack, grid, and justified layouts
Maintainers
Readme
Gallery Library
A modern, responsive gallery library built with React and TypeScript, supporting multiple layout types with customizable options.
Features
- 🎨 Multiple layout types (grid, masonry, stack, justified)
- 📱 Responsive design with automatic container width detection
- 🖱️ Touch device support
- 🚀 Lazy loading support
- 🎯 Customizable item rendering
- 📦 TypeScript support
- 📚 Comprehensive documentation
- 🧪 Example implementation
- 📏 Aspect ratio control
- 📐 Pixel-perfect layout calculations
Installation
npm install react-gallery-layouts
# or
yarn add react-gallery-layoutsUsage
import { Gallery } from 'react-gallery-layouts';
const MyGallery = () => {
const items = [
{ id: 1, src: 'image1.jpg', alt: 'Image 1' },
{ id: 2, src: 'image2.jpg', alt: 'Image 2' },
// ... more items
];
return (
<Gallery
items={items}
layout="masonry"
layoutOptions={{
masonry: {
columns: 3,
gutter: 10,
containerWidth: 1200 // Optional fixed container width
}
}}
lazyLoad={true}
onItemClick={(item, index) => console.log('Clicked:', item, index)}
/>
);
};Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| items | GalleryItem[] | [] | Array of gallery items |
| layout | 'grid' \| 'masonry' \| 'stack' \| 'justified' | 'masonry' | Layout type |
| layoutOptions | LayoutOptions | {} | Options specific to each layout type |
| renderItem | (item: GalleryItem, index: number) => React.ReactNode | undefined | Custom item renderer |
| className | string | '' | Additional CSS class for the container |
| style | React.CSSProperties | {} | Additional styles for the container |
| itemClassName | string | '' | Additional CSS class for items |
| itemStyle | React.CSSProperties | {} | Additional styles for items |
| onItemClick | (item: GalleryItem, index: number) => void | undefined | Item click handler |
| lazyLoad | boolean | false | Enable lazy loading |
Layout Options
Grid Layout
The Grid layout arranges items in a fixed-height grid with equal-sized cells. Each item can optionally span multiple columns and rows using colSpan and rowSpan properties.
Options:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| columns | number \| { [breakpoint: number]: number } | 3 | Number of columns, can be responsive |
| gutter | number \| { [breakpoint: number]: number } | 10 | Space between items in pixels |
| itemHeight | number | 200 | Fixed height for all items |
| aspectRatio | number | undefined | Fixed aspect ratio for items (width/height) |
| containerWidth | number | undefined | Fixed container width in pixels |
Masonry Layout
The Masonry layout arranges items in a grid with variable-sized columns. Each item can optionally span multiple columns using colSpan property. The layout uses absolute positioning for optimal performance and precise control.
Options:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| columns | number \| { [breakpoint: number]: number } | 3 | Number of columns, can be responsive |
| gutter | number \| { [breakpoint: number]: number } | 10 | Space between items in pixels |
| containerWidth | number | undefined | Fixed container width in pixels |
Example:
layoutOptions={{
masonry: {
columns: 3, // Number of columns
gutter: 10, // Space between items
containerWidth: 1200 // Optional fixed container width
}
}}Stack Layout
The Stack layout arranges items in a single column with a maximum width.
Options:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| columns | number \| { [breakpoint: number]: number } | 2 | Number of columns, can be responsive |
| gutter | number \| { [breakpoint: number]: number } | 10 | Space between items in pixels |
| maxWidth | number | 800 | Maximum width of the container |
| alignment | 'flex-start' \| 'center' \| 'flex-end' | 'flex-start' | Alignment of items within the container |
Example:
layoutOptions={{
stack: {
columns: 2, // Number of columns
gutter: 10, // Space between items
maxWidth: 800 // Maximum width of the container
}
}}Justified Layout
The Justified layout arranges items in rows with a target height and maximum height.
Options:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| targetRowHeight | number | 200 | Target height for each row |
| maxRowHeight | number | 300 | Maximum row height |
| containerPadding | number | 10 | Padding around the container |
| gutter | number | 10 | Space between items |
Example:
layoutOptions={{
justified: {
targetRowHeight: 200, // Target height for rows
maxRowHeight: 300, // Maximum row height
containerPadding: 10, // Padding around the container
gutter: 10 // Space between items
}
}}Responsive Configuration
Both columns and gutter support responsive configuration using breakpoints. You can specify different values for different screen sizes:
layoutOptions={{
masonry: {
// Responsive columns
columns: {
default: 2, // Default: 2 columns (screen < 768px)
768: 3, // Tablet: 3 columns (768px <= screen < 1024px)
1024: 4, // Desktop: 4 columns (1024px <= screen < 1440px)
1440: 5 // Large Desktop: 5 columns (screen >= 1440px)
},
// Responsive gutter
gutter: {
default: 10, // Default: 10px gap (screen < 768px)
768: 15, // Tablet: 15px gap (768px <= screen < 1024px)
1024: 20, // Desktop: 20px gap (1024px <= screen < 1440px)
1440: 25 // Large Desktop: 25px gap (screen >= 1440px)
}
}
}}The breakpoints system works as follows:
- Use
defaultfor the base value (smallest screens) - Add breakpoint values in pixels for larger screens
- Values are applied when screen width is >= breakpoint
- Breakpoints are automatically sorted in ascending order
Example of how responsive values are applied:
// For a screen width of 1200px:
// Simple number
columns={3} // Always 3 columns
// Responsive object
columns={{
default: 2, // < 768px
768: 3, // >= 768px
1024: 4, // >= 1024px
1440: 5 // >= 1440px
}}
// Will use 4 columns (matches 1024 breakpoint)
// Same applies for gutter spacing
gutter={{
default: 10,
768: 15,
1024: 20,
1440: 25
}}
// Will use 20px gutter (matches 1024 breakpoint)This responsive configuration is available for all layout types (Grid, Masonry, Stack, Justified).
Custom Item Rendering
You can provide a custom renderer for gallery items. The renderItem prop receives the item data and index, and should return a React node:
interface GalleryItem {
id?: string | number;
src: string;
alt?: string;
width?: number;
height?: number;
colSpan?: number;
// ... any additional custom properties
}
// Basic example with image only
const defaultRenderItem = (item: GalleryItem, index: number) => (
<img
src={item.src}
alt={item.alt || `Gallery item ${index}`}
loading="lazy"
style={{
width: '100%',
height: '100%',
objectFit: 'cover',
display: 'block',
}}
/>
);
// Advanced example with overlay and additional content
const renderItem = (item: GalleryItem, index: number) => (
<div className="custom-item">
<img
src={item.src}
alt={item.alt}
loading="lazy"
style={{
width: '100%',
height: '100%',
objectFit: 'cover',
}}
/>
<div className="overlay">
<h3>{item.title}</h3>
<p>{item.description}</p>
<div className="actions">
<button onClick={() => handleLike(item)}>Like</button>
<button onClick={() => handleShare(item)}>Share</button>
</div>
</div>
</div>
);
// Usage in Gallery component
<Gallery
items={items}
renderItem={renderItem} // Custom renderer
// or
renderItem={defaultRenderItem} // Default renderer
/>The renderItem function has access to:
- All properties of the GalleryItem
- The item's index in the gallery
- The full context of the gallery layout
Best practices for custom rendering:
- Always maintain the aspect ratio of the container
- Use
width: 100%andheight: 100%for the main image - Set
objectFit: 'cover'for proper image scaling - Consider using
loading="lazy"for better performance - Handle image loading states and errors appropriately
Example with loading and error states:
const renderItem = (item: GalleryItem, index: number) => {
const [isLoading, setIsLoading] = useState(true);
const [hasError, setHasError] = useState(false);
return (
<div className="gallery-item">
{isLoading && <div className="loading-placeholder" />}
{hasError && <div className="error-placeholder">Failed to load image</div>}
<img
src={item.src}
alt={item.alt || `Gallery item ${index}`}
loading="lazy"
style={{
width: '100%',
height: '100%',
objectFit: 'cover',
display: hasError ? 'none' : 'block',
opacity: isLoading ? 0 : 1,
transition: 'opacity 0.3s ease-in-out',
}}
onLoad={() => setIsLoading(false)}
onError={() => {
setIsLoading(false);
setHasError(true);
}}
/>
</div>
);
};Styling
The library uses CSS modules for styling. You can customize the appearance by overriding the default styles:
/* Your custom styles */
.gallery-container {
/* Override container styles */
}
.gallery-item {
/* Override item styles */
}
.gallery-grid {
/* Override grid layout styles */
}
.gallery-masonry {
/* Override masonry layout styles */
}License
This project is licensed under the MIT License - see the LICENSE file for details.
AI generated code.
