vuetify
Version:
Vue Material Component Framework
112 lines (111 loc) • 4.09 kB
JavaScript
import { createVNode as _createVNode, Fragment as _Fragment, normalizeStyle as _normalizeStyle, createElementVNode as _createElementVNode, normalizeClass as _normalizeClass } from "vue";
// Styles
import "./VVirtualScroll.css";
// Components
import { VVirtualScrollItem } from "./VVirtualScrollItem.js"; // Composables
import { makeComponentProps } from "../../composables/component.js";
import { makeDimensionProps, useDimension } from "../../composables/dimensions.js";
import { useToggleScope } from "../../composables/toggleScope.js";
import { makeVirtualProps, useVirtual } from "../../composables/virtual.js"; // Utilities
import { onMounted, onScopeDispose, toRef } from 'vue';
import { convertToUnit, genericComponent, getCurrentInstance, getScrollParent, propsFactory, useRender } from "../../util/index.js"; // 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 {
calculateVisibleItems,
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.key,
"renderless": props.renderless,
"onUpdate:height": height => handleItemResize(item.index, height)
}, {
default: slotProps => slots.default?.({
item: item.raw,
index: item.index,
...slotProps
})
}));
return props.renderless ? _createElementVNode(_Fragment, null, [_createElementVNode("div", {
"ref": markerRef,
"class": "v-virtual-scroll__spacer",
"style": _normalizeStyle({
paddingTop: convertToUnit(paddingTop.value)
})
}, null), children, _createElementVNode("div", {
"class": "v-virtual-scroll__spacer",
"style": _normalizeStyle({
paddingBottom: convertToUnit(paddingBottom.value)
})
}, null)]) : _createElementVNode("div", {
"ref": containerRef,
"class": _normalizeClass(['v-virtual-scroll', props.class]),
"onScrollPassive": handleScroll,
"onScrollend": handleScrollend,
"style": _normalizeStyle([dimensionStyles.value, props.style])
}, [_createElementVNode("div", {
"ref": markerRef,
"class": "v-virtual-scroll__container",
"style": _normalizeStyle({
paddingTop: convertToUnit(paddingTop.value),
paddingBottom: convertToUnit(paddingBottom.value)
})
}, [children])]);
});
return {
calculateVisibleItems,
scrollToIndex
};
}
});
//# sourceMappingURL=VVirtualScroll.js.map