react-pic-gallery 2.0.1 → 2.0.2
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 +27 -7
- package/dist/Gallery.d.ts +1 -1
- package/dist/PicGallery.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/layout.d.ts +9 -0
- package/dist/react-pic-gallery.js +326 -208
- package/dist/styles.css +1 -1
- package/dist/types.d.ts +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
Small, accessible React image gallery and lightbox with a polished default UI and typed escape hatches for custom controls.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/react-pic-gallery)
|
|
6
|
+
[](https://bundlephobia.com/package/react-pic-gallery@2.0.2)
|
|
6
7
|
|
|
7
8
|
[Live playground and docs](https://marcelrsoub.github.io/react-pic-gallery/)
|
|
8
9
|
|
|
10
|
+

|
|
11
|
+
|
|
9
12
|
## Install
|
|
10
13
|
|
|
11
14
|
```bash
|
|
@@ -20,16 +23,17 @@ bun add react-pic-gallery
|
|
|
20
23
|
|
|
21
24
|
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
25
|
|
|
23
|
-
The package is intentionally lightweight: it has no runtime dependencies
|
|
26
|
+
The package is intentionally lightweight: it has no runtime dependencies and React is a peer dependency. The built JavaScript and CSS together are about **7.7 KB gzipped** (5.55 KB JS + 2.16 KB CSS).
|
|
24
27
|
|
|
25
28
|
## Why react-pic-gallery
|
|
26
29
|
|
|
27
|
-
- **Tiny by design** — no runtime dependencies, no context providers, no polyfills; ~
|
|
30
|
+
- **Tiny by design** — no runtime dependencies, no context providers, no polyfills; ~7.7 KB gzipped total.
|
|
28
31
|
- **Simple by default** — one component, one stylesheet import, sensible accessible defaults.
|
|
29
32
|
- **Yours when needed** — typed `renderActions`, `renderCaption`, and `renderControls` callbacks let you add custom UI without rebuilding the lightbox; extra fields on your image objects flow through fully typed.
|
|
30
33
|
- **Accessible** — native modal `<dialog>`, focus containment and restoration, Escape to close, screen-reader announcements, `prefers-reduced-motion` support.
|
|
31
34
|
- **Keyboard and touch friendly** — arrow-key navigation in the grid (roving tabindex) and in the lightbox, Enter to open, swipe navigation on touch devices.
|
|
32
35
|
- **Themeable** — namespaced classes and CSS variables (`--gallery-accent`, `--gallery-overlay`, `--gallery-motion`, …).
|
|
36
|
+
- **Three layouts** — choose a uniform grid, proportional justified rows, or an editorial mosaic.
|
|
33
37
|
|
|
34
38
|
## Quick start
|
|
35
39
|
|
|
@@ -53,6 +57,21 @@ export function App() {
|
|
|
53
57
|
|
|
54
58
|
`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.
|
|
55
59
|
|
|
60
|
+
## Gallery layouts
|
|
61
|
+
|
|
62
|
+
The default is the existing three-column grid. Choose another layout with `layout`:
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
<PicGallery images={images} layout='justified' />
|
|
66
|
+
<PicGallery images={images} layout='mosaic' />
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- **`grid`** — consistent tiles with a configurable fixed column count.
|
|
70
|
+
- **`justified`** — proportional photos arranged in aligned rows; the final row stays left-aligned.
|
|
71
|
+
- **`mosaic`** — alternating featured photos and smaller supporting tiles.
|
|
72
|
+
|
|
73
|
+
Image `width` and `height` are recommended, but optional. Justified rows use them when supplied and fall back to 3:2 when either dimension is missing or invalid. Accurate dimensions give the most faithful layout and help reserve space while images load. `rowHeight` sets the tile height for the grid, the base row height for the mosaic, and the target row height for justified galleries. `columns` applies to the grid only.
|
|
74
|
+
|
|
56
75
|
## Custom UI
|
|
57
76
|
|
|
58
77
|
Add actions without rebuilding the lightbox:
|
|
@@ -116,7 +135,7 @@ The lightbox uses the native modal `<dialog>` element and includes:
|
|
|
116
135
|
- Instagram-Stories-style edge taps on touch screens: tap the right edge of the image to go forward, the left edge to go back (navigation buttons are hidden on small screens where tap zones take over).
|
|
117
136
|
- Reduced-motion support, safe-area padding, rounded image surfaces, and animated transitions.
|
|
118
137
|
|
|
119
|
-
|
|
138
|
+
Gallery tiles use roving focus. Left/Right follow image order; in the grid, Up/Down jump a row, and in justified and mosaic layouts they follow the nearest tile position. Home/End move to the first/last image. Enter opens the lightbox, and focus returns to the same tile when it closes.
|
|
120
139
|
|
|
121
140
|
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.
|
|
122
141
|
|
|
@@ -134,7 +153,7 @@ The stylesheet uses namespaced classes and CSS variables. Import it once, then o
|
|
|
134
153
|
}
|
|
135
154
|
```
|
|
136
155
|
|
|
137
|
-
The default
|
|
156
|
+
The default grid uses three columns. Pass `columns` for a different fixed count. `rowHeight` accepts CSS height values or numeric pixels; its meaning depends on the selected layout as described above.
|
|
138
157
|
|
|
139
158
|
## API
|
|
140
159
|
|
|
@@ -143,15 +162,16 @@ The default gallery uses three columns. Pass `columns` for a different fixed cou
|
|
|
143
162
|
| Prop | Type | Description |
|
|
144
163
|
| --- | --- | --- |
|
|
145
164
|
| `images` | `readonly GalleryImage[]` | Images to display. |
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
165
|
+
| `layout` | `'grid' \| 'justified' \| 'mosaic'` | Defaults to `'grid'`. |
|
|
166
|
+
| `columns` | `number` | Optional fixed grid column count. Defaults to three; only applies to `grid`. |
|
|
167
|
+
| `rowHeight` | `CSSProperties['height']` | Grid tile height, mosaic base row height, or justified target row height. |
|
|
148
168
|
| `renderActions` | `LightboxRenderer` | Adds controls to the default toolbar. |
|
|
149
169
|
| `renderCaption` | `LightboxRenderer` | Replaces the current caption. |
|
|
150
170
|
| `renderControls` | `LightboxRenderer` | Replaces the complete default control layer. |
|
|
151
171
|
| `showCounter` | `boolean` | Shows the current image count. Defaults to `true`. |
|
|
152
172
|
| `showNavigation` | `boolean` | Shows previous/next controls. Defaults to `true`. |
|
|
153
173
|
|
|
154
|
-
`Gallery` accepts `images`, `onImageClick`, `columns`, `rowHeight`, `className`, and `style`.
|
|
174
|
+
`Gallery` accepts `images`, `onImageClick`, `layout`, `columns`, `rowHeight`, `className`, and `style`.
|
|
155
175
|
|
|
156
176
|
`Lightbox` accepts `images`, controlled `index`, `onIndexChange`, the renderer props, `showCounter`, `showNavigation`, and `className`.
|
|
157
177
|
|
package/dist/Gallery.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
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;
|
|
2
|
+
declare function GalleryComponent<T extends GalleryImage>({ images, onImageClick, layout, columns, rowHeight, className, style }: GalleryProps<T>): import('react').JSX.Element;
|
|
3
3
|
export declare const Gallery: typeof GalleryComponent;
|
|
4
4
|
export {};
|
package/dist/PicGallery.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
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;
|
|
2
|
+
export declare function PicGallery<T extends GalleryImage>({ images, layout, columns, rowHeight, className, galleryClassName, style, renderActions, renderCaption, renderControls, showCounter, showNavigation }: PicGalleryProps<T>): import('react').JSX.Element;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { Gallery } from './Gallery';
|
|
2
2
|
export { Lightbox } from './Lightbox';
|
|
3
3
|
export { PicGallery } from './PicGallery';
|
|
4
|
-
export type { GalleryImage, GalleryProps, LightboxContext, LightboxProps, LightboxRenderer, PicGalleryProps } from './types';
|
|
4
|
+
export type { GalleryImage, GalleryLayout, GalleryProps, LightboxContext, LightboxProps, LightboxRenderer, PicGalleryProps } from './types';
|
|
5
5
|
export { PicGallery as default } from './PicGallery';
|
package/dist/layout.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GalleryImage } from './types';
|
|
2
|
+
export declare const FALLBACK_ASPECT_RATIO: number;
|
|
3
|
+
export type JustifiedRow = {
|
|
4
|
+
indices: number[];
|
|
5
|
+
widths: number[];
|
|
6
|
+
height: number;
|
|
7
|
+
};
|
|
8
|
+
export declare function getAspectRatio(image: Pick<GalleryImage, 'width' | 'height'>): number;
|
|
9
|
+
export declare function buildJustifiedRows(images: readonly Pick<GalleryImage, 'width' | 'height'>[], containerWidth: number, targetHeight: number, gap: number): JustifiedRow[];
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { memo as e, useCallback as t, useEffect as n, useId as r,
|
|
2
|
-
import { jsx as
|
|
3
|
-
import { createPortal as
|
|
1
|
+
import { memo as e, useCallback as t, useEffect as n, useId as r, useLayoutEffect as i, useRef as a, useState as o } from "react";
|
|
2
|
+
import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
3
|
+
import { createPortal as u } from "react-dom";
|
|
4
4
|
//#region src/lib/Image.tsx
|
|
5
|
-
function
|
|
6
|
-
let g =
|
|
5
|
+
function d({ src: e, alt: t, className: r = "", imageClassName: i = "", style: s, imageStyle: u, onAnimationEnd: d, eager: f = !1, objectFit: p = "cover", width: m, height: h }) {
|
|
6
|
+
let g = a(null), [_, v] = o("loading");
|
|
7
7
|
return n(() => {
|
|
8
8
|
v("loading");
|
|
9
9
|
let e = g.current;
|
|
10
10
|
e?.complete && v(e.naturalWidth > 0 ? "loaded" : "error");
|
|
11
|
-
}, [e]), /* @__PURE__ */
|
|
11
|
+
}, [e]), /* @__PURE__ */ l("span", {
|
|
12
12
|
className: `react-pic-gallery__image ${r}`.trim(),
|
|
13
|
-
style:
|
|
13
|
+
style: s,
|
|
14
14
|
"aria-busy": _ === "loading",
|
|
15
15
|
onAnimationEnd: d,
|
|
16
16
|
children: [
|
|
17
|
-
/* @__PURE__ */
|
|
17
|
+
/* @__PURE__ */ c("img", {
|
|
18
18
|
ref: g,
|
|
19
19
|
src: e,
|
|
20
20
|
alt: t,
|
|
21
|
-
className: `react-pic-gallery__image-element ${
|
|
21
|
+
className: `react-pic-gallery__image-element ${i}`.trim(),
|
|
22
22
|
style: {
|
|
23
23
|
objectFit: p,
|
|
24
24
|
...u
|
|
@@ -30,12 +30,12 @@ function l({ src: e, alt: t, className: r = "", imageClassName: c = "", style: l
|
|
|
30
30
|
onLoad: () => v("loaded"),
|
|
31
31
|
onError: () => v("error")
|
|
32
32
|
}),
|
|
33
|
-
_ === "loading" && /* @__PURE__ */
|
|
33
|
+
_ === "loading" && /* @__PURE__ */ c("span", {
|
|
34
34
|
className: "react-pic-gallery__image-loader",
|
|
35
35
|
role: "progressbar",
|
|
36
36
|
"aria-label": "Loading image"
|
|
37
37
|
}),
|
|
38
|
-
_ === "error" && /* @__PURE__ */
|
|
38
|
+
_ === "error" && /* @__PURE__ */ c("span", {
|
|
39
39
|
className: "react-pic-gallery__image-error",
|
|
40
40
|
role: "status",
|
|
41
41
|
children: "Unable to load image"
|
|
@@ -44,295 +44,412 @@ function l({ src: e, alt: t, className: r = "", imageClassName: c = "", style: l
|
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
//#endregion
|
|
47
|
+
//#region src/lib/layout.ts
|
|
48
|
+
var f = 3 / 2;
|
|
49
|
+
function p(e) {
|
|
50
|
+
return Number.isFinite(e.width) && Number.isFinite(e.height) && e.width !== void 0 && e.height !== void 0 && e.width > 0 && e.height > 0 ? e.width / e.height : f;
|
|
51
|
+
}
|
|
52
|
+
function m(e, t, n, r) {
|
|
53
|
+
if (e.length === 0) return [];
|
|
54
|
+
let i = Math.max(1, t), a = Math.max(1, n), o = Math.max(0, r), s = e.map(p), c = [], l = 0;
|
|
55
|
+
for (; l < e.length;) {
|
|
56
|
+
let t = l + 1, n = i / s[l], r = Math.abs(n - a), u = s[l];
|
|
57
|
+
for (let c = l + 1; c < e.length; c += 1) {
|
|
58
|
+
let e = u + s[c], d = (i - o * (c - l + 1 - 1)) / e, f = Math.abs(d - a);
|
|
59
|
+
if (f < r) t = c + 1, n = d, r = f;
|
|
60
|
+
else if (d < a) break;
|
|
61
|
+
u = e;
|
|
62
|
+
}
|
|
63
|
+
let d = t - l, f = s.slice(l, t).reduce((e, t) => e + t, 0), p = t === e.length ? Math.min(a, (i - o * (d - 1)) / f) : n;
|
|
64
|
+
c.push({
|
|
65
|
+
indices: Array.from({ length: d }, (e, t) => l + t),
|
|
66
|
+
widths: s.slice(l, t).map((e) => e * p),
|
|
67
|
+
height: p
|
|
68
|
+
}), l = t;
|
|
69
|
+
}
|
|
70
|
+
return c;
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
47
73
|
//#region src/lib/Gallery.tsx
|
|
48
|
-
var
|
|
49
|
-
function
|
|
50
|
-
let
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
74
|
+
var h = 3, g = 192, _ = 12, v = typeof window > "u" ? n : i;
|
|
75
|
+
function y({ images: e, onImageClick: n, layout: r = "grid", columns: i, rowHeight: u, className: f = "", style: p }) {
|
|
76
|
+
let y = a([]), b = a(null), x = a(null), [S, C] = o(0), [w, T] = o({
|
|
77
|
+
width: 1024,
|
|
78
|
+
rowHeight: g,
|
|
79
|
+
gap: _
|
|
80
|
+
}), E = i !== void 0 && Number.isFinite(i) && i >= 1 ? Math.floor(i) : h, D = e.length - 1, O = Math.min(S, Math.max(D, 0)), k = typeof u == "number" ? `${u}px` : u, A = {
|
|
81
|
+
...p,
|
|
82
|
+
...r === "grid" && i !== void 0 && Number.isFinite(i) && i >= 1 ? { gridTemplateColumns: `repeat(${E}, minmax(0, 1fr))` } : {},
|
|
83
|
+
...k ? { "--gallery-row-height": k } : {}
|
|
84
|
+
};
|
|
85
|
+
v(() => {
|
|
86
|
+
if (r !== "justified") return;
|
|
87
|
+
let e = b.current, t = x.current;
|
|
88
|
+
if (!e || !t) return;
|
|
89
|
+
let n = () => {
|
|
90
|
+
let n = e.getBoundingClientRect().width || e.clientWidth || window.innerWidth || 1024, r = t.getBoundingClientRect(), i = Number.parseFloat(window.getComputedStyle(t).width), a = typeof u == "number" ? u : typeof u == "string" && /^\s*\d+(?:\.\d+)?px\s*$/.test(u) ? Number.parseFloat(u) : g;
|
|
91
|
+
T((e) => {
|
|
92
|
+
let t = {
|
|
93
|
+
width: n,
|
|
94
|
+
rowHeight: r.height || a,
|
|
95
|
+
gap: Number.isFinite(i) ? i : r.width || _
|
|
96
|
+
};
|
|
97
|
+
return e.width === t.width && e.rowHeight === t.rowHeight && e.gap === t.gap ? e : t;
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
n();
|
|
101
|
+
let i = typeof ResizeObserver > "u" ? null : new ResizeObserver(n);
|
|
102
|
+
return i?.observe(e), i?.observe(t), window.addEventListener("resize", n), () => {
|
|
103
|
+
i?.disconnect(), window.removeEventListener("resize", n);
|
|
104
|
+
};
|
|
105
|
+
}, [
|
|
106
|
+
r,
|
|
107
|
+
u,
|
|
108
|
+
k
|
|
109
|
+
]);
|
|
110
|
+
let j = t((e) => {
|
|
111
|
+
C(e), y.current[e]?.focus();
|
|
112
|
+
}, []), M = t((t, n) => {
|
|
113
|
+
let i = y.current[t];
|
|
114
|
+
if (!i) return null;
|
|
115
|
+
let a = i.getBoundingClientRect();
|
|
116
|
+
if (r === "mosaic" && i.classList.contains("react-pic-gallery__tile--mosaic-featured")) {
|
|
117
|
+
let r = i.closest(".react-pic-gallery__mosaic-group"), o = a.left + a.width / 2, s = a.top + a.height / 2, c = null, l = Infinity;
|
|
118
|
+
if (y.current.slice(0, e.length).forEach((e, i) => {
|
|
119
|
+
if (!e || i === t || !r?.contains(e)) return;
|
|
120
|
+
let a = e.getBoundingClientRect(), u = a.left + a.width / 2, d = a.top + a.height / 2, f = n === "up" ? s - d : d - s;
|
|
121
|
+
if (f <= 0) return;
|
|
122
|
+
let p = f + Math.abs(u - o);
|
|
123
|
+
p < l && (l = p, c = i);
|
|
124
|
+
}), c !== null) return c;
|
|
125
|
+
}
|
|
126
|
+
let o = null, s = Infinity;
|
|
127
|
+
return y.current.slice(0, e.length).forEach((e, r) => {
|
|
128
|
+
if (!e || r === t) return;
|
|
129
|
+
let i = e.getBoundingClientRect(), c = n === "up" ? a.top - i.bottom : i.top - a.bottom;
|
|
130
|
+
if (c < 0) return;
|
|
131
|
+
let l = c + (i.right < a.left ? a.left - i.right : a.right < i.left ? i.left - a.right : 0);
|
|
132
|
+
l < s && (s = l, o = r);
|
|
133
|
+
}), o;
|
|
134
|
+
}, [e.length, r]), N = t((e, t) => {
|
|
135
|
+
let n = null;
|
|
136
|
+
if (e.key === "Home") n = 0;
|
|
137
|
+
else if (e.key === "End") n = D;
|
|
138
|
+
else if (r === "grid") {
|
|
139
|
+
let r = {
|
|
140
|
+
ArrowRight: 1,
|
|
141
|
+
ArrowLeft: -1,
|
|
142
|
+
ArrowDown: E,
|
|
143
|
+
ArrowUp: -E
|
|
144
|
+
}[e.key];
|
|
145
|
+
if (r !== void 0) {
|
|
146
|
+
let e = t + r;
|
|
147
|
+
e >= 0 && e <= D && (n = e);
|
|
148
|
+
}
|
|
149
|
+
} else if (e.key === "ArrowRight" && t < D) n = t + 1;
|
|
150
|
+
else if (e.key === "ArrowLeft" && t > 0) n = t - 1;
|
|
151
|
+
else if (e.key === "ArrowDown") n = M(t, "down");
|
|
152
|
+
else if (e.key === "ArrowUp") n = M(t, "up");
|
|
64
153
|
else return;
|
|
65
|
-
|
|
154
|
+
n !== null && n !== t && (e.preventDefault(), j(n));
|
|
66
155
|
}, [
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
156
|
+
E,
|
|
157
|
+
M,
|
|
158
|
+
D,
|
|
159
|
+
r,
|
|
160
|
+
j
|
|
161
|
+
]), P = (e, t, r = {}) => /* @__PURE__ */ c("button", {
|
|
162
|
+
className: `react-pic-gallery__tile ${r.className ?? ""}`.trim(),
|
|
163
|
+
type: "button",
|
|
164
|
+
disabled: !n,
|
|
165
|
+
tabIndex: t === O ? 0 : -1,
|
|
166
|
+
ref: (e) => {
|
|
167
|
+
y.current[t] = e;
|
|
168
|
+
},
|
|
169
|
+
style: r.style,
|
|
170
|
+
onKeyDown: (e) => N(e, t),
|
|
171
|
+
onClick: () => {
|
|
172
|
+
C(t), n?.(t);
|
|
173
|
+
},
|
|
174
|
+
"aria-label": `Open ${e.alt}`,
|
|
175
|
+
children: /* @__PURE__ */ c(d, {
|
|
176
|
+
src: e.thumbnailSrc ?? e.src,
|
|
177
|
+
alt: e.alt,
|
|
178
|
+
objectFit: "cover",
|
|
179
|
+
width: e.width,
|
|
180
|
+
height: e.height
|
|
181
|
+
})
|
|
182
|
+
}, e.id ?? `${e.src}-${t}`), F = r === "justified" ? m(e, w.width, w.rowHeight, w.gap) : [], I = Array(e.length);
|
|
183
|
+
return F.forEach((e) => {
|
|
184
|
+
e.indices.forEach((t, n) => {
|
|
185
|
+
I[t] = {
|
|
186
|
+
width: `${e.widths[n]}px`,
|
|
187
|
+
height: `${e.height}px`
|
|
188
|
+
};
|
|
189
|
+
});
|
|
190
|
+
}), /* @__PURE__ */ l("div", {
|
|
191
|
+
ref: b,
|
|
192
|
+
className: `react-pic-gallery__gallery react-pic-gallery__gallery--${r} ${r === "grid" ? "react-pic-gallery__grid" : ""} ${f}`.trim(),
|
|
193
|
+
style: A,
|
|
194
|
+
"data-testid": r === "grid" ? "react-pic-gallery-grid" : void 0,
|
|
195
|
+
"data-layout": r,
|
|
196
|
+
children: [
|
|
197
|
+
r === "grid" && e.map((e, t) => P(e, t)),
|
|
198
|
+
r === "justified" && /* @__PURE__ */ l(s, { children: [e.map((e, t) => P(e, t, {
|
|
199
|
+
className: "react-pic-gallery__tile--justified",
|
|
200
|
+
style: I[t]
|
|
201
|
+
})), /* @__PURE__ */ c("span", {
|
|
202
|
+
ref: x,
|
|
203
|
+
className: "react-pic-gallery__row-height-probe",
|
|
204
|
+
"aria-hidden": "true"
|
|
205
|
+
})] }),
|
|
206
|
+
r === "mosaic" && Array.from({ length: Math.ceil(e.length / 3) }, (t, n) => {
|
|
207
|
+
let r = n * 3, i = e.slice(r, r + 3), a = n % 2 == 0 ? "left" : "top";
|
|
208
|
+
return /* @__PURE__ */ c("div", {
|
|
209
|
+
className: `react-pic-gallery__mosaic-group react-pic-gallery__mosaic-group--${a} react-pic-gallery__mosaic-group--count-${i.length}`,
|
|
210
|
+
children: i.map((e, t) => {
|
|
211
|
+
let n = r + t, a = i.length === 3 ? t === 0 ? "featured" : "supporting" : "simple";
|
|
212
|
+
return P(e, n, { className: `react-pic-gallery__tile--mosaic react-pic-gallery__tile--mosaic-${a}` });
|
|
213
|
+
})
|
|
214
|
+
}, `mosaic-${r}`);
|
|
98
215
|
})
|
|
99
|
-
|
|
216
|
+
]
|
|
100
217
|
});
|
|
101
218
|
}
|
|
102
|
-
var
|
|
103
|
-
function
|
|
104
|
-
return e instanceof Element && e.closest(
|
|
219
|
+
var b = e(y), x = /* @__PURE__ */ new Set(), S = null, C = "a[href], button, input, select, textarea, [role=\"combobox\"], [role=\"menu\"], [role=\"slider\"], [role=\"spinbutton\"], [role=\"tab\"]", w = "input, select, textarea, [role=\"combobox\"], [role=\"menu\"], [role=\"slider\"], [role=\"spinbutton\"], [role=\"tab\"]", T = "(max-width: 600px), (pointer: coarse)", E = .3;
|
|
220
|
+
function D(e) {
|
|
221
|
+
return e instanceof Element && e.closest(C) !== null;
|
|
105
222
|
}
|
|
106
|
-
function
|
|
107
|
-
if (!
|
|
108
|
-
if (
|
|
223
|
+
function O(e) {
|
|
224
|
+
if (!x.has(e)) {
|
|
225
|
+
if (x.size === 0) {
|
|
109
226
|
let e = document.body, t = window.innerWidth - document.documentElement.clientWidth, n = Number.parseFloat(window.getComputedStyle(e).paddingRight) || 0;
|
|
110
|
-
|
|
227
|
+
S = {
|
|
111
228
|
overflow: e.style.overflow,
|
|
112
229
|
paddingRight: e.style.paddingRight
|
|
113
230
|
}, e.style.overflow = "hidden", t > 0 && (e.style.paddingRight = `${n + t}px`);
|
|
114
231
|
}
|
|
115
|
-
|
|
232
|
+
x.add(e);
|
|
116
233
|
}
|
|
117
234
|
}
|
|
118
|
-
function
|
|
119
|
-
return
|
|
235
|
+
function k(e) {
|
|
236
|
+
return x.delete(e), x.size > 0 || !S ? !1 : (document.body.style.overflow = S.overflow, document.body.style.paddingRight = S.paddingRight, S = null, !0);
|
|
120
237
|
}
|
|
121
|
-
function
|
|
238
|
+
function A(e) {
|
|
122
239
|
let t = e.trim();
|
|
123
240
|
return t.endsWith("ms") ? Number.parseFloat(t) : t.endsWith("s") ? Number.parseFloat(t) * 1e3 : 0;
|
|
124
241
|
}
|
|
125
|
-
function
|
|
242
|
+
function j(e) {
|
|
126
243
|
let t = window.getComputedStyle(e), n = t.animationDuration.split(","), r = t.animationDelay.split(",");
|
|
127
|
-
return Math.max(...n.map((e, t) =>
|
|
244
|
+
return Math.max(...n.map((e, t) => A(e) + A(r[t % r.length] ?? "0s")), 0);
|
|
128
245
|
}
|
|
129
|
-
function
|
|
130
|
-
return /* @__PURE__ */
|
|
246
|
+
function M() {
|
|
247
|
+
return /* @__PURE__ */ c("svg", {
|
|
131
248
|
viewBox: "0 0 24 24",
|
|
132
249
|
"aria-hidden": "true",
|
|
133
250
|
focusable: "false",
|
|
134
|
-
children: /* @__PURE__ */
|
|
251
|
+
children: /* @__PURE__ */ c("path", { d: "M6 6l12 12M18 6L6 18" })
|
|
135
252
|
});
|
|
136
253
|
}
|
|
137
|
-
function
|
|
138
|
-
return /* @__PURE__ */
|
|
254
|
+
function N({ direction: e }) {
|
|
255
|
+
return /* @__PURE__ */ c("svg", {
|
|
139
256
|
viewBox: "0 0 24 24",
|
|
140
257
|
"aria-hidden": "true",
|
|
141
258
|
focusable: "false",
|
|
142
|
-
children: /* @__PURE__ */
|
|
259
|
+
children: /* @__PURE__ */ c("path", { d: e === "left" ? "M14.5 5l-7 7 7 7" : "M9.5 5l7 7-7 7" })
|
|
143
260
|
});
|
|
144
261
|
}
|
|
145
|
-
function
|
|
262
|
+
function P(...e) {
|
|
146
263
|
return e.filter(Boolean).join(" ");
|
|
147
264
|
}
|
|
148
|
-
function
|
|
149
|
-
let
|
|
150
|
-
|
|
151
|
-
let
|
|
152
|
-
|
|
153
|
-
}, []),
|
|
154
|
-
let e =
|
|
155
|
-
if (e !== null &&
|
|
265
|
+
function F({ images: e, index: i, onIndexChange: s, renderActions: f, renderCaption: p, renderControls: m, showCounter: h = !0, showNavigation: g = !0, className: _ }) {
|
|
266
|
+
let v = a(null), y = a(s), b = a(null), x = a(null), S = a(null), C = a(!1), A = a(!1), F = a({}), I = a(e), L = a(null), R = r(), [z, B] = o(!1), [V, H] = o(null), U = i !== null && i >= 0 && i < e.length ? i : null, W = U === null ? void 0 : e[U];
|
|
267
|
+
y.current = s, S.current = U, C.current = z, I.current = e;
|
|
268
|
+
let G = t(() => {
|
|
269
|
+
b.current !== null && (window.clearTimeout(b.current), b.current = null), x.current = null;
|
|
270
|
+
}, []), K = t(() => {
|
|
271
|
+
let e = S.current;
|
|
272
|
+
if (e !== null && x.current === null) {
|
|
156
273
|
if (typeof window < "u" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
|
|
157
|
-
|
|
274
|
+
y.current(null);
|
|
158
275
|
return;
|
|
159
276
|
}
|
|
160
|
-
|
|
277
|
+
x.current = { index: e }, C.current = !0, B(!0);
|
|
161
278
|
}
|
|
162
|
-
}, []), K = t(() => {
|
|
163
|
-
let e = j.current;
|
|
164
|
-
!M.current && e !== null && e > 0 && O.current(e - 1);
|
|
165
279
|
}, []), q = t(() => {
|
|
166
|
-
let e =
|
|
167
|
-
!
|
|
280
|
+
let e = S.current;
|
|
281
|
+
!C.current && e !== null && e > 0 && y.current(e - 1);
|
|
168
282
|
}, []), J = t(() => {
|
|
169
|
-
let e =
|
|
170
|
-
|
|
283
|
+
let e = S.current;
|
|
284
|
+
!C.current && e !== null && e < I.current.length - 1 && y.current(e + 1);
|
|
171
285
|
}, []), Y = t(() => {
|
|
172
|
-
let e =
|
|
173
|
-
|
|
174
|
-
}, []),
|
|
175
|
-
e.
|
|
176
|
-
|
|
177
|
-
|
|
286
|
+
let e = S.current;
|
|
287
|
+
C.current || e === null || e === 0 || (H("previous"), y.current(e - 1));
|
|
288
|
+
}, []), X = t(() => {
|
|
289
|
+
let e = S.current;
|
|
290
|
+
C.current || e === null || e >= I.current.length - 1 || (H("next"), y.current(e + 1));
|
|
291
|
+
}, []), ee = t((e) => {
|
|
292
|
+
e.preventDefault(), K();
|
|
293
|
+
}, [K]), Z = t(() => {
|
|
294
|
+
let e = x.current;
|
|
178
295
|
if (e) {
|
|
179
|
-
if (
|
|
180
|
-
|
|
296
|
+
if (S.current !== e.index) {
|
|
297
|
+
G(), C.current = !1, B(!1);
|
|
181
298
|
return;
|
|
182
299
|
}
|
|
183
|
-
|
|
300
|
+
G(), C.current = !1, B(!1), y.current(null);
|
|
184
301
|
}
|
|
185
|
-
}, [
|
|
302
|
+
}, [G]), te = t((e) => {
|
|
186
303
|
if (e.defaultPrevented) return;
|
|
187
304
|
let t = e.target;
|
|
188
|
-
t instanceof HTMLElement && (t.isContentEditable || t.closest(
|
|
189
|
-
}, [
|
|
190
|
-
if (e.touches.length !== 1 ||
|
|
191
|
-
|
|
305
|
+
t instanceof HTMLElement && (t.isContentEditable || t.closest(w)) || (e.key === "ArrowLeft" ? (e.preventDefault(), q()) : e.key === "ArrowRight" && (e.preventDefault(), J()));
|
|
306
|
+
}, [J, q]), ne = t((e) => {
|
|
307
|
+
if (e.touches.length !== 1 || D(e.target)) {
|
|
308
|
+
L.current = null;
|
|
192
309
|
return;
|
|
193
310
|
}
|
|
194
311
|
let t = e.touches[0];
|
|
195
|
-
|
|
312
|
+
L.current = {
|
|
196
313
|
x: t.clientX,
|
|
197
314
|
y: t.clientY
|
|
198
315
|
};
|
|
199
|
-
}, []),
|
|
200
|
-
let t =
|
|
201
|
-
if (
|
|
316
|
+
}, []), re = t((e) => {
|
|
317
|
+
let t = L.current;
|
|
318
|
+
if (L.current = null, !t || e.changedTouches.length === 0) return;
|
|
202
319
|
let n = e.changedTouches[0], r = n.clientX - t.x, i = n.clientY - t.y, a = Math.abs(r);
|
|
203
|
-
a < 48 || a <= Math.abs(i) || (r < 0 ?
|
|
204
|
-
}, [
|
|
205
|
-
|
|
320
|
+
a < 48 || a <= Math.abs(i) || (r < 0 ? X() : Y());
|
|
321
|
+
}, [X, Y]), ie = t(() => {
|
|
322
|
+
L.current = null;
|
|
323
|
+
}, []), ae = t((e) => {
|
|
324
|
+
e.target === e.currentTarget && H(null);
|
|
206
325
|
}, []), oe = t((e) => {
|
|
207
|
-
e.target === e.currentTarget &&
|
|
208
|
-
}, []), se = t((
|
|
209
|
-
|
|
210
|
-
}, [
|
|
211
|
-
N.current || (W(), M.current = !1, z(!1), j.current !== null && O.current(null));
|
|
212
|
-
}, [W]);
|
|
326
|
+
e.target === e.currentTarget && e.animationName === "react-pic-gallery-fade-out" && Z();
|
|
327
|
+
}, [Z]), se = t(() => {
|
|
328
|
+
A.current || (G(), C.current = !1, B(!1), S.current !== null && y.current(null));
|
|
329
|
+
}, [G]);
|
|
213
330
|
if (n(() => {
|
|
214
|
-
let e =
|
|
215
|
-
e &&
|
|
216
|
-
}, [
|
|
217
|
-
if (!
|
|
218
|
-
let e =
|
|
219
|
-
return
|
|
220
|
-
|
|
331
|
+
let e = x.current;
|
|
332
|
+
e && U !== e.index && (G(), C.current = !1, B(!1));
|
|
333
|
+
}, [U, G]), n(() => {
|
|
334
|
+
if (!z || !x.current || !v.current) return;
|
|
335
|
+
let e = j(v.current);
|
|
336
|
+
return b.current = window.setTimeout(Z, e), () => {
|
|
337
|
+
b.current !== null && (window.clearTimeout(b.current), b.current = null);
|
|
221
338
|
};
|
|
222
|
-
}, [
|
|
223
|
-
if (
|
|
224
|
-
let e =
|
|
339
|
+
}, [Z, z]), n(() => {
|
|
340
|
+
if (U === null) return;
|
|
341
|
+
let e = v.current;
|
|
225
342
|
if (!e) return;
|
|
226
343
|
let t = document.activeElement;
|
|
227
|
-
return
|
|
228
|
-
|
|
344
|
+
return O(F.current), e.open || e.showModal(), () => {
|
|
345
|
+
G(), A.current = !0, e.open && e.close(), A.current = !1, k(F.current) && t?.isConnected && t.focus();
|
|
229
346
|
};
|
|
230
|
-
}, [
|
|
231
|
-
let
|
|
232
|
-
image:
|
|
233
|
-
index:
|
|
347
|
+
}, [U !== null, G]), U === null || !W || typeof document > "u") return null;
|
|
348
|
+
let Q = {
|
|
349
|
+
image: W,
|
|
350
|
+
index: U,
|
|
234
351
|
count: e.length,
|
|
235
|
-
close:
|
|
236
|
-
next:
|
|
237
|
-
previous:
|
|
238
|
-
canGoNext:
|
|
239
|
-
canGoPrevious:
|
|
240
|
-
},
|
|
241
|
-
e.target === e.currentTarget &&
|
|
352
|
+
close: K,
|
|
353
|
+
next: J,
|
|
354
|
+
previous: q,
|
|
355
|
+
canGoNext: U < e.length - 1,
|
|
356
|
+
canGoPrevious: U > 0
|
|
357
|
+
}, ce = g && !m && Q.canGoPrevious, le = g && !m && Q.canGoNext, $ = g && !m && e.length > 1, ue = (e) => {
|
|
358
|
+
e.target === e.currentTarget && K();
|
|
242
359
|
};
|
|
243
|
-
return
|
|
244
|
-
ref:
|
|
245
|
-
className:
|
|
246
|
-
"aria-labelledby":
|
|
247
|
-
onAnimationEnd:
|
|
248
|
-
onClose:
|
|
249
|
-
onMouseDown:
|
|
250
|
-
onCancel:
|
|
251
|
-
onKeyDown:
|
|
360
|
+
return u(/* @__PURE__ */ l("dialog", {
|
|
361
|
+
ref: v,
|
|
362
|
+
className: P("react-pic-gallery__lightbox", z ? "react-pic-gallery__lightbox--closing" : void 0, _),
|
|
363
|
+
"aria-labelledby": R,
|
|
364
|
+
onAnimationEnd: oe,
|
|
365
|
+
onClose: se,
|
|
366
|
+
onMouseDown: ue,
|
|
367
|
+
onCancel: ee,
|
|
368
|
+
onKeyDown: te,
|
|
252
369
|
children: [
|
|
253
|
-
/* @__PURE__ */
|
|
370
|
+
/* @__PURE__ */ c("h2", {
|
|
254
371
|
className: "react-pic-gallery__sr-only",
|
|
255
|
-
id:
|
|
372
|
+
id: R,
|
|
256
373
|
children: "Image viewer"
|
|
257
374
|
}),
|
|
258
|
-
/* @__PURE__ */
|
|
375
|
+
/* @__PURE__ */ l("p", {
|
|
259
376
|
className: "react-pic-gallery__sr-only",
|
|
260
377
|
"aria-live": "polite",
|
|
261
378
|
children: [
|
|
262
|
-
|
|
379
|
+
W.alt,
|
|
263
380
|
", image ",
|
|
264
|
-
|
|
381
|
+
U + 1,
|
|
265
382
|
" of ",
|
|
266
383
|
e.length
|
|
267
384
|
]
|
|
268
385
|
}),
|
|
269
|
-
/* @__PURE__ */
|
|
386
|
+
/* @__PURE__ */ l("div", {
|
|
270
387
|
className: "react-pic-gallery__lightbox-content",
|
|
271
388
|
children: [
|
|
272
|
-
m ? /* @__PURE__ */
|
|
389
|
+
m ? /* @__PURE__ */ c("div", {
|
|
273
390
|
className: "react-pic-gallery__custom-controls",
|
|
274
|
-
children: m(
|
|
275
|
-
}) : /* @__PURE__ */
|
|
391
|
+
children: m(Q)
|
|
392
|
+
}) : /* @__PURE__ */ l("div", {
|
|
276
393
|
className: "react-pic-gallery__toolbar",
|
|
277
|
-
children: [/* @__PURE__ */
|
|
394
|
+
children: [/* @__PURE__ */ l("div", {
|
|
278
395
|
className: "react-pic-gallery__toolbar-actions",
|
|
279
|
-
children: [h && /* @__PURE__ */
|
|
396
|
+
children: [h && /* @__PURE__ */ l("span", {
|
|
280
397
|
"aria-live": "polite",
|
|
281
398
|
children: [
|
|
282
|
-
|
|
399
|
+
U + 1,
|
|
283
400
|
" / ",
|
|
284
401
|
e.length
|
|
285
402
|
]
|
|
286
|
-
}), f?.(
|
|
287
|
-
}), /* @__PURE__ */
|
|
403
|
+
}), f?.(Q)]
|
|
404
|
+
}), /* @__PURE__ */ c("button", {
|
|
288
405
|
className: "react-pic-gallery__control",
|
|
289
406
|
type: "button",
|
|
290
|
-
onClick:
|
|
407
|
+
onClick: K,
|
|
291
408
|
"aria-label": "Close image viewer",
|
|
292
|
-
children: /* @__PURE__ */
|
|
409
|
+
children: /* @__PURE__ */ c(M, {})
|
|
293
410
|
})]
|
|
294
411
|
}),
|
|
295
|
-
/* @__PURE__ */
|
|
296
|
-
className:
|
|
297
|
-
onMouseDown:
|
|
412
|
+
/* @__PURE__ */ l("div", {
|
|
413
|
+
className: P("react-pic-gallery__viewport", $ ? "react-pic-gallery__viewport--has-navigation" : void 0),
|
|
414
|
+
onMouseDown: ue,
|
|
298
415
|
onClick: (e) => {
|
|
299
|
-
if (
|
|
416
|
+
if (!$ || C.current || !(e.target instanceof Element) || e.target.closest("button") || window.matchMedia?.(T)?.matches !== !0) return;
|
|
300
417
|
let t = e.currentTarget.getBoundingClientRect();
|
|
301
418
|
if (t.width <= 0) return;
|
|
302
419
|
let n = (e.clientX - t.left) / t.width;
|
|
303
|
-
n <
|
|
420
|
+
n < E ? q() : n > .7 && J();
|
|
304
421
|
},
|
|
305
|
-
onTouchCancel:
|
|
306
|
-
onTouchEnd:
|
|
307
|
-
onTouchStart:
|
|
422
|
+
onTouchCancel: ie,
|
|
423
|
+
onTouchEnd: re,
|
|
424
|
+
onTouchStart: ne,
|
|
308
425
|
children: [
|
|
309
|
-
|
|
426
|
+
ce && /* @__PURE__ */ c("button", {
|
|
310
427
|
className: "react-pic-gallery__control react-pic-gallery__control--previous",
|
|
311
428
|
type: "button",
|
|
312
|
-
onClick:
|
|
429
|
+
onClick: q,
|
|
313
430
|
"aria-label": "Previous image",
|
|
314
|
-
children: /* @__PURE__ */
|
|
431
|
+
children: /* @__PURE__ */ c(N, { direction: "left" })
|
|
315
432
|
}),
|
|
316
|
-
/* @__PURE__ */
|
|
317
|
-
src:
|
|
318
|
-
alt:
|
|
433
|
+
/* @__PURE__ */ c(d, {
|
|
434
|
+
src: W.src,
|
|
435
|
+
alt: W.alt,
|
|
319
436
|
eager: !0,
|
|
320
437
|
objectFit: "contain",
|
|
321
|
-
className:
|
|
322
|
-
onAnimationEnd:
|
|
323
|
-
},
|
|
324
|
-
|
|
438
|
+
className: P("react-pic-gallery__lightbox-image", V ? `react-pic-gallery__lightbox-image--swipe-${V}` : void 0),
|
|
439
|
+
onAnimationEnd: ae
|
|
440
|
+
}, W.src),
|
|
441
|
+
le && /* @__PURE__ */ c("button", {
|
|
325
442
|
className: "react-pic-gallery__control react-pic-gallery__control--next",
|
|
326
443
|
type: "button",
|
|
327
|
-
onClick:
|
|
444
|
+
onClick: J,
|
|
328
445
|
"aria-label": "Next image",
|
|
329
|
-
children: /* @__PURE__ */
|
|
446
|
+
children: /* @__PURE__ */ c(N, { direction: "right" })
|
|
330
447
|
})
|
|
331
448
|
]
|
|
332
449
|
}),
|
|
333
|
-
(p ||
|
|
450
|
+
(p || W.caption) && /* @__PURE__ */ c("div", {
|
|
334
451
|
className: "react-pic-gallery__caption",
|
|
335
|
-
children: p ? p(
|
|
452
|
+
children: p ? p(Q) : W.caption
|
|
336
453
|
})
|
|
337
454
|
]
|
|
338
455
|
})
|
|
@@ -341,28 +458,29 @@ function E({ images: e, index: u, onIndexChange: d, renderActions: f, renderCapt
|
|
|
341
458
|
}
|
|
342
459
|
//#endregion
|
|
343
460
|
//#region src/lib/PicGallery.tsx
|
|
344
|
-
function
|
|
345
|
-
let [h, g] =
|
|
346
|
-
return /* @__PURE__ */
|
|
347
|
-
className: `react-pic-gallery ${
|
|
348
|
-
style:
|
|
349
|
-
children: [/* @__PURE__ */
|
|
461
|
+
function I({ images: e, layout: t, columns: n, rowHeight: r, className: i, galleryClassName: a, style: s, renderActions: u, renderCaption: d, renderControls: f, showCounter: p, showNavigation: m }) {
|
|
462
|
+
let [h, g] = o(null);
|
|
463
|
+
return /* @__PURE__ */ l("div", {
|
|
464
|
+
className: `react-pic-gallery ${i ?? ""}`.trim(),
|
|
465
|
+
style: s,
|
|
466
|
+
children: [/* @__PURE__ */ c(b, {
|
|
350
467
|
images: e,
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
468
|
+
layout: t,
|
|
469
|
+
columns: n,
|
|
470
|
+
rowHeight: r,
|
|
471
|
+
className: a,
|
|
354
472
|
onImageClick: g
|
|
355
|
-
}), /* @__PURE__ */
|
|
473
|
+
}), /* @__PURE__ */ c(F, {
|
|
356
474
|
images: e,
|
|
357
475
|
index: h,
|
|
358
476
|
onIndexChange: g,
|
|
359
|
-
renderActions:
|
|
360
|
-
renderCaption:
|
|
361
|
-
renderControls:
|
|
477
|
+
renderActions: u,
|
|
478
|
+
renderCaption: d,
|
|
479
|
+
renderControls: f,
|
|
362
480
|
showCounter: p,
|
|
363
481
|
showNavigation: m
|
|
364
482
|
})]
|
|
365
483
|
});
|
|
366
484
|
}
|
|
367
485
|
//#endregion
|
|
368
|
-
export {
|
|
486
|
+
export { b as Gallery, F as Lightbox, I as PicGallery, I as default };
|
package/dist/styles.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
:where(.react-pic-gallery,.react-pic-gallery__lightbox){--gallery-gap:.75rem;--gallery-radius:1rem;--gallery-row-height:12rem;--gallery-accent:#9ef01a;--gallery-overlay:#070b10f0;--gallery-control-size:2.75rem;--gallery-motion:.18s;color:#f8fafc}.react-pic-gallery{width:100%;min-width:0}.react-pic-gallery__grid{gap:var(--gallery-gap);grid-template-columns:repeat(3,minmax(0,1fr));width:100%;display:grid}.react-pic-gallery__tile{min-width:0;height:var(--gallery-row-height);cursor:pointer;border-radius:var(--gallery-radius);isolation:isolate;background:#e2e8f0;border:0;padding:0;position:relative;overflow:hidden}.react-pic-gallery__tile:after{content:"";pointer-events:none;border-radius:inherit;transition:border-color var(--gallery-motion) ease;border:2px solid #0000;position:absolute;inset:0}.react-pic-gallery__tile:hover .react-pic-gallery__image-element,.react-pic-gallery__tile:focus-visible .react-pic-gallery__image-element{transform:scale(1.04)}.react-pic-gallery__tile:focus-visible{outline:3px solid var(--gallery-accent);outline-offset:3px}.react-pic-gallery__tile:focus-visible:after{border-color:var(--gallery-accent)}.react-pic-gallery__tile:disabled{cursor:default}.react-pic-gallery__image{background:linear-gradient(135deg,#e2e8f0,#cbd5e1);width:100%;height:100%;display:block;position:relative;overflow:hidden}.react-pic-gallery__image-element{width:100%;height:100%;transition:transform var(--gallery-motion) ease, opacity var(--gallery-motion) ease;display:block}.react-pic-gallery__image-loader,.react-pic-gallery__image-error{place-items:center;display:grid;position:absolute;inset:0}.react-pic-gallery__image-loader:after{content:"";border:2px solid #0f172a29;border-top-color:var(--gallery-accent);border-radius:50%;width:1.5rem;height:1.5rem;animation:.7s linear infinite react-pic-gallery-spin}.react-pic-gallery__image-error{color:#475569;text-align:center;background:#e2e8f0e6;padding:1rem;font-size:.875rem}:where(dialog.react-pic-gallery__lightbox){z-index:1000;box-sizing:border-box;width:100%;max-width:none;height:100dvh;max-height:none;padding:max(1rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right)) max(1rem, env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left));color:#f8fafc;background:var(--gallery-overlay);animation:react-pic-gallery-fade-in var(--gallery-motion) ease both;border:0;place-items:center;margin:0;display:grid;position:fixed;inset:0;overflow:hidden}dialog.react-pic-gallery__lightbox:not([open]){display:none}dialog.react-pic-gallery__lightbox::backdrop{background:0 0}.react-pic-gallery__lightbox--closing{animation:react-pic-gallery-fade-out var(--gallery-motion) ease both}.react-pic-gallery__lightbox-content{box-sizing:border-box;width:min(90rem,100vw - 2rem);min-width:0;max-width:100%;height:min(54rem,100dvh - 2rem);min-height:0;max-height:100%;animation:react-pic-gallery-rise-in var(--gallery-motion) ease both;flex-direction:column;display:flex}.react-pic-gallery__lightbox--closing .react-pic-gallery__lightbox-content{animation:react-pic-gallery-rise-out var(--gallery-motion) ease both}.react-pic-gallery__toolbar,.react-pic-gallery__custom-controls{flex-wrap:wrap;flex:none;justify-content:space-between;align-items:center;gap:1rem;min-height:3.5rem;display:flex}.react-pic-gallery__toolbar-actions{color:#cbd5e1;align-items:center;gap:.75rem;min-width:0;font-size:.875rem;display:flex}.react-pic-gallery__control{width:var(--gallery-control-size);height:var(--gallery-control-size);color:#f8fafc;cursor:pointer;transition:background var(--gallery-motion) ease, color var(--gallery-motion) ease, transform var(--gallery-motion) ease;background:0 0;border:0;border-radius:.7rem;flex:none;place-items:center;padding:0;font-size:1.4rem;line-height:1;display:inline-grid}.react-pic-gallery__control:hover{background:#f8fafc24}.react-pic-gallery__control:focus-visible{outline:3px solid var(--gallery-accent);outline-offset:3px}.react-pic-gallery__control svg{fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.8px;width:1.25rem;height:1.25rem}.react-pic-gallery__viewport{touch-action:pan-y pinch-zoom;flex:1 1 0;place-items:center;min-width:0;min-height:0;padding:.75rem;display:grid;position:relative;overflow:hidden}.react-pic-gallery__viewport--has-navigation{padding-inline:3.5rem}.react-pic-gallery__viewport--has-navigation .react-pic-gallery__lightbox-image{inset-inline:3.5rem}.react-pic-gallery__lightbox-image{pointer-events:none;width:auto;min-width:0;max-width:82rem;height:auto;min-height:0;max-height:none;animation:react-pic-gallery-image-in var(--gallery-motion) ease both;background:0 0;border-radius:0;grid-template-rows:minmax(0,1fr);grid-template-columns:minmax(0,1fr);place-items:center;margin-inline:auto;display:grid;position:absolute;inset:.75rem;overflow:visible}.react-pic-gallery__lightbox-image .react-pic-gallery__image-element{pointer-events:auto;touch-action:inherit;border-radius:var(--gallery-radius);background:0 0;width:auto;max-width:100%;height:auto;max-height:100%;object-fit:contain!important}.react-pic-gallery__lightbox-image .react-pic-gallery__image-loader{pointer-events:none;background:0 0}.react-pic-gallery__lightbox-image .react-pic-gallery__image-error{pointer-events:none}.react-pic-gallery__lightbox-image--swipe-next{animation-name:react-pic-gallery-slide-in-from-right}.react-pic-gallery__lightbox-image--swipe-previous{animation-name:react-pic-gallery-slide-in-from-left}.react-pic-gallery__control--previous,.react-pic-gallery__control--next{z-index:1;position:absolute;top:50%;transform:translateY(-50%)}.react-pic-gallery__control--previous{left:0}.react-pic-gallery__control--next{right:0}.react-pic-gallery__caption{color:#cbd5e1;text-align:center;flex:none;max-height:8rem;padding:.75rem 0 0;font-size:.95rem;line-height:1.4;overflow:hidden}.react-pic-gallery__sr-only{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;padding:0;position:absolute;overflow:hidden}@keyframes react-pic-gallery-spin{to{transform:rotate(360deg)}}@keyframes react-pic-gallery-fade-in{0%{opacity:0}to{opacity:1}}@keyframes react-pic-gallery-fade-out{0%{opacity:1}to{opacity:0}}@keyframes react-pic-gallery-rise-in{0%{opacity:0;transform:translateY(.5rem)scale(.99)}to{opacity:1;transform:translateY(0)scale(1)}}@keyframes react-pic-gallery-rise-out{0%{opacity:1;transform:translateY(0)scale(1)}to{opacity:0;transform:translateY(.5rem)scale(.99)}}@keyframes react-pic-gallery-image-in{0%{opacity:0;transform:scale(.985)}to{opacity:1;transform:scale(1)}}@keyframes react-pic-gallery-slide-in-from-right{0%{opacity:0;transform:translate(18%)}to{opacity:1;transform:translate(0)}}@keyframes react-pic-gallery-slide-in-from-left{0%{opacity:0;transform:translate(-18%)}to{opacity:1;transform:translate(0)}}@media (width<=600px){:where(.react-pic-gallery,.react-pic-gallery__lightbox){--gallery-gap:.5rem;--gallery-radius:.75rem;--gallery-row-height:8rem}:where(dialog.react-pic-gallery__lightbox){padding:max(.375rem, env(safe-area-inset-top)) max(.375rem, env(safe-area-inset-right)) max(.375rem, env(safe-area-inset-bottom)) max(.375rem, env(safe-area-inset-left))}.react-pic-gallery__lightbox-content{width:min(90rem,100vw - .75rem);height:min(54rem,100dvh - .75rem)}.react-pic-gallery__toolbar,.react-pic-gallery__custom-controls{min-height:3rem}.react-pic-gallery__viewport{padding:.25rem}.react-pic-gallery__lightbox-image{inset:.25rem}.react-pic-gallery__viewport--has-navigation .react-pic-gallery__lightbox-image{inset-inline:.25rem}.react-pic-gallery__control--previous,.react-pic-gallery__control--next{display:none}}@media (height<=600px){:where(dialog.react-pic-gallery__lightbox){padding:max(.25rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right)) max(.25rem, env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left))}.react-pic-gallery__lightbox-content{height:min(54rem,100dvh - .5rem)}.react-pic-gallery__toolbar,.react-pic-gallery__custom-controls{min-height:2.25rem}.react-pic-gallery__caption{max-height:4rem;padding:.35rem 0 0;font-size:.85rem}.react-pic-gallery__viewport{padding:.25rem}.react-pic-gallery__lightbox-image{inset:.25rem}}@media (prefers-reduced-motion:reduce){:where(.react-pic-gallery,.react-pic-gallery__lightbox){--gallery-motion:0s}.react-pic-gallery__image-loader:after{animation:none}}
|
|
1
|
+
:where(.react-pic-gallery,.react-pic-gallery__lightbox){--gallery-gap:.75rem;--gallery-radius:1rem;--gallery-row-height:12rem;--gallery-accent:#9ef01a;--gallery-overlay:#070b10f0;--gallery-control-size:2.75rem;--gallery-motion:.18s;color:#f8fafc}.react-pic-gallery{width:100%;min-width:0}.react-pic-gallery__gallery{width:100%;min-width:0;position:relative}.react-pic-gallery__grid{gap:var(--gallery-gap,.75rem);grid-template-columns:repeat(3,minmax(0,1fr));width:100%;display:grid}.react-pic-gallery__gallery--justified{align-content:flex-start;gap:var(--gallery-gap,.75rem);flex-wrap:wrap;display:flex}.react-pic-gallery__gallery--justified>.react-pic-gallery__tile--justified{flex:none;height:auto}.react-pic-gallery__row-height-probe{width:var(--gallery-gap,.75rem);height:var(--gallery-row-height,12rem);visibility:hidden;pointer-events:none;position:absolute;overflow:hidden}.react-pic-gallery__gallery--mosaic{gap:var(--gallery-gap,.75rem);display:grid}.react-pic-gallery__mosaic-group{grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);grid-template-rows:repeat(2, minmax(0, var(--gallery-row-height,12rem)));gap:var(--gallery-gap,.75rem);min-width:0;display:grid}.react-pic-gallery__mosaic-group--top{grid-template-columns:repeat(2,minmax(0,1fr))}.react-pic-gallery__mosaic-group .react-pic-gallery__tile--mosaic{min-width:0;height:auto}.react-pic-gallery__mosaic-group--left .react-pic-gallery__tile--mosaic-featured{grid-area:1/1/span 2}.react-pic-gallery__mosaic-group--top .react-pic-gallery__tile--mosaic-featured{grid-area:1/1/auto/-1}.react-pic-gallery__mosaic-group--count-2{grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:minmax(0, var(--gallery-row-height,12rem))}.react-pic-gallery__mosaic-group--count-1{grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(0, var(--gallery-row-height,12rem))}.react-pic-gallery__tile{min-width:0;height:var(--gallery-row-height,12rem);cursor:pointer;border-radius:var(--gallery-radius,1rem);isolation:isolate;background:#e2e8f0;border:0;padding:0;position:relative;overflow:hidden}.react-pic-gallery__tile:after{content:"";pointer-events:none;border-radius:inherit;transition:border-color var(--gallery-motion,.18s) ease;border:2px solid #0000;position:absolute;inset:0}.react-pic-gallery__tile:hover .react-pic-gallery__image-element,.react-pic-gallery__tile:focus-visible .react-pic-gallery__image-element{transform:scale(1.04)}.react-pic-gallery__tile:focus-visible{outline:3px solid var(--gallery-accent,#9ef01a);outline-offset:3px}.react-pic-gallery__tile:focus-visible:after{border-color:var(--gallery-accent,#9ef01a)}.react-pic-gallery__tile:disabled{cursor:default}.react-pic-gallery__image{background:linear-gradient(135deg,#e2e8f0,#cbd5e1);width:100%;height:100%;display:block;position:relative;overflow:hidden}.react-pic-gallery__image-element{width:100%;height:100%;transition:transform var(--gallery-motion,.18s) ease, opacity var(--gallery-motion,.18s) ease;display:block}.react-pic-gallery__image-loader,.react-pic-gallery__image-error{place-items:center;display:grid;position:absolute;inset:0}.react-pic-gallery__image-loader:after{content:"";border:2px solid #0f172a29;border-top-color:var(--gallery-accent,#9ef01a);border-radius:50%;width:1.5rem;height:1.5rem;animation:.7s linear infinite react-pic-gallery-spin}.react-pic-gallery__image-error{color:#475569;text-align:center;background:#e2e8f0e6;padding:1rem;font-size:.875rem}:where(dialog.react-pic-gallery__lightbox){z-index:1000;box-sizing:border-box;width:100%;max-width:none;height:100dvh;max-height:none;padding:max(1rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right)) max(1rem, env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left));color:#f8fafc;background:var(--gallery-overlay);animation:react-pic-gallery-fade-in var(--gallery-motion) ease both;border:0;place-items:center;margin:0;display:grid;position:fixed;inset:0;overflow:hidden}dialog.react-pic-gallery__lightbox:not([open]){display:none}dialog.react-pic-gallery__lightbox::backdrop{background:0 0}.react-pic-gallery__lightbox--closing{animation:react-pic-gallery-fade-out var(--gallery-motion) ease both}.react-pic-gallery__lightbox-content{box-sizing:border-box;width:min(90rem,100vw - 2rem);min-width:0;max-width:100%;height:min(54rem,100dvh - 2rem);min-height:0;max-height:100%;animation:react-pic-gallery-rise-in var(--gallery-motion) ease both;flex-direction:column;display:flex}.react-pic-gallery__lightbox--closing .react-pic-gallery__lightbox-content{animation:react-pic-gallery-rise-out var(--gallery-motion) ease both}.react-pic-gallery__toolbar,.react-pic-gallery__custom-controls{flex-wrap:wrap;flex:none;justify-content:space-between;align-items:center;gap:1rem;min-height:3.5rem;display:flex}.react-pic-gallery__toolbar-actions{color:#cbd5e1;align-items:center;gap:.75rem;min-width:0;font-size:.875rem;display:flex}.react-pic-gallery__control{width:var(--gallery-control-size);height:var(--gallery-control-size);color:#f8fafc;cursor:pointer;transition:background var(--gallery-motion) ease, color var(--gallery-motion) ease, transform var(--gallery-motion) ease;background:0 0;border:0;border-radius:.7rem;flex:none;place-items:center;padding:0;font-size:1.4rem;line-height:1;display:inline-grid}.react-pic-gallery__control:hover{background:#f8fafc24}.react-pic-gallery__control:focus-visible{outline:3px solid var(--gallery-accent);outline-offset:3px}.react-pic-gallery__control svg{fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.8px;width:1.25rem;height:1.25rem}.react-pic-gallery__viewport{touch-action:pan-y pinch-zoom;flex:1 1 0;place-items:center;min-width:0;min-height:0;padding:.75rem;display:grid;position:relative;overflow:hidden}.react-pic-gallery__viewport--has-navigation{padding-inline:3.5rem}.react-pic-gallery__viewport--has-navigation .react-pic-gallery__lightbox-image{inset-inline:3.5rem}.react-pic-gallery__lightbox-image{pointer-events:none;width:auto;min-width:0;max-width:82rem;height:auto;min-height:0;max-height:none;animation:react-pic-gallery-image-in var(--gallery-motion) ease both;background:0 0;border-radius:0;grid-template-rows:minmax(0,1fr);grid-template-columns:minmax(0,1fr);place-items:center;margin-inline:auto;display:grid;position:absolute;inset:.75rem;overflow:visible}.react-pic-gallery__lightbox-image .react-pic-gallery__image-element{pointer-events:auto;touch-action:inherit;border-radius:var(--gallery-radius);background:0 0;width:auto;max-width:100%;height:auto;max-height:100%;object-fit:contain!important}.react-pic-gallery__lightbox-image .react-pic-gallery__image-loader{pointer-events:none;background:0 0}.react-pic-gallery__lightbox-image .react-pic-gallery__image-error{pointer-events:none}.react-pic-gallery__lightbox-image--swipe-next{animation-name:react-pic-gallery-slide-in-from-right}.react-pic-gallery__lightbox-image--swipe-previous{animation-name:react-pic-gallery-slide-in-from-left}.react-pic-gallery__control--previous,.react-pic-gallery__control--next{z-index:1;position:absolute;top:50%;transform:translateY(-50%)}.react-pic-gallery__control--previous{left:0}.react-pic-gallery__control--next{right:0}.react-pic-gallery__caption{color:#cbd5e1;text-align:center;flex:none;max-height:8rem;padding:.75rem 0 0;font-size:.95rem;line-height:1.4;overflow:hidden}.react-pic-gallery__sr-only{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;padding:0;position:absolute;overflow:hidden}@keyframes react-pic-gallery-spin{to{transform:rotate(360deg)}}@keyframes react-pic-gallery-fade-in{0%{opacity:0}to{opacity:1}}@keyframes react-pic-gallery-fade-out{0%{opacity:1}to{opacity:0}}@keyframes react-pic-gallery-rise-in{0%{opacity:0;transform:translateY(.5rem)scale(.99)}to{opacity:1;transform:translateY(0)scale(1)}}@keyframes react-pic-gallery-rise-out{0%{opacity:1;transform:translateY(0)scale(1)}to{opacity:0;transform:translateY(.5rem)scale(.99)}}@keyframes react-pic-gallery-image-in{0%{opacity:0;transform:scale(.985)}to{opacity:1;transform:scale(1)}}@keyframes react-pic-gallery-slide-in-from-right{0%{opacity:0;transform:translate(18%)}to{opacity:1;transform:translate(0)}}@keyframes react-pic-gallery-slide-in-from-left{0%{opacity:0;transform:translate(-18%)}to{opacity:1;transform:translate(0)}}@media (width<=600px){:where(.react-pic-gallery,.react-pic-gallery__lightbox){--gallery-gap:.5rem;--gallery-radius:.75rem;--gallery-row-height:8rem}:where(dialog.react-pic-gallery__lightbox){padding:max(.375rem, env(safe-area-inset-top)) max(.375rem, env(safe-area-inset-right)) max(.375rem, env(safe-area-inset-bottom)) max(.375rem, env(safe-area-inset-left))}.react-pic-gallery__mosaic-group--count-3{grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:minmax(8rem, var(--gallery-row-height,12rem)) minmax(5rem, .65fr)}.react-pic-gallery__mosaic-group--count-3 .react-pic-gallery__tile--mosaic-featured{grid-area:1/1/auto/-1}.react-pic-gallery__lightbox-content{width:min(90rem,100vw - .75rem);height:min(54rem,100dvh - .75rem)}.react-pic-gallery__toolbar,.react-pic-gallery__custom-controls{min-height:3rem}.react-pic-gallery__viewport{padding:.25rem}.react-pic-gallery__lightbox-image{inset:.25rem}.react-pic-gallery__viewport--has-navigation .react-pic-gallery__lightbox-image{inset-inline:.25rem}.react-pic-gallery__control--previous,.react-pic-gallery__control--next{display:none}}@media (height<=600px){:where(dialog.react-pic-gallery__lightbox){padding:max(.25rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right)) max(.25rem, env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left))}.react-pic-gallery__lightbox-content{height:min(54rem,100dvh - .5rem)}.react-pic-gallery__toolbar,.react-pic-gallery__custom-controls{min-height:2.25rem}.react-pic-gallery__caption{max-height:4rem;padding:.35rem 0 0;font-size:.85rem}.react-pic-gallery__viewport{padding:.25rem}.react-pic-gallery__lightbox-image{inset:.25rem}}@media (prefers-reduced-motion:reduce){:where(.react-pic-gallery,.react-pic-gallery__lightbox){--gallery-motion:0s}.react-pic-gallery__image-loader:after{animation:none}}
|
|
2
2
|
/*$vite$:1*/
|
package/dist/types.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export type GalleryImage = {
|
|
|
8
8
|
width?: number;
|
|
9
9
|
height?: number;
|
|
10
10
|
};
|
|
11
|
+
export type GalleryLayout = 'grid' | 'justified' | 'mosaic';
|
|
11
12
|
export type LightboxContext<T extends GalleryImage = GalleryImage> = {
|
|
12
13
|
image: T;
|
|
13
14
|
index: number;
|
|
@@ -22,6 +23,7 @@ export type LightboxRenderer<T extends GalleryImage = GalleryImage> = (context:
|
|
|
22
23
|
export type GalleryProps<T extends GalleryImage = GalleryImage> = {
|
|
23
24
|
images: readonly T[];
|
|
24
25
|
onImageClick?: (index: number) => void;
|
|
26
|
+
layout?: GalleryLayout;
|
|
25
27
|
columns?: number;
|
|
26
28
|
rowHeight?: CSSProperties['height'];
|
|
27
29
|
className?: string;
|
|
@@ -40,6 +42,7 @@ export type LightboxProps<T extends GalleryImage = GalleryImage> = {
|
|
|
40
42
|
};
|
|
41
43
|
export type PicGalleryProps<T extends GalleryImage = GalleryImage> = {
|
|
42
44
|
images: readonly T[];
|
|
45
|
+
layout?: GalleryLayout;
|
|
43
46
|
columns?: number;
|
|
44
47
|
rowHeight?: CSSProperties['height'];
|
|
45
48
|
className?: string;
|