import type { VNodeProps, Ref, ShallowRef } from 'vue';
import { GetKey, CacheMap } from '../virtual-list-types';
import { watch, ref } from 'vue';
export default function useHeights<T>(
mergedData: ShallowRef<unknown[]>,
getKey: GetKey<T>,
): [(item: T, instance: HTMLElement & { $el: never }) => void, () => void, CacheMap, Ref<symbol>] {
const instance = new Map<VNodeProps['key'], HTMLElement>();
let heights = new Map();
const updatedMark = ref(Symbol('update'));
watch(mergedData, () => {
heights = new Map();
updatedMark.value = Symbol('update');
});
let heightUpdateId = 0;
function collectHeight() {
heightUpdateId += 1;
const currentId = heightUpdateId;
Promise.resolve().then(() => {
if (currentId !== heightUpdateId) {return;}
instance.forEach((element, key) => {
if (element && element.offsetParent) {
const { offsetHeight } = element;
if (heights.get(key) !== offsetHeight) {
updatedMark.value = Symbol('update');
heights.set(key, element.offsetHeight);
}
}
});
});
}
function setInstance(item: T, ins: HTMLElement & { $el: never }) {
const key = getKey(item);
if (ins) {
instance.set(key, ins.$el || ins);
collectHeight();
} else {
instance.delete(key);
}
}
return [setInstance, collectHeight, heights, updatedMark];
}