VVirtualScroll.mjs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import { Fragment as _Fragment, createVNode as _createVNode } from "vue";
  2. // Styles
  3. import "./VVirtualScroll.css";
  4. // Components
  5. import { VVirtualScrollItem } from "./VVirtualScrollItem.mjs"; // Composables
  6. import { makeComponentProps } from "../../composables/component.mjs";
  7. import { makeDimensionProps, useDimension } from "../../composables/dimensions.mjs";
  8. import { useToggleScope } from "../../composables/toggleScope.mjs";
  9. import { makeVirtualProps, useVirtual } from "../../composables/virtual.mjs"; // Utilities
  10. import { onMounted, onScopeDispose, toRef } from 'vue';
  11. import { convertToUnit, genericComponent, getCurrentInstance, getScrollParent, propsFactory, useRender } from "../../util/index.mjs"; // Types
  12. export const makeVVirtualScrollProps = propsFactory({
  13. items: {
  14. type: Array,
  15. default: () => []
  16. },
  17. renderless: Boolean,
  18. ...makeVirtualProps(),
  19. ...makeComponentProps(),
  20. ...makeDimensionProps()
  21. }, 'VVirtualScroll');
  22. export const VVirtualScroll = genericComponent()({
  23. name: 'VVirtualScroll',
  24. props: makeVVirtualScrollProps(),
  25. setup(props, _ref) {
  26. let {
  27. slots
  28. } = _ref;
  29. const vm = getCurrentInstance('VVirtualScroll');
  30. const {
  31. dimensionStyles
  32. } = useDimension(props);
  33. const {
  34. calculateVisibleItems,
  35. containerRef,
  36. markerRef,
  37. handleScroll,
  38. handleScrollend,
  39. handleItemResize,
  40. scrollToIndex,
  41. paddingTop,
  42. paddingBottom,
  43. computedItems
  44. } = useVirtual(props, toRef(props, 'items'));
  45. useToggleScope(() => props.renderless, () => {
  46. function handleListeners() {
  47. let add = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
  48. const method = add ? 'addEventListener' : 'removeEventListener';
  49. if (containerRef.value === document.documentElement) {
  50. document[method]('scroll', handleScroll, {
  51. passive: true
  52. });
  53. document[method]('scrollend', handleScrollend);
  54. } else {
  55. containerRef.value?.[method]('scroll', handleScroll, {
  56. passive: true
  57. });
  58. containerRef.value?.[method]('scrollend', handleScrollend);
  59. }
  60. }
  61. onMounted(() => {
  62. containerRef.value = getScrollParent(vm.vnode.el, true);
  63. handleListeners(true);
  64. });
  65. onScopeDispose(handleListeners);
  66. });
  67. useRender(() => {
  68. const children = computedItems.value.map(item => _createVNode(VVirtualScrollItem, {
  69. "key": item.key,
  70. "renderless": props.renderless,
  71. "onUpdate:height": height => handleItemResize(item.index, height)
  72. }, {
  73. default: slotProps => slots.default?.({
  74. item: item.raw,
  75. index: item.index,
  76. ...slotProps
  77. })
  78. }));
  79. return props.renderless ? _createVNode(_Fragment, null, [_createVNode("div", {
  80. "ref": markerRef,
  81. "class": "v-virtual-scroll__spacer",
  82. "style": {
  83. paddingTop: convertToUnit(paddingTop.value)
  84. }
  85. }, null), children, _createVNode("div", {
  86. "class": "v-virtual-scroll__spacer",
  87. "style": {
  88. paddingBottom: convertToUnit(paddingBottom.value)
  89. }
  90. }, null)]) : _createVNode("div", {
  91. "ref": containerRef,
  92. "class": ['v-virtual-scroll', props.class],
  93. "onScrollPassive": handleScroll,
  94. "onScrollend": handleScrollend,
  95. "style": [dimensionStyles.value, props.style]
  96. }, [_createVNode("div", {
  97. "ref": markerRef,
  98. "class": "v-virtual-scroll__container",
  99. "style": {
  100. paddingTop: convertToUnit(paddingTop.value),
  101. paddingBottom: convertToUnit(paddingBottom.value)
  102. }
  103. }, [children])]);
  104. });
  105. return {
  106. calculateVisibleItems,
  107. scrollToIndex
  108. };
  109. }
  110. });
  111. //# sourceMappingURL=VVirtualScroll.mjs.map