@reelkit/react-lightbox
Advanced tools
+1
-1
@@ -53,3 +53,3 @@ /** | ||
| export type { UseVideoSlideRendererResult } from './lib/useVideoSlideRenderer'; | ||
| export { default as useFullscreen } from './lib/useFullscreen'; | ||
| export { useFullscreen } from './lib/useFullscreen'; | ||
| export type { UseFullscreenProps, UseFullscreenResult, } from './lib/useFullscreen'; |
+231
-239
@@ -1,73 +0,74 @@ | ||
| import { jsx as n, jsxs as E, Fragment as O } from "react/jsx-runtime"; | ||
| import { useState as L, useRef as C, useEffect as x, useCallback as w, useLayoutEffect as ae, useMemo as de } from "react"; | ||
| import { createPortal as he } from "react-dom"; | ||
| import { createSignal as I, createGestureController as me } from "@reelkit/core"; | ||
| import { Observe as ee, useBodyLock as fe, Reel as ge } from "@reelkit/react"; | ||
| import { X as ve, Minimize as be, Maximize as pe, VolumeX as we, Volume2 as xe, ChevronLeft as ke, ChevronRight as Ee } from "lucide-react"; | ||
| const q = () => { | ||
| import { jsx as n, jsxs as k, Fragment as q } from "react/jsx-runtime"; | ||
| import { useState as y, useRef as L, useEffect as w, useCallback as p, useLayoutEffect as ie, useMemo as ce } from "react"; | ||
| import { createPortal as ae } from "react-dom"; | ||
| import { createSignal as S, createGestureController as ue, Observe as Q, useBodyLock as de, Reel as he, createSharedVideo as me, noop as fe, captureFrame as ge } from "@reelkit/react"; | ||
| import { X as ve, Minimize as be, Maximize as pe, VolumeX as we, Volume2 as xe, ChevronLeft as ke, ChevronRight as Fe } from "lucide-react"; | ||
| const T = () => { | ||
| const e = document; | ||
| return (e.fullscreenElement ?? e.webkitFullscreenElement ?? e.mozFullScreenElement ?? e.msFullscreenElement) != null; | ||
| }, V = () => { | ||
| }, $ = () => { | ||
| const e = document; | ||
| return e.exitFullscreen ? e.exitFullscreen() : e.webkitExitFullscreen ? e.webkitExitFullscreen() : e.mozCancelFullScreen ? e.mozCancelFullScreen() : e.msExitFullscreen ? e.msExitFullscreen() : Promise.resolve(); | ||
| }, Fe = (e) => { | ||
| }, Ee = (e) => { | ||
| const t = e; | ||
| return t.requestFullscreen ? t.requestFullscreen() : t.webkitRequestFullscreen ? t.webkitRequestFullscreen() : t.webkitEnterFullscreen ? t.webkitEnterFullscreen() : t.mozRequestFullScreen ? t.mozRequestFullScreen() : t.msRequestFullscreen ? t.msRequestFullscreen() : Promise.resolve(); | ||
| }, ye = (e) => { | ||
| const [t, r] = L(!1), s = C(!0); | ||
| x(() => (s.current = !0, () => { | ||
| s.current = !1; | ||
| const [t, o] = y(!1), l = L(!0); | ||
| w(() => (l.current = !0, () => { | ||
| l.current = !1; | ||
| }), []); | ||
| const i = w(() => { | ||
| e.ref.current !== null && (q() && V(), Fe(e.ref.current).then(() => { | ||
| s.current && r(!0); | ||
| }).catch((o) => { | ||
| const i = p(() => { | ||
| e.ref.current !== null && (T() && $(), Ee(e.ref.current).then(() => { | ||
| l.current && o(!0); | ||
| }).catch((r) => { | ||
| console.log( | ||
| `Error attempting to enable full-screen mode: ${o.message} (${o.name})` | ||
| `Error attempting to enable full-screen mode: ${r.message} (${r.name})` | ||
| ); | ||
| })); | ||
| }, [e.ref]), d = w(() => { | ||
| V().then(() => { | ||
| s.current && r(!1); | ||
| }).catch((o) => { | ||
| }, []), u = p(() => { | ||
| $().then(() => { | ||
| l.current && o(!1); | ||
| }).catch((r) => { | ||
| console.log( | ||
| `Error attempting to exit full-screen mode: ${o.message} (${o.name})` | ||
| `Error attempting to exit full-screen mode: ${r.message} (${r.name})` | ||
| ); | ||
| }); | ||
| }, []), a = p(() => { | ||
| T() ? u() : i(); | ||
| }, []); | ||
| return x(() => { | ||
| const o = () => { | ||
| s.current && r(q()); | ||
| return w(() => { | ||
| const r = () => { | ||
| l.current && o(T()); | ||
| }; | ||
| return document.addEventListener("fullscreenchange", o), document.addEventListener("webkitfullscreenchange", o), document.addEventListener("mozfullscreenchange", o), document.addEventListener("MSFullscreenChange", o), () => { | ||
| document.removeEventListener("fullscreenchange", o), document.removeEventListener( | ||
| return document.addEventListener("fullscreenchange", r), document.addEventListener("webkitfullscreenchange", r), document.addEventListener("mozfullscreenchange", r), document.addEventListener("MSFullscreenChange", r), () => { | ||
| document.removeEventListener("fullscreenchange", r), document.removeEventListener( | ||
| "webkitfullscreenchange", | ||
| o | ||
| r | ||
| ), document.removeEventListener( | ||
| "mozfullscreenchange", | ||
| o | ||
| r | ||
| ), document.removeEventListener( | ||
| "MSFullscreenChange", | ||
| o | ||
| r | ||
| ); | ||
| }; | ||
| }, []), x(() => () => { | ||
| q() && V(); | ||
| }, []), [t, i, d]; | ||
| }, []), w(() => () => { | ||
| T() && $(); | ||
| }, []), [t, i, u, a]; | ||
| }, Le = ({ | ||
| enabled: e, | ||
| onClose: t, | ||
| children: r, | ||
| className: s | ||
| children: o, | ||
| className: l | ||
| }) => { | ||
| const i = C(null), d = C(null), [o, u, c] = L( | ||
| () => [I(0), I(1), I(!1)] | ||
| )[0], h = C(!1); | ||
| return x(() => { | ||
| const i = L(null), u = L(null), [a, r, c] = y( | ||
| () => [S(0), S(1), S(!1)] | ||
| )[0], h = L(!1); | ||
| return w(() => { | ||
| if (!e || !i.current) return; | ||
| const l = window.innerHeight, g = l * 0.2, k = () => { | ||
| c.value = !0, o.value = 0, u.value = 1, setTimeout(() => { | ||
| const s = window.innerHeight, f = s * 0.2, x = () => { | ||
| c.value = !0, a.value = 0, r.value = 1, setTimeout(() => { | ||
| c.value = !1; | ||
| }, 300); | ||
| }, v = me( | ||
| }, g = ue( | ||
| { useTouchEventsOnly: !0 }, | ||
@@ -79,10 +80,10 @@ { | ||
| onVerticalDragUpdate: (F) => { | ||
| const { primaryDistance: b } = F; | ||
| if (b < 0) { | ||
| o.value = b; | ||
| const R = Math.min( | ||
| Math.abs(b) / (l * 0.3), | ||
| const { primaryDistance: v } = F; | ||
| if (v < 0) { | ||
| a.value = v; | ||
| const C = Math.min( | ||
| Math.abs(v) / (s * 0.3), | ||
| 1 | ||
| ); | ||
| u.value = 1 - R * 0.8; | ||
| r.value = 1 - C * 0.8; | ||
| } | ||
@@ -92,4 +93,4 @@ }, | ||
| h.current = !0; | ||
| const { primaryDistance: b } = F; | ||
| b < 0 && Math.abs(b) > g ? (c.value = !0, o.value = -l, u.value = 0, setTimeout(t, 300)) : k(); | ||
| const { primaryDistance: v } = F; | ||
| v < 0 && Math.abs(v) > f ? (c.value = !0, a.value = -s, r.value = 0, setTimeout(t, 300)) : x(); | ||
| }, | ||
@@ -99,26 +100,26 @@ // Fallback: reset if vertical drag started but onVerticalDragEnd wasn't called | ||
| onDragEnd: () => { | ||
| !h.current && o.value !== 0 && k(); | ||
| !h.current && a.value !== 0 && x(); | ||
| } | ||
| } | ||
| ); | ||
| return v.attach(i.current), v.observe(), d.current = v, () => { | ||
| v.unobserve(), v.detach(), d.current = null; | ||
| return g.attach(i.current), g.observe(), u.current = g, () => { | ||
| g.unobserve(), g.detach(), u.current = null; | ||
| }; | ||
| }, [e, t, o, u, c]), /* @__PURE__ */ n(ee, { signals: [o, u, c], children: () => /* @__PURE__ */ n( | ||
| }, [e, t, a, r, c]), /* @__PURE__ */ n(Q, { signals: [a, r, c], children: () => /* @__PURE__ */ n( | ||
| "div", | ||
| { | ||
| ref: i, | ||
| className: s, | ||
| className: l, | ||
| style: { | ||
| transform: `translateY(${o.value}px)`, | ||
| opacity: u.value, | ||
| transform: `translateY(${a.value}px)`, | ||
| opacity: r.value, | ||
| transition: c.value ? "transform 300ms ease-out, opacity 300ms ease-out" : "none" | ||
| }, | ||
| children: r | ||
| children: o | ||
| } | ||
| ) }); | ||
| }, te = ({ | ||
| }, Z = ({ | ||
| onClick: e, | ||
| className: t = "rk-lightbox-close", | ||
| style: r | ||
| style: o | ||
| }) => /* @__PURE__ */ n( | ||
@@ -130,26 +131,26 @@ "button", | ||
| title: "Close (Esc)", | ||
| style: r, | ||
| style: o, | ||
| children: /* @__PURE__ */ n(ve, { size: 24 }) | ||
| } | ||
| ), ne = ({ | ||
| ), K = ({ | ||
| currentIndex: e, | ||
| count: t, | ||
| className: r = "rk-lightbox-counter", | ||
| style: s | ||
| }) => /* @__PURE__ */ E("span", { className: r, style: s, children: [ | ||
| className: o = "rk-lightbox-counter", | ||
| style: l | ||
| }) => /* @__PURE__ */ k("span", { className: o, style: l, children: [ | ||
| e + 1, | ||
| " / ", | ||
| t | ||
| ] }), re = ({ | ||
| ] }), ee = ({ | ||
| isFullscreen: e, | ||
| onToggle: t, | ||
| className: r = "rk-lightbox-btn", | ||
| style: s | ||
| className: o = "rk-lightbox-btn", | ||
| style: l | ||
| }) => /* @__PURE__ */ n( | ||
| "button", | ||
| { | ||
| className: r, | ||
| className: o, | ||
| onClick: t, | ||
| title: e ? "Exit Fullscreen" : "Enter Fullscreen", | ||
| style: s, | ||
| style: l, | ||
| children: e ? /* @__PURE__ */ n(be, { size: 20 }) : /* @__PURE__ */ n(pe, { size: 20 }) | ||
@@ -160,11 +161,11 @@ } | ||
| onToggle: t, | ||
| className: r = "rk-lightbox-btn", | ||
| style: s | ||
| className: o = "rk-lightbox-btn", | ||
| style: l | ||
| }) => /* @__PURE__ */ n( | ||
| "button", | ||
| { | ||
| className: r, | ||
| className: o, | ||
| onClick: t, | ||
| title: e ? "Unmute" : "Mute", | ||
| style: s, | ||
| style: l, | ||
| children: e ? /* @__PURE__ */ n(we, { size: 20 }) : /* @__PURE__ */ n(xe, { size: 20 }) | ||
@@ -175,12 +176,12 @@ } | ||
| currentIndex: t, | ||
| count: r, | ||
| isFullscreen: s, | ||
| count: o, | ||
| isFullscreen: l, | ||
| onToggleFullscreen: i | ||
| }) => /* @__PURE__ */ E(O, { children: [ | ||
| /* @__PURE__ */ E("div", { className: "rk-lightbox-controls-left", children: [ | ||
| /* @__PURE__ */ n(ne, { currentIndex: t, count: r }), | ||
| }) => /* @__PURE__ */ k(q, { children: [ | ||
| /* @__PURE__ */ k("div", { className: "rk-lightbox-controls-left", children: [ | ||
| /* @__PURE__ */ n(K, { currentIndex: t, count: o }), | ||
| /* @__PURE__ */ n( | ||
| re, | ||
| ee, | ||
| { | ||
| isFullscreen: s, | ||
| isFullscreen: l, | ||
| onToggle: i | ||
@@ -190,6 +191,6 @@ } | ||
| ] }), | ||
| /* @__PURE__ */ n(te, { onClick: e }) | ||
| ] }), Y = 2, J = /* @__PURE__ */ new Set(), Q = (e) => { | ||
| if (J.has(e)) return; | ||
| J.add(e); | ||
| /* @__PURE__ */ n(Z, { onClick: e }) | ||
| ] }), U = 2, X = /* @__PURE__ */ new Set(), Y = (e) => { | ||
| if (X.has(e)) return; | ||
| X.add(e); | ||
| const t = new Image(); | ||
@@ -200,70 +201,68 @@ t.src = e; | ||
| initialIndex: t = 0, | ||
| onClose: r, | ||
| transition: s = "slide", | ||
| onClose: o, | ||
| transition: l = "slide", | ||
| onSlideChange: i, | ||
| apiRef: d, | ||
| renderControls: o, | ||
| renderNavigation: u, | ||
| apiRef: u, | ||
| renderControls: a, | ||
| renderNavigation: r, | ||
| renderInfo: c, | ||
| renderSlide: h, | ||
| // Reel proxy props with defaults | ||
| transitionDuration: l, | ||
| swipeDistanceFactor: g, | ||
| loop: k = !1, | ||
| useNavKeys: v = !0, | ||
| transitionDuration: s, | ||
| swipeDistanceFactor: f, | ||
| loop: x = !1, | ||
| useNavKeys: g = !0, | ||
| enableWheel: F = !0, | ||
| wheelDebounceMs: b | ||
| wheelDebounceMs: v | ||
| }) => { | ||
| const R = C(null), le = C(null), z = d ?? le, [m, se] = L(t), j = C(m); | ||
| j.current = m; | ||
| const [S] = L( | ||
| () => I( | ||
| const C = L(null), ne = L(null), z = u ?? ne, [m, re] = y(t), D = L(m); | ||
| D.current = m; | ||
| const [I] = y( | ||
| () => S( | ||
| typeof window < "u" ? [window.innerWidth, window.innerHeight] : [0, 0] | ||
| ) | ||
| ), [M, B, T] = ye({ | ||
| ref: R | ||
| }), [$, ie] = L( | ||
| ), [M, Pe, O, B] = ye({ | ||
| ref: C | ||
| }), [V, oe] = y( | ||
| () => typeof window < "u" ? "ontouchstart" in window || navigator.maxTouchPoints > 0 : !1 | ||
| ); | ||
| fe(!0), x(() => { | ||
| const a = () => { | ||
| S.value = [window.innerWidth, window.innerHeight], ie("ontouchstart" in window || navigator.maxTouchPoints > 0); | ||
| de(!0), w(() => { | ||
| const d = () => { | ||
| I.value = [window.innerWidth, window.innerHeight], oe("ontouchstart" in window || navigator.maxTouchPoints > 0); | ||
| }; | ||
| return window.addEventListener("resize", a), () => window.removeEventListener("resize", a); | ||
| }, []), x(() => { | ||
| const a = Math.max(0, m - Y), P = Math.min(e.length - 1, m + Y); | ||
| for (let p = a; p <= P; p++) | ||
| if (p !== m) { | ||
| const y = e[p]; | ||
| (y.type ?? "image") === "video" ? y.poster && Q(y.poster) : Q(y.src); | ||
| return window.addEventListener("resize", d), () => window.removeEventListener("resize", d); | ||
| }, []), w(() => { | ||
| const d = Math.max(0, m - U), P = Math.min(e.length - 1, m + U); | ||
| for (let b = d; b <= P; b++) | ||
| if (b !== m) { | ||
| const E = e[b]; | ||
| (E.type ?? "image") === "video" ? E.poster && Y(E.poster) : Y(E.src); | ||
| } | ||
| }, [m, e]), x(() => { | ||
| const a = (P) => { | ||
| P.key === "Escape" && (M ? T() : r()); | ||
| }, [m, e]), w(() => { | ||
| const d = (P) => { | ||
| P.key === "Escape" && (M ? O() : o()); | ||
| }; | ||
| return window.addEventListener("keydown", a), () => window.removeEventListener("keydown", a); | ||
| }, [M, T, r]); | ||
| const ce = w( | ||
| (a) => { | ||
| se(a), i?.(a); | ||
| return window.addEventListener("keydown", d), () => window.removeEventListener("keydown", d); | ||
| }, [M, O, o]); | ||
| const se = p( | ||
| (d) => { | ||
| re(d), i?.(d); | ||
| }, | ||
| [i] | ||
| ), H = w(() => { | ||
| ), j = p(() => { | ||
| z.current?.prev(); | ||
| }, [z]), W = w(() => { | ||
| }, [z]), H = p(() => { | ||
| z.current?.next(); | ||
| }, [z]), A = w(() => { | ||
| M ? T() : B(); | ||
| }, [M, B, T]), N = e[m], ue = w( | ||
| (a, P, p) => { | ||
| const y = e[a], G = a === j.current, X = `rk-lightbox-slide ${s !== "slide" ? `rk-transition-${s}` : ""} ${G ? "rk-active" : ""}`.trim(); | ||
| }, [z]), R = e[m], le = p( | ||
| (d, P, b) => { | ||
| const E = e[d], W = d === D.current, _ = `rk-lightbox-slide ${l !== "slide" ? `rk-transition-${l}` : ""} ${W ? "rk-active" : ""}`.trim(); | ||
| if (h) { | ||
| const _ = h(y, a, p, G); | ||
| if (_ !== null) | ||
| const G = h(E, d, b, W); | ||
| if (G !== null) | ||
| return /* @__PURE__ */ n( | ||
| "div", | ||
| { | ||
| className: X, | ||
| style: { width: p[0], height: p[1] }, | ||
| children: _ | ||
| className: _, | ||
| style: { width: b[0], height: b[1] }, | ||
| children: G | ||
| } | ||
@@ -275,11 +274,12 @@ ); | ||
| { | ||
| className: X, | ||
| style: { width: p[0], height: p[1] }, | ||
| className: _, | ||
| style: { width: b[0], height: b[1] }, | ||
| children: /* @__PURE__ */ n( | ||
| "img", | ||
| { | ||
| src: y.src, | ||
| alt: y.title || `Image ${a + 1}`, | ||
| src: E.src, | ||
| alt: E.title || `Image ${d + 1}`, | ||
| className: "rk-lightbox-img", | ||
| draggable: !1 | ||
| draggable: !1, | ||
| loading: "lazy" | ||
| } | ||
@@ -290,44 +290,44 @@ ) | ||
| }, | ||
| [e, s, h] | ||
| ), U = /* @__PURE__ */ E("div", { ref: R, className: "rk-lightbox-container", children: [ | ||
| o ? o({ | ||
| onClose: r, | ||
| [e, l, h] | ||
| ), A = /* @__PURE__ */ k("div", { ref: C, className: "rk-lightbox-container", children: [ | ||
| a ? a({ | ||
| onClose: o, | ||
| currentIndex: m, | ||
| count: e.length, | ||
| isFullscreen: M, | ||
| onToggleFullscreen: A | ||
| onToggleFullscreen: B | ||
| }) : /* @__PURE__ */ n( | ||
| Re, | ||
| { | ||
| onClose: r, | ||
| onClose: o, | ||
| currentIndex: m, | ||
| count: e.length, | ||
| isFullscreen: M, | ||
| onToggleFullscreen: A | ||
| onToggleFullscreen: B | ||
| } | ||
| ), | ||
| /* @__PURE__ */ n(Le, { enabled: $, onClose: r, children: /* @__PURE__ */ n(ee, { signals: [S], children: () => /* @__PURE__ */ n( | ||
| ge, | ||
| /* @__PURE__ */ n(Le, { enabled: V, onClose: o, children: /* @__PURE__ */ n(Q, { signals: [I], children: () => /* @__PURE__ */ n( | ||
| he, | ||
| { | ||
| count: e.length, | ||
| size: S.value, | ||
| size: I.value, | ||
| direction: "horizontal", | ||
| initialIndex: t, | ||
| apiRef: z, | ||
| afterChange: ce, | ||
| transitionDuration: l, | ||
| swipeDistanceFactor: g, | ||
| loop: k, | ||
| useNavKeys: v, | ||
| afterChange: se, | ||
| transitionDuration: s, | ||
| swipeDistanceFactor: f, | ||
| loop: x, | ||
| useNavKeys: g, | ||
| enableWheel: F, | ||
| wheelDebounceMs: b, | ||
| itemBuilder: ue | ||
| wheelDebounceMs: v, | ||
| itemBuilder: le | ||
| } | ||
| ) }) }), | ||
| u ? u({ | ||
| onPrev: H, | ||
| onNext: W, | ||
| r ? r({ | ||
| onPrev: j, | ||
| onNext: H, | ||
| activeIndex: m, | ||
| count: e.length | ||
| }) : !$ && e.length > 1 && /* @__PURE__ */ E(O, { children: [ | ||
| }) : !V && e.length > 1 && /* @__PURE__ */ k(q, { children: [ | ||
| m > 0 && /* @__PURE__ */ n( | ||
@@ -337,3 +337,3 @@ "button", | ||
| className: "rk-lightbox-nav rk-lightbox-nav-prev", | ||
| onClick: H, | ||
| onClick: j, | ||
| title: "Previous", | ||
@@ -347,69 +347,61 @@ children: /* @__PURE__ */ n(ke, { size: 32 }) | ||
| className: "rk-lightbox-nav rk-lightbox-nav-next", | ||
| onClick: W, | ||
| onClick: H, | ||
| title: "Next", | ||
| children: /* @__PURE__ */ n(Ee, { size: 32 }) | ||
| children: /* @__PURE__ */ n(Fe, { size: 32 }) | ||
| } | ||
| ) | ||
| ] }), | ||
| c ? c({ item: N, index: m }) : (N?.title || N?.description) && /* @__PURE__ */ E("div", { className: "rk-lightbox-info", children: [ | ||
| N.title && /* @__PURE__ */ n("h3", { className: "rk-lightbox-title", children: N.title }), | ||
| N.description && /* @__PURE__ */ n("p", { className: "rk-lightbox-description", children: N.description }) | ||
| c ? c({ item: R, index: m }) : (R?.title || R?.description) && /* @__PURE__ */ k("div", { className: "rk-lightbox-info", children: [ | ||
| R.title && /* @__PURE__ */ n("h3", { className: "rk-lightbox-title", children: R.title }), | ||
| R.description && /* @__PURE__ */ n("p", { className: "rk-lightbox-description", children: R.description }) | ||
| ] }), | ||
| $ && /* @__PURE__ */ n("div", { className: "rk-lightbox-swipe-hint", children: "Swipe up to close" }) | ||
| V && /* @__PURE__ */ n("div", { className: "rk-lightbox-swipe-hint", children: "Swipe up to close" }) | ||
| ] }); | ||
| return typeof document > "u" ? U : he(U, document.body); | ||
| }, He = (e) => e.isOpen ? /* @__PURE__ */ n(Ne, { ...e }) : null; | ||
| let f = null; | ||
| const Z = /* @__PURE__ */ new Map(), D = /* @__PURE__ */ new Map(), Me = (e) => { | ||
| try { | ||
| const t = document.createElement("canvas"); | ||
| t.width = e.videoWidth, t.height = e.videoHeight; | ||
| const r = t.getContext("2d"); | ||
| return !r || e.videoWidth === 0 ? null : (r.drawImage(e, 0, 0), t.toDataURL("image/jpeg", 0.8)); | ||
| } catch { | ||
| return null; | ||
| } | ||
| }, ze = () => (f || (f = document.createElement("video"), f.playsInline = !0, f.loop = !0, f.preload = "auto", f.muted = !0, f.autoplay = !0, f.crossOrigin = "anonymous", f.className = "rk-lightbox-video-element"), f); | ||
| let oe = !0; | ||
| const K = (e) => { | ||
| oe = e, f && (f.muted = e); | ||
| }, Te = typeof window < "u" ? ae : x, Pe = () => { | ||
| }, Ie = ({ | ||
| return typeof document > "u" ? A : ae(A, document.body); | ||
| }, Oe = (e) => e.isOpen ? /* @__PURE__ */ n(Ne, { ...e }) : null, N = me({ | ||
| className: "rk-lightbox-video-element" | ||
| }); | ||
| let te = !0; | ||
| const J = (e) => { | ||
| te = e; | ||
| const t = N.getVideo(); | ||
| t.muted = e; | ||
| }, ze = typeof window < "u" ? ie : w, Me = ({ | ||
| src: e, | ||
| poster: t, | ||
| isActive: r, | ||
| size: s, | ||
| isActive: o, | ||
| size: l, | ||
| slideKey: i | ||
| }) => { | ||
| const d = C(null), [o, u] = L(!1), [c, h] = L(!0); | ||
| return Te(() => { | ||
| if (!r || !d.current) return; | ||
| const l = ze(), g = d.current; | ||
| u(!0), h(!0); | ||
| const k = () => u(!1), v = () => u(!0), F = () => { | ||
| u(!1), h(!1); | ||
| const u = L(null), [a, r] = y(!1), [c, h] = y(!0); | ||
| return ze(() => { | ||
| if (!o || !u.current) return; | ||
| const s = N.getVideo(), f = u.current; | ||
| r(!0), h(!0); | ||
| const x = () => r(!1), g = () => r(!0), F = () => { | ||
| r(!1), h(!1); | ||
| }; | ||
| l.addEventListener("canplay", k), l.addEventListener("waiting", v), l.addEventListener("playing", F), l.src = e, l.muted = oe, l.style.objectFit = "contain"; | ||
| const b = Z.get(i); | ||
| return l.currentTime = b ?? 0, g.appendChild(l), l.play().catch(Pe), () => { | ||
| l.removeEventListener("canplay", k), l.removeEventListener("waiting", v), l.removeEventListener("playing", F), Z.set(i, l.currentTime); | ||
| const R = Me(l); | ||
| R && D.set(i, R), l.parentNode === g && g.removeChild(l), u(!1); | ||
| s.addEventListener("canplay", x), s.addEventListener("waiting", g), s.addEventListener("playing", F), s.src = e, s.muted = te, s.style.objectFit = "contain"; | ||
| const v = N.playbackPositions.get(i); | ||
| return s.currentTime = v ?? 0, f.appendChild(s), s.play().catch(fe), () => { | ||
| s.removeEventListener("canplay", x), s.removeEventListener("waiting", g), s.removeEventListener("playing", F), N.playbackPositions.set(i, s.currentTime); | ||
| const C = ge(s); | ||
| C && N.capturedFrames.set(i, C), s.parentNode === f && f.removeChild(s), r(!1); | ||
| }; | ||
| }, [r, e, i]), /* @__PURE__ */ E( | ||
| }, [o, e, i]), /* @__PURE__ */ k( | ||
| "div", | ||
| { | ||
| ref: d, | ||
| ref: u, | ||
| className: "rk-lightbox-video-container", | ||
| style: { | ||
| width: s[0], | ||
| height: s[1] | ||
| width: l[0], | ||
| height: l[1] | ||
| }, | ||
| children: [ | ||
| (D.get(i) ?? t) && /* @__PURE__ */ n( | ||
| (N.capturedFrames.get(i) ?? t) && /* @__PURE__ */ n( | ||
| "img", | ||
| { | ||
| src: D.get(i) ?? t, | ||
| src: N.capturedFrames.get(i) ?? t, | ||
| alt: "", | ||
| className: `rk-lightbox-video-poster ${!r || c ? "rk-visible" : ""}`, | ||
| className: `rk-lightbox-video-poster ${!o || c ? "rk-visible" : ""}`, | ||
| style: { objectFit: "contain" } | ||
@@ -421,3 +413,3 @@ } | ||
| { | ||
| className: `rk-lightbox-video-loader ${o ? "rk-visible" : ""}` | ||
| className: `rk-lightbox-video-loader ${a ? "rk-visible" : ""}` | ||
| } | ||
@@ -429,22 +421,22 @@ ) | ||
| }; | ||
| function We(e, t) { | ||
| const [r, s] = L(!0), i = w(() => { | ||
| s((c) => !c); | ||
| }, []), d = de( | ||
| function Be(e, t) { | ||
| const [o, l] = y(!0), i = p(() => { | ||
| l((c) => !c); | ||
| }, []), u = ce( | ||
| () => e.some((c) => c.type === "video"), | ||
| [e] | ||
| ); | ||
| x(() => { | ||
| K(r); | ||
| }, [r]), x(() => { | ||
| t === !1 && (s(!0), K(!0)); | ||
| w(() => { | ||
| J(o); | ||
| }, [o]), w(() => { | ||
| t === !1 && (l(!0), J(!0)); | ||
| }, [t]); | ||
| const o = w( | ||
| (c, h, l, g) => (c.type ?? "image") !== "video" ? null : /* @__PURE__ */ n( | ||
| Ie, | ||
| const a = p( | ||
| (c, h, s, f) => (c.type ?? "image") !== "video" ? null : /* @__PURE__ */ n( | ||
| Me, | ||
| { | ||
| src: c.src, | ||
| poster: c.poster, | ||
| isActive: g, | ||
| size: l, | ||
| isActive: f, | ||
| size: s, | ||
| slideKey: `lightbox-${h}` | ||
@@ -454,36 +446,36 @@ } | ||
| [] | ||
| ), u = w( | ||
| ), r = p( | ||
| ({ | ||
| onClose: c, | ||
| currentIndex: h, | ||
| count: l, | ||
| isFullscreen: g, | ||
| onToggleFullscreen: k | ||
| }) => /* @__PURE__ */ E(O, { children: [ | ||
| /* @__PURE__ */ E("div", { className: "rk-lightbox-controls-left", children: [ | ||
| /* @__PURE__ */ n(ne, { currentIndex: h, count: l }), | ||
| count: s, | ||
| isFullscreen: f, | ||
| onToggleFullscreen: x | ||
| }) => /* @__PURE__ */ k(q, { children: [ | ||
| /* @__PURE__ */ k("div", { className: "rk-lightbox-controls-left", children: [ | ||
| /* @__PURE__ */ n(K, { currentIndex: h, count: s }), | ||
| /* @__PURE__ */ n( | ||
| re, | ||
| ee, | ||
| { | ||
| isFullscreen: g, | ||
| onToggle: k | ||
| isFullscreen: f, | ||
| onToggle: x | ||
| } | ||
| ), | ||
| d && /* @__PURE__ */ n(Ce, { isMuted: r, onToggle: i }) | ||
| u && /* @__PURE__ */ n(Ce, { isMuted: o, onToggle: i }) | ||
| ] }), | ||
| /* @__PURE__ */ n(te, { onClick: c }) | ||
| /* @__PURE__ */ n(Z, { onClick: c }) | ||
| ] }), | ||
| [d, r, i] | ||
| [u, o, i] | ||
| ); | ||
| return { renderSlide: o, isMuted: r, onToggleMute: i, hasVideo: d, renderControls: u }; | ||
| return { renderSlide: a, isMuted: o, onToggleMute: i, hasVideo: u, renderControls: r }; | ||
| } | ||
| export { | ||
| te as CloseButton, | ||
| ne as Counter, | ||
| re as FullscreenButton, | ||
| He as LightboxOverlay, | ||
| Ie as LightboxVideoSlide, | ||
| Z as CloseButton, | ||
| K as Counter, | ||
| ee as FullscreenButton, | ||
| Oe as LightboxOverlay, | ||
| Me as LightboxVideoSlide, | ||
| Ce as SoundButton, | ||
| ye as useFullscreen, | ||
| We as useVideoSlideRenderer | ||
| Be as useVideoSlideRenderer | ||
| }; |
@@ -83,3 +83,6 @@ import { MutableRefObject, ReactNode, FC } from 'react'; | ||
| images: LightboxItem[]; | ||
| /** Zero-based index of the initially visible image. @default 0 */ | ||
| /** | ||
| * Zero-based index of the initially visible image. | ||
| * @default 0 | ||
| */ | ||
| initialIndex?: number; | ||
@@ -86,0 +89,0 @@ /** Callback to close the lightbox. Triggered by close button or Escape key. */ |
@@ -17,2 +17,3 @@ import { MutableRefObject } from 'react'; | ||
| * - `[2]` — Function to exit fullscreen. | ||
| * - `[3]` — Toggle function that requests or exits fullscreen based on current state. | ||
| */ | ||
@@ -22,3 +23,4 @@ export type UseFullscreenResult = [ | ||
| requestFullscreen: () => void, | ||
| exitFullscreen: () => void | ||
| exitFullscreen: () => void, | ||
| toggleFullscreen: () => void | ||
| ]; | ||
@@ -38,6 +40,5 @@ /** | ||
| * const ref = useRef<HTMLDivElement>(null); | ||
| * const [isFs, requestFs, exitFs] = useFullscreen({ ref }); | ||
| * const [isFs, requestFs, exitFs, toggleFs] = useFullscreen({ ref }); | ||
| * ``` | ||
| */ | ||
| declare const useFullscreen: <E extends HTMLElement>(props: UseFullscreenProps<E>) => UseFullscreenResult; | ||
| export default useFullscreen; | ||
| export declare const useFullscreen: <E extends HTMLElement>(props: UseFullscreenProps<E>) => UseFullscreenResult; |
+1
-1
| { | ||
| "name": "@reelkit/react-lightbox", | ||
| "version": "0.1.3", | ||
| "version": "0.2.0", | ||
| "type": "module", | ||
@@ -5,0 +5,0 @@ "sideEffects": [ |
+5
-5
@@ -5,7 +5,7 @@ # @reelkit/react-lightbox | ||
| <a href="https://www.npmjs.com/package/@reelkit/react-lightbox"><img src="https://img.shields.io/npm/v/@reelkit/react-lightbox?color=6366f1&label=npm" alt="npm" /></a> | ||
| <img src="https://img.shields.io/badge/gzip-3.4%20kB-6366f1" alt="Bundle size" /> | ||
| <img src="https://img.shields.io/badge/gzip-3.2%20kB-6366f1" alt="Bundle size" /> | ||
| <a href="https://github.com/KonstantinKai/reelkit"><img src="https://img.shields.io/github/stars/KonstantinKai/reelkit?style=social" alt="Star on GitHub" /></a> | ||
| </p> | ||
| Full-screen image gallery lightbox for React. Touch gestures, keyboard navigation, fullscreen API, transition effects, and render props for full customization. ~3.4 kB gzip. | ||
| Image gallery lightbox for React — opens full-screen with swipe navigation, keyboard controls, and transition effects. Everything is replaceable via render props if the defaults don't fit. ~3.2 kB gzip. | ||
@@ -66,3 +66,3 @@ ## Installation | ||
| - Info overlay — title and description with gradient | ||
| - Render props — `renderControls`, `renderNavigation`, `renderInfo`, `renderSlide` for full customization | ||
| - Render props — `renderControls`, `renderNavigation`, `renderInfo`, `renderSlide` to override any part of the UI | ||
| - Sub-components — `CloseButton`, `Counter`, `FullscreenButton`, `SoundButton` for composing custom controls | ||
@@ -235,7 +235,7 @@ | ||
| Full documentation, interactive demos, and customization examples at **[reelkit.dev/docs/lightbox](https://reelkit.dev/docs/lightbox)**. | ||
| Docs, demos, and customization examples at **[reelkit.dev/docs/lightbox](https://reelkit.dev/docs/lightbox)**. | ||
| ## Support | ||
| If you find ReelKit useful, give it a star on GitHub — it helps others discover the project and keeps development going. | ||
| If ReelKit saved you some time, a star on GitHub would mean a lot — it's a small thing, but it really helps the project get noticed. | ||
@@ -242,0 +242,0 @@ [](https://github.com/KonstantinKai/reelkit) |
47262
-0.55%968
-0.41%