UNPKG

vue-virtual-scroller

Version:
2 lines (1 loc) 43 kB
var VueVirtualScroller=function(e,t){"use strict";t=t&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t;var n={itemsLimit:1e3};function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?s(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=new Array(t);n<t;n++)i[n]=e[n];return i}function a(e){if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(e=function(e,t){if(e){if("string"==typeof e)return l(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(n):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?l(e,t):void 0}}(e))){var t=0,n=function(){};return{s:n,n:function(){return t>=e.length?{done:!0}:{done:!1,value:e[t++]}},e:function(e){throw e},f:n}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,r,s=!0,o=!1;return{s:function(){i=e[Symbol.iterator]()},n:function(){var e=i.next();return s=e.done,e},e:function(e){o=!0,r=e},f:function(){try{s||null==i.return||i.return()}finally{if(o)throw r}}}}var c=void 0;function d(){d.init||(d.init=!0,c=-1!==function(){var e=window.navigator.userAgent,t=e.indexOf("MSIE ");if(t>0)return parseInt(e.substring(t+5,e.indexOf(".",t)),10);if(e.indexOf("Trident/")>0){var n=e.indexOf("rv:");return parseInt(e.substring(n+3,e.indexOf(".",n)),10)}var i=e.indexOf("Edge/");return i>0?parseInt(e.substring(i+5,e.indexOf(".",i)),10):-1}())}var u={render:function(){var e=this.$createElement;return(this._self._c||e)("div",{staticClass:"resize-observer",attrs:{tabindex:"-1"}})},staticRenderFns:[],_scopeId:"data-v-b329ee4c",name:"resize-observer",methods:{compareAndNotify:function(){this._w===this.$el.offsetWidth&&this._h===this.$el.offsetHeight||(this._w=this.$el.offsetWidth,this._h=this.$el.offsetHeight,this.$emit("notify"))},addResizeHandlers:function(){this._resizeObject.contentDocument.defaultView.addEventListener("resize",this.compareAndNotify),this.compareAndNotify()},removeResizeHandlers:function(){this._resizeObject&&this._resizeObject.onload&&(!c&&this._resizeObject.contentDocument&&this._resizeObject.contentDocument.defaultView.removeEventListener("resize",this.compareAndNotify),delete this._resizeObject.onload)}},mounted:function(){var e=this;d(),this.$nextTick((function(){e._w=e.$el.offsetWidth,e._h=e.$el.offsetHeight}));var t=document.createElement("object");this._resizeObject=t,t.setAttribute("aria-hidden","true"),t.setAttribute("tabindex",-1),t.onload=this.addResizeHandlers,t.type="text/html",c&&this.$el.appendChild(t),t.data="about:blank",c||this.$el.appendChild(t)},beforeDestroy:function(){this.removeResizeHandlers()}};var h={version:"0.4.5",install:function(e){e.component("resize-observer",u),e.component("ResizeObserver",u)}},f=null;function v(e){return(v="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function p(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function m(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}(e)||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}"undefined"!=typeof window?f=window.Vue:"undefined"!=typeof global&&(f=global.Vue),f&&f.use(h);var y=function(){function e(t,n,i){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.el=t,this.observer=null,this.frozen=!1,this.createObserver(n,i)}var t,n,i;return t=e,(n=[{key:"createObserver",value:function(e,t){var n=this;if(this.observer&&this.destroyObserver(),!this.frozen){var i;if(this.options="function"==typeof(i=e)?{callback:i}:i,this.callback=function(e,t){n.options.callback(e,t),e&&n.options.once&&(n.frozen=!0,n.destroyObserver())},this.callback&&this.options.throttle){var r=(this.options.throttleOptions||{}).leading;this.callback=function(e,t){var n,i,r,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=function(o){for(var l=arguments.length,a=new Array(l>1?l-1:0),c=1;c<l;c++)a[c-1]=arguments[c];if(r=a,!n||o!==i){var d=s.leading;"function"==typeof d&&(d=d(o,i)),n&&o===i||!d||e.apply(void 0,[o].concat(m(r))),i=o,clearTimeout(n),n=setTimeout((function(){e.apply(void 0,[o].concat(m(r))),n=0}),t)}};return o._clear=function(){clearTimeout(n),n=null},o}(this.callback,this.options.throttle,{leading:function(e){return"both"===r||"visible"===r&&e||"hidden"===r&&!e}})}this.oldResult=void 0,this.observer=new IntersectionObserver((function(e){var t=e[0];if(e.length>1){var i=e.find((function(e){return e.isIntersecting}));i&&(t=i)}if(n.callback){var r=t.isIntersecting&&t.intersectionRatio>=n.threshold;if(r===n.oldResult)return;n.oldResult=r,n.callback(r,t)}}),this.options.intersection),t.context.$nextTick((function(){n.observer&&n.observer.observe(n.el)}))}}},{key:"destroyObserver",value:function(){this.observer&&(this.observer.disconnect(),this.observer=null),this.callback&&this.callback._clear&&(this.callback._clear(),this.callback=null)}},{key:"threshold",get:function(){return this.options.intersection&&this.options.intersection.threshold||0}}])&&p(t.prototype,n),i&&p(t,i),e}();function b(e,t,n){var i=t.value;if(i)if("undefined"==typeof IntersectionObserver)console.warn("[vue-observe-visibility] IntersectionObserver API is not available in your browser. Please install this polyfill: https://github.com/w3c/IntersectionObserver/tree/master/polyfill");else{var r=new y(e,i,n);e._vue_visibilityState=r}}function w(e){var t=e._vue_visibilityState;t&&(t.destroyObserver(),delete e._vue_visibilityState)}var g={bind:b,update:function(e,t,n){var i=t.value;if(!function e(t,n){if(t===n)return!0;if("object"===v(t)){for(var i in t)if(!e(t[i],n[i]))return!1;return!0}return!1}(i,t.oldValue)){var r=e._vue_visibilityState;i?r?r.createObserver(i,n):b(e,{value:i},n):w(e)}},unbind:w};var z={version:"0.4.6",install:function(e){e.directive("observe-visibility",g)}},_=null;"undefined"!=typeof window?_=window.Vue:"undefined"!=typeof global&&(_=global.Vue),_&&_.use(z);var A="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var S=function(e,t){return e(t={exports:{}},t.exports),t.exports}((function(e){var t,n;t=A,n=function(){var e=/(auto|scroll)/,t=function(e,n){return null===e.parentNode?n:t(e.parentNode,n.concat([e]))},n=function(e,t){return getComputedStyle(e,null).getPropertyValue(t)},i=function(t){return e.test(function(e){return n(e,"overflow")+n(e,"overflow-y")+n(e,"overflow-x")}(t))};return function(e){if(e instanceof HTMLElement||e instanceof SVGElement){for(var n=t(e.parentNode,[]),r=0;r<n.length;r+=1)if(i(n[r]))return n[r];return document.scrollingElement||document.documentElement}}},e.exports?e.exports=n():t.Scrollparent=n()})),$={items:{type:Array,required:!0},keyField:{type:String,default:"id"},direction:{type:String,default:"vertical",validator:function(e){return["vertical","horizontal"].includes(e)}}};function x(){return this.items.length&&"object"!==i(this.items[0])}var I=!1;if("undefined"!=typeof window){I=!1;try{var V=Object.defineProperty({},"passive",{get:function(){I=!0}});window.addEventListener("test",null,V)}catch(e){}}var O=0,k={name:"RecycleScroller",components:{ResizeObserver:u},directives:{ObserveVisibility:g},props:o({},$,{itemSize:{type:Number,default:null},minItemSize:{type:[Number,String],default:null},sizeField:{type:String,default:"size"},typeField:{type:String,default:"type"},buffer:{type:Number,default:200},pageMode:{type:Boolean,default:!1},prerender:{type:Number,default:0},emitUpdate:{type:Boolean,default:!1}}),data:function(){return{pool:[],totalSize:0,ready:!1,hoverKey:null}},computed:{sizes:function(){if(null===this.itemSize){for(var e,t={"-1":{accumulator:0}},n=this.items,i=this.sizeField,r=this.minItemSize,s=0,o=0,l=n.length;o<l;o++)s+=e=n[o][i]||r,t[o]={accumulator:s,size:e};return t}return[]},simpleArray:x},watch:{items:function(){this.updateVisibleItems(!0)},pageMode:function(){this.applyPageMode(),this.updateVisibleItems(!1)},sizes:{handler:function(){this.updateVisibleItems(!1)},deep:!0}},created:function(){this.$_startIndex=0,this.$_endIndex=0,this.$_views=new Map,this.$_unusedViews=new Map,this.$_scrollDirty=!1,this.$isServer&&this.updateVisibleItems(!1)},mounted:function(){var e=this;this.applyPageMode(),this.$nextTick((function(){e.updateVisibleItems(!0),e.ready=!0}))},beforeDestroy:function(){this.removeListeners()},methods:{addView:function(e,t,n,i,r){var s={item:n,position:0},o={id:O++,index:t,used:!0,key:i,type:r};return Object.defineProperty(s,"nr",{configurable:!1,value:o}),e.push(s),s},unuseView:function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=this.$_unusedViews,i=e.nr.type,r=n.get(i);r||(r=[],n.set(i,r)),r.push(e),t||(e.nr.used=!1,e.position=-9999,this.$_views.delete(e.nr.key))},handleResize:function(){this.$emit("resize"),this.ready&&this.updateVisibleItems(!1)},handleScroll:function(e){var t=this;this.$_scrollDirty||(this.$_scrollDirty=!0,requestAnimationFrame((function(){t.$_scrollDirty=!1,t.updateVisibleItems(!1).continuous||(clearTimeout(t.$_refreshTimout),t.$_refreshTimout=setTimeout(t.handleScroll,100))})))},handleVisibilityChange:function(e,t){var n=this;this.ready&&(e||0!==t.boundingClientRect.width||0!==t.boundingClientRect.height?(this.$emit("visible"),requestAnimationFrame((function(){n.updateVisibleItems(!1)}))):this.$emit("hidden"))},updateVisibleItems:function(e){var t,i,r,s,o=this.itemSize,l=this.typeField,a=this.simpleArray?null:this.keyField,c=this.items,d=c.length,u=this.sizes,h=this.$_views,f=this.$_unusedViews,v=this.pool;if(d)if(this.$isServer)t=0,i=this.prerender,r=null;else{var p=this.getScroll(),m=this.buffer;if(p.start-=m,p.end+=m,null===o){var y,b=0,w=d-1,g=~~(d/2);do{y=g,u[g].accumulator<p.start?b=g:g<d-1&&u[g+1].accumulator>p.start&&(w=g),g=~~((b+w)/2)}while(g!==y);for(g<0&&(g=0),t=g,r=u[d-1].accumulator,i=g;i<d&&u[i].accumulator<p.end;i++);-1===i?i=c.length-1:++i>d&&(i=d)}else(t=~~(p.start/o))<0&&(t=0),(i=Math.ceil(p.end/o))>d&&(i=d),r=d*o}else t=i=r=0;i-t>n.itemsLimit&&this.itemsLimitError(),this.totalSize=r;var z,_,A,S,$,x=t<=this.$_endIndex&&i>=this.$_startIndex;if(this.$_continuous!==x){if(x){h.clear(),f.clear();for(var I=0,V=v.length;I<V;I++)s=v[I],this.unuseView(s)}this.$_continuous=x}else if(x)for(var O=0,k=v.length;O<k;O++)(s=v[O]).nr.used&&(e&&(s.nr.index=c.findIndex((function(e){return a?e[a]===s.item[a]:e===s.item}))),(-1===s.nr.index||s.nr.index<t||s.nr.index>=i)&&this.unuseView(s));x||(z=new Map);for(var E=t;E<i;E++){_=c[E];var R=a?_[a]:_;if(null==R)throw new Error("Key is ".concat(R," on item (keyField is '").concat(a,"')"));s=h.get(R),o||u[E].size?(s?(s.nr.used=!0,s.item=_):(A=_[l],x?(S=f.get(A))&&S.length?((s=S.pop()).item=_,s.nr.used=!0,s.nr.index=E,s.nr.key=R,s.nr.type=A):s=this.addView(v,E,_,R,A):(S=f.get(A),$=z.get(A)||0,S&&$<S.length?((s=S[$]).item=_,s.nr.used=!0,s.nr.index=E,s.nr.key=R,s.nr.type=A,z.set(A,$+1)):(s=this.addView(v,E,_,R,A),this.unuseView(s,!0)),$++),h.set(R,s)),s.position=null===o?u[E-1].accumulator:E*o):s&&this.unuseView(s)}return this.$_startIndex=t,this.$_endIndex=i,this.emitUpdate&&this.$emit("update",t,i),{continuous:x}},getListenerTarget:function(){var e=S(this.$el);return!window.document||e!==window.document.documentElement&&e!==window.document.body||(e=window),e},getScroll:function(){var e,t=this.$el,n="vertical"===this.direction;if(this.pageMode){var i=t.getBoundingClientRect(),r=n?i.height:i.width,s=-(n?i.top:i.left),o=n?window.innerHeight:window.innerWidth;s<0&&(o+=s,s=0),s+o>r&&(o=r-s),e={start:s,end:s+o}}else e=n?{start:t.scrollTop,end:t.scrollTop+t.clientHeight}:{start:t.scrollLeft,end:t.scrollLeft+t.clientWidth};return e},applyPageMode:function(){this.pageMode?this.addListeners():this.removeListeners()},addListeners:function(){this.listenerTarget=this.getListenerTarget(),this.listenerTarget.addEventListener("scroll",this.handleScroll,!!I&&{passive:!0}),this.listenerTarget.addEventListener("resize",this.handleResize)},removeListeners:function(){this.listenerTarget&&(this.listenerTarget.removeEventListener("scroll",this.handleScroll),this.listenerTarget.removeEventListener("resize",this.handleResize),this.listenerTarget=null)},scrollToItem:function(e){var t;t=null===this.itemSize?e>0?this.sizes[e-1].accumulator:0:e*this.itemSize,this.scrollToPosition(t)},scrollToPosition:function(e){"vertical"===this.direction?this.$el.scrollTop=e:this.$el.scrollLeft=e},itemsLimitError:function(){var e=this;throw setTimeout((function(){console.log("It seems the scroller element isn't scrolling, so it tries to render all the items at once.","Scroller:",e.$el),console.log("Make sure the scroller has a fixed height (or width) and 'overflow-y' (or 'overflow-x') set to 'auto' so it can scroll correctly and only render the items visible in the scroll viewport.")})),new Error("Rendered items limit reached")}}};function E(e,t,n,i,r,s,o,l,a,c){"boolean"!=typeof o&&(a=l,l=o,o=!1);const d="function"==typeof n?n.options:n;let u;if(e&&e.render&&(d.render=e.render,d.staticRenderFns=e.staticRenderFns,d._compiled=!0,r&&(d.functional=!0)),i&&(d._scopeId=i),s?(u=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),t&&t.call(this,a(e)),e&&e._registeredComponents&&e._registeredComponents.add(s)},d._ssrRegister=u):t&&(u=o?function(e){t.call(this,c(e,this.$root.$options.shadowRoot))}:function(e){t.call(this,l(e))}),u)if(d.functional){const e=d.render;d.render=function(t,n){return u.call(n),e(t,n)}}else{const e=d.beforeCreate;d.beforeCreate=e?[].concat(e,u):[u]}return n}const R="undefined"!=typeof navigator&&/msie [6-9]\\b/.test(navigator.userAgent.toLowerCase());let T;const C={};const P=k;var D=function(){var e,t,n=this,i=n.$createElement,r=n._self._c||i;return r("div",{directives:[{name:"observe-visibility",rawName:"v-observe-visibility",value:n.handleVisibilityChange,expression:"handleVisibilityChange"}],staticClass:"vue-recycle-scroller",class:(e={ready:n.ready,"page-mode":n.pageMode},e["direction-"+n.direction]=!0,e),on:{"&scroll":function(e){return n.handleScroll(e)}}},[n.$slots.before?r("div",{staticClass:"vue-recycle-scroller__slot"},[n._t("before")],2):n._e(),n._v(" "),r("div",{ref:"wrapper",staticClass:"vue-recycle-scroller__item-wrapper",style:(t={},t["vertical"===n.direction?"minHeight":"minWidth"]=n.totalSize+"px",t)},n._l(n.pool,(function(e){return r("div",{key:e.nr.id,staticClass:"vue-recycle-scroller__item-view",class:{hover:n.hoverKey===e.nr.key},style:n.ready?{transform:"translate"+("vertical"===n.direction?"Y":"X")+"("+e.position+"px)"}:null,on:{mouseenter:function(t){n.hoverKey=e.nr.key},mouseleave:function(e){n.hoverKey=null}}},[n._t("default",null,{item:e.item,index:e.nr.index,active:e.nr.used})],2)})),0),n._v(" "),n.$slots.after?r("div",{staticClass:"vue-recycle-scroller__slot"},[n._t("after")],2):n._e(),n._v(" "),r("ResizeObserver",{on:{notify:n.handleResize}})],1)};D._withStripped=!0;const L=E({render:D,staticRenderFns:[]},(function(e){e&&e("data-v-5c61d14b_0",{source:"\n.vue-recycle-scroller {\n position: relative;\n}\n.vue-recycle-scroller.direction-vertical:not(.page-mode) {\n overflow-y: auto;\n}\n.vue-recycle-scroller.direction-horizontal:not(.page-mode) {\n overflow-x: auto;\n}\n.vue-recycle-scroller.direction-horizontal {\n display: flex;\n}\n.vue-recycle-scroller__slot {\n flex: auto 0 0;\n}\n.vue-recycle-scroller__item-wrapper {\n flex: 1;\n box-sizing: border-box;\n overflow: hidden;\n position: relative;\n}\n.vue-recycle-scroller.ready .vue-recycle-scroller__item-view {\n position: absolute;\n top: 0;\n left: 0;\n will-change: transform;\n}\n.vue-recycle-scroller.direction-vertical .vue-recycle-scroller__item-wrapper {\n width: 100%;\n}\n.vue-recycle-scroller.direction-horizontal .vue-recycle-scroller__item-wrapper {\n height: 100%;\n}\n.vue-recycle-scroller.ready.direction-vertical .vue-recycle-scroller__item-view {\n width: 100%;\n}\n.vue-recycle-scroller.ready.direction-horizontal .vue-recycle-scroller__item-view {\n height: 100%;\n}\n",map:{version:3,sources:["/home/akryum/Projects/vue-virtual-scroller/src/components/RecycleScroller.vue"],names:[],mappings:";AAqjBA;EACA,kBAAA;AACA;AAEA;EACA,gBAAA;AACA;AAEA;EACA,gBAAA;AACA;AAEA;EACA,aAAA;AACA;AAEA;EACA,cAAA;AACA;AAEA;EACA,OAAA;EACA,sBAAA;EACA,gBAAA;EACA,kBAAA;AACA;AAEA;EACA,kBAAA;EACA,MAAA;EACA,OAAA;EACA,sBAAA;AACA;AAEA;EACA,WAAA;AACA;AAEA;EACA,YAAA;AACA;AAEA;EACA,WAAA;AACA;AAEA;EACA,YAAA;AACA",file:"RecycleScroller.vue",sourcesContent:["<template>\n <div\n v-observe-visibility=\"handleVisibilityChange\"\n class=\"vue-recycle-scroller\"\n :class=\"{\n ready,\n 'page-mode': pageMode,\n [`direction-${direction}`]: true,\n }\"\n @scroll.passive=\"handleScroll\"\n >\n <div\n v-if=\"$slots.before\"\n class=\"vue-recycle-scroller__slot\"\n >\n <slot\n name=\"before\"\n />\n </div>\n\n <div\n ref=\"wrapper\"\n :style=\"{ [direction === 'vertical' ? 'minHeight' : 'minWidth']: totalSize + 'px' }\"\n class=\"vue-recycle-scroller__item-wrapper\"\n >\n <div\n v-for=\"view of pool\"\n :key=\"view.nr.id\"\n :style=\"ready ? { transform: `translate${direction === 'vertical' ? 'Y' : 'X'}(${view.position}px)` } : null\"\n class=\"vue-recycle-scroller__item-view\"\n :class=\"{ hover: hoverKey === view.nr.key }\"\n @mouseenter=\"hoverKey = view.nr.key\"\n @mouseleave=\"hoverKey = null\"\n >\n <slot\n :item=\"view.item\"\n :index=\"view.nr.index\"\n :active=\"view.nr.used\"\n />\n </div>\n </div>\n\n <div\n v-if=\"$slots.after\"\n class=\"vue-recycle-scroller__slot\"\n >\n <slot\n name=\"after\"\n />\n </div>\n\n <ResizeObserver @notify=\"handleResize\" />\n </div>\n</template>\n\n<script>\nimport { ResizeObserver } from 'vue-resize'\nimport { ObserveVisibility } from 'vue-observe-visibility'\nimport ScrollParent from 'scrollparent'\nimport config from '../config'\nimport { props, simpleArray } from './common'\nimport { supportsPassive } from '../utils'\n\nlet uid = 0\n\nexport default {\n name: 'RecycleScroller',\n\n components: {\n ResizeObserver,\n },\n\n directives: {\n ObserveVisibility,\n },\n\n props: {\n ...props,\n\n itemSize: {\n type: Number,\n default: null,\n },\n\n minItemSize: {\n type: [Number, String],\n default: null,\n },\n\n sizeField: {\n type: String,\n default: 'size',\n },\n\n typeField: {\n type: String,\n default: 'type',\n },\n\n buffer: {\n type: Number,\n default: 200,\n },\n\n pageMode: {\n type: Boolean,\n default: false,\n },\n\n prerender: {\n type: Number,\n default: 0,\n },\n\n emitUpdate: {\n type: Boolean,\n default: false,\n },\n },\n\n data () {\n return {\n pool: [],\n totalSize: 0,\n ready: false,\n hoverKey: null,\n }\n },\n\n computed: {\n sizes () {\n if (this.itemSize === null) {\n const sizes = {\n '-1': { accumulator: 0 },\n }\n const items = this.items\n const field = this.sizeField\n const minItemSize = this.minItemSize\n let accumulator = 0\n let current\n for (let i = 0, l = items.length; i < l; i++) {\n current = items[i][field] || minItemSize\n accumulator += current\n sizes[i] = { accumulator, size: current }\n }\n return sizes\n }\n return []\n },\n\n simpleArray,\n },\n\n watch: {\n items () {\n this.updateVisibleItems(true)\n },\n\n pageMode () {\n this.applyPageMode()\n this.updateVisibleItems(false)\n },\n\n sizes: {\n handler () {\n this.updateVisibleItems(false)\n },\n deep: true,\n },\n },\n\n created () {\n this.$_startIndex = 0\n this.$_endIndex = 0\n this.$_views = new Map()\n this.$_unusedViews = new Map()\n this.$_scrollDirty = false\n\n if (this.$isServer) {\n this.updateVisibleItems(false)\n }\n },\n\n mounted () {\n this.applyPageMode()\n this.$nextTick(() => {\n this.updateVisibleItems(true)\n this.ready = true\n })\n },\n\n beforeDestroy () {\n this.removeListeners()\n },\n\n methods: {\n addView (pool, index, item, key, type) {\n const view = {\n item,\n position: 0,\n }\n const nonReactive = {\n id: uid++,\n index,\n used: true,\n key,\n type,\n }\n Object.defineProperty(view, 'nr', {\n configurable: false,\n value: nonReactive,\n })\n pool.push(view)\n return view\n },\n\n unuseView (view, fake = false) {\n const unusedViews = this.$_unusedViews\n const type = view.nr.type\n let unusedPool = unusedViews.get(type)\n if (!unusedPool) {\n unusedPool = []\n unusedViews.set(type, unusedPool)\n }\n unusedPool.push(view)\n if (!fake) {\n view.nr.used = false\n view.position = -9999\n this.$_views.delete(view.nr.key)\n }\n },\n\n handleResize () {\n this.$emit('resize')\n if (this.ready) this.updateVisibleItems(false)\n },\n\n handleScroll (event) {\n if (!this.$_scrollDirty) {\n this.$_scrollDirty = true\n requestAnimationFrame(() => {\n this.$_scrollDirty = false\n const { continuous } = this.updateVisibleItems(false)\n\n // It seems sometimes chrome doesn't fire scroll event :/\n // When non continous scrolling is ending, we force a refresh\n if (!continuous) {\n clearTimeout(this.$_refreshTimout)\n this.$_refreshTimout = setTimeout(this.handleScroll, 100)\n }\n })\n }\n },\n\n handleVisibilityChange (isVisible, entry) {\n if (this.ready) {\n if (isVisible || entry.boundingClientRect.width !== 0 || entry.boundingClientRect.height !== 0) {\n this.$emit('visible')\n requestAnimationFrame(() => {\n this.updateVisibleItems(false)\n })\n } else {\n this.$emit('hidden')\n }\n }\n },\n\n updateVisibleItems (checkItem) {\n const itemSize = this.itemSize\n const typeField = this.typeField\n const keyField = this.simpleArray ? null : this.keyField\n const items = this.items\n const count = items.length\n const sizes = this.sizes\n const views = this.$_views\n const unusedViews = this.$_unusedViews\n const pool = this.pool\n let startIndex, endIndex\n let totalSize\n\n if (!count) {\n startIndex = endIndex = totalSize = 0\n } else if (this.$isServer) {\n startIndex = 0\n endIndex = this.prerender\n totalSize = null\n } else {\n const scroll = this.getScroll()\n const buffer = this.buffer\n scroll.start -= buffer\n scroll.end += buffer\n\n // Variable size mode\n if (itemSize === null) {\n let h\n let a = 0\n let b = count - 1\n let i = ~~(count / 2)\n let oldI\n\n // Searching for startIndex\n do {\n oldI = i\n h = sizes[i].accumulator\n if (h < scroll.start) {\n a = i\n } else if (i < count - 1 && sizes[i + 1].accumulator > scroll.start) {\n b = i\n }\n i = ~~((a + b) / 2)\n } while (i !== oldI)\n i < 0 && (i = 0)\n startIndex = i\n\n // For container style\n totalSize = sizes[count - 1].accumulator\n\n // Searching for endIndex\n for (endIndex = i; endIndex < count && sizes[endIndex].accumulator < scroll.end; endIndex++);\n if (endIndex === -1) {\n endIndex = items.length - 1\n } else {\n endIndex++\n // Bounds\n endIndex > count && (endIndex = count)\n }\n } else {\n // Fixed size mode\n startIndex = ~~(scroll.start / itemSize)\n endIndex = Math.ceil(scroll.end / itemSize)\n\n // Bounds\n startIndex < 0 && (startIndex = 0)\n endIndex > count && (endIndex = count)\n\n totalSize = count * itemSize\n }\n }\n\n if (endIndex - startIndex > config.itemsLimit) {\n this.itemsLimitError()\n }\n\n this.totalSize = totalSize\n\n let view\n\n const continuous = startIndex <= this.$_endIndex && endIndex >= this.$_startIndex\n let unusedIndex\n\n if (this.$_continuous !== continuous) {\n if (continuous) {\n views.clear()\n unusedViews.clear()\n for (let i = 0, l = pool.length; i < l; i++) {\n view = pool[i]\n this.unuseView(view)\n }\n }\n this.$_continuous = continuous\n } else if (continuous) {\n for (let i = 0, l = pool.length; i < l; i++) {\n view = pool[i]\n if (view.nr.used) {\n // Update view item index\n if (checkItem) {\n view.nr.index = items.findIndex(\n item => keyField ? item[keyField] === view.item[keyField] : item === view.item,\n )\n }\n\n // Check if index is still in visible range\n if (\n view.nr.index === -1 ||\n view.nr.index < startIndex ||\n view.nr.index >= endIndex\n ) {\n this.unuseView(view)\n }\n }\n }\n }\n\n if (!continuous) {\n unusedIndex = new Map()\n }\n\n let item, type, unusedPool\n let v\n for (let i = startIndex; i < endIndex; i++) {\n item = items[i]\n const key = keyField ? item[keyField] : item\n if (key == null) {\n throw new Error(`Key is ${key} on item (keyField is '${keyField}')`)\n }\n view = views.get(key)\n\n if (!itemSize && !sizes[i].size) {\n if (view) this.unuseView(view)\n continue\n }\n\n // No view assigned to item\n if (!view) {\n type = item[typeField]\n\n if (continuous) {\n unusedPool = unusedViews.get(type)\n // Reuse existing view\n if (unusedPool && unusedPool.length) {\n view = unusedPool.pop()\n view.item = item\n view.nr.used = true\n view.nr.index = i\n view.nr.key = key\n view.nr.type = type\n } else {\n view = this.addView(pool, i, item, key, type)\n }\n } else {\n unusedPool = unusedViews.get(type)\n v = unusedIndex.get(type) || 0\n // Use existing view\n // We don't care if they are already used\n // because we are not in continous scrolling\n if (unusedPool && v < unusedPool.length) {\n view = unusedPool[v]\n view.item = item\n view.nr.used = true\n view.nr.index = i\n view.nr.key = key\n view.nr.type = type\n unusedIndex.set(type, v + 1)\n } else {\n view = this.addView(pool, i, item, key, type)\n this.unuseView(view, true)\n }\n v++\n }\n views.set(key, view)\n } else {\n view.nr.used = true\n view.item = item\n }\n\n // Update position\n if (itemSize === null) {\n view.position = sizes[i - 1].accumulator\n } else {\n view.position = i * itemSize\n }\n }\n\n this.$_startIndex = startIndex\n this.$_endIndex = endIndex\n\n if (this.emitUpdate) this.$emit('update', startIndex, endIndex)\n\n return {\n continuous,\n }\n },\n\n getListenerTarget () {\n let target = ScrollParent(this.$el)\n // Fix global scroll target for Chrome and Safari\n if (window.document && (target === window.document.documentElement || target === window.document.body)) {\n target = window\n }\n return target\n },\n\n getScroll () {\n const { $el: el, direction } = this\n const isVertical = direction === 'vertical'\n let scrollState\n\n if (this.pageMode) {\n const bounds = el.getBoundingClientRect()\n const boundsSize = isVertical ? bounds.height : bounds.width\n let start = -(isVertical ? bounds.top : bounds.left)\n let size = isVertical ? window.innerHeight : window.innerWidth\n if (start < 0) {\n size += start\n start = 0\n }\n if (start + size > boundsSize) {\n size = boundsSize - start\n }\n scrollState = {\n start,\n end: start + size,\n }\n } else if (isVertical) {\n scrollState = {\n start: el.scrollTop,\n end: el.scrollTop + el.clientHeight,\n }\n } else {\n scrollState = {\n start: el.scrollLeft,\n end: el.scrollLeft + el.clientWidth,\n }\n }\n\n return scrollState\n },\n\n applyPageMode () {\n if (this.pageMode) {\n this.addListeners()\n } else {\n this.removeListeners()\n }\n },\n\n addListeners () {\n this.listenerTarget = this.getListenerTarget()\n this.listenerTarget.addEventListener('scroll', this.handleScroll, supportsPassive ? {\n passive: true,\n } : false)\n this.listenerTarget.addEventListener('resize', this.handleResize)\n },\n\n removeListeners () {\n if (!this.listenerTarget) {\n return\n }\n\n this.listenerTarget.removeEventListener('scroll', this.handleScroll)\n this.listenerTarget.removeEventListener('resize', this.handleResize)\n\n this.listenerTarget = null\n },\n\n scrollToItem (index) {\n let scroll\n if (this.itemSize === null) {\n scroll = index > 0 ? this.sizes[index - 1].accumulator : 0\n } else {\n scroll = index * this.itemSize\n }\n this.scrollToPosition(scroll)\n },\n\n scrollToPosition (position) {\n if (this.direction === 'vertical') {\n this.$el.scrollTop = position\n } else {\n this.$el.scrollLeft = position\n }\n },\n\n itemsLimitError () {\n setTimeout(() => {\n console.log('It seems the scroller element isn\\'t scrolling, so it tries to render all the items at once.', 'Scroller:', this.$el)\n console.log('Make sure the scroller has a fixed height (or width) and \\'overflow-y\\' (or \\'overflow-x\\') set to \\'auto\\' so it can scroll correctly and only render the items visible in the scroll viewport.')\n })\n throw new Error('Rendered items limit reached')\n },\n },\n}\n<\/script>\n\n<style>\n.vue-recycle-scroller {\n position: relative;\n}\n\n.vue-recycle-scroller.direction-vertical:not(.page-mode) {\n overflow-y: auto;\n}\n\n.vue-recycle-scroller.direction-horizontal:not(.page-mode) {\n overflow-x: auto;\n}\n\n.vue-recycle-scroller.direction-horizontal {\n display: flex;\n}\n\n.vue-recycle-scroller__slot {\n flex: auto 0 0;\n}\n\n.vue-recycle-scroller__item-wrapper {\n flex: 1;\n box-sizing: border-box;\n overflow: hidden;\n position: relative;\n}\n\n.vue-recycle-scroller.ready .vue-recycle-scroller__item-view {\n position: absolute;\n top: 0;\n left: 0;\n will-change: transform;\n}\n\n.vue-recycle-scroller.direction-vertical .vue-recycle-scroller__item-wrapper {\n width: 100%;\n}\n\n.vue-recycle-scroller.direction-horizontal .vue-recycle-scroller__item-wrapper {\n height: 100%;\n}\n\n.vue-recycle-scroller.ready.direction-vertical .vue-recycle-scroller__item-view {\n width: 100%;\n}\n\n.vue-recycle-scroller.ready.direction-horizontal .vue-recycle-scroller__item-view {\n height: 100%;\n}\n</style>\n"]},media:void 0})}),P,void 0,!1,void 0,!1,(function(e){return(e,t)=>function(e,t){const n=R?t.media||"default":e,i=C[n]||(C[n]={ids:new Set,styles:[]});if(!i.ids.has(e)){i.ids.add(e);let n=t.source;if(t.map&&(n+="\n/*# sourceURL="+t.map.sources[0]+" */",n+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(t.map))))+" */"),i.element||(i.element=document.createElement("style"),i.element.type="text/css",t.media&&i.element.setAttribute("media",t.media),void 0===T&&(T=document.head||document.getElementsByTagName("head")[0]),T.appendChild(i.element)),"styleSheet"in i.element)i.styles.push(n),i.element.styleSheet.cssText=i.styles.filter(Boolean).join("\n");else{const e=i.ids.size-1,t=document.createTextNode(n),r=i.element.childNodes;r[e]&&i.element.removeChild(r[e]),r.length?i.element.insertBefore(t,r[e]):i.element.appendChild(t)}}}(e,t)}),void 0,void 0);const F={name:"DynamicScroller",components:{RecycleScroller:L},inheritAttrs:!1,provide:function(){return"undefined"!=typeof ResizeObserver&&(this.$_resizeObserver=new ResizeObserver((function(e){var t,n=a(e);try{for(n.s();!(t=n.n()).done;){var i=t.value;if(i.target){var r=new CustomEvent("resize",{detail:{contentRect:i.contentRect}});i.target.dispatchEvent(r)}}}catch(e){n.e(e)}finally{n.f()}}))),{vscrollData:this.vscrollData,vscrollParent:this,vscrollResizeObserver:this.$_resizeObserver}},props:o({},$,{minItemSize:{type:[Number,String],required:!0}}),data:function(){return{vscrollData:{active:!0,sizes:{},validSizes:{},keyField:this.keyField,simpleArray:!1}}},computed:{simpleArray:x,itemsWithSize:function(){for(var e=[],t=this.items,n=this.keyField,i=this.simpleArray,r=this.vscrollData.sizes,s=0;s<t.length;s++){var o=t[s],l=i?s:o[n],a=r[l];void 0!==a||this.$_undefinedMap[l]||(a=0),e.push({item:o,id:l,size:a})}return e},listeners:function(){var e={};for(var t in this.$listeners)"resize"!==t&&"visible"!==t&&(e[t]=this.$listeners[t]);return e}},watch:{items:function(){this.forceUpdate(!1)},simpleArray:{handler:function(e){this.vscrollData.simpleArray=e},immediate:!0},direction:function(e){this.forceUpdate(!0)}},created:function(){this.$_updates=[],this.$_undefinedSizes=0,this.$_undefinedMap={}},activated:function(){this.vscrollData.active=!0},deactivated:function(){this.vscrollData.active=!1},methods:{onScrollerResize:function(){this.$refs.scroller&&this.forceUpdate(),this.$emit("resize")},onScrollerVisible:function(){this.$emit("vscroll:update",{force:!1}),this.$emit("visible")},forceUpdate:function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];(e||this.simpleArray)&&(this.vscrollData.validSizes={}),this.$emit("vscroll:update",{force:!0})},scrollToItem:function(e){var t=this.$refs.scroller;t&&t.scrollToItem(e)},getItemSize:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0,n=this.simpleArray?null!=t?t:this.items.indexOf(e):e[this.keyField];return this.vscrollData.sizes[n]||0},scrollToBottom:function(){var e=this;if(!this.$_scrollingToBottom){this.$_scrollingToBottom=!0;var t=this.$el;this.$nextTick((function(){t.scrollTop=9999999999;requestAnimationFrame((function n(){t.scrollTop=9999999999,requestAnimationFrame((function(){t.scrollTop=9999999999,0===e.$_undefinedSizes?e.$_scrollingToBottom=!1:requestAnimationFrame(n)}))}))}))}}}};var M=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("RecycleScroller",e._g(e._b({ref:"scroller",attrs:{items:e.itemsWithSize,"min-item-size":e.minItemSize,direction:e.direction,"key-field":"id"},on:{resize:e.onScrollerResize,visible:e.onScrollerVisible},scopedSlots:e._u([{key:"default",fn:function(t){var n=t.item,i=t.index,r=t.active;return[e._t("default",null,null,{item:n.item,index:i,active:r,itemWithSize:n})]}}],null,!0)},"RecycleScroller",e.$attrs,!1),e.listeners),[e._v(" "),n("template",{slot:"before"},[e._t("before")],2),e._v(" "),n("template",{slot:"after"},[e._t("after")],2)],2)};M._withStripped=!0;const j=E({render:M,staticRenderFns:[]},void 0,F,void 0,!1,void 0,!1,void 0,void 0,void 0);const U=E({},void 0,{name:"DynamicScrollerItem",inject:["vscrollData","vscrollParent","vscrollResizeObserver"],props:{item:{required:!0},watchData:{type:Boolean,default:!1},active:{type:Boolean,required:!0},index:{type:Number,default:void 0},sizeDependencies:{type:[Array,Object],default:null},emitResize:{type:Boolean,default:!1},tag:{type:String,default:"div"}},computed:{id:function(){return this.vscrollData.simpleArray?this.index:this.item[this.vscrollData.keyField]},size:function(){return this.vscrollData.validSizes[this.id]&&this.vscrollData.sizes[this.id]||0}},watch:{watchData:"updateWatchData",id:function(){this.size||this.onDataUpdate()},active:function(e){this.size||(e?this.vscrollParent.$_undefinedMap[this.id]||(this.vscrollParent.$_undefinedSizes++,this.vscrollParent.$_undefinedMap[this.id]=!0):this.vscrollParent.$_undefinedMap[this.id]&&(this.vscrollParent.$_undefinedSizes--,this.vscrollParent.$_undefinedMap[this.id]=!1)),this.vscrollResizeObserver?e?this.observeSize():this.unobserveSize():e&&this.$_pendingVScrollUpdate===this.id&&this.updateSize()}},created:function(){var e=this;if(!this.$isServer&&(this.$_forceNextVScrollUpdate=null,this.updateWatchData(),!this.vscrollResizeObserver)){var t=function(t){e.$watch((function(){return e.sizeDependencies[t]}),e.onDataUpdate)};for(var n in this.sizeDependencies)t(n);this.vscrollParent.$on("vscroll:update",this.onVscrollUpdate),this.vscrollParent.$on("vscroll:update-size",this.onVscrollUpdateSize)}},mounted:function(){this.vscrollData.active&&(this.updateSize(),this.observeSize())},beforeDestroy:function(){this.vscrollParent.$off("vscroll:update",this.onVscrollUpdate),this.vscrollParent.$off("vscroll:update-size",this.onVscrollUpdateSize),this.unobserveSize()},methods:{updateSize:function(){this.active&&this.vscrollData.active?this.$_pendingSizeUpdate!==this.id&&(this.$_pendingSizeUpdate=this.id,this.$_forceNextVScrollUpdate=null,this.$_pendingVScrollUpdate=null,this.active&&this.vscrollData.active&&this.computeSize(this.id)):this.$_forceNextVScrollUpdate=this.id},updateWatchData:function(){var e=this;this.watchData?this.$_watchData=this.$watch("data",(function(){e.onDataUpdate()}),{deep:!0}):this.$_watchData&&(this.$_watchData(),this.$_watchData=null)},onVscrollUpdate:function(e){var t=e.force;!this.active&&t&&(this.$_pendingVScrollUpdate=this.id),this.$_forceNextVScrollUpdate!==this.id&&!t&&this.size||this.updateSize()},onDataUpdate:function(){this.updateSize()},computeSize:function(e){var t=this;this.$nextTick((function(){if(t.id===e){var n=t.$el.offsetWidth,i=t.$el.offsetHeight;t.applySize(n,i)}t.$_pendingSizeUpdate=null}))},applySize:function(e,t){var n=Math.round("vertical"===this.vscrollParent.direction?t:e);n&&this.size!==n&&(this.vscrollParent.$_undefinedMap[this.id]&&(this.vscrollParent.$_undefinedSizes--,this.vscrollParent.$_undefinedMap[this.id]=void 0),this.$set(this.vscrollData.sizes,this.id,n),this.$set(this.vscrollData.validSizes,this.id,!0),this.emitResize&&this.$emit("resize",this.id))},observeSize:function(){this.vscrollResizeObserver&&(this.vscrollResizeObserver.observe(this.$el.parentNode),this.$el.parentNode.addEventListener("resize",this.onResize))},unobserveSize:function(){this.vscrollResizeObserver&&(this.vscrollResizeObserver.unobserve(this.$el.parentNode),this.$el.parentNode.removeEventListener("resize",this.onResize))},onResize:function(e){var t=e.detail.contentRect,n=t.width,i=t.height;this.applySize(n,i)}},render:function(e){return e(this.tag,this.$slots.default)}},void 0,void 0,void 0,!1,void 0,void 0,void 0);var N={version:"1.0.2",install:function(e,t){var i=Object.assign({},{installComponents:!0,componentsPrefix:""},t);for(var r in i)void 0!==i[r]&&(n[r]=i[r]);i.installComponents&&function(e,t){e.component("".concat(t,"recycle-scroller"),L),e.component("".concat(t,"RecycleScroller"),L),e.component("".concat(t,"dynamic-scroller"),j),e.component("".concat(t,"DynamicScroller"),j),e.component("".concat(t,"dynamic-scroller-item"),U),e.component("".concat(t,"DynamicScrollerItem"),U)}(e,i.componentsPrefix)}},B=null;return"undefined"!=typeof window?B=window.Vue:"undefined"!=typeof global&&(B=global.Vue),B&&B.use(N),e.DynamicScroller=j,e.DynamicScrollerItem=U,e.IdState=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.idProp,i=void 0===n?function(e){return e.item.id}:n,r={},s=new t({data:function(){return{store:r}}});return{data:function(){return{idState:null}},created:function(){var e=this;this.$_id=null,this.$_getId="function"==typeof i?function(){return i.call(e,e)}:function(){return e[i]},this.$watch(this.$_getId,{handler:function(e){var t=this;this.$nextTick((function(){t.$_id=e}))},immediate:!0}),this.$_updateIdState()},beforeUpdate:function(){this.$_updateIdState()},methods:{$_idStateInit:function(e){var t=this.$options.idState;if("function"==typeof t){var n=t.call(this,this);return s.$set(r,e,n),this.$_id=e,n}throw new Error("[mixin IdState] Missing `idState` function on component definition.")},$_updateIdState:function(){var e=this.$_getId();null==e&&console.warn("No id found for IdState with idProp: '".concat(i,"'.")),e!==this.$_id&&(r[e]||this.$_idStateInit(e),this.idState=r[e])}}}},e.RecycleScroller=L,e.default=N,e}({},Vue);