react-pic-gallery 1.5.16 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,105 +1,204 @@
1
- # react-pic-gallery
2
-
3
- >
4
-
5
- [![NPM](https://img.shields.io/npm/v/react-pic-gallery.svg)](https://www.npmjs.com/package/react-pic-gallery)
6
-
7
- React library for a simple image gallery with lightbox implemented.
8
-
9
- ## Features
10
-
11
- - 📱 Responsive
12
- - 🚵 Lazy load on pictures
13
- - ✏ Buttons and CSS customization classes are accessible
14
- - 💡 Lightbox implemented with pinch zoom by [react-zoom-pan-pinch](https://www.npmjs.com/package/react-zoom-pan-pinch)
15
-
16
- ## Demo
17
-
18
- https://marcelrsoub.github.io/react-pic-gallery/
19
-
20
- ![demo gif](https://i.imgur.com/qMhra73.gif)
21
-
22
- ## Install
23
-
24
- ```bash
25
- npm install --save react-pic-gallery
26
- ```
27
-
28
- or with yarn:
29
-
30
- ```bash
31
- yarn add react-pic-gallery
32
- ```
33
-
34
- ## Usage
35
-
36
- A list of objects containing a thumbnail source and the full source is the only needed parameter.
37
-
38
- ```jsx
39
- import React from 'react'
40
- import PicGallery from 'react-pic-gallery'
41
-
42
- const listOfImages = [
43
- {
44
- thumbnailSrc: 'https://picsum.photos/id/237/200/300',
45
- fullSrc: 'https://picsum.photos/id/237/800/600'
46
- },
47
- {
48
- thumbnailSrc: 'https://picsum.photos/id/154/200/150',
49
- fullSrc: 'https://picsum.photos/id/154/200/150'
50
- }
51
- ]
52
-
53
- const App = () => {
54
- return (
55
- <div>
56
- <PicGallery imgList={listOfImages} />
57
- </div>
58
- )
59
- }
60
-
61
- export default App
62
- ```
63
-
64
- ## Options
65
-
66
- The options interface can be imported from the library and the object can be passed in the main component:
67
-
68
- ```tsx
69
- import React from 'react'
70
- import PicGallery from 'react-pic-gallery'
71
-
72
- const listOfImages = [
73
- {
74
- thumbnailSrc: 'https://picsum.photos/id/237/200/300',
75
- fullSrc: 'https://picsum.photos/id/237/800/600',
76
- description: 'A Dog standing on a wooden floor'
77
- },
78
- {
79
- thumbnailSrc: 'https://picsum.photos/id/154/200/150',
80
- fullSrc: 'https://picsum.photos/id/154/200/150'
81
- }
82
- ]
83
-
84
- const options = {
85
- // customLoadComponent: () => <h3>Loading</h3>,
86
- // hidePagination: false,
87
- // externalLightbox: true,
88
- // rowHeight: '100px',
89
- // picsPerRow:3
90
- }
91
-
92
- const App = () => {
93
- return (
94
- <div>
95
- <PicGallery imgList={listOfImages} options={options} />
96
- </div>
97
- )
98
- }
99
-
100
- export default App
101
- ```
102
-
103
- ## License
104
-
105
- MIT © [marcelrsoub](https://github.com/marcelrsoub)
1
+ # react-pic-gallery
2
+
3
+ Small, accessible React image gallery and lightbox with a polished default UI and typed escape hatches for custom controls.
4
+
5
+ [![NPM](https://img.shields.io/npm/v/react-pic-gallery.svg)](https://www.npmjs.com/package/react-pic-gallery)
6
+
7
+ [Live playground and docs](https://marcelrsoub.github.io/react-pic-gallery/)
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install react-pic-gallery
13
+ ```
14
+
15
+ ```bash
16
+ pnpm add react-pic-gallery
17
+ yarn add react-pic-gallery
18
+ bun add react-pic-gallery
19
+ ```
20
+
21
+ React 18.3+ and React 19 are supported. The [Quick start docs](https://marcelrsoub.github.io/react-pic-gallery/docs/getting-started/) provide these commands in a package-manager switcher.
22
+
23
+ The package is intentionally lightweight: it has no runtime dependencies, React is a peer dependency, and the built JavaScript and CSS together are roughly 6 KB gzipped.
24
+
25
+ ## Quick start
26
+
27
+ ```tsx
28
+ import { PicGallery } from 'react-pic-gallery'
29
+ import 'react-pic-gallery/styles.css'
30
+
31
+ const images = [
32
+ {
33
+ src: 'https://example.com/photo-large.jpg',
34
+ thumbnailSrc: 'https://example.com/photo-thumb.jpg',
35
+ alt: 'A mountain reflected in a lake',
36
+ caption: 'Morning at the lake'
37
+ }
38
+ ]
39
+
40
+ export function App() {
41
+ return <PicGallery images={images} />
42
+ }
43
+ ```
44
+
45
+ `src` and `alt` are required. `id`, `thumbnailSrc`, `caption`, `width`, and `height` are optional. Image objects can include application-specific fields; those fields remain available in renderer callbacks when using TypeScript generics.
46
+
47
+ ## Custom UI
48
+
49
+ Add actions without rebuilding the lightbox:
50
+
51
+ ```tsx
52
+ <PicGallery
53
+ images={images}
54
+ renderActions={({ image }) => (
55
+ <button type='button' onClick={() => saveImage(image)}>
56
+ Save
57
+ </button>
58
+ )}
59
+ />
60
+ ```
61
+
62
+ Every renderer receives:
63
+
64
+ ```ts
65
+ {
66
+ image,
67
+ index,
68
+ count,
69
+ close,
70
+ next,
71
+ previous,
72
+ canGoNext,
73
+ canGoPrevious
74
+ }
75
+ ```
76
+
77
+ Use `renderCaption` to replace the caption, or `renderControls` to replace the complete default control layer. When `renderControls` is provided, your controls are responsible for rendering close and navigation actions.
78
+
79
+ ## Standalone components
80
+
81
+ Use the thumbnail grid and lightbox separately when your application owns selection state:
82
+
83
+ ```tsx
84
+ import { useState } from 'react'
85
+ import { Gallery, Lightbox } from 'react-pic-gallery'
86
+
87
+ export function CustomViewer({ images }) {
88
+ const [index, setIndex] = useState<number | null>(null)
89
+
90
+ return (
91
+ <>
92
+ <Gallery images={images} onImageClick={setIndex} />
93
+ <Lightbox images={images} index={index} onIndexChange={setIndex} />
94
+ </>
95
+ )
96
+ }
97
+ ```
98
+
99
+ ## Lightbox behavior
100
+
101
+ The lightbox uses the native modal `<dialog>` element and includes:
102
+
103
+ - Keyboard navigation, Escape-to-close, focus containment, and focus restoration.
104
+ - Backdrop closing with stable page width while scrolling is locked.
105
+ - Native lazy loading for thumbnails and explicit image loading/error states.
106
+ - Horizontal swipe navigation on touch devices.
107
+ - Pinch zoom up to 3x with one-finger panning while zoomed.
108
+ - Reduced-motion support, safe-area padding, rounded image surfaces, and animated transitions.
109
+
110
+ Native modal behavior targets modern browsers: Chrome 37+, Edge 79+, Firefox 98+, and Safari/iOS 15.4+. The package does not ship a dialog polyfill.
111
+
112
+ ## Styling
113
+
114
+ The stylesheet uses namespaced classes and CSS variables. Import it once, then override variables globally or on the lightbox class:
115
+
116
+ ```css
117
+ :root,
118
+ .react-pic-gallery__lightbox {
119
+ --gallery-accent: #ff7a59;
120
+ --gallery-overlay: rgba(10, 10, 14, 0.98);
121
+ --gallery-control-size: 3rem;
122
+ --gallery-motion: 240ms;
123
+ }
124
+ ```
125
+
126
+ The default gallery uses three columns. Pass `columns` for a different fixed count; `rowHeight` accepts CSS height values or numeric pixels.
127
+
128
+ ## API
129
+
130
+ ### `PicGallery`
131
+
132
+ | Prop | Type | Description |
133
+ | --- | --- | --- |
134
+ | `images` | `readonly GalleryImage[]` | Images to display. |
135
+ | `columns` | `number` | Optional fixed column count. The default is three columns. |
136
+ | `rowHeight` | `CSSProperties['height']` | Thumbnail height. |
137
+ | `renderActions` | `LightboxRenderer` | Adds controls to the default toolbar. |
138
+ | `renderCaption` | `LightboxRenderer` | Replaces the current caption. |
139
+ | `renderControls` | `LightboxRenderer` | Replaces the complete default control layer. |
140
+ | `showCounter` | `boolean` | Shows the current image count. Defaults to `true`. |
141
+ | `showNavigation` | `boolean` | Shows previous/next controls. Defaults to `true`. |
142
+
143
+ `Gallery` accepts `images`, `onImageClick`, `columns`, `rowHeight`, `className`, and `style`.
144
+
145
+ `Lightbox` accepts `images`, controlled `index`, `onIndexChange`, the renderer props, `showCounter`, `showNavigation`, and `className`.
146
+
147
+ ## Migrating from v1
148
+
149
+ v2 intentionally removes the old configuration and external lightbox workaround.
150
+
151
+ | v1 | v2 |
152
+ | --- | --- |
153
+ | `imgList` | `images` |
154
+ | `fullSrc` | `src` |
155
+ | `thumbnailSrc` | `thumbnailSrc` |
156
+ | `description` | `caption` |
157
+ | default import | named `PicGallery` import (default import remains available) |
158
+ | `options.picsPerRow` | `columns` |
159
+ | `options.rowHeight` | `rowHeight` |
160
+ | `topCustomContent` / `bottomCustomContent` | `renderActions`, `renderCaption`, or `renderControls` |
161
+ | `externalLightbox` / `setExtLightboxChildren` | controlled `Lightbox` |
162
+ | `customLoadComponent` | CSS overrides or your own `Gallery` composition |
163
+ | `react-zoom-pan-pinch` | removed dependency; native lightbox pinch zoom |
164
+
165
+ Before:
166
+
167
+ ```tsx
168
+ <PicGallery
169
+ imgList={[{ fullSrc, thumbnailSrc }]}
170
+ options={{ picsPerRow: 4 }}
171
+ />
172
+ ```
173
+
174
+ After:
175
+
176
+ ```tsx
177
+ <PicGallery
178
+ images={[{ src: fullSrc, thumbnailSrc, alt: 'Description' }]}
179
+ columns={4}
180
+ />
181
+ ```
182
+
183
+ The package is ESM-only in v2. Import `styles.css` explicitly in applications that do not automatically process CSS imported by JavaScript.
184
+
185
+ ## Development
186
+
187
+ Node 22.12+ is required for the Astro documentation workflow.
188
+
189
+ ```bash
190
+ npm install
191
+ npm run dev
192
+ npm run dev:library
193
+ npm test
194
+ npm run typecheck
195
+ npm run build
196
+ npm run build:docs
197
+ npm pack --dry-run
198
+ ```
199
+
200
+ `npm run dev` starts the Astro playground and docs site. `npm run dev:library` starts the standalone Vite library demo. Publishing runs the package build automatically through `prepack`.
201
+
202
+ ## License
203
+
204
+ MIT © [marcelrsoub](https://github.com/marcelrsoub)
@@ -0,0 +1,4 @@
1
+ import { GalleryImage, GalleryProps } from './types';
2
+ declare function GalleryComponent<T extends GalleryImage>({ images, onImageClick, columns, rowHeight, className, style }: GalleryProps<T>): import('react').JSX.Element;
3
+ export declare const Gallery: typeof GalleryComponent;
4
+ export {};
@@ -0,0 +1,16 @@
1
+ import { AnimationEventHandler, CSSProperties } from 'react';
2
+ type ImageProps = {
3
+ src: string;
4
+ alt: string;
5
+ className?: string;
6
+ imageClassName?: string;
7
+ style?: CSSProperties;
8
+ imageStyle?: CSSProperties;
9
+ onAnimationEnd?: AnimationEventHandler<HTMLSpanElement>;
10
+ eager?: boolean;
11
+ objectFit?: 'cover' | 'contain';
12
+ width?: number;
13
+ height?: number;
14
+ };
15
+ export declare function Image({ src, alt, className, imageClassName, style, imageStyle, onAnimationEnd, eager, objectFit, width, height }: ImageProps): import('react').JSX.Element;
16
+ export {};
@@ -0,0 +1,2 @@
1
+ import { GalleryImage, LightboxProps } from './types';
2
+ export declare function Lightbox<T extends GalleryImage>({ images, index, onIndexChange, renderActions, renderCaption, renderControls, showCounter, showNavigation, className }: LightboxProps<T>): import('react').ReactPortal | null;
@@ -0,0 +1,2 @@
1
+ import { GalleryImage, PicGalleryProps } from './types';
2
+ export declare function PicGallery<T extends GalleryImage>({ images, columns, rowHeight, className, galleryClassName, style, renderActions, renderCaption, renderControls, showCounter, showNavigation }: PicGalleryProps<T>): import('react').JSX.Element;
@@ -0,0 +1,5 @@
1
+ export { Gallery } from './Gallery';
2
+ export { Lightbox } from './Lightbox';
3
+ export { PicGallery } from './PicGallery';
4
+ export type { GalleryImage, GalleryProps, LightboxContext, LightboxProps, LightboxRenderer, PicGalleryProps } from './types';
5
+ export { PicGallery as default } from './PicGallery';