@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
623 lines (622 loc) • 18.6 kB
JavaScript
import { returnFirstEl as e } from "./common/utils/index.js";
import { t } from "./_plugin-vue_export-helper-BTgDAbhb.js";
import { Fragment as n, computed as r, createBlock as i, createElementBlock as a, createVNode as o, guardReactiveProps as s, h as c, markRaw as l, mergeProps as u, nextTick as d, normalizeClass as f, normalizeProps as p, normalizeStyle as m, onMounted as h, openBlock as g, provide as _, reactive as v, ref as y, renderList as b, renderSlot as x, resolveComponent as S, resolveDynamicComponent as C, shallowReactive as w, toHandlers as T, unref as E, watch as D, withCtx as O } from "vue";
//#region components/scroller/modules/core_scroller.vue
var k = {
__name: "core_scroller",
props: {
items: {
type: Array,
required: !0
},
keyField: {
type: String,
default: "id"
},
direction: {
type: String,
default: "vertical",
validator: (e) => ["vertical", "horizontal"].includes(e)
},
itemSize: {
type: Number,
default: null
},
minItemSize: {
type: [Number, String],
default: null
},
sizeField: {
type: String,
default: "size"
},
buffer: {
type: Number,
default: 200
},
skipHover: {
type: Boolean,
default: !1
},
listTag: {
type: String,
default: "div"
},
itemTag: {
type: String,
default: "div"
},
listClass: {
type: [
String,
Object,
Array
],
default: ""
},
itemClass: {
type: [
String,
Object,
Array
],
default: ""
}
},
emits: ["user-position"],
setup(e, { expose: t, emit: o }) {
let s = e, c = o, p = v(/* @__PURE__ */ new Map()), _ = v(/* @__PURE__ */ new Map()), S = y([]), k = y(null), A = y(!1), j = y(null), M = y("top"), N = 0, P = 0, F = !1, I = 0, L = null, R = null, z = 0, B = 0, V = r(() => {
if (s.itemSize === null) {
let e = { "-1": { accumulator: 0 } }, t = s.items, n = s.sizeField, r = s.minItemSize, i = 1e4, a = 0, o;
for (let s = 0, c = t.length; s < c; s++) o = t[s][n] || r, o < i && (i = o), a += o, e[s] = {
accumulator: a,
size: o
};
return R = i, e;
}
return [];
}), H = r(() => s.items.length && typeof s.items[0] != "object"), U = r(() => {
let e = {};
for (let t = 0, n = s.items.length; t < n; t++) e[s.items[t][s.keyField]] = t;
return e;
});
D(V, () => {
Y(!1);
}, { deep: !0 }), h(() => {
d(() => {
Y(!0), A.value = !0;
});
});
let W = (e, t, n, r, i) => {
let a = w({
item: n,
position: 0,
nr: l({
id: B++,
index: t,
used: !0,
key: r,
type: i
})
});
return e.value.push(a), a;
}, G = (e, t = !1) => {
let n = _, r = e.nr.type, i = n.get(r);
i || (i = [], n.set(r, i)), i.push(e), t || (e.nr.used = !1, e.position = -9999);
}, K = () => {
let e = s.direction === "vertical", t;
return t = e ? {
start: j.value.scrollTop,
end: j.value.scrollTop + j.value.clientHeight
} : {
start: j.value.scrollLeft,
end: j.value.scrollLeft + j.value.clientWidth
}, t;
}, q = () => {
throw setTimeout(() => {
console.error("It seems the scroller element isn't scrolling, so it tries to render all the items at once.", "Scroller:", j), console.error("Make sure the scroller has a fixed height (or width) and 'overflow-y' (or 'overflow-x') set to 'auto' so it can scroll correctly and only render the items visible in the scroll viewport.");
}), Error("Rendered items limit reached");
}, J = () => {
S.value.sort((e, t) => e.nr.index - t.nr.index);
}, Y = (e, t = !1) => {
let n = s.itemSize, r = R, i = H.value ? null : s.keyField, a = s.items, o = a.length, c = V.value, l = p, u = _, d = S, f = U, m, h, g, v, y;
if (!o) m = h = v = y = g = 0;
else {
let e = K();
if (t) {
let t = e.start - I.value;
if (t < 0 && (t = -t), n === null && t < r.value || t < n) return { continuous: !0 };
}
I = e.start;
let i = s.buffer;
if (e.start -= i, e.end += i, n === null) {
let t, n = 0, r = o - 1, i = ~~(o / 2), s;
do
s = i, t = c[i]?.accumulator, t < e.start ? n = i : i < o - 1 && c[i + 1]?.accumulator > e.start && (r = i), i = ~~((n + r) / 2);
while (i !== s);
for (i < 0 && (i = 0), m = i, g = c[o - 1]?.accumulator, h = i; h < o && c[h]?.accumulator < e.end; h++);
for (h === -1 ? h = a.length - 1 : (h++, h > o && (h = o)), v = N; v < o && c[v]?.accumulator < e.start; v++);
for (y = v; y < o && c[y]?.accumulator < e.end; y++);
} else {
m = ~~(e.start / n);
let t = m % 1;
m -= t, h = Math.ceil(e.end / n), v = Math.max(0, Math.floor(e.start / n)), y = Math.floor(e.end / n), m < 0 && (m = 0), h > o && (h = o), v < 0 && (v = 0), y > o && (y = o), g = Math.ceil(o / 1) * n;
}
}
h - m > 1e3 && q(), z = g;
let b, x = m <= P && h >= m;
if (x) for (let t = 0, n = d.value.length; t < n; t++) b = d.value[t], b?.nr.used && (e && (b.nr.index = f[b.item[i]]), (b.nr.index == null || b.nr.index < m || b.nr.index >= h) && G(b));
let C = x ? null : /* @__PURE__ */ new Map(), w, T, E;
for (let e = m; e < h; e++) {
w = a[e];
let t = i ? w?.[i] : w;
if (t == null) throw Error(`Key is ${t} on item (keyField is '${i}')`);
if (b = l.get(t), !n && !c[e]?.size) {
b && G(b);
continue;
}
T = w.type;
let r = u.get(T);
if (!b) x ? b = r && r.length ? r.pop() : W(d, e, w, t, T) : (E = C.get(T) || 0, (!r || E >= r.length) && (b = W(d, e, w, t, T), G(b, !0), r = u.get(T)), b = r[E], C.set(T, E + 1)), l.delete(b.nr.key), b.nr.used = !0, b.nr.index = e, b.nr.key = t, b.nr.type = T, l.set(t, b);
else if (!b.nr.used && (b.nr.used = !0, r)) {
let e = r.indexOf(b);
e !== -1 && r.splice(e, 1);
}
b.item = w, n === null ? (b.position = c[e - 1]?.accumulator, b.offset = 0) : (b.position = Math.floor(e) * n, b.offset = e % 1 * n);
}
return N = m, P = h, clearTimeout(L), L = setTimeout(J, 300), { continuous: x };
}, X = (e) => {
let t = s.direction === "vertical" ? {
scroll: "scrollTop",
start: "top"
} : {
scroll: "scrollLeft",
start: "left"
}, n = j.value, r = t.scroll;
n[r] = e;
}, Z = (e) => {
let t;
t = s.itemSize === null ? e > 0 ? V.value[e - 1]?.accumulator : 0 : Math.floor(e) * s.itemSize, X(t);
}, Q = () => {
let e = j.value;
M.value !== "middle" && (M.value = "middle", c("user-position", "middle")), e.scrollTop === 0 && (M.value = "top", c("user-position", "top")), e.scrollTop + e.clientHeight === e.scrollHeight && (M.value = "bottom", c("user-position", "bottom")), F || (F = !0, requestAnimationFrame(() => {
F = !1, Y(!1, !0);
}));
};
return t({
scrollToItem: Z,
_updateVisibleItems: Y
}), (t, r) => (g(), a("div", {
ref_key: "scroller",
ref: j,
class: f(["vue-recycle-scroller", {
ready: A.value,
[`direction-${e.direction}`]: !0
}]),
onScrollPassive: Q
}, [(g(), i(C(e.listTag), {
ref: "wrapper",
style: m({ [e.direction === "vertical" ? "minHeight" : "minWidth"]: `${E(z)}px` }),
class: f(["vue-recycle-scroller__item-wrapper", e.listClass])
}, {
default: O(() => [(g(!0), a(n, null, b(S.value, (n) => (g(), i(C(e.itemTag), u({
key: n.nr.id,
style: A.value ? {
transform: `translate${e.direction === "vertical" ? "Y" : "X"}(${n.position}px) translate${e.direction === "vertical" ? "X" : "Y"}(${n.offset}px)`,
width: void 0,
height: void 0
} : null,
class: ["vue-recycle-scroller__item-view", [e.itemClass, { hover: !e.skipHover && k.value === n.nr.key }]]
}, T(e.skipHover ? {} : {
mouseenter: () => {
k.value = n.nr.key;
},
mouseleave: () => {
k.value = null;
}
})), {
default: O(() => [x(t.$slots, "default", {
item: n.item,
index: n.nr.index,
active: n.nr.used
})]),
_: 2
}, 1040, ["style", "class"]))), 128))]),
_: 3
}, 8, ["style", "class"]))], 34));
}
}, A = {
name: "DynamicScroller",
components: {
CoreScroller: k,
DtScrollerItem: {
name: "DtScrollerItem",
inject: [
"vscrollData",
"vscrollParent",
"vscrollResizeObserver"
],
props: {
item: { required: !0 },
watchData: {
type: Boolean,
default: !1
},
active: {
type: Boolean,
required: !0
},
index: {
type: Number,
default: void 0
},
sizeDependencies: {
type: [Array, Object],
default: null
},
tag: {
type: String,
default: "div"
}
},
computed: {
id() {
if (this.vscrollData.simpleArray) return this.index;
if (this.vscrollData.keyField in this.item) return this.item[this.vscrollData.keyField];
throw Error(`keyField '${this.vscrollData.keyField}' not found in your item. You should set a valid keyField prop on your Scroller`);
},
size() {
return this.vscrollData.sizes[this.id] || 0;
},
finalActive() {
return this.active && this.vscrollData.active;
}
},
watch: {
watchData: "updateWatchData",
id(t, n) {
if (e(this.$el).$_vs_id = this.id, this.size || this.onDataUpdate(), this.$_sizeObserved) {
let e = this.vscrollData.sizes[n], r = this.vscrollData.sizes[t];
e != null && e !== r && this.applySize(e);
}
},
finalActive(e) {
this.size || (e ? this.vscrollParent.$_undefinedMap[this.id] || (this.vscrollParent.$_undefinedSizes++, this.vscrollParent.$_undefinedMap[this.id] = !0) : this.vscrollParent.$_undefinedMap[this.id] && (this.vscrollParent.$_undefinedSizes--, this.vscrollParent.$_undefinedMap[this.id] = !1)), this.vscrollResizeObserver ? e ? this.observeSize() : this.unobserveSize() : e && this.$_pendingVScrollUpdate === this.id && this.updateSize();
}
},
created() {
if (!this.$isServer && (this.$_forceNextVScrollUpdate = null, this.updateWatchData(), !this.vscrollResizeObserver)) for (let e in this.sizeDependencies) this.$watch(() => this.sizeDependencies[e], this.onDataUpdate);
},
mounted() {
this.finalActive && (this.updateSize(), this.observeSize());
},
beforeUnmount() {
this.unobserveSize();
},
methods: {
updateSize() {
this.finalActive ? this.$_pendingSizeUpdate !== this.id && (this.$_pendingSizeUpdate = this.id, this.$_forceNextVScrollUpdate = null, this.$_pendingVScrollUpdate = null, this.computeSize(this.id)) : this.$_forceNextVScrollUpdate = this.id;
},
updateWatchData() {
this.watchData && !this.vscrollResizeObserver ? this.$_watchData = this.$watch("item", () => {
this.onDataUpdate();
}, { deep: !0 }) : this.$_watchData && (this.$_watchData(), this.$_watchData = null);
},
onVscrollUpdate({ force: e }) {
!this.finalActive && e && (this.$_pendingVScrollUpdate = this.id), (this.$_forceNextVScrollUpdate === this.id || e || !this.size) && this.updateSize();
},
onDataUpdate() {
this.updateSize();
},
computeSize(t) {
this.$nextTick(() => {
if (this.id === t) {
let t = e(this.$el).offsetWidth, n = e(this.$el).offsetHeight;
this.applyWidthHeight(t, n);
}
this.$_pendingSizeUpdate = null;
});
},
applyWidthHeight(e, t) {
let n = ~~(this.vscrollParent.direction === "vertical" ? t : e);
n && this.size !== n && this.applySize(n);
},
applySize(e) {
this.vscrollParent.$_undefinedMap[this.id] && (this.vscrollParent.$_undefinedSizes--, this.vscrollParent.$_undefinedMap[this.id] = void 0), this.vscrollData.sizes[this.id] = e;
},
observeSize() {
this.vscrollResizeObserver && (this.$_sizeObserved || (this.vscrollResizeObserver.observe(e(this.$el)), this.$el.$_vs_id = this.id, this.$el.$_vs_onResize = this.onResize, this.$_sizeObserved = !0));
},
unobserveSize() {
this.vscrollResizeObserver && this.$_sizeObserved && (this.vscrollResizeObserver.unobserve(e(this.$el)), this.$el.$_vs_onResize = void 0, this.$_sizeObserved = !1);
},
onResize(e, t, n) {
this.id === e && this.applyWidthHeight(t, n);
}
},
render() {
return c(this.tag, this.$slots.default());
}
}
},
provide() {
return typeof ResizeObserver < "u" && (this.$_resizeObserver = new ResizeObserver((e) => {
requestAnimationFrame(() => {
if (Array.isArray(e)) {
for (let t of e) if (t.target && t.target.$_vs_onResize) {
let e, n;
if (t.borderBoxSize) {
let r = t.borderBoxSize[0];
e = r.inlineSize, n = r.blockSize;
} else e = t.contentRect.width, n = t.contentRect.height;
t.target.$_vs_onResize(t.target.$_vs_id, e, n);
}
}
});
})), {
vscrollData: this.vscrollData,
vscrollParent: this,
vscrollResizeObserver: this.$_resizeObserver
};
},
inheritAttrs: !1,
props: {
items: {
type: Array,
required: !0
},
dynamic: {
type: Boolean,
default: !1
},
keyField: {
type: String,
default: "id"
},
direction: {
type: String,
default: "vertical",
validator: (e) => ["vertical", "horizontal"].includes(e)
},
listTag: {
type: String,
default: "div"
},
itemTag: {
type: String,
default: "div"
},
minItemSize: { type: [Number, String] }
},
data() {
return { vscrollData: {
active: !0,
sizes: {},
keyField: this.keyField,
simpleArray: !1
} };
},
computed: {
simpleArray() {
return this.items.length && typeof this.items[0] != "object";
},
itemsWithSize() {
let e = [], { items: t, keyField: n, simpleArray: r } = this, i = this.vscrollData.sizes, a = t.length;
for (let o = 0; o < a; o++) {
let a = t[o], s = r ? o : a[n], c = i[s];
c === void 0 && !this.$_undefinedMap[s] && (c = 0), e.push({
item: a,
[n]: s,
size: c
});
}
return e;
}
},
watch: {
simpleArray: {
handler(e) {
this.vscrollData.simpleArray = e;
},
immediate: !0
},
itemsWithSize(t, n) {
let r = e(this.$el).scrollTop, i = 0, a = 0, o = Math.min(t.length, n.length);
for (let e = 0; e < o && !(i >= r); e++) i += n[e].size || this.minItemSize, a += t[e].size || this.minItemSize;
let s = a - i;
s !== 0 && (e(this.$el).scrollTop += s);
}
},
beforeCreate() {
this.$_updates = [], this.$_undefinedSizes = 0, this.$_undefinedMap = {};
},
activated() {
this.vscrollData.active = !0;
},
deactivated() {
this.vscrollData.active = !1;
},
methods: {
dynamicScrollerUpdateItems() {
let e = this.$refs.scroller;
e && e._updateVisibleItems(!0);
},
dynamicScrollerUpdateItemsFromBottom() {
let e = this.$refs.scroller;
e && e._updateVisibleItems(!1, !0);
},
scrollToItem(e) {
let t = this.$refs.scroller;
t && t.scrollToItem(e);
},
scrollToBottom() {
if (this.$_scrollingToBottom) return;
this.$_scrollingToBottom = !0;
let t = e(this.$el);
this.$nextTick(() => {
t.scrollTop = t.scrollHeight + 5e3;
let e = () => {
t.scrollTop = t.scrollHeight + 5e3, requestAnimationFrame(() => {
t.scrollTop = t.scrollHeight + 5e3, this.$_undefinedSizes === 0 ? this.$_scrollingToBottom = !1 : requestAnimationFrame(e);
});
};
requestAnimationFrame(e);
});
}
}
};
function j(e, t, n, r, a, c) {
let l = S("dt-scroller-item"), d = S("core-scroller");
return g(), i(d, u({
ref: "scroller",
items: c.itemsWithSize,
"min-item-size": n.minItemSize,
direction: n.direction,
"key-field": n.keyField,
"list-tag": n.listTag,
"item-tag": n.itemTag
}, e.$attrs), {
default: O(({ item: t, index: n, active: r }) => [o(l, {
item: t,
active: r,
"size-dependencies": [t.message],
"data-index": n
}, {
default: O(() => [x(e.$slots, "default", p(s({
item: t.item,
index: n,
active: r,
itemWithSize: t
})))]),
_: 2
}, 1032, [
"item",
"active",
"size-dependencies",
"data-index"
])]),
_: 3
}, 16, [
"items",
"min-item-size",
"direction",
"key-field",
"list-tag",
"item-tag"
]);
}
var M = /* @__PURE__ */ t(A, [["render", j]]), N = /* @__PURE__ */ Object.assign({ name: "DtScroller" }, {
__name: "scroller",
props: {
direction: {
type: String,
default: "vertical",
validator: (e) => ["vertical", "horizontal"].includes(e)
},
dynamic: {
type: Boolean,
default: !1
},
itemSize: {
type: Number,
default: null
},
itemTag: {
type: String,
default: "div"
},
items: {
type: Array,
required: !0
},
keyField: {
type: String,
default: "id"
},
listTag: {
type: String,
default: "div"
},
minItemSize: {
type: [Number, String],
default: null
},
scrollerHeight: {
type: [String, Number],
default: "100%"
},
scrollerWidth: {
type: [String, Number],
default: "100%"
}
},
emits: ["user-position"],
setup(e, { expose: t, emit: n }) {
let a = e;
_("emit", n);
let o = y(null), c = r(() => ({
width: typeof a.scrollerWidth == "number" ? `${a.scrollerWidth}px` : a.scrollerWidth,
height: typeof a.scrollerHeight == "number" ? `${a.scrollerHeight}px` : a.scrollerHeight
}));
D(a, () => {
h();
}, {
deep: !0,
immediate: !0
});
function l() {
o.value && o.value.scrollToBottom();
}
function u(e) {
o.value && o.value.scrollToItem(e);
}
function d() {
o.value && (a.dynamic ? o.value.dynamicScrollerUpdateItems() : o.value._updateVisibleItems(!0));
}
function f() {
o.value && (a.dynamic ? o.value.dynamicScrollerUpdateItemsFromBottom() : o.value._updateVisibleItems(!1, !0));
}
function h() {
a.dynamic && !a.minItemSize && console.error("scroller error: 'minItemSize' is required on 'dynamic' mode."), !a.dynamic && !a.itemSize && console.error("scroller error: 'itemSize' is required.");
}
return t({
scrollToBottom: l,
scrollToItem: u,
updateItems: d,
updateItemsFromBottom: f
}), (t, n) => (g(), i(C(e.dynamic ? M : k), {
ref_key: "scroller",
ref: o,
"data-qa": "dt-scroller",
items: e.items,
"item-size": e.itemSize,
"min-item-size": e.minItemSize,
direction: e.direction,
"key-field": e.keyField,
"list-tag": e.listTag,
"item-tag": e.itemTag,
style: m(c.value),
tabindex: "0",
onUserPosition: n[0] || (n[0] = (e) => t.$emit("user-position", e))
}, {
default: O(({ item: e, index: n, active: r }) => [x(t.$slots, "default", p(s({
item: e,
index: n,
active: r
})))]),
_: 3
}, 40, [
"items",
"item-size",
"min-item-size",
"direction",
"key-field",
"list-tag",
"item-tag",
"style"
]));
}
});
//#endregion
export { N as t };
//# sourceMappingURL=scroller-BGVDh3sq.js.map