React gallery layouts library with masonry, stack, grid, and justified layouts
npm install react-gallery-layoutsA modern, responsive gallery library built with React and TypeScript, supporting multiple layout types with customizable options.
- ๐จ 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
``bash`
npm install react-gallery-layoutsor
yarn add react-gallery-layouts
`tsx
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 (
layout="masonry"
layoutOptions={{
masonry: {
columns: 3,
gutter: 10,
containerWidth: 1200 // Optional fixed container width
}
}}
lazyLoad={true}
onItemClick={(item, index) => console.log('Clicked:', item, index)}
/>
);
};
`
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| items | GalleryItem[] | [] | Array of gallery items |'grid' \| 'masonry' \| 'stack' \| 'justified'
| layout | | 'masonry' | Layout type |LayoutOptions
| layoutOptions | | {} | Options specific to each layout type |(item: GalleryItem, index: number) => React.ReactNode
| renderItem | | undefined | Custom item renderer |string
| className | | '' | Additional CSS class for the container |React.CSSProperties
| style | | {} | Additional styles for the container |string
| itemClassName | | '' | Additional CSS class for items |React.CSSProperties
| itemStyle | | {} | Additional styles for items |(item: GalleryItem, index: number) => void
| onItemClick | | undefined | Item click handler |boolean
| lazyLoad | | false | Enable lazy loading |
#### 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 |number \| { [breakpoint: number]: number }
| gutter | | 10 | Space between items in pixels |number
| itemHeight | | 200 | Fixed height for all items |number
| aspectRatio | | undefined | Fixed aspect ratio for items (width/height) |number
| containerWidth | | 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 |number \| { [breakpoint: number]: number }
| gutter | | 10 | Space between items in pixels |number
| containerWidth | | undefined | Fixed container width in pixels |
Example:
`tsx`
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 |number \| { [breakpoint: number]: number }
| gutter | | 10 | Space between items in pixels |number
| maxWidth | | 800 | Maximum width of the container |'flex-start' \| 'center' \| 'flex-end'
| alignment | | 'flex-start' | Alignment of items within the container |
Example:
`tsx`
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 |number
| maxRowHeight | | 300 | Maximum row height |number
| containerPadding | | 10 | Padding around the container |number
| gutter | | 10 | Space between items |
Example:
`tsx`
layoutOptions={{
justified: {
targetRowHeight: 200, // Target height for rows
maxRowHeight: 300, // Maximum row height
containerPadding: 10, // Padding around the container
gutter: 10 // Space between items
}
}}
Both columns and gutter support responsive configuration using breakpoints. You can specify different values for different screen sizes:
`tsx`
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 default for 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:
`tsx
// 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).
You can provide a custom renderer for gallery items. The renderItem prop receives the item data and index, and should return a React node:
`tsx
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) => (
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) => (
{item.description}
// Usage in Gallery component
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% and height: 100% for the main imageobjectFit: 'cover'
- Set for proper image scalingloading="lazy"
- Consider using for better performance
- Handle image loading states and errors appropriately
Example with loading and error states:
`tsx
const renderItem = (item: GalleryItem, index: number) => {
const [isLoading, setIsLoading] = useState(true);
const [hasError, setHasError] = useState(false);
return (
}
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);
}}
/>
Styling
The library uses CSS modules for styling. You can customize the appearance by overriding the default styles:
`css
/ 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 /
}
``This project is licensed under the MIT License - see the LICENSE file for details.
AI generated code.