Livewire UI Components - v1.0-beta2
ImageGallery Component
The ImageGallery component provides a responsive grid-based layout for displaying collections of images with advanced features like filtering, pagination, lazy loading, and PhotoSwipe lightbox integration.
Features
- Responsive Grid Layout: Configurable columns for different screen sizes
- Aspect Ratio Control: Consistent image sizing options (square, landscape, portrait, auto)
- Gap Control: Configurable spacing between images
- PhotoSwipe Integration: Full-screen lightbox viewing with zoom and navigation
- Filtering System: Category/tag-based image filtering
- Lazy Loading: Performance optimization with intersection observer
- Pagination: Optional pagination for large image sets
- Loading States: Multiple loading animation styles (skeleton, spinner, fade)
- Captions: Optional image captions with overlay display
- Dark Mode: Full dark mode compatibility
- Accessibility: WCAG 2.1 AA compliance
Basic Usage
Simple Image Array
<x-image-gallery
:images="[
'https://example.com/image1.jpg',
'https://example.com/image2.jpg',
'https://example.com/image3.jpg',
'https://example.com/image4.jpg'
]"
/>
Image Objects with Metadata
<x-image-gallery
:images="[
[
'url' => 'https://example.com/image1.jpg',
'alt' => 'Beautiful landscape',
'caption' => 'Mountain sunrise in the Alps',
'category' => 'nature',
'width' => 1200,
'height' => 800
],
[
'src' => 'https://example.com/image2.jpg',
'alt' => 'City skyline',
'caption' => 'Downtown at night',
'tags' => ['urban', 'architecture'],
'width' => 1600,
'height' => 900
]
]"
:show-captions="true"
/>
Component Props
Required Props
| Prop | Type | Description |
|---|---|---|
images |
array |
Array of image URLs or image objects |
Optional Props
| Prop | Type | Default | Description |
|---|---|---|---|
id |
string|null |
null |
Custom ID for the gallery |
columns |
array |
['default' => 1, 'sm' => 2, 'md' => 3, 'lg' => 4, 'xl' => 5] |
Responsive column configuration |
aspectRatio |
string |
'square' |
Image aspect ratio: square, landscape, portrait, auto |
gap |
string |
'md' |
Gap between images: xs, sm, md, lg, xl |
enableLightbox |
bool |
true |
Enable PhotoSwipe lightbox |
showCaptions |
bool |
false |
Show image captions |
layout |
string |
'grid' |
Layout type: grid, masonry |
lazyLoad |
bool |
true |
Enable lazy loading |
filters |
array|null |
null |
Category filters array |
itemsPerPage |
int |
0 |
Items per page (0 = no pagination) |
loadingStyle |
string |
'skeleton' |
Loading style: skeleton, spinner, fade |
Responsive Columns
Configure different column counts for various screen sizes:
<!-- Default responsive columns -->
<x-image-gallery :images="$images" />
<!-- Custom responsive configuration -->
<x-image-gallery
:images="$images"
:columns="[
'default' => 1,
'sm' => 2,
'md' => 4,
'lg' => 6,
'xl' => 8
]"
/>
<!-- Simple 3-column grid -->
<x-image-gallery
:images="$images"
:columns="['default' => 3]"
/>
Aspect Ratios
Control the aspect ratio of image containers:
<!-- Square format (default) -->
<x-image-gallery :images="$images" aspect-ratio="square" />
<!-- Landscape format -->
<x-image-gallery :images="$images" aspect-ratio="landscape" />
<!-- Portrait format -->
<x-image-gallery :images="$images" aspect-ratio="portrait" />
<!-- Auto height (maintains original proportions) -->
<x-image-gallery :images="$images" aspect-ratio="auto" />
Gap Control
Configure spacing between images:
<!-- Extra small gaps -->
<x-image-gallery :images="$images" gap="xs" />
<!-- Large gaps -->
<x-image-gallery :images="$images" gap="lg" />
<!-- Extra large gaps -->
<x-image-gallery :images="$images" gap="xl" />
Filtering System
Enable category-based filtering:
<x-image-gallery
:images="$images"
:filters="['nature', 'urban', 'architecture', 'people']"
/>
The filtering works with image objects that have category or tags properties:
$images = [
[
'url' => 'image1.jpg',
'category' => 'nature',
// ...
],
[
'url' => 'image2.jpg',
'tags' => ['urban', 'architecture'],
// ...
]
];
Pagination
Enable pagination for large image sets:
<!-- Show 12 images per page -->
<x-image-gallery
:images="$images"
:items-per-page="12"
/>
<!-- Show 24 images per page with spinner loading -->
<x-image-gallery
:images="$images"
:items-per-page="24"
loading-style="spinner"
/>
Captions
Display image captions with overlay:
<x-image-gallery
:images="$imagesWithCaptions"
:show-captions="true"
/>
Loading Styles
Choose from different loading animations:
<!-- Skeleton loading (default) -->
<x-image-gallery :images="$images" loading-style="skeleton" />
<!-- Spinner loading -->
<x-image-gallery :images="$images" loading-style="spinner" />
<!-- Fade loading -->
<x-image-gallery :images="$images" loading-style="fade" />
Disable Features
<!-- Disable lightbox -->
<x-image-gallery
:images="$images"
:enable-lightbox="false"
/>
<!-- Disable lazy loading -->
<x-image-gallery
:images="$images"
:lazy-load="false"
/>
Advanced Configuration
<!-- Fully customized gallery -->
<x-image-gallery
:images="$images"
id="product-gallery"
:columns="[
'default' => 1,
'sm' => 2,
'md' => 3,
'lg' => 4,
'xl' => 6
]"
aspect-ratio="landscape"
gap="lg"
:enable-lightbox="true"
:show-captions="true"
layout="grid"
:lazy-load="true"
:filters="$categories"
:items-per-page="20"
loading-style="skeleton"
class="rounded-lg shadow-lg"
/>
Image Object Structure
When using image objects, you can include rich metadata:
$images = [
[
'url' => 'https://example.com/image1.jpg', // Image URL (required)
'alt' => 'Alternative text', // Alt text for accessibility
'caption' => 'Image caption text', // Caption for overlay
'category' => 'nature', // Category for filtering
'tags' => ['landscape', 'mountains'], // Tags for filtering
'width' => 1200, // Image width (for lightbox)
'height' => 800, // Image height (for lightbox)
],
[
'src' => 'https://example.com/image2.jpg', // Alternative to 'url'
'alt' => 'Another image',
'caption' => 'Another caption',
'category' => 'urban',
'width' => 1600,
'height' => 900,
]
];
Masonry Layout
Enable masonry (Pinterest-style) layout:
<x-image-gallery
:images="$images"
layout="masonry"
aspect-ratio="auto"
:columns="[
'default' => 2,
'md' => 3,
'lg' => 4
]"
/>
Examples
Photo Portfolio
<x-image-gallery
:images="$portfolioImages"
:columns="[
'default' => 1,
'sm' => 2,
'lg' => 3
]"
aspect-ratio="landscape"
gap="lg"
:show-captions="true"
:enable-lightbox="true"
class="max-w-6xl mx-auto"
/>
Product Gallery with Filtering
<x-image-gallery
:images="$productImages"
:columns="[
'default' => 2,
'md' => 4,
'lg' => 6
]"
aspect-ratio="square"
gap="sm"
:filters="['front', 'back', 'side', 'detail']"
:items-per-page="24"
/>
Blog Image Grid
<x-image-gallery
:images="$blogImages"
:columns="[
'default' => 1,
'sm' => 2,
'md' => 3
]"
aspect-ratio="landscape"
:show-captions="true"
:lazy-load="true"
class="mb-8"
/>
Instagram-style Feed
<x-image-gallery
:images="$feedImages"
:columns="[
'default' => 3,
'md' => 3,
'lg' => 3
]"
aspect-ratio="square"
gap="xs"
:lazy-load="true"
:items-per-page="21"
/>
Performance Considerations
Lazy Loading
The component uses Intersection Observer for efficient lazy loading:
- First 12 images load immediately
- Remaining images load when they come into view
- 50px root margin for smooth loading experience
Optimization Tips
- Use appropriately sized images (recommended max width: 1200px for grid items)
- Consider WebP format for better compression
- Provide width/height in image objects for better layout stability
- Use consistent aspect ratios within the same gallery for better visual flow
PhotoSwipe Integration
The component includes PhotoSwipe lightbox integration with:
- Full-screen viewing
- Zoom and pan support
- Touch/swipe navigation
- Keyboard navigation (ESC, arrows)
- Image information display
Requirements
PhotoSwipe CSS and JavaScript must be included in your project:
<!-- Add to your layout -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@5.3.7/dist/photoswipe.css">
<script src="https://cdn.jsdelivr.net/npm/photoswipe@5.3.7/dist/photoswipe.esm.js"></script>
<script src="https://cdn.jsdelivr.net/npm/photoswipe@5.3.7/dist/photoswipe-lightbox.esm.js"></script>
Accessibility Features
The ImageGallery component follows WCAG 2.1 AA guidelines:
- Proper ARIA labels and semantic HTML structure
- Keyboard navigation support in lightbox
- Screen reader announcements for filtering and pagination
- Focus management and high contrast support
- Alternative text for all images
Styling and Customization
Custom CSS Classes
<x-image-gallery
:images="$images"
class="max-w-4xl mx-auto shadow-lg rounded-lg p-6"
/>
Dark Mode
The component fully supports dark mode with automatic theme detection:
- Dark mode loading states
- Dark mode filter buttons
- Dark mode pagination controls
Browser Support
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
- iOS Safari 12+
- Android Chrome 60+
Related Components
- ImageSlider - Carousel/slider for sequential image navigation
- ImageLibrary - Component for managing and selecting images
- File - File upload component for image uploads
- Modal - Modal dialogs for image viewing
Migration from Old ImageGallery
The old carousel-based ImageGallery has been replaced with this grid-based version. For carousel functionality, use the new ImageSlider component:
<!-- Old carousel-style ImageGallery -->
<x-image-gallery :images="$images" :with-arrows="true" />
<!-- New grid-based ImageGallery -->
<x-image-gallery :images="$images" />
<!-- For carousel/slider functionality -->
<x-image-slider :images="$images" :with-arrows="true" />
See the Migration Guide for detailed migration instructions.