react-perfect-gallery
v1.0.3
Published
๐ผ๏ธ Modern React image gallery component with touch gestures, infinite scrolling, zoom, and beautiful UI. Mobile-first design with TypeScript support.
Maintainers
Readme
๐ผ๏ธ React Perfect Gallery
A modern, lightweight, and beautiful image gallery React component with mobile-first gestures, infinite scrolling, zoom, and accessibility features. Built with TypeScript and optimized for performance.
โจ Features
- ๐ฑ Mobile-First Design - Optimized for touch devices with swipe gestures
- ๐ฏ Infinite Scrolling - Optional infinite loop through images
- ๐ Zoom Functionality - Mouse wheel zoom and pan support
- โจ๏ธ Keyboard Navigation - Arrow keys, Escape, and Tab support
- ๐จ Highly Customizable - Custom styles, classes, IDs, and components
- ๐ Responsive Design - Works perfectly on all screen sizes
- ๐ช Thumbnail Navigation - Interactive thumbnail strip with auto-scroll
- ๐ญ Loading States - Beautiful loading spinners for images
- โฟ Accessibility - ARIA labels, focus trapping, and screen reader support
- โก Performance - Image preloading and lazy loading optimization
๐ฆ Installation
npm install react-perfect-gallery๏ฟฝ Screenshots
Desktop View
Mobile View
import React, { useState } from 'react';
import { Gallery, GalleryImage } from 'react-perfect-gallery';
// if you use types use it, if not you can remove it
const images: GalleryImage[] = [
{
src: 'https://example.com/image1.jpg',
alt: 'Beautiful landscape',
thumbnail: 'https://example.com/thumb1.jpg'
},
// ... more images
];
function App() {
const [isOpen, setIsOpen] = useState(false);
const [currentIndex, setCurrentIndex] = useState(0);
const openGallery = (index: number) => {
setCurrentIndex(index);
setIsOpen(true);
};
const closeGallery = () => {
setIsOpen(false);
};
return (
<div>
<div className="thumbnail-grid">
{images.map((image, index) => (
<div
key={index}
className="thumbnail-item"
onClick={() => openGallery(index)}
>
<img
src={image.thumbnail}
alt={image.alt}
className="thumbnail-image"
/>
<div className="thumbnail-overlay">
<span className="view-icon">๐</span>
</div>
</div>
))}
</div>
<Gallery
images={images}
isOpen={isOpen}
initialIndex={currentIndex}
onClose={closeGallery}
enableZoom={true}
enableSwipe={true}
infiniteScroll={true}
showThumbnails={true}
/>
</div>
);
}
export default App;๐ Props
Basic Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| images | GalleryImage[] | Required | Array of image objects |
| isOpen | boolean | Required | Controls gallery visibility |
| onClose | () => void | Required | Called when gallery closes |
| initialIndex | number | 0 | Starting image index |
| className | string | '' | Additional CSS classes |
Feature Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| showThumbnails | boolean | true | Show/hide thumbnail strip |
| enableZoom | boolean | true | Enable mouse wheel zoom |
| enableSwipe | boolean | true | Enable touch swipe gestures |
| infiniteScroll | boolean | true | Loop infinitely through images |
| centerNavigation | boolean | true | Center navigation arrows |
Customization Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| customClasses | GalleryCustomClasses | {} | Override CSS classes |
| customIds | GalleryCustomIds | {} | Set custom element IDs |
| customStyles | GalleryCustomStyles | {} | Inline style overrides |
| customCloseButton | ReactNode | undefined | Custom close button |
| customPrevButton | ReactNode | undefined | Custom previous button |
| customNextButton | ReactNode | undefined | Custom next button |
| customCounter | (current, total) => ReactNode | undefined | Custom counter component |
| customThumbnail | (image, index, isActive) => ReactNode | undefined | Custom thumbnail component |
๐จ Customization Examples
Custom Classes and IDs
const customClasses = {
modal: 'my-custom-modal',
backdrop: 'my-dark-backdrop',
content: 'my-rounded-content',
close: 'my-red-close-btn',
nav: 'my-blue-nav-btns'
};
const customIds = {
modal: 'myImageGallery',
close: 'closeGalleryBtn',
image: 'mainGalleryImage'
};
<Gallery
images={images}
isOpen={isOpen}
onClose={handleClose}
customClasses={customClasses}
customIds={customIds}
/>Custom Styles
const customStyles = {
modal: {
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'
},
content: {
backgroundColor: 'rgba(255, 255, 255, 0.1)',
borderRadius: '20px',
border: '2px solid rgba(255, 255, 255, 0.2)'
},
close: {
backgroundColor: '#ff4757',
color: 'white',
borderRadius: '50%'
}
};
<Gallery
images={images}
isOpen={isOpen}
onClose={handleClose}
customStyles={customStyles}
/>Custom Components
const customCloseButton = (
<button className="my-custom-close" onClick={handleClose}>
Close Gallery โ
</button>
);
const customCounter = (current: number, total: number) => (
<div className="my-counter">
Image {current} of {total}
</div>
);
const customThumbnail = (image: GalleryImage, index: number, isActive: boolean) => (
<div className={`my-thumbnail ${isActive ? 'active' : ''}`}>
<img src={image.thumbnail} alt={image.alt} />
<span>{index + 1}</span>
</div>
);
<Gallery
images={images}
isOpen={isOpen}
onClose={handleClose}
customCloseButton={customCloseButton}
customCounter={customCounter}
customThumbnail={customThumbnail}
/>๐๏ธ Navigation Options
Infinite vs Bounded Scrolling
// Infinite scrolling (loops forever)
<Gallery infiniteScroll={true} />
// Bounded scrolling (stops at boundaries)
<Gallery infiniteScroll={false} />Navigation Positioning
// Centered navigation (arrows in middle)
<Gallery centerNavigation={true} />
// Edge navigation (arrows on sides)
<Gallery centerNavigation={false} />๐ฑ Mobile Usage
The gallery is optimized for mobile devices:
- Swipe Gestures: Swipe left/right to navigate, swipe down to close
- Touch Optimized: Large touch targets and smooth animations
- Responsive Design: Adapts to all screen sizes
- Performance: Optimized for mobile browsers
โจ๏ธ Keyboard Navigation
Escape: Close galleryArrow Left: Previous imageArrow Right: Next imageTab: Navigate through interactive elementsShift + Tab: Navigate backwards
๐ฏ TypeScript Support
Full TypeScript support with comprehensive type definitions:
import { GalleryImage, GalleryProps, GalleryCustomClasses } from 'react-images-gallery';
const images: GalleryImage[] = [
{
src: 'https://example.com/image.jpg',
alt: 'Description',
thumbnail: 'https://example.com/thumb.jpg'
}
];๐จ CSS Classes
Override default styles using these CSS classes:
.gallery-modal /* Main modal container */
.gallery-backdrop /* Background overlay */
.gallery-content /* Content container */
.gallery-close /* Close button */
.gallery-nav /* Navigation buttons */
.gallery-nav-prev /* Previous button */
.gallery-nav-next /* Next button */
.gallery-image-container /* Image container */
.gallery-image /* Main image */
.gallery-counter /* Image counter */
.gallery-thumbnails /* Thumbnail strip */
.gallery-thumbnail /* Individual thumbnail */
.gallery-thumbnail.active /* Active thumbnail */๐ง Advanced Usage
Disable Features
<Gallery
images={images}
isOpen={isOpen}
onClose={handleClose}
showThumbnails={false} // Hide thumbnails
enableZoom={false} // Disable zoom
enableSwipe={false} // Disable swipe
infiniteScroll={false} // Bounded scrolling
centerNavigation={false} // Edge navigation
/>Performance Tips
- Use optimized image sizes and formats
- Enable lazy loading for large galleries
- Consider disabling thumbnails for very large collections
- Use the
thumbnailprop for faster loading
๐ Examples
Basic Gallery
<Gallery
images={images}
isOpen={isOpen}
onClose={handleClose}
/>Full Customization
<Gallery
images={images}
isOpen={isOpen}
onClose={handleClose}
infiniteScroll={true}
centerNavigation={true}
showThumbnails={true}
enableZoom={true}
enableSwipe={true}
customStyles={{
modal: { background: 'rgba(0, 0, 0, 0.95)' },
content: { borderRadius: '20px' }
}}
customCounter={(current, total) => (
<span style={{ color: 'white' }}>
๐ธ {current} / {total}
</span>
)}
/>๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
GitHub: https://github.com/razan-aboushi/React-image-gallery
๐ License
MIT ยฉ Razan Aboushi
MIT License - see the LICENSE file for details.
๐ Acknowledgments
- Built with React and TypeScript
- Inspired by modern gallery designs
- Optimized for performance and accessibility
React Perfect Gallery - Modern, beautiful, and highly customizable image galleries for React applications.
