images-viewer-vue3
Version:
A lightweight image viewer for Vue3
857 lines (856 loc) • 24 kB
JavaScript
import { createTextVNode as ce, Fragment as Z, Comment as me, defineComponent as M, provide as be, getCurrentInstance as R, inject as H, ref as F, onBeforeUnmount as C, withDirectives as ee, toRef as O, computed as ve, h as $, Teleport as we, onMounted as k, watch as z, nextTick as ye, renderSlot as xe } from "vue";
import { a as S, o as I } from "./npm-evtd-Bc7Iy9dF.js";
import { f as $e, e as ge, a as Me } from "./npm-seemly-CoNZSdNO.js";
import { u as Ee } from "./npm-@css-render-vue3-ssr-DxhlTTo_.js";
import { f as ze, u as _, o as Se, i as Fe } from "./npm-vooks-BdFeHE_F.js";
import { C as Ae } from "./npm-css-render-D6klN3og.js";
import { z as Te } from "./npm-vdirs-BihFuFC6.js";
import { R as Be } from "./npm-@juggle-resize-observer-CjQQRv6Z.js";
function V(n, e, t = "default") {
const o = e[t];
if (o === void 0)
throw new Error(`[vueuc/${n}]: slot[${t}] is empty.`);
return o();
}
function Y(n, e = !0, t = []) {
return n.forEach((o) => {
if (o !== null) {
if (typeof o != "object") {
(typeof o == "string" || typeof o == "number") && t.push(ce(String(o)));
return;
}
if (Array.isArray(o)) {
Y(o, e, t);
return;
}
if (o.type === Z) {
if (o.children === null)
return;
Array.isArray(o.children) && Y(o.children, e, t);
} else o.type !== me && t.push(o);
}
}), t;
}
function j(n, e, t = "default") {
const o = e[t];
if (o === void 0)
throw new Error(`[vueuc/${n}]: slot[${t}] is empty.`);
const s = Y(o());
if (s.length === 1)
return s[0];
throw new Error(`[vueuc/${n}]: slot[${t}] should have exactly one child.`);
}
let x = null;
function te() {
if (x === null && (x = document.getElementById("v-binder-view-measurer"), x === null)) {
x = document.createElement("div"), x.id = "v-binder-view-measurer";
const { style: n } = x;
n.position = "fixed", n.left = "0", n.right = "0", n.top = "0", n.bottom = "0", n.pointerEvents = "none", n.visibility = "hidden", document.body.appendChild(x);
}
return x.getBoundingClientRect();
}
function Oe(n, e) {
const t = te();
return {
top: e,
left: n,
height: 0,
width: 0,
right: t.width - n,
bottom: t.height - e
};
}
function X(n) {
const e = n.getBoundingClientRect(), t = te();
return {
left: e.left - t.left,
top: e.top - t.top,
bottom: t.height + t.top - e.bottom,
right: t.width + t.left - e.right,
width: e.width,
height: e.height
};
}
function Ce(n) {
return n.nodeType === 9 ? null : n.parentNode;
}
function ne(n) {
if (n === null)
return null;
const e = Ce(n);
if (e === null)
return null;
if (e.nodeType === 9)
return document;
if (e.nodeType === 1) {
const { overflow: t, overflowX: o, overflowY: s } = getComputedStyle(e);
if (/(auto|scroll|overlay)/.test(t + s + o))
return e;
}
return ne(e);
}
const Ze = M({
name: "Binder",
props: {
syncTargetWithParent: Boolean,
syncTarget: {
type: Boolean,
default: !0
}
},
setup(n) {
var e;
be("VBinder", (e = R()) === null || e === void 0 ? void 0 : e.proxy);
const t = H("VBinder", null), o = F(null), s = (r) => {
o.value = r, t && n.syncTargetWithParent && t.setTargetRef(r);
};
let d = [];
const p = () => {
let r = o.value;
for (; r = ne(r), r !== null; )
d.push(r);
for (const c of d)
I("scroll", c, w, !0);
}, m = () => {
for (const r of d)
S("scroll", r, w, !0);
d = [];
}, u = /* @__PURE__ */ new Set(), b = (r) => {
u.size === 0 && p(), u.has(r) || u.add(r);
}, v = (r) => {
u.has(r) && u.delete(r), u.size === 0 && m();
}, w = () => {
$e(l);
}, l = () => {
u.forEach((r) => r());
}, a = /* @__PURE__ */ new Set(), h = (r) => {
a.size === 0 && I("resize", window, i), a.has(r) || a.add(r);
}, f = (r) => {
a.has(r) && a.delete(r), a.size === 0 && S("resize", window, i);
}, i = () => {
a.forEach((r) => r());
};
return C(() => {
S("resize", window, i), m();
}), {
targetRef: o,
setTargetRef: s,
addScrollListener: b,
removeScrollListener: v,
addResizeListener: h,
removeResizeListener: f
};
},
render() {
return V("binder", this.$slots);
}
}), Re = M({
name: "Target",
setup() {
const { setTargetRef: n, syncTarget: e } = H("VBinder");
return {
syncTarget: e,
setTargetDirective: {
mounted: n,
updated: n
}
};
},
render() {
const { syncTarget: n, setTargetDirective: e } = this;
return n ? ee(j("follower", this.$slots), [
[e]
]) : j("follower", this.$slots);
}
});
function U(n, e) {
console.error(`[vueuc/${n}]: ${e}`);
}
const { c: T } = Ae(), Le = "vueuc-style";
function q(n) {
return typeof n == "string" ? document.querySelector(n) : n();
}
const Xe = M({
name: "LazyTeleport",
props: {
to: {
type: [String, Object],
default: void 0
},
disabled: Boolean,
show: {
type: Boolean,
required: !0
}
},
setup(n) {
return {
showTeleport: ze(O(n, "show")),
mergedTo: ve(() => {
const { to: e } = n;
return e ?? "body";
})
};
},
render() {
return this.showTeleport ? this.disabled ? V("lazy-teleport", this.$slots) : $(we, {
disabled: this.disabled,
to: this.mergedTo
}, V("lazy-teleport", this.$slots)) : null;
}
}), B = {
top: "bottom",
bottom: "top",
left: "right",
right: "left"
}, K = {
start: "end",
center: "center",
end: "start"
}, D = {
top: "height",
bottom: "height",
left: "width",
right: "width"
}, De = {
"bottom-start": "top left",
bottom: "top center",
"bottom-end": "top right",
"top-start": "bottom left",
top: "bottom center",
"top-end": "bottom right",
"right-start": "top left",
right: "center left",
"right-end": "bottom left",
"left-start": "top right",
left: "center right",
"left-end": "bottom right"
}, Ie = {
"bottom-start": "bottom left",
bottom: "bottom center",
"bottom-end": "bottom right",
"top-start": "top left",
top: "top center",
"top-end": "top right",
"right-start": "top right",
right: "center right",
"right-end": "bottom right",
"left-start": "top left",
left: "center left",
"left-end": "bottom left"
}, Ve = {
"bottom-start": "right",
"bottom-end": "left",
"top-start": "right",
"top-end": "left",
"right-start": "bottom",
"right-end": "top",
"left-start": "bottom",
"left-end": "top"
}, G = {
top: !0,
bottom: !1,
left: !0,
right: !1
// left--
}, J = {
top: "end",
bottom: "start",
left: "end",
right: "start"
};
function Ye(n, e, t, o, s, d) {
if (!s || d)
return { placement: n, top: 0, left: 0 };
const [p, m] = n.split("-");
let u = m ?? "center", b = {
top: 0,
left: 0
};
const v = (a, h, f) => {
let i = 0, r = 0;
const c = t[a] - e[h] - e[a];
return c > 0 && o && (f ? r = G[h] ? c : -c : i = G[h] ? c : -c), {
left: i,
top: r
};
}, w = p === "left" || p === "right";
if (u !== "center") {
const a = Ve[n], h = B[a], f = D[a];
if (t[f] > e[f]) {
if (
// current space is not enough
// ----------[ target ]---------|
// -------[ follower ]
e[a] + e[f] < t[f]
) {
const i = (t[f] - e[f]) / 2;
e[a] < i || e[h] < i ? e[a] < e[h] ? (u = K[m], b = v(f, h, w)) : b = v(f, a, w) : u = "center";
}
} else t[f] < e[f] && e[h] < 0 && // opposite align has larger space
// ------------[ target ]
// ----------------[follower]
e[a] > e[h] && (u = K[m]);
} else {
const a = p === "bottom" || p === "top" ? "left" : "top", h = B[a], f = D[a], i = (t[f] - e[f]) / 2;
// center is not enough
// ----------- [ target ]--|
// -------[ follower ]
(e[a] < i || e[h] < i) && (e[a] > e[h] ? (u = J[a], b = v(f, a, w)) : (u = J[h], b = v(f, h, w)));
}
let l = p;
return (
// space is not enough
e[p] < t[D[p]] && // opposite position's space is larger
e[p] < e[B[p]] && (l = B[p]), {
placement: u !== "center" ? `${l}-${u}` : l,
left: b.left,
top: b.top
}
);
}
function He(n, e) {
return e ? Ie[n] : De[n];
}
function ke(n, e, t, o, s, d) {
if (d)
switch (n) {
case "bottom-start":
return {
top: `${Math.round(t.top - e.top + t.height)}px`,
left: `${Math.round(t.left - e.left)}px`,
transform: "translateY(-100%)"
};
case "bottom-end":
return {
top: `${Math.round(t.top - e.top + t.height)}px`,
left: `${Math.round(t.left - e.left + t.width)}px`,
transform: "translateX(-100%) translateY(-100%)"
};
case "top-start":
return {
top: `${Math.round(t.top - e.top)}px`,
left: `${Math.round(t.left - e.left)}px`,
transform: ""
};
case "top-end":
return {
top: `${Math.round(t.top - e.top)}px`,
left: `${Math.round(t.left - e.left + t.width)}px`,
transform: "translateX(-100%)"
};
case "right-start":
return {
top: `${Math.round(t.top - e.top)}px`,
left: `${Math.round(t.left - e.left + t.width)}px`,
transform: "translateX(-100%)"
};
case "right-end":
return {
top: `${Math.round(t.top - e.top + t.height)}px`,
left: `${Math.round(t.left - e.left + t.width)}px`,
transform: "translateX(-100%) translateY(-100%)"
};
case "left-start":
return {
top: `${Math.round(t.top - e.top)}px`,
left: `${Math.round(t.left - e.left)}px`,
transform: ""
};
case "left-end":
return {
top: `${Math.round(t.top - e.top + t.height)}px`,
left: `${Math.round(t.left - e.left)}px`,
transform: "translateY(-100%)"
};
case "top":
return {
top: `${Math.round(t.top - e.top)}px`,
left: `${Math.round(t.left - e.left + t.width / 2)}px`,
transform: "translateX(-50%)"
};
case "right":
return {
top: `${Math.round(t.top - e.top + t.height / 2)}px`,
left: `${Math.round(t.left - e.left + t.width)}px`,
transform: "translateX(-100%) translateY(-50%)"
};
case "left":
return {
top: `${Math.round(t.top - e.top + t.height / 2)}px`,
left: `${Math.round(t.left - e.left)}px`,
transform: "translateY(-50%)"
};
case "bottom":
default:
return {
top: `${Math.round(t.top - e.top + t.height)}px`,
left: `${Math.round(t.left - e.left + t.width / 2)}px`,
transform: "translateX(-50%) translateY(-100%)"
};
}
switch (n) {
case "bottom-start":
return {
top: `${Math.round(t.top - e.top + t.height + o)}px`,
left: `${Math.round(t.left - e.left + s)}px`,
transform: ""
};
case "bottom-end":
return {
top: `${Math.round(t.top - e.top + t.height + o)}px`,
left: `${Math.round(t.left - e.left + t.width + s)}px`,
transform: "translateX(-100%)"
};
case "top-start":
return {
top: `${Math.round(t.top - e.top + o)}px`,
left: `${Math.round(t.left - e.left + s)}px`,
transform: "translateY(-100%)"
};
case "top-end":
return {
top: `${Math.round(t.top - e.top + o)}px`,
left: `${Math.round(t.left - e.left + t.width + s)}px`,
transform: "translateX(-100%) translateY(-100%)"
};
case "right-start":
return {
top: `${Math.round(t.top - e.top + o)}px`,
left: `${Math.round(t.left - e.left + t.width + s)}px`,
transform: ""
};
case "right-end":
return {
top: `${Math.round(t.top - e.top + t.height + o)}px`,
left: `${Math.round(t.left - e.left + t.width + s)}px`,
transform: "translateY(-100%)"
};
case "left-start":
return {
top: `${Math.round(t.top - e.top + o)}px`,
left: `${Math.round(t.left - e.left + s)}px`,
transform: "translateX(-100%)"
};
case "left-end":
return {
top: `${Math.round(t.top - e.top + t.height + o)}px`,
left: `${Math.round(t.left - e.left + s)}px`,
transform: "translateX(-100%) translateY(-100%)"
};
case "top":
return {
top: `${Math.round(t.top - e.top + o)}px`,
left: `${Math.round(t.left - e.left + t.width / 2 + s)}px`,
transform: "translateY(-100%) translateX(-50%)"
};
case "right":
return {
top: `${Math.round(t.top - e.top + t.height / 2 + o)}px`,
left: `${Math.round(t.left - e.left + t.width + s)}px`,
transform: "translateY(-50%)"
};
case "left":
return {
top: `${Math.round(t.top - e.top + t.height / 2 + o)}px`,
left: `${Math.round(t.left - e.left + s)}px`,
transform: "translateY(-50%) translateX(-100%)"
};
case "bottom":
default:
return {
top: `${Math.round(t.top - e.top + t.height + o)}px`,
left: `${Math.round(t.left - e.left + t.width / 2 + s)}px`,
transform: "translateX(-50%)"
};
}
}
const We = T([
T(".v-binder-follower-container", {
position: "absolute",
left: "0",
right: "0",
top: "0",
height: "0",
pointerEvents: "none",
zIndex: "auto"
}),
T(".v-binder-follower-content", {
position: "absolute",
zIndex: "auto"
}, [
T("> *", {
pointerEvents: "all"
})
])
]), et = M({
name: "Follower",
inheritAttrs: !1,
props: {
show: Boolean,
enabled: {
type: Boolean,
default: void 0
},
placement: {
type: String,
default: "bottom"
},
syncTrigger: {
type: Array,
default: ["resize", "scroll"]
},
to: [String, Object],
flip: {
type: Boolean,
default: !0
},
internalShift: Boolean,
x: Number,
y: Number,
width: String,
minWidth: String,
containerClass: String,
teleportDisabled: Boolean,
zindexable: {
type: Boolean,
default: !0
},
zIndex: Number,
overlap: Boolean
},
setup(n) {
const e = H("VBinder"), t = _(() => n.enabled !== void 0 ? n.enabled : n.show), o = F(null), s = F(null), d = () => {
const { syncTrigger: l } = n;
l.includes("scroll") && e.addScrollListener(u), l.includes("resize") && e.addResizeListener(u);
}, p = () => {
e.removeScrollListener(u), e.removeResizeListener(u);
};
k(() => {
t.value && (u(), d());
});
const m = Ee();
We.mount({
id: "vueuc/binder",
head: !0,
anchorMetaName: Le,
ssr: m
}), C(() => {
p();
}), Se(() => {
t.value && u();
});
const u = () => {
if (!t.value)
return;
const l = o.value;
if (l === null)
return;
const a = e.targetRef, { x: h, y: f, overlap: i } = n, r = h !== void 0 && f !== void 0 ? Oe(h, f) : X(a);
l.style.setProperty("--v-target-width", `${Math.round(r.width)}px`), l.style.setProperty("--v-target-height", `${Math.round(r.height)}px`);
const { width: c, minWidth: y, placement: A, internalShift: se, flip: ue } = n;
l.setAttribute("v-placement", A), i ? l.setAttribute("v-overlap", "") : l.removeAttribute("v-overlap");
const { style: g } = l;
c === "target" ? g.width = `${r.width}px` : c !== void 0 ? g.width = c : g.width = "", y === "target" ? g.minWidth = `${r.width}px` : y !== void 0 ? g.minWidth = y : g.minWidth = "";
const ae = X(l), de = X(s.value), { left: W, top: N, placement: L } = Ye(A, r, ae, se, ue, i), P = He(L, i), { left: fe, top: he, transform: pe } = ke(L, de, r, N, W, i);
l.setAttribute("v-placement", L), l.style.setProperty("--v-offset-left", `${Math.round(W)}px`), l.style.setProperty("--v-offset-top", `${Math.round(N)}px`), l.style.transform = `translateX(${fe}) translateY(${he}) ${pe}`, l.style.setProperty("--v-transform-origin", P), l.style.transformOrigin = P;
};
z(t, (l) => {
l ? (d(), b()) : p();
});
const b = () => {
ye().then(u).catch((l) => console.error(l));
};
[
"placement",
"x",
"y",
"internalShift",
"flip",
"width",
"overlap",
"minWidth"
].forEach((l) => {
z(O(n, l), u);
}), ["teleportDisabled"].forEach((l) => {
z(O(n, l), b);
}), z(O(n, "syncTrigger"), (l) => {
l.includes("resize") ? e.addResizeListener(u) : e.removeResizeListener(u), l.includes("scroll") ? e.addScrollListener(u) : e.removeScrollListener(u);
});
const v = Fe(), w = _(() => {
const { to: l } = n;
if (l !== void 0)
return l;
v.value;
});
return {
VBinder: e,
mergedEnabled: t,
offsetContainerRef: s,
followerRef: o,
mergedTo: w,
syncPosition: u
};
},
render() {
return $(Xe, {
show: this.show,
to: this.mergedTo,
disabled: this.teleportDisabled
}, {
default: () => {
var n, e;
const t = $("div", {
class: ["v-binder-follower-container", this.containerClass],
ref: "offsetContainerRef"
}, [
$("div", {
class: "v-binder-follower-content",
ref: "followerRef"
}, (e = (n = this.$slots).default) === null || e === void 0 ? void 0 : e.call(n))
]);
return this.zindexable ? ee(t, [
[
Te,
{
enabled: this.mergedEnabled,
zIndex: this.zIndex
}
]
]) : t;
}
});
}
});
class Ne {
constructor() {
this.handleResize = this.handleResize.bind(this), this.observer = new (typeof window < "u" && window.ResizeObserver || Be)(this.handleResize), this.elHandlersMap = /* @__PURE__ */ new Map();
}
handleResize(e) {
for (const t of e) {
const o = this.elHandlersMap.get(t.target);
o !== void 0 && o(t);
}
}
registerHandler(e, t) {
this.elHandlersMap.set(e, t), this.observer.observe(e);
}
unregisterHandler(e) {
this.elHandlersMap.has(e) && (this.elHandlersMap.delete(e), this.observer.unobserve(e));
}
}
const Q = new Ne(), tt = M({
name: "ResizeObserver",
props: {
onResize: Function
},
setup(n) {
let e = !1;
const t = R().proxy;
function o(s) {
const { onResize: d } = n;
d !== void 0 && d(s);
}
k(() => {
const s = t.$el;
if (s === void 0) {
U("resize-observer", "$el does not exist.");
return;
}
if (s.nextElementSibling !== s.nextSibling && s.nodeType === 3 && s.nodeValue !== "") {
U("resize-observer", "$el can not be observed (it may be a text node).");
return;
}
s.nextElementSibling !== null && (Q.registerHandler(s.nextElementSibling, o), e = !0);
}), C(() => {
e && Q.unregisterHandler(t.$el.nextElementSibling);
});
},
render() {
return xe(this.$slots, "default");
}
});
function re(n) {
return n instanceof HTMLElement;
}
function oe(n) {
for (let e = 0; e < n.childNodes.length; e++) {
const t = n.childNodes[e];
if (re(t) && (le(t) || oe(t)))
return !0;
}
return !1;
}
function ie(n) {
for (let e = n.childNodes.length - 1; e >= 0; e--) {
const t = n.childNodes[e];
if (re(t) && (le(t) || ie(t)))
return !0;
}
return !1;
}
function le(n) {
if (!Pe(n))
return !1;
try {
n.focus({ preventScroll: !0 });
} catch {
}
return document.activeElement === n;
}
function Pe(n) {
if (n.tabIndex > 0 || n.tabIndex === 0 && n.getAttribute("tabIndex") !== null)
return !0;
if (n.getAttribute("disabled"))
return !1;
switch (n.nodeName) {
case "A":
return !!n.href && n.rel !== "ignore";
case "INPUT":
return n.type !== "hidden" && n.type !== "file";
case "BUTTON":
case "SELECT":
case "TEXTAREA":
return !0;
default:
return !1;
}
}
let E = [];
const nt = M({
name: "FocusTrap",
props: {
disabled: Boolean,
active: Boolean,
autoFocus: {
type: Boolean,
default: !0
},
onEsc: Function,
initialFocusTo: String,
finalFocusTo: String,
returnFocusOnDeactivated: {
type: Boolean,
default: !0
}
},
setup(n) {
const e = ge(), t = F(null), o = F(null);
let s = !1, d = !1;
const p = typeof document > "u" ? null : document.activeElement;
function m() {
return E[E.length - 1] === e;
}
function u(i) {
var r;
i.code === "Escape" && m() && ((r = n.onEsc) === null || r === void 0 || r.call(n, i));
}
k(() => {
z(() => n.active, (i) => {
i ? (w(), I("keydown", document, u)) : (S("keydown", document, u), s && l());
}, {
immediate: !0
});
}), C(() => {
S("keydown", document, u), s && l();
});
function b(i) {
if (!d && m()) {
const r = v();
if (r === null || r.contains(Me(i)))
return;
a("first");
}
}
function v() {
const i = t.value;
if (i === null)
return null;
let r = i;
for (; r = r.nextSibling, !(r === null || r instanceof Element && r.tagName === "DIV"); )
;
return r;
}
function w() {
var i;
if (!n.disabled) {
if (E.push(e), n.autoFocus) {
const { initialFocusTo: r } = n;
r === void 0 ? a("first") : (i = q(r)) === null || i === void 0 || i.focus({ preventScroll: !0 });
}
s = !0, document.addEventListener("focus", b, !0);
}
}
function l() {
var i;
if (n.disabled || (document.removeEventListener("focus", b, !0), E = E.filter((c) => c !== e), m()))
return;
const { finalFocusTo: r } = n;
r !== void 0 ? (i = q(r)) === null || i === void 0 || i.focus({ preventScroll: !0 }) : n.returnFocusOnDeactivated && p instanceof HTMLElement && (d = !0, p.focus({ preventScroll: !0 }), d = !1);
}
function a(i) {
if (m() && n.active) {
const r = t.value, c = o.value;
if (r !== null && c !== null) {
const y = v();
if (y == null || y === c) {
d = !0, r.focus({ preventScroll: !0 }), d = !1;
return;
}
d = !0;
const A = i === "first" ? oe(y) : ie(y);
d = !1, A || (d = !0, r.focus({ preventScroll: !0 }), d = !1);
}
}
}
function h(i) {
if (d)
return;
const r = v();
r !== null && (i.relatedTarget !== null && r.contains(i.relatedTarget) ? a("last") : a("first"));
}
function f(i) {
d || (i.relatedTarget !== null && i.relatedTarget === t.value ? a("last") : a("first"));
}
return {
focusableStartRef: t,
focusableEndRef: o,
focusableStyle: "position: absolute; height: 0; width: 0;",
handleStartFocus: h,
handleEndFocus: f
};
},
render() {
const { default: n } = this.$slots;
if (n === void 0)
return null;
if (this.disabled)
return n();
const { active: e, focusableStyle: t } = this;
return $(Z, null, [
$("div", {
"aria-hidden": "true",
tabindex: e ? "0" : "-1",
ref: "focusableStartRef",
style: t,
onFocus: this.handleStartFocus
}),
n(),
$("div", {
"aria-hidden": "true",
style: t,
ref: "focusableEndRef",
tabindex: e ? "0" : "-1",
onFocus: this.handleEndFocus
})
]);
}
});
export {
Ze as B,
nt as F,
Xe as L,
tt as V,
et as a,
Re as b
};