Skip to content

Commit 1ca227b

Browse files
authored
Merge pull request #8340 from primefaces/v11-gallery
New Component Gallery
2 parents ba78ce6 + 65df908 commit 1ca227b

68 files changed

Lines changed: 2873 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { useGalleryChangeEvent } from '@primereact/types/shared/gallery';
2+
import { Gallery } from 'primereact/gallery';
3+
import * as React from 'react';
4+
5+
const images = [
6+
'https://images.unsplash.com/photo-1759800805589-54b5fc10a52e?q=80&w=1285&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
7+
'https://images.unsplash.com/photo-1759559790290-a3c6fce1d55f?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
8+
'https://images.unsplash.com/photo-1755398104149-961fa827e015?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
9+
'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',
10+
'https://images.unsplash.com/photo-1757684945606-7644757a3eb9?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
11+
'https://images.unsplash.com/photo-1743701168206-bd617221b559?q=80&w=2614&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
12+
'https://images.unsplash.com/photo-1758944966741-fc79410be873?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
13+
'https://images.unsplash.com/photo-1758964112991-84be3393d9b1?q=80&w=2942&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'
14+
];
15+
16+
function BasicDemo() {
17+
const [activeIndex, setActiveIndex] = React.useState<number>(3);
18+
19+
return (
20+
<div className="mb-12">
21+
<Gallery className="w-full h-[600px] relative overflow-hidden" activeIndex={activeIndex} onActiveIndexChange={(e: useGalleryChangeEvent) => setActiveIndex(e.value ?? 0)}>
22+
<Gallery.Backdrop />
23+
<Gallery.Prev>
24+
<i className="pi pi-arrow-left"></i>
25+
</Gallery.Prev>
26+
<Gallery.Next>
27+
<i className="pi pi-arrow-right"></i>
28+
</Gallery.Next>
29+
<Gallery.Toolbar>
30+
<Gallery.ToolbarItem action="rotateLeft">
31+
<i className="pi pi-replay"></i>
32+
</Gallery.ToolbarItem>
33+
<Gallery.ToolbarItem action="rotateRight">
34+
<i className="pi pi-refresh"></i>
35+
</Gallery.ToolbarItem>
36+
<Gallery.ToolbarItem action="zoomIn">
37+
<i className="pi pi-search-plus"></i>
38+
</Gallery.ToolbarItem>
39+
<Gallery.ToolbarItem action="flipX">
40+
<i className="pi pi-arrows-h"></i>
41+
</Gallery.ToolbarItem>
42+
<Gallery.ToolbarItem action="flipY">
43+
<i className="pi pi-arrows-v"></i>
44+
</Gallery.ToolbarItem>
45+
<Gallery.ToolbarItem action="download">
46+
<i className="pi pi-download"></i>
47+
</Gallery.ToolbarItem>
48+
<Gallery.ToolbarItem action="toggleFullScreen">{() => <i className="pi pi-arrow-up-right-and-arrow-down-left-from-center"></i>}</Gallery.ToolbarItem>
49+
</Gallery.Toolbar>
50+
<Gallery.Content>
51+
{images.map((image) => (
52+
<Gallery.Item key={image}>
53+
<img src={image} alt="image" />
54+
</Gallery.Item>
55+
))}
56+
</Gallery.Content>
57+
<Gallery.Thumbnail align="center" slide={activeIndex} spacing={2} loop>
58+
<Gallery.ThumbnailContent className="h-16">
59+
{images.map((image, index) => (
60+
<Gallery.ThumbnailItem
61+
key={index}
62+
size={20}
63+
onClick={(e: React.MouseEvent) => {
64+
e.preventDefault();
65+
setActiveIndex(index);
66+
}}
67+
>
68+
<div className={`h-full w-full border-2 rounded-md overflow-hidden ${activeIndex === index ? 'border-orange-500' : 'border-transparent'}`}>
69+
<img draggable={false} src={image} className="h-full w-full object-cover hover:opacity-75 transition-opacity"></img>
70+
</div>
71+
</Gallery.ThumbnailItem>
72+
))}
73+
</Gallery.ThumbnailContent>
74+
</Gallery.Thumbnail>
75+
</Gallery>
76+
</div>
77+
);
78+
}
79+
80+
export default BasicDemo;
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { usePresence } from '@primereact/hooks';
2+
import { useGalleryChangeEvent } from '@primereact/types/shared/gallery';
3+
import { Gallery } from 'primereact/gallery';
4+
import { Portal } from 'primereact/portal';
5+
import * as React from 'react';
6+
7+
const images = [
8+
'https://images.unsplash.com/photo-1759800805589-54b5fc10a52e?q=80&w=1285&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
9+
'https://images.unsplash.com/photo-1759559790290-a3c6fce1d55f?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
10+
'https://images.unsplash.com/photo-1755398104149-961fa827e015?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
11+
'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',
12+
'https://images.unsplash.com/photo-1757684945606-7644757a3eb9?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
13+
'https://images.unsplash.com/photo-1743701168206-bd617221b559?q=80&w=2614&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
14+
'https://images.unsplash.com/photo-1758944966741-fc79410be873?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
15+
'https://images.unsplash.com/photo-1758964112991-84be3393d9b1?q=80&w=2942&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'
16+
];
17+
18+
function BasicDemo() {
19+
const [activeIndex, setActiveIndex] = React.useState<number>(3);
20+
const [open, setOpen] = React.useState<boolean>(false);
21+
22+
const { present, exiting, mounted, ref } = usePresence(open);
23+
24+
const handleOpen = (index: number) => {
25+
setOpen(true);
26+
setActiveIndex(index);
27+
};
28+
29+
const isVisible = present && mounted && !exiting;
30+
31+
return (
32+
<div className="card">
33+
<div className="grid grid-cols-4 gap-4">
34+
{images.map((image, index) => (
35+
<div key={image} className="h-[300px] hover:opacity-75 transition-opacity" onClick={() => handleOpen(index)}>
36+
<img src={image} alt="image" className="w-full h-full object-cover rounded-lg" />
37+
</div>
38+
))}
39+
</div>
40+
<Portal>
41+
{present && (
42+
<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`}>
43+
<Gallery className="w-full h-full" activeIndex={activeIndex} onActiveIndexChange={(e: useGalleryChangeEvent) => setActiveIndex(e.value ?? 0)}>
44+
<Gallery.Backdrop />
45+
<Gallery.Prev>
46+
<i className="pi pi-arrow-left"></i>
47+
</Gallery.Prev>
48+
<Gallery.Next>
49+
<i className="pi pi-arrow-right"></i>
50+
</Gallery.Next>
51+
<Gallery.Toolbar>
52+
<Gallery.ToolbarItem action="rotateLeft">
53+
<i className="pi pi-replay"></i>
54+
</Gallery.ToolbarItem>
55+
<Gallery.ToolbarItem action="rotateRight">
56+
<i className="pi pi-refresh"></i>
57+
</Gallery.ToolbarItem>
58+
<Gallery.ToolbarItem action="zoomIn">
59+
<i className="pi pi-search-plus"></i>
60+
</Gallery.ToolbarItem>
61+
<Gallery.ToolbarItem action="flipX">
62+
<i className="pi pi-arrows-h"></i>
63+
</Gallery.ToolbarItem>
64+
<Gallery.ToolbarItem action="flipY">
65+
<i className="pi pi-arrows-v"></i>
66+
</Gallery.ToolbarItem>
67+
<Gallery.ToolbarItem action="download">
68+
<i className="pi pi-download"></i>
69+
</Gallery.ToolbarItem>
70+
<Gallery.ToolbarItem onClick={() => setOpen(false)}>
71+
<i className="pi pi-times"></i>
72+
</Gallery.ToolbarItem>
73+
</Gallery.Toolbar>
74+
<Gallery.Content>
75+
{images.map((image) => (
76+
<Gallery.Item key={image}>
77+
<img src={image} alt="image" className={`${isVisible ? 'scale-100 blur-none' : 'scale-[0.9] blur-2xl'} transition-[scale,filter] duration-300`} />
78+
</Gallery.Item>
79+
))}
80+
</Gallery.Content>
81+
<Gallery.Thumbnail align="center" slide={activeIndex} spacing={2} loop>
82+
<Gallery.ThumbnailContent className="h-16">
83+
{images.map((image, index) => (
84+
<Gallery.ThumbnailItem
85+
key={index}
86+
size={20}
87+
onClick={(e: React.MouseEvent) => {
88+
e.preventDefault();
89+
setActiveIndex(index);
90+
}}
91+
>
92+
<div className={`h-full w-full border-2 rounded-md overflow-hidden ${activeIndex === index ? 'border-orange-500' : 'border-transparent'}`}>
93+
<img draggable={false} src={image} className="h-full w-full object-cover hover:opacity-75 transition-opacity"></img>
94+
</div>
95+
</Gallery.ThumbnailItem>
96+
))}
97+
</Gallery.ThumbnailContent>
98+
</Gallery.Thumbnail>
99+
</Gallery>
100+
</div>
101+
)}
102+
</Portal>
103+
</div>
104+
);
105+
}
106+
107+
export default BasicDemo;
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
---
2+
title: Gallery API
3+
description: API documentation for Gallery component
4+
component: gallery
5+
---
6+
7+
## Gallery
8+
9+
### Props
10+
11+
<DocTable name="Gallery" category="api" type="props" />
12+
13+
### Interfaces
14+
15+
<DocTable name="Gallery" category="api" type="interfaces" />
16+
17+
### Types
18+
19+
<DocTable name="Gallery" category="api" type="types" />
20+
21+
## GalleryBackdrop
22+
23+
### Props
24+
25+
<DocTable name="GalleryBackdrop" category="api" type="props" />
26+
27+
### Interfaces
28+
29+
<DocTable name="GalleryBackdrop" category="api" type="interfaces" />
30+
31+
### Types
32+
33+
<DocTable name="GalleryBackdrop" category="api" type="types" />
34+
35+
## GalleryContent
36+
37+
### Props
38+
39+
<DocTable name="GalleryContent" category="api" type="props" />
40+
41+
### Interfaces
42+
43+
<DocTable name="GalleryContent" category="api" type="interfaces" />
44+
45+
### Types
46+
47+
<DocTable name="GalleryContent" category="api" type="types" />
48+
49+
## GalleryItem
50+
51+
### Props
52+
53+
<DocTable name="GalleryItem" category="api" type="props" />
54+
55+
### Interfaces
56+
57+
<DocTable name="GalleryItem" category="api" type="interfaces" />
58+
59+
### Types
60+
61+
<DocTable name="GalleryItem" category="api" type="types" />
62+
63+
## GalleryNext
64+
65+
### Props
66+
67+
<DocTable name="GalleryNext" category="api" type="props" />
68+
69+
### Interfaces
70+
71+
<DocTable name="GalleryNext" category="api" type="interfaces" />
72+
73+
### Types
74+
75+
<DocTable name="GalleryNext" category="api" type="types" />
76+
77+
## GalleryPrev
78+
79+
### Props
80+
81+
<DocTable name="GalleryPrev" category="api" type="props" />
82+
83+
### Interfaces
84+
85+
<DocTable name="GalleryPrev" category="api" type="interfaces" />
86+
87+
### Types
88+
89+
<DocTable name="GalleryPrev" category="api" type="types" />
90+
91+
## GalleryToolbar
92+
93+
### Props
94+
95+
<DocTable name="GalleryToolbar" category="api" type="props" />
96+
97+
### Interfaces
98+
99+
<DocTable name="GalleryToolbar" category="api" type="interfaces" />
100+
101+
### Types
102+
103+
<DocTable name="GalleryToolbar" category="api" type="types" />
104+
105+
## GalleryToolbarItem
106+
107+
### Props
108+
109+
<DocTable name="GalleryToolbarItem" category="api" type="props" />
110+
111+
### Interfaces
112+
113+
<DocTable name="GalleryToolbarItem" category="api" type="interfaces" />
114+
115+
### Types
116+
117+
<DocTable name="GalleryToolbarItem" category="api" type="types" />
118+
119+
## GalleryThumbnail
120+
121+
### Props
122+
123+
<DocTable name="GalleryThumbnail" category="api" type="props" />
124+
125+
### Interfaces
126+
127+
<DocTable name="GalleryThumbnail" category="api" type="interfaces" />
128+
129+
### Types
130+
131+
<DocTable name="GalleryThumbnail" category="api" type="types" />
132+
133+
## GalleryThumbnailContent
134+
135+
### Props
136+
137+
<DocTable name="GalleryThumbnailContent" category="api" type="props" />
138+
139+
### Interfaces
140+
141+
<DocTable name="GalleryThumbnailContent" category="api" type="interfaces" />
142+
143+
### Types
144+
145+
<DocTable name="GalleryThumbnailContent" category="api" type="types" />
146+
147+
## GalleryThumbnailItem
148+
149+
### Props
150+
151+
<DocTable name="GalleryThumbnailItem" category="api" type="props" />
152+
153+
### Interfaces
154+
155+
<DocTable name="GalleryThumbnailItem" category="api" type="interfaces" />
156+
157+
### Types
158+
159+
<DocTable name="GalleryThumbnailItem" category="api" type="types" />
160+
161+
## useGallery
162+
163+
### Types
164+
165+
<DocTable name="useGallery" category="api" type="types" />
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
title: Gallery
3+
description: Gallery is a component to display a collection of images in a gallery.
4+
component: gallery
5+
---
6+
7+
## Usage
8+
9+
```tsx
10+
import { Gallery } from 'primereact/gallery';
11+
```
12+
13+
```tsx
14+
<Gallery>
15+
<Gallery.Backdrop />
16+
<Gallery.Prev></Gallery.Prev>
17+
<Gallery.Next></Gallery.Next>
18+
<Gallery.Toolbar>
19+
<Gallery.ToolbarItem action=""></Gallery.ToolbarItem>
20+
</Gallery.Toolbar>
21+
<Gallery.Content>
22+
<Gallery.Item>
23+
<img />
24+
</Gallery.Item>
25+
</Gallery.Content>
26+
<Gallery.Thumbnail>
27+
<Gallery.ThumbnailContent>
28+
<Gallery.ThumbnailItem></Gallery.ThumbnailItem>
29+
</Gallery.ThumbnailContent>
30+
</Gallery.Thumbnail>
31+
</Gallery>
32+
```
33+
34+
## Examples
35+
36+
### Basic
37+
38+
<DocDemoViewer name="gallery:basic-demo" />
39+
40+
### Grid
41+
42+
<DocDemoViewer name="gallery:grid-demo" />

0 commit comments

Comments
 (0)