@wethegit/react-gallery
Version:
A customizable, accessible gallery component for React projects.
549 lines (548 loc) • 16.3 kB
JavaScript
import oe, { createContext as se, useState as W, useRef as ie, useCallback as S, useEffect as ce, useContext as ue } from "react";
var z = { exports: {} }, I = {};
/**
* @license React
* react-jsx-runtime.production.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var B;
function fe() {
if (B) return I;
B = 1;
var r = Symbol.for("react.transitional.element"), c = Symbol.for("react.fragment");
function f(_, s, l) {
var a = null;
if (l !== void 0 && (a = "" + l), s.key !== void 0 && (a = "" + s.key), "key" in s) {
l = {};
for (var i in s)
i !== "key" && (l[i] = s[i]);
} else l = s;
return s = l.ref, {
$$typeof: r,
type: _,
key: a,
ref: s !== void 0 ? s : null,
props: l
};
}
return I.Fragment = c, I.jsx = f, I.jsxs = f, I;
}
var C = {};
/**
* @license React
* react-jsx-runtime.development.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var K;
function _e() {
return K || (K = 1, process.env.NODE_ENV !== "production" && function() {
function r(e) {
if (e == null) return null;
if (typeof e == "function")
return e.$$typeof === ae ? null : e.displayName || e.name || null;
if (typeof e == "string") return e;
switch (e) {
case p:
return "Fragment";
case x:
return "Profiler";
case A:
return "StrictMode";
case T:
return "Suspense";
case $:
return "SuspenseList";
case te:
return "Activity";
}
if (typeof e == "object")
switch (typeof e.tag == "number" && console.error(
"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
), e.$$typeof) {
case b:
return "Portal";
case Y:
return (e.displayName || "Context") + ".Provider";
case N:
return (e._context.displayName || "Context") + ".Consumer";
case E:
var t = e.render;
return e = e.displayName, e || (e = t.displayName || t.name || "", e = e !== "" ? "ForwardRef(" + e + ")" : "ForwardRef"), e;
case re:
return t = e.displayName || null, t !== null ? t : r(e.type) || "Memo";
case V:
t = e._payload, e = e._init;
try {
return r(e(t));
} catch {
}
}
return null;
}
function c(e) {
return "" + e;
}
function f(e) {
try {
c(e);
var t = !1;
} catch {
t = !0;
}
if (t) {
t = console;
var u = t.error, d = typeof Symbol == "function" && Symbol.toStringTag && e[Symbol.toStringTag] || e.constructor.name || "Object";
return u.call(
t,
"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
d
), c(e);
}
}
function _(e) {
if (e === p) return "<>";
if (typeof e == "object" && e !== null && e.$$typeof === V)
return "<...>";
try {
var t = r(e);
return t ? "<" + t + ">" : "<...>";
} catch {
return "<...>";
}
}
function s() {
var e = M.A;
return e === null ? null : e.getOwner();
}
function l() {
return Error("react-stack-top-frame");
}
function a(e) {
if (q.call(e, "key")) {
var t = Object.getOwnPropertyDescriptor(e, "key").get;
if (t && t.isReactWarning) return !1;
}
return e.key !== void 0;
}
function i(e, t) {
function u() {
X || (X = !0, console.error(
"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
t
));
}
u.isReactWarning = !0, Object.defineProperty(e, "key", {
get: u,
configurable: !0
});
}
function o() {
var e = r(this.type);
return J[e] || (J[e] = !0, console.error(
"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
)), e = this.props.ref, e !== void 0 ? e : null;
}
function n(e, t, u, d, O, R, F, L) {
return u = R.ref, e = {
$$typeof: P,
type: e,
key: t,
props: R,
_owner: O
}, (u !== void 0 ? u : null) !== null ? Object.defineProperty(e, "ref", {
enumerable: !1,
get: o
}) : Object.defineProperty(e, "ref", { enumerable: !1, value: null }), e._store = {}, Object.defineProperty(e._store, "validated", {
configurable: !1,
enumerable: !1,
writable: !0,
value: 0
}), Object.defineProperty(e, "_debugInfo", {
configurable: !1,
enumerable: !1,
writable: !0,
value: null
}), Object.defineProperty(e, "_debugStack", {
configurable: !1,
enumerable: !1,
writable: !0,
value: F
}), Object.defineProperty(e, "_debugTask", {
configurable: !1,
enumerable: !1,
writable: !0,
value: L
}), Object.freeze && (Object.freeze(e.props), Object.freeze(e)), e;
}
function g(e, t, u, d, O, R, F, L) {
var m = t.children;
if (m !== void 0)
if (d)
if (le(m)) {
for (d = 0; d < m.length; d++)
h(m[d]);
Object.freeze && Object.freeze(m);
} else
console.error(
"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
);
else h(m);
if (q.call(t, "key")) {
m = r(e);
var w = Object.keys(t).filter(function(ne) {
return ne !== "key";
});
d = 0 < w.length ? "{key: someKey, " + w.join(": ..., ") + ": ...}" : "{key: someKey}", Z[m + d] || (w = 0 < w.length ? "{" + w.join(": ..., ") + ": ...}" : "{}", console.error(
`A props object containing a "key" prop is being spread into JSX:
let props = %s;
<%s {...props} />
React keys must be passed directly to JSX without using spread:
let props = %s;
<%s key={someKey} {...props} />`,
d,
m,
w,
m
), Z[m + d] = !0);
}
if (m = null, u !== void 0 && (f(u), m = "" + u), a(t) && (f(t.key), m = "" + t.key), "key" in t) {
u = {};
for (var U in t)
U !== "key" && (u[U] = t[U]);
} else u = t;
return m && i(
u,
typeof e == "function" ? e.displayName || e.name || "Unknown" : e
), n(
e,
m,
R,
O,
s(),
u,
F,
L
);
}
function h(e) {
typeof e == "object" && e !== null && e.$$typeof === P && e._store && (e._store.validated = 1);
}
var v = oe, P = Symbol.for("react.transitional.element"), b = Symbol.for("react.portal"), p = Symbol.for("react.fragment"), A = Symbol.for("react.strict_mode"), x = Symbol.for("react.profiler"), N = Symbol.for("react.consumer"), Y = Symbol.for("react.context"), E = Symbol.for("react.forward_ref"), T = Symbol.for("react.suspense"), $ = Symbol.for("react.suspense_list"), re = Symbol.for("react.memo"), V = Symbol.for("react.lazy"), te = Symbol.for("react.activity"), ae = Symbol.for("react.client.reference"), M = v.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, q = Object.prototype.hasOwnProperty, le = Array.isArray, G = console.createTask ? console.createTask : function() {
return null;
};
v = {
"react-stack-bottom-frame": function(e) {
return e();
}
};
var X, J = {}, H = v["react-stack-bottom-frame"].bind(
v,
l
)(), Q = G(_(l)), Z = {};
C.Fragment = p, C.jsx = function(e, t, u, d, O) {
var R = 1e4 > M.recentlyCreatedOwnerStacks++;
return g(
e,
t,
u,
!1,
d,
O,
R ? Error("react-stack-top-frame") : H,
R ? G(_(e)) : Q
);
}, C.jsxs = function(e, t, u, d, O) {
var R = 1e4 > M.recentlyCreatedOwnerStacks++;
return g(
e,
t,
u,
!0,
d,
O,
R ? Error("react-stack-top-frame") : H,
R ? G(_(e)) : Q
);
};
}()), C;
}
process.env.NODE_ENV === "production" ? z.exports = fe() : z.exports = _e();
var k = z.exports;
const j = (r = []) => {
if (!r || !Array.isArray(r) || !r.length) return null;
let c = [];
return r.forEach((f) => {
typeof f == "string" && c.push(f);
}), c.join(" ");
}, ge = "gallery-module__gallery__VCgDes", de = "gallery-module__gallery__main__iLoFEC", me = "gallery-module__gallery__item__Y54ZpS", ye = "gallery-module__gallery__nav__LiuEC8", ve = "gallery-module__gallery__pagination__Fq3Nx2", y = {
"visually-hidden": "gallery-module__visually-hidden__8zDx-H",
gallery: ge,
"gallery--draggable": "gallery-module__gallery--draggable__f9wp7C",
gallery__main: de,
gallery__item: me,
"gallery__item--draggable": "gallery-module__gallery__item--draggable__bk-grQ",
"gallery__item--dragging": "gallery-module__gallery__item--dragging__QyPOcL",
gallery__nav: ye,
gallery__pagination: ve,
"gallery__pagination-item": "gallery-module__gallery__pagination-item__ys5srP"
}, ee = se(), be = {
isDragging: !1,
start: 0,
xOffset: 0,
offsetting: !1,
scrolling: !0
}, pe = 50, Te = ({
loop: r = !1,
draggable: c = !0,
startIndex: f = 0,
visibleRange: _ = -1,
ariaLiveText: s = "Item $i of $t.",
items: l,
onChange: a,
className: i,
children: o
}) => {
const [n, g] = W(() => f || 0), [h, v] = W(
() => f || 0
), [P, b] = W(() => be), p = ie([]);
if (!Array.isArray(l)) throw new Error("<Gallery> items prop must be an Array.");
const A = S(() => {
v(n), g((E) => {
let T = E + 1;
return E === l.length - 1 && (T = r ? 0 : E), a && a({ oldIndex: E, newIndex: T, direction: 1 }), T;
});
}, [n, l.length, r, a]), x = S(() => {
v(n), g((E) => {
let T = E - 1;
return E === 0 && (T = r ? l.length - 1 : E), a && a({ oldIndex: E, newIndex: T, direction: 0 }), T;
});
}, [n, l.length, r, a]), N = S(
(E) => {
const T = l[E] ? E : 0;
v(n), g(T);
const $ = T - n > 0 ? 1 : 0;
a && a({ oldIndex: n, newIndex: T, direction: $ });
},
[n, a, l]
);
ce(() => {
l[n] || N();
}, [n, l, N]);
const Y = {
galleryItems: l,
itemNodes: p,
startIndex: f,
activeIndex: n,
setActiveIndex: g,
previouslyActiveIndex: h,
setPreviouslyActiveIndex: v,
goToIndex: N,
next: A,
previous: x,
loop: r,
draggable: c,
touchState: P,
setTouchState: b,
swipeThreshold: pe,
onChange: a,
visibleRange: _
};
return /* @__PURE__ */ k.jsx(ee.Provider, { value: Y, children: /* @__PURE__ */ k.jsxs(
"div",
{
className: j([
y.gallery,
c && y["gallery--draggable"],
i
]),
style: { "--touch-offset": P.xOffset },
children: [
o,
s && /* @__PURE__ */ k.jsx("p", { "aria-live": "polite", className: y["visually-hidden"], children: s.replace("$i", n + 1).replace("$t", l.length) })
]
}
) });
}, D = () => {
const r = ue(ee);
if (!r)
throw new Error("useGallery must be called from within a <Gallery>.");
return r;
}, he = ({ renderGalleryItem: r, className: c, ...f }) => {
const {
activeIndex: _,
galleryItems: s,
next: l,
previous: a,
draggable: i,
touchState: o,
setTouchState: n,
swipeThreshold: g
} = D(), h = S(() => {
i && n((b) => ({ ...b, isDragging: !0 }));
}, [i, n]), v = S(
(b) => {
if (i && !o.scrolling && o.isDragging === !0 && b.clientY)
if (!o.start)
n((p) => ({
...p,
start: { x: b.clientX, y: b.clientY }
}));
else {
const p = b.clientX - o.start.x, A = b.clientY - o.start.y;
o.offsetting ? n((x) => ({ ...x, xOffset: p })) : (Math.abs(A) > 20 && n((x) => ({ ...x, scrolling: !0 })), Math.abs(p) > 10 && n((x) => ({ ...x, offsetting: !0, xOffset: p })));
}
},
[
i,
o.scrolling,
o.isDragging,
o.start,
o.offsetting,
n
]
), P = S(() => {
i && o.isDragging && (Math.abs(o.xOffset) > g && (o.xOffset < 0 ? l() : a()), n((b) => ({
...b,
isDragging: !1,
xOffset: 0,
start: 0,
offsetting: !1,
scrolling: !1
})));
}, [
i,
o.isDragging,
o.xOffset,
g,
n,
l,
a
]);
return /* @__PURE__ */ k.jsx(
"ul",
{
className: j([y.gallery__main, c]),
onPointerDown: i ? h : null,
onPointerMove: i ? v : null,
onPointerUp: i ? P : null,
style: { "--selected": _, "--total": s.length },
...f,
children: s.map((b, p) => r({ item: b, index: p, activeIndex: _, active: _ === p }))
}
);
}, Re = ({ renderPaginationItem: r, className: c, ...f }) => {
const { activeIndex: _, galleryItems: s } = D();
return /* @__PURE__ */ k.jsx("ul", { className: j([y.gallery__pagination, c]), ...f, children: s.map((l, a) => r({ index: a, active: _ === a, activeIndex: _, item: l })) });
}, xe = ({
index: r,
active: c,
className: f,
buttonClassName: _,
buttonProps: s,
children: l,
...a
}) => {
const { goToIndex: i, itemNodes: o } = D(), n = (g) => {
i(g), o.current[g].focus({ preventScroll: !0 });
};
return /* @__PURE__ */ k.jsx(
"li",
{
className: j([y["gallery__pagination-item"], f]),
...a,
children: /* @__PURE__ */ k.jsx(
"button",
{
className: _,
"aria-current": c ? "true" : null,
onClick: () => n(r),
...s,
children: l
}
)
}
);
}, ke = ({
direction: r,
renderNavItem: c,
className: f,
children: _,
...s
}) => {
const { next: l, previous: a, loop: i, activeIndex: o, galleryItems: n } = D(), g = () => {
r ? l() : a();
}, h = r && o === n.length - 1 || !r && o === 0, v = {
disabled: h ? !0 : null,
"aria-disabled": h ? "true" : null
};
return !_ && !c ? null : /* @__PURE__ */ k.jsx(
"button",
{
className: j([
y.gallery__nav,
y[`gallery__nav--${r ? "next" : "previous"}`],
f
]),
onClick: g,
...!i && v,
...s,
children: _ || c({ activeIndex: o, disabled: !i && h })
}
);
}, Oe = ({ index: r, active: c, className: f, children: _, ...s }) => {
const {
itemNodes: l,
activeIndex: a,
previouslyActiveIndex: i,
draggable: o,
touchState: n,
visibleRange: g
} = D(), h = {
"aria-hidden": c ? null : "true",
tabIndex: c ? 0 : -1
};
return /* @__PURE__ */ k.jsx(
"li",
{
ref: (v) => l.current[r] = v,
...h,
...s,
className: j([
y.gallery__item,
o && y["gallery__item--draggable"],
o && n.offsetting && y["gallery__item--dragging"],
c && y["gallery__item--active"],
r === i && y["gallery__item--was-active"],
r < a && y["gallery__item--left"],
r > a && y["gallery__item--right"],
(g === -1 || Math.abs(r - a) <= g) && y["gallery__item--visible"],
f
]),
style: {
"--i": r,
"--center-offset": Math.abs(r - a),
"--index-offset": r - a,
"--side": r < a ? -1 : r > a ? 1 : 0,
"--active": c ? 1 : 0
},
children: _
}
);
};
export {
Te as Gallery,
Oe as GalleryItem,
he as GalleryMain,
ke as GalleryNav,
Re as GalleryPagination,
xe as GalleryPaginationItem,
D as useGallery
};