vuux
Version:
Vue3 Nuxt3 Nuxt4 组件库
95 lines (94 loc) • 3.74 kB
JavaScript
import { ref as G, reactive as X, computed as Y, watch as D, nextTick as P, onBeforeUnmount as J } from "vue";
const Q = (A, v, u, T) => {
const l = G(!1), o = X({
position: "fixed",
top: "0px",
left: "0px",
visibility: "hidden"
}), z = G("placement-top"), S = Y(() => {
const t = [z.value];
return A.shadow && t.push("is-shadow"), t.join(" ");
}), p = 8, d = 12, m = (t, n, e) => Math.max(n, Math.min(e, t)), U = (t, n, e, M, C, k) => {
const a = Math.max(0, t), s = Math.max(0, n), h = Math.min(C, t + e), y = Math.min(k, n + M), i = Math.max(0, h - a), O = Math.max(0, y - s);
return i * O;
};
let w = null, f = null, g = null, x = null, b = !1;
const _ = () => {
l.value = !1, T("close");
}, j = () => {
l.value = !1, T("ok");
}, B = async () => {
if (!v.value || !u.value)
return;
const t = v.value, n = u.value;
o.visibility = "hidden", o.top = "0px", o.left = "0px", await P();
const e = t.getBoundingClientRect(), M = window.innerWidth, C = window.innerHeight, k = n.getBoundingClientRect(), a = k.width, s = k.height, h = 14, y = [
{
name: "placement-top",
left: e.left + (e.width - a) / 2,
top: e.top - s - h
},
{
name: "placement-bottom",
left: e.left + (e.width - a) / 2,
top: e.bottom + h
},
{
name: "placement-left",
left: e.left - a - h,
top: e.top + (e.height - s) / 2
},
{
name: "placement-right",
left: e.right + h,
top: e.top + (e.height - s) / 2
}
];
let i = y[0], O = -1;
for (const E of y) {
const $ = U(E.left, E.top, a, s, M, C), F = E.name === "placement-top" ? 1e-4 : 0;
$ + F > O && (O = $ + F, i = E);
}
const R = m(i.left, p, Math.max(p, M - a - p)), W = m(i.top, p, Math.max(p, C - s - p)), N = e.left + e.width / 2, V = e.top + e.height / 2;
let c = 0;
i.name === "placement-top" || i.name === "placement-bottom" ? (c = N - R, c = m(c, d, Math.max(d, a - d))) : (c = V - W, c = m(c, d, Math.max(d, s - d))), o.left = `${Math.round(R)}px`, o.top = `${Math.round(W)}px`, o["--arrow-position"] = `${Math.round(c)}px`, z.value = i.name, o.visibility = "visible";
}, r = () => {
l.value && (b || (b = !0, x = requestAnimationFrame(() => {
B().catch(() => {
}), b = !1;
})));
}, q = () => {
!v.value || !u.value || (w = new ResizeObserver(() => r()), f = new ResizeObserver(() => r()), w.observe(v.value), f.observe(u.value), g = new IntersectionObserver(
(t) => {
for (const n of t)
n.intersectionRatio < 1 && r();
},
{ threshold: [0, 0.25, 0.5, 0.75, 1] }
), g.observe(u.value), window.addEventListener("scroll", r, { passive: !0, capture: !0 }), window.addEventListener("resize", r, { passive: !0 }));
}, I = () => {
w?.disconnect(), w = null, f?.disconnect(), f = null, g?.disconnect(), g = null, window.removeEventListener("scroll", r, !0), window.removeEventListener("resize", r), x && (cancelAnimationFrame(x), x = null), b = !1;
}, H = () => {
A.disabled || (l.value = !0);
}, L = (t) => {
const n = u.value, e = v.value;
!n || !e || n.contains(t.target) || e.contains(t.target) || (l.value = !1);
};
return D(
() => l.value,
async (t) => {
t ? (await P(), await B(), q(), document.addEventListener("click", L)) : (o.visibility = "hidden", I(), document.removeEventListener("click", L));
}
), J(() => {
I(), document.removeEventListener("click", L);
}), {
isOpen: l,
popupStyle: o,
placementClass: S,
handleTriggerClick: H,
emitCancel: _,
emitConfirm: j
};
};
export {
Q as useConfirmPopup
};