Lightbox
The following lightbox component is used for displaying images in a modal, and has good accessibility with keyboard. You have to pass in an array of images and set state variables to use it. You can customize it very easily via Tailwind and it’s also a single component. An example of usage is:
No extra libraries required. Assuming you have Tailwind CSS installed
// App.jsximport React, { useState } from 'react';import Lightbox from './components/lightbox';
const App = () => { const [isOpen, setIsOpen] = useState(false); const [currentIndex, setCurrentIndex] = useState(0);
const images = [ 'https://via.placeholder.com/900x600/1', 'https://via.placeholder.com/800x600/2', 'https://via.placeholder.com/800x600/3', ];
const openLightbox = (index) => { setCurrentIndex(index); setIsOpen(true); };
return ( <div className="p-4"> <h1 className="text-xl mb-4">Lightbox Component Example</h1> <div className="grid grid-cols-3 gap-4"> {images.map((src, index) => ( <img key={index} src={src} alt={`Thumbnail ${index + 1}`} className="cursor-pointer rounded-lg hover:shadow-lg" onClick={() => openLightbox(index)} /> ))} </div> <Lightbox isOpen={isOpen} onClose={() => setIsOpen(false)} images={images} currentIndex={currentIndex} setCurrentIndex={setCurrentIndex} /> </div> );};
export default App;
// Lightbox.jsximport React, { useEffect } from 'react';
const Lightbox = ({ isOpen, onClose, images, currentIndex, setCurrentIndex }) => { if (!isOpen || !images.length) return null;
const handleKeyDown = (e) => { if (e.key === 'Escape') { onClose(); } };
const handleNext = () => { if (currentIndex < images.length - 1) { setCurrentIndex((prevIndex) => prevIndex + 1); } };
const handlePrev = () => { if (currentIndex > 0) { setCurrentIndex((prevIndex) => prevIndex - 1); } };
useEffect(() => { document.addEventListener('keydown', handleKeyDown); return () => { document.removeEventListener('keydown', handleKeyDown); }; }, []);
return ( <div className="fixed inset-0 z-50 bg-black bg-opacity-75 flex justify-center items-center"> <div className="relative"> <button className="absolute top-2 right-2 text-white text-2xl" onClick={onClose} > × </button> <button className="absolute left-2 top-1/2 transform -translate-y-1/2 text-white text-2xl" onClick={handlePrev} disabled={currentIndex === 0} > < </button> <button className="absolute right-2 top-1/2 transform -translate-y-1/2 text-white text-2xl" onClick={handleNext} disabled={currentIndex === images.length - 1} > > </button> <img src={images[currentIndex]} alt="" className="max-w-full max-h-screen" /> </div> </div> );};
export default Lightbox;