UNPKG

@wethegit/react-gallery

Version:

A customizable, accessible gallery component for React projects.

549 lines (548 loc) 16.3 kB
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 };