@opentiny/vue-renderless
Version:
An enterprise-class UI component library, support both Vue.js 2 and Vue.js 3, as well as PC and mobile.
118 lines (117 loc) • 3.52 kB
JavaScript
import "../chunk-G2ADBYYC.js";
const computedItemsWithSize = ({ props, state }) => () => {
const result = [];
const { items, keyField } = props;
const { simpleArray, vscrollData } = state;
const { sizes } = vscrollData;
const l = items.length;
for (let i = 0; i < l; i++) {
const item = items[i];
const id = simpleArray ? i : item[keyField];
let size = sizes[id];
if (typeof size === "undefined" && !state.temporary.undefinedMap[id]) {
size = 0;
}
result.push({ item, id, size });
}
return result;
};
const onScrollerResize = ({ api, emit, vm }) => () => {
const scroller = vm.$refs.scroller;
if (scroller) {
api.forceUpdate();
}
emit("resize");
};
const onScrollerVisible = ({ emit, state }) => () => {
state.temporary.events.emit("vscroll:update", { force: false });
emit("visible");
};
const forceUpdate = (state) => (clear = false) => {
if (clear || state.simpleArray) {
state.vscrollData.sizes = {};
}
state.temporary.events.emit("vscroll:update", { force: true });
};
const prepareProvide = (state) => {
if (typeof ResizeObserver !== "undefined") {
state.temporary.resizeObserver = new ResizeObserver((entries) => {
requestAnimationFrame(() => {
if (!Array.isArray(entries))
return;
for (const entry of entries) {
if (entry.target && entry.target._onResize) {
let width, height;
if (entry.borderBoxSize) {
const resizeObserverSize = entry.borderBoxSize[0];
width = resizeObserverSize.inlineSize;
height = resizeObserverSize.blockSize;
} else {
width = entry.contentRect.width;
height = entry.contentRect.height;
}
entry.target._onResize(entry.target._id, width, height);
}
}
});
});
}
};
const watchItemsWithSize = ({ props, vm }) => (next, prev) => {
const scrollTop = vm.$el.scrollTop;
const length = Math.min(next.length, prev.length);
let prevActiveTop = 0;
let activeTop = 0;
for (let i = 0; i < length; i++) {
if (prevActiveTop >= scrollTop)
break;
prevActiveTop += prev[i].size || props.minItemSize;
activeTop += next[i].size || props.minItemSize;
}
const offset = activeTop - prevActiveTop;
if (offset === 0)
return;
vm.$el.scrollTop += offset;
};
const scrollToItem = (vm) => (index) => {
const scroller = vm.$refs.scroller;
if (scroller)
scroller.scrollToItem(index);
};
const getItemSize = ({ props, state }) => (item, index = void 0) => {
const id = state.simpleArray ? index === 0 || index ? index : props.items.indexOf(item) : item[props.keyField];
return state.vscrollData.sizes[id] || 0;
};
const scrollToBottom = ({ state, vm, nextTick }) => () => {
if (state.temporary.scrollingToBottom)
return;
state.temporary.scrollingToBottom = true;
const el = vm.$el;
const step = (el2) => el2.scrollTop = el2.scrollHeight + 5e3;
nextTick(() => {
step(el);
const cb = () => {
step(el);
requestAnimationFrame(() => {
step(el);
if (state.temporary.undefinedSizes === 0) {
state.temporary.scrollingToBottom = false;
} else {
requestAnimationFrame(cb);
}
});
};
requestAnimationFrame(cb);
});
};
export {
computedItemsWithSize,
forceUpdate,
getItemSize,
onScrollerResize,
onScrollerVisible,
prepareProvide,
scrollToBottom,
scrollToItem,
watchItemsWithSize
};