@gitlab/ui
Version:
GitLab UI Components
185 lines (162 loc) • 5.52 kB
JavaScript
import throttle from 'lodash/throttle';
import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
var throttleDuration = 1000;
/**
* After adding more items, scroll will adjust slightly.
* Values in pixels, should be a small amount.
*/
var adjustScrollGap = 5;
var script = {
props: {
totalItems: {
type: Number,
required: false,
default: 0
},
fetchedItems: {
type: Number,
required: true
},
maxListHeight: {
type: Number,
required: false,
default: 0
}
},
computed: {
listHeight: function listHeight() {
return {
maxHeight: this.maxListHeight ? "".concat(this.maxListHeight, "px") : 'auto'
};
},
legendText: function legendText() {
if (this.totalItems > 0) {
return "Showing ".concat(this.fetchedItems, " of ").concat(this.totalItems, " items");
}
return "Showing ".concat(this.fetchedItems, " items");
}
},
watch: {
fetchedItems: function fetchedItems(newVal, oldVal) {
// Re-adjust scroll to the current item if more items are added
if (newVal > oldVal) {
var _this$$refs$infiniteC = this.$refs.infiniteContainer,
scrollHeight = _this$$refs$infiniteC.scrollHeight,
scrollTop = _this$$refs$infiniteC.scrollTop; // Only when scrolled to the top
if (scrollHeight !== 0 && scrollTop === 0) {
// Store scrollHeight to know how far to scroll
this.$options.adjustScrollHeight = scrollHeight;
}
}
}
},
mounted: function mounted() {
var _this = this;
// Scroll to bottom for reverse effect
this.$nextTick(function () {
if (_this.$listeners.topReached && !_this.$listeners.bottomReached) {
_this.scrollDown();
}
});
},
updated: function updated() {
var _this2 = this;
// Wait until the DOM is fully updated to adjust scroll
this.$nextTick(function () {
if (_this2.$options.adjustScrollHeight) {
var scrollHeight = _this2.$refs.infiniteContainer.scrollHeight; // New scrollTop is the new height, minus the old height
// minus a small space to allow the user to trigger a scroll once more
var top = scrollHeight - _this2.$options.adjustScrollHeight - adjustScrollGap; // Never adjust to 0, or a new event may be be triggered
if (top < 1) {
top = 1;
}
_this2.scrollTo({
top: top
}); // Prevent subsequent updates
_this2.$options.adjustScrollHeight = null;
}
});
},
methods: {
/**
* Scroll to the top of the container, leaving a gap
* to avoid triggering the event.
*/
scrollUp: function scrollUp() {
this.scrollTo({
top: adjustScrollGap
});
},
/**
* Scroll to the bottom of the container, leaving a gap
* to avoid triggering the event.
*/
scrollDown: function scrollDown() {
var scrollHeight = this.$refs.infiniteContainer.scrollHeight;
this.scrollTo({
top: scrollHeight - adjustScrollGap
});
},
/**
* Scroll to a location in the container
*
* @param params.top - Number of pixels along Y axis to
* scroll the list container.
*/
scrollTo: function scrollTo(_ref) {
var top = _ref.top;
this.$refs.infiniteContainer.scrollTo({
top: top
});
},
topReached: throttle(function topReachedThrottled() {
this.$emit('topReached');
}, throttleDuration),
bottomReached: throttle(function bottomReachedThrottled() {
this.$emit('bottomReached');
}, throttleDuration),
itemsListHeight: function itemsListHeight() {
return this.$refs.infiniteContainer.scrollHeight;
},
scrollTop: function scrollTop() {
return this.$refs.infiniteContainer.scrollTop;
},
handleScroll: throttle(function handleScrollThrottled() {
if (this.scrollTop() + this.maxListHeight >= this.itemsListHeight()) {
this.bottomReached();
} else if (this.scrollTop() === 0) {
this.topReached();
}
})
}
};
/* script */
const __vue_script__ = script;
/* template */
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[_vm._t("header"),_vm._v(" "),_c('div',_vm._g(_vm._b({ref:"infiniteContainer",staticClass:"gl-infinite-scroll-container",style:(_vm.listHeight),on:{"scroll":_vm.handleScroll}},'div',_vm.$attrs,false),_vm.$listeners),[_vm._t("items")],2),_vm._v(" "),_c('p',{staticClass:"gl-infinite-scroll-legend"},[_vm._t("default",[_vm._v("\n "+_vm._s(_vm.legendText)+"\n ")],{"fetchedItems":_vm.fetchedItems,"totalItems":_vm.totalItems})],2)],2)};
var __vue_staticRenderFns__ = [];
/* style */
const __vue_inject_styles__ = undefined;
/* scoped */
const __vue_scope_id__ = undefined;
/* module identifier */
const __vue_module_identifier__ = undefined;
/* functional template */
const __vue_is_functional_template__ = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__ = __vue_normalize__(
{ render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
__vue_inject_styles__,
__vue_script__,
__vue_scope_id__,
__vue_is_functional_template__,
__vue_module_identifier__,
false,
undefined,
undefined,
undefined
);
export default __vue_component__;
export { adjustScrollGap };