UNPKG

y-design-ssr

Version:

SSR component library of YUI with Vue3

393 lines (392 loc) 10.7 kB
import { ref as d, reactive as J, defineComponent as F, createVNode as i, computed as S, onMounted as K, onUpdated as Q, nextTick as X, onUnmounted as Z, createTextVNode as ee } from "vue"; const te = (e) => (n) => Object.prototype.toString.call(n) === `[object ${e}]`, ne = te("Number"), _ = (e, n) => n ? typeof n == "string" ? ` ${e}--${n}` : Array.isArray(n) ? n.reduce((u, l) => u + _(e, l), "") : Object.keys(n).reduce( (u, l) => u + (n[l] ? _(e, l) : ""), "" ) : "", ae = (e) => (n, u) => { let l = n, f = u; return l && typeof l != "string" && (f = l, l = ""), l = l ? `${e}__${l}` : e, `${l}${_(l, f)}`; }, le = () => (e, n) => n ? `${_(`y-${e}`, n)}` : `y-${e}`, re = { "pull-refresh": { pulling: "下拉刷新...", loosing: "释放刷新...", loading: "数据加载中...", success: "数据已更新", failed: "数据跟新失败,请稍后再试" }, "form-item": { validateMessage: "请输入正确内容" } }; d("zh-CN"); J({ "zh-CN": re }); const P = (e) => { const n = `y-${e}`; return [n, ae(n), le()]; }, H = (e) => isNaN(Number(e)) && typeof e == "string" ? e : `${e}px`, ie = (e) => { switch (e) { case "top": return "column-reverse"; case "bottom": return "column"; case "left": return "row-reverse"; case "right": return "row"; default: return "column"; } }, [ue, R] = P("loading"), oe = { // Loading icon 的颜色 color: { type: String, default: "" }, // 背景色 bgColor: { type: String, default: "" }, bgBorderRadius: { type: [Number, String], default: "16px" }, // 粗细 thick: { type: [Number, String], default: 8 }, // 方向 direction: { type: String, default: "forward" }, // 大小 size: { type: [Number, String], default: "24px" }, padding: { type: [Number, String], default: "" }, // 文案 text: { type: String, default: "" }, // 文案位置 textLocation: { type: String, default: "bottom" }, // 文案大小 textSize: { type: [Number, String], default: "" }, // 文案颜色 textColor: { type: String, default: "" }, // 布局位置 position: { type: String, default: "relative" } }, ce = /* @__PURE__ */ F({ name: ue, props: oe, setup(e, { slots: n }) { return () => { var w, B; const { position: u, textLocation: l, bgColor: f, bgBorderRadius: h, size: o, padding: x, color: v, thick: T, direction: C, text: s, textColor: p, textSize: r } = e, k = ((w = n.default) == null ? void 0 : w.call(n)) || s; return i("div", { class: R({ [u]: u !== "relative" }) }, [i("div", { class: R("bg", { [u]: u !== "relative" }), style: { flexDirection: ie(l), backgroundColor: f, borderRadius: H(h), padding: H(x) } }, [i("span", { class: R("icon-wrapper"), style: { width: H(o), height: H(o) } }, [((B = n.icon) == null ? void 0 : B.call(n)) || i("svg", { class: R("icon", { [C]: C }), viewBox: "25 25 50 50" }, [i("circle", { class: R("icon-circle"), style: { stroke: v, strokeWidth: H(T) }, cx: "50", cy: "50", r: "20", fill: "none" }, null)])]), k && i("span", { class: R("text", { [l]: l }), style: { color: p, fontSize: H(r) } }, [k])])]); }; } }), [se, m] = P("list"), de = /* @__PURE__ */ F({ name: se, props: { // 加载中 文案 loadingText: { type: String, default: "加载中..." }, // 加载完成 文案 finishedText: { type: String, default: "没有更多了~" }, // 加载失败 文案 errorText: { type: String, default: "请求失败,点击重新加载" }, // 容器高度 height: { type: [Number, String], default: "auto" }, // 唯一键名称 keyName: { type: String, default: "_index" }, // 列表数组 dataSource: { type: Array, default: () => [] }, // 是否在初始化时立即执行滚动位置检查 immediateCheck: { type: Boolean, default: !0 }, // 滚动条与底部距离小于多少时触发加载 loadOffset: { type: Number, default: 300 }, // 是否使用虚拟列表 virtual: { type: Boolean, default: !1 }, // 缓冲区比例 bufferScale: { type: Number, default: 1 }, // 列表子项预估高度 itemHeight: { type: [String, Number], default: "80" }, // 是否是不定高度子项 dynamicItemHeight: { type: Boolean, default: !1 } }, emits: ["load"], setup(e, { slots: n, emit: u, expose: l }) { const f = d(0), h = d(!1), o = d("normal"), x = d(), v = d(), T = d(), C = d([]), s = d(0), p = d(0), r = d([]), k = S(() => ne(e.height) ? `${e.height}px` : e.height), w = S(() => r.value.length ? r.value[r.value.length - 1].bottom : 0), B = S(() => { if (e.virtual) { const t = s.value - M.value, a = p.value + V.value; return E.value.slice(t, a); } return E.value; }), M = S(() => Math.min(s.value, e.bufferScale * $.value)), V = S(() => Math.min(e.dataSource.length - p.value, e.bufferScale * $.value)), $ = S(() => Math.ceil(f.value / parseInt(String(e.itemHeight)))), E = S(() => e.dataSource.map((t, a) => (t[e.keyName] = a, t))), A = () => h.value ? document.documentElement.scrollTop || document.body.scrollTop : x.value.scrollTop, G = () => h.value ? document.documentElement.scrollHeight : x.value.scrollHeight, L = () => { o.value !== "loading" && (o.value = "loading", u("load", (t) => { if (o.value === "loading") switch (t) { case "error": o.value = "error"; break; case "finished": o.value = "finished", e.virtual && D(), e.virtual && e.dynamicItemHeight && j(); break; default: o.value = "normal", e.virtual && (j(), e.dataSource.length < $.value + V.value && L()); } })); }, z = () => { o.value === "normal" && G() - A() - f.value <= e.loadOffset && L(); }, D = () => { r.value = E.value.map((t, a) => { const c = parseInt(String(e.itemHeight)); return { index: a, height: c, top: a * c, bottom: (a + 1) * c }; }); }, j = () => { D(); for (let t = 1; t < r.value.length; t++) r.value[t].top = r.value[t - 1].bottom, r.value[t].bottom = r.value[t].top + r.value[t].height; }, W = (t, a) => { let c = 0, N = t.length - 1, g = -1; for (; c <= N; ) { const y = Math.floor((c + N) / 2), b = t[y].bottom; if (b === a) return y + 1; b < a ? c = y + 1 : b > a && ((g === -1 || g > y) && (g = y), N = y - 1); } return g; }, Y = (t) => W(r.value, t), O = () => { if (z(), e.virtual) { const t = A(); U(t); } }, U = (t) => { if (!v.value) return; const a = t || 0; if (e.dynamicItemHeight) { s.value = Y(a), p.value = s.value + $.value; const c = r.value[s.value - M.value].top ? r.value[s.value - M.value].top : 0; v.value.style.transform = `translate3d(0, ${c}px, 0)`; } else { s.value = Math.floor(a / parseInt(String(e.itemHeight))), p.value = s.value + $.value; const c = s.value * parseInt(String(e.itemHeight)) - M.value * parseInt(String(e.itemHeight)); v.value.style.transform = `translate3d(0, ${c}px, 0)`; } }, q = () => { if (!v.value || !T.value) return; const t = v.value.children; t && t.length > 0 && [...t].forEach((a) => { if (a instanceof HTMLDivElement) { const c = a.getBoundingClientRect(), { height: N } = c, g = Number(a.dataset.index), b = r.value[g].height - N; if (b) { r.value[g].bottom -= b, r.value[g].height = N; for (let I = g + 1; I < r.value.length; I++) r.value[I].top = r.value[I - 1].bottom, r.value[I].bottom -= b; } } }); }; return l({ ...e, checkIsScrollToBottom: z, loadData: L }), K(() => { e.height !== "auto" ? (h.value = !1, f.value = x.value.clientHeight) : e.height === "auto" && (h.value = !0, f.value = document.documentElement.clientHeight, document.addEventListener("scroll", O)), e.virtual && (D(), U()), e.immediateCheck && z(); }), Q(async () => { var t, a; if (e.virtual && e.dynamicItemHeight) { if (await X(), !((a = (t = v.value) == null ? void 0 : t.children) != null && a.length)) return; q(); } }), Z(() => { h.value && document.removeEventListener("scroll", O); }), () => i("div", { ref: x, class: `${m()} ${e.virtual ? m({ virtual: !0 }) : ""}`, style: { height: k.value }, onScroll: O }, [e.virtual && i("div", { ref: T, class: m("phantom"), style: { height: `${w.value}px` } }, null), i("div", { ref: v, class: m("content") }, [B.value.map((t) => { var a; return i("div", { ref: C, class: m("item"), "data-index": t._index }, [(a = n.default) == null ? void 0 : a.call(n, { item: t })]); })]), o.value === "loading" && i("div", { class: m({ loading: !0 }) }, [n.loading ? n.loading() : i(ce, { "text-location": "right" }, { default: () => [ee("加载中...")] })]), o.value === "finished" && i("div", { class: m({ finished: !0 }) }, [e.finishedText]), o.value === "error" && i("div", { class: m("error"), role: "presentation", onClick: L }, [e.errorText]), o.value === "normal" && i("div", { class: m({ normal: !0 }) }, [n.normal ? n.normal() : null])]); } }); function fe(e) { const n = e; return n.install = (u) => { const { name: l } = e; l && u.component(l, e); }, n; } const ge = fe(de); export { ge as default };