@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, createElementBlock as J, openBlock as K, normalizeStyle as B, normalizeClass as I, unref 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) => (K(), J("div", {
ref_key: "wrapper",
ref: p,
class: I(T(C).b()),
style: B(V.value)
}, [
O("div", {
class: I({ [T(C).bm("fixed")]: n.value }),
style: B(q.value)
}, [
Q(t.$slots, "default")
], 6)
], 6));
}
});
export {
pe as default
};
//# sourceMappingURL=affix.vue2.mjs.map