110 lines
3.7 KiB
JavaScript
110 lines
3.7 KiB
JavaScript
import { Fragment as _Fragment, createVNode as _createVNode } from "vue";
|
|
// Styles
|
|
import "./VVirtualScroll.css";
|
|
|
|
// Components
|
|
import { VVirtualScrollItem } from "./VVirtualScrollItem.mjs"; // Composables
|
|
import { makeComponentProps } from "../../composables/component.mjs";
|
|
import { makeDimensionProps, useDimension } from "../../composables/dimensions.mjs";
|
|
import { useToggleScope } from "../../composables/toggleScope.mjs";
|
|
import { makeVirtualProps, useVirtual } from "../../composables/virtual.mjs"; // Utilities
|
|
import { onMounted, onScopeDispose, toRef } from 'vue';
|
|
import { convertToUnit, genericComponent, getCurrentInstance, getScrollParent, propsFactory, useRender } from "../../util/index.mjs"; // Types
|
|
export const makeVVirtualScrollProps = propsFactory({
|
|
items: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
renderless: Boolean,
|
|
...makeVirtualProps(),
|
|
...makeComponentProps(),
|
|
...makeDimensionProps()
|
|
}, 'VVirtualScroll');
|
|
export const VVirtualScroll = genericComponent()({
|
|
name: 'VVirtualScroll',
|
|
props: makeVVirtualScrollProps(),
|
|
setup(props, _ref) {
|
|
let {
|
|
slots
|
|
} = _ref;
|
|
const vm = getCurrentInstance('VVirtualScroll');
|
|
const {
|
|
dimensionStyles
|
|
} = useDimension(props);
|
|
const {
|
|
containerRef,
|
|
markerRef,
|
|
handleScroll,
|
|
handleScrollend,
|
|
handleItemResize,
|
|
scrollToIndex,
|
|
paddingTop,
|
|
paddingBottom,
|
|
computedItems
|
|
} = useVirtual(props, toRef(props, 'items'));
|
|
useToggleScope(() => props.renderless, () => {
|
|
function handleListeners() {
|
|
let add = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
const method = add ? 'addEventListener' : 'removeEventListener';
|
|
if (containerRef.value === document.documentElement) {
|
|
document[method]('scroll', handleScroll, {
|
|
passive: true
|
|
});
|
|
document[method]('scrollend', handleScrollend);
|
|
} else {
|
|
containerRef.value?.[method]('scroll', handleScroll, {
|
|
passive: true
|
|
});
|
|
containerRef.value?.[method]('scrollend', handleScrollend);
|
|
}
|
|
}
|
|
onMounted(() => {
|
|
containerRef.value = getScrollParent(vm.vnode.el, true);
|
|
handleListeners(true);
|
|
});
|
|
onScopeDispose(handleListeners);
|
|
});
|
|
useRender(() => {
|
|
const children = computedItems.value.map(item => _createVNode(VVirtualScrollItem, {
|
|
"key": item.index,
|
|
"renderless": props.renderless,
|
|
"onUpdate:height": height => handleItemResize(item.index, height)
|
|
}, {
|
|
default: slotProps => slots.default?.({
|
|
item: item.raw,
|
|
index: item.index,
|
|
...slotProps
|
|
})
|
|
}));
|
|
return props.renderless ? _createVNode(_Fragment, null, [_createVNode("div", {
|
|
"ref": markerRef,
|
|
"class": "v-virtual-scroll__spacer",
|
|
"style": {
|
|
paddingTop: convertToUnit(paddingTop.value)
|
|
}
|
|
}, null), children, _createVNode("div", {
|
|
"class": "v-virtual-scroll__spacer",
|
|
"style": {
|
|
paddingBottom: convertToUnit(paddingBottom.value)
|
|
}
|
|
}, null)]) : _createVNode("div", {
|
|
"ref": containerRef,
|
|
"class": ['v-virtual-scroll', props.class],
|
|
"onScrollPassive": handleScroll,
|
|
"onScrollend": handleScrollend,
|
|
"style": [dimensionStyles.value, props.style]
|
|
}, [_createVNode("div", {
|
|
"ref": markerRef,
|
|
"class": "v-virtual-scroll__container",
|
|
"style": {
|
|
paddingTop: convertToUnit(paddingTop.value),
|
|
paddingBottom: convertToUnit(paddingBottom.value)
|
|
}
|
|
}, [children])]);
|
|
});
|
|
return {
|
|
scrollToIndex
|
|
};
|
|
}
|
|
});
|
|
//# sourceMappingURL=VVirtualScroll.mjs.map
|