Gallery

Gallery is a component to display a collection of images in a gallery.

Usage#

import { Gallery } from 'primereact/gallery';
<Gallery>
    <Gallery.Backdrop />
    <Gallery.Prev></Gallery.Prev>
    <Gallery.Next></Gallery.Next>
    <Gallery.Toolbar>
        <Gallery.ToolbarItem action=""></Gallery.ToolbarItem>
    </Gallery.Toolbar>
    <Gallery.Content>
        <Gallery.Item>
            <img />
        </Gallery.Item>
    </Gallery.Content>
    <Gallery.Thumbnail>
        <Gallery.ThumbnailContent>
            <Gallery.ThumbnailItem></Gallery.ThumbnailItem>
        </Gallery.ThumbnailContent>
    </Gallery.Thumbnail>
</Gallery>

Examples#

Basic#

basic-demo.tsx
'use client';

import { useGalleryChangeEvent } from '@primereact/types/shared/gallery';
import { Gallery } from 'primereact/gallery';
import * as React from 'react';

const images = [
    'https://images.unsplash.com/photo-1759800805589-54b5fc10a52e?q=80&w=1285&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
    'https://images.unsplash.com/photo-1759559790290-a3c6fce1d55f?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
    'https://images.unsplash.com/photo-1755398104149-961fa827e015?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
    'https://plus.unsplash.com/premium_photo-1722944969391-1d21a2d404ea?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
    'https://images.unsplash.com/photo-1757684945606-7644757a3eb9?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
    'https://images.unsplash.com/photo-1743701168206-bd617221b559?q=80&w=2614&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
    'https://images.unsplash.com/photo-1758944966741-fc79410be873?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
    'https://images.unsplash.com/photo-1758964112991-84be3393d9b1?q=80&w=2942&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'
];

function BasicDemo() {
    const [activeIndex, setActiveIndex] = React.useState<number>(3);

    return (
        <div className="mb-12">
            <Gallery
                className="w-full h-[600px] relative overflow-hidden"
                activeIndex={activeIndex}
                onActiveIndexChange={(e: useGalleryChangeEvent) => setActiveIndex(e.value ?? 0)}
            >
                <Gallery.Backdrop />
                <Gallery.Prev>
                    <i className="pi pi-arrow-left"></i>
                </Gallery.Prev>
                <Gallery.Next>
                    <i className="pi pi-arrow-right"></i>
                </Gallery.Next>
                <Gallery.Toolbar>
                    <Gallery.ToolbarItem action="rotateLeft">
                        <i className="pi pi-replay"></i>
                    </Gallery.ToolbarItem>
                    <Gallery.ToolbarItem action="rotateRight">
                        <i className="pi pi-refresh"></i>
                    </Gallery.ToolbarItem>
                    <Gallery.ToolbarItem action="zoomIn">
                        <i className="pi pi-search-plus"></i>
                    </Gallery.ToolbarItem>
                    <Gallery.ToolbarItem action="flipX">
                        <i className="pi pi-arrows-h"></i>
                    </Gallery.ToolbarItem>
                    <Gallery.ToolbarItem action="flipY">
                        <i className="pi pi-arrows-v"></i>
                    </Gallery.ToolbarItem>
                    <Gallery.ToolbarItem action="download">
                        <i className="pi pi-download"></i>
                    </Gallery.ToolbarItem>
                    <Gallery.ToolbarItem action="toggleFullScreen">
                        {() => <i className="pi pi-arrow-up-right-and-arrow-down-left-from-center"></i>}
                    </Gallery.ToolbarItem>
                </Gallery.Toolbar>
                <Gallery.Content>
                    {images.map((image) => (
                        <Gallery.Item key={image}>
                            <img src={image} alt="image" />
                        </Gallery.Item>
                    ))}
                </Gallery.Content>
                <Gallery.Thumbnail align="center" slide={activeIndex} spacing={2} loop slidesPerPage={4}>
                    <Gallery.ThumbnailContent className="h-24">
                        {images.map((image, index) => (
                            <Gallery.ThumbnailItem
                                key={index}
                                onClick={() => setActiveIndex(index)}
                                className={`border-2 rounded-md overflow-hidden ${activeIndex === index ? 'border-orange-500' : 'border-transparent'}`}
                            >
                                <img draggable={false} src={image} className="h-full w-full object-cover hover:opacity-75 transition-opacity" />
                            </Gallery.ThumbnailItem>
                        ))}
                    </Gallery.ThumbnailContent>
                </Gallery.Thumbnail>
            </Gallery>
        </div>
    );
}

export default BasicDemo;

Grid#

image
image
image
image
image
image
image
image
grid-demo.tsx
'use client';

import { usePresence } from '@primereact/hooks';
import { useGalleryChangeEvent } from '@primereact/types/shared/gallery';
import { Gallery } from 'primereact/gallery';
import { Portal } from 'primereact/portal';
import * as React from 'react';

const images = [
    'https://images.unsplash.com/photo-1759800805589-54b5fc10a52e?q=80&w=1285&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
    'https://images.unsplash.com/photo-1759559790290-a3c6fce1d55f?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
    'https://images.unsplash.com/photo-1755398104149-961fa827e015?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
    'https://plus.unsplash.com/premium_photo-1722944969391-1d21a2d404ea?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
    'https://images.unsplash.com/photo-1757684945606-7644757a3eb9?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
    'https://images.unsplash.com/photo-1743701168206-bd617221b559?q=80&w=2614&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
    'https://images.unsplash.com/photo-1758944966741-fc79410be873?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
    'https://images.unsplash.com/photo-1758964112991-84be3393d9b1?q=80&w=2942&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'
];

function BasicDemo() {
    const [activeIndex, setActiveIndex] = React.useState<number>(3);
    const [open, setOpen] = React.useState<boolean>(false);

    const { present, exiting, mounted, ref } = usePresence(open);

    const handleOpen = (index: number) => {
        setOpen(true);
        setActiveIndex(index);
    };

    const isVisible = present && mounted && !exiting;

    return (
        <div>
            <div className="grid grid-cols-4 gap-4">
                {images.map((image, index) => (
                    <div key={image} className="h-[300px] hover:opacity-75 transition-opacity" onClick={() => handleOpen(index)}>
                        <img src={image} alt="image" className="w-full h-full object-cover rounded-lg" />
                    </div>
                ))}
            </div>
            <Portal>
                {present && (
                    <div
                        ref={ref as React.RefObject<HTMLDivElement>}
                        className={`w-full h-[100dvh] top-0 left-0 !fixed z-[100000] ${isVisible ? 'opacity-100' : 'opacity-0'} transition-opacity duration-200`}
                    >
                        <Gallery
                            className="w-full h-full"
                            activeIndex={activeIndex}
                            onActiveIndexChange={(e: useGalleryChangeEvent) => setActiveIndex(e.value ?? 0)}
                        >
                            <Gallery.Backdrop />
                            <Gallery.Prev>
                                <i className="pi pi-arrow-left"></i>
                            </Gallery.Prev>
                            <Gallery.Next>
                                <i className="pi pi-arrow-right"></i>
                            </Gallery.Next>
                            <Gallery.Toolbar>
                                <Gallery.ToolbarItem action="rotateLeft">
                                    <i className="pi pi-replay"></i>
                                </Gallery.ToolbarItem>
                                <Gallery.ToolbarItem action="rotateRight">
                                    <i className="pi pi-refresh"></i>
                                </Gallery.ToolbarItem>
                                <Gallery.ToolbarItem action="zoomIn">
                                    <i className="pi pi-search-plus"></i>
                                </Gallery.ToolbarItem>
                                <Gallery.ToolbarItem action="flipX">
                                    <i className="pi pi-arrows-h"></i>
                                </Gallery.ToolbarItem>
                                <Gallery.ToolbarItem action="flipY">
                                    <i className="pi pi-arrows-v"></i>
                                </Gallery.ToolbarItem>
                                <Gallery.ToolbarItem action="download">
                                    <i className="pi pi-download"></i>
                                </Gallery.ToolbarItem>
                                <Gallery.ToolbarItem onClick={() => setOpen(false)}>
                                    <i className="pi pi-times"></i>
                                </Gallery.ToolbarItem>
                            </Gallery.Toolbar>
                            <Gallery.Content>
                                {images.map((image) => (
                                    <Gallery.Item key={image}>
                                        <img
                                            src={image}
                                            alt="image"
                                            className={`${isVisible ? 'scale-100 blur-none' : 'scale-[0.9] blur-2xl'}  transition-[scale,filter] duration-300`}
                                        />
                                    </Gallery.Item>
                                ))}
                            </Gallery.Content>
                            <Gallery.Thumbnail align="center" slide={activeIndex} spacing={2} loop slidesPerPage={4}>
                                <Gallery.ThumbnailContent className="h-24">
                                    {images.map((image, index) => (
                                        <Gallery.ThumbnailItem
                                            key={index}
                                            onClick={() => setActiveIndex(index)}
                                            className={`border-2 rounded-md overflow-hidden ${activeIndex === index ? 'border-orange-500' : 'border-transparent'}`}
                                        >
                                            <img
                                                draggable={false}
                                                src={image}
                                                className="h-full w-full object-cover hover:opacity-75 transition-opacity"
                                            />
                                        </Gallery.ThumbnailItem>
                                    ))}
                                </Gallery.ThumbnailContent>
                            </Gallery.Thumbnail>
                        </Gallery>
                    </div>
                )}
            </Portal>
        </div>
    );
}

export default BasicDemo;