@extclp/vexip-ui
Version:
A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good
112 lines (111 loc) • 4.47 kB
JavaScript
import { defineComponent as U, getCurrentInstance as W, shallowRef as $, ref as s, computed as R, watchEffect as Y, watch as j, onMounted as D, onBeforeUnmount as G, openBlock as J, createElementBlock as K, normalizeClass as B, unref as I, normalizeStyle as T, createElementVNode as O, renderSlot as Q } from "vue";
import { useProps as X, useNameHelper as Z, emitEvent as H } from "@vexip-ui/config";
import { affixProps as ee } from "./props.mjs";
import { isElement as N, callIfFunc as te, isClient as le } from "@vexip-ui/utils";
import { handleLastScroller as oe, clearLastScroller as ne } from "./helpers.mjs";
const pe = /* @__PURE__ */ U({
name: "Affix",
__name: "affix",
props: ee,
setup(k, { expose: A }) {
const e = X("affix", k, {
offset: 0,
zIndex: 100,
position: "top",
target: null
}), C = Z("affix"), P = W(), p = $(), a = $(), l = $();
let m = !1, r = null;
const n = s(!1), d = s(0), g = s(0), h = s(0), x = s(0), c = s(0), V = R(() => ({
height: n.value ? `${d.value}px` : "",
width: n.value ? `${g.value}px` : ""
})), q = R(() => {
if (!n.value) return {};
let t = e.offset, o = e.offset;
return N(l.value) && (e.target && e.position === "top" ? t += c.value : o += c.value), {
height: `${d.value}px`,
width: `${g.value}px`,
top: e.position === "top" ? `${t}px` : "",
bottom: e.position === "bottom" ? `${o}px` : "",
zIndex: e.zIndex
};
});
Y(w), j(n, (t) => {
H(e.onChange, t);
}), A({ update: w }), D(() => {
if (e.target) {
const t = te(e.target);
if (typeof t == "string") {
if (a.value = document.querySelector(t) ?? void 0, !a.value)
throw new Error(`[vexip-ui:Affix] target not exists: ${e.target}`);
} else
a.value = t;
} else
a.value = document.documentElement;
F();
}), G(() => {
L();
});
function w() {
if (!p.value || !a.value || !l.value) return;
const t = p.value.getBoundingClientRect(), o = a.value.getBoundingClientRect();
d.value = t.height, g.value = t.width, h.value = l.value === window ? document.documentElement.scrollTop : l.value.scrollY || 0, h.value = document.documentElement.scrollTop, x.value = document.documentElement.clientHeight, e.position === "top" ? e.target ? (c.value = o.top, n.value = t.top < o.top + e.offset) : n.value = e.offset > t.top : e.target ? (c.value = x.value - o.bottom, n.value = o.bottom < e.offset + t.bottom) : n.value = x.value - e.offset < t.bottom;
}
function u() {
oe(a), w(), H(e.onScroll, {
scrollTop: h.value,
fixed: n.value
});
}
function F() {
var t, o, y;
if (L(), !!le)
if (e.target)
l.value = a.value, l.value.addEventListener("scroll", u);
else {
let i = P.parent;
const M = "scroll";
for (; i; ) {
const z = (t = i.type) == null ? void 0 : t.name;
if (z === "Scroll" || z === "NativeScroll") {
const { exposeProxy: E, exposed: S, proxy: b } = i, v = new Proxy({}, {
get(ie, _) {
return (b == null ? void 0 : b[_]) ?? (E == null ? void 0 : E[_]) ?? (S == null ? void 0 : S[_]);
}
});
if (!((o = (v == null ? void 0 : v.$el).getAttribute("class")) != null && o.includes("vxp-native-scroll--horizontal"))) {
r = v;
break;
}
}
const f = (y = i.refs) == null ? void 0 : y[M];
if (f) {
N(f) ? (m = !0, l.value = f) : r = f;
break;
}
i = i.parent;
}
r ? (r.addScrollListener(u), l.value = r.$el) : l.value || (m = !0, l.value = window), m && l.value && l.value.addEventListener("scroll", u);
}
}
function L() {
r && (r.removeScrollListener(u), r = null), l.value && (l.value.removeEventListener("scroll", u), l.value = void 0), ne(a);
}
return (t, o) => (J(), K("div", {
ref_key: "wrapper",
ref: p,
class: B(I(C).b()),
style: T(V.value)
}, [
O("div", {
class: B({ [I(C).bm("fixed")]: n.value }),
style: T(q.value)
}, [
Q(t.$slots, "default")
], 6)
], 6));
}
});
export {
pe as default
};
//# sourceMappingURL=affix.vue2.mjs.map