UNPKG

vue3-infinite-list

Version:

An infinite scrolling list of vue3, of course vue2 can also be used.

2 lines (1 loc) 8.35 kB
var ge=Object.defineProperty,Ie=Object.defineProperties;var ze=Object.getOwnPropertyDescriptors;var H=Object.getOwnPropertySymbols;var ye=Object.prototype.hasOwnProperty,Ae=Object.prototype.propertyIsEnumerable;var _=(r,s,f)=>s in r?ge(r,s,{enumerable:!0,configurable:!0,writable:!0,value:f}):r[s]=f,E=(r,s)=>{for(var f in s||(s={}))ye.call(s,f)&&_(r,f,s[f]);if(H)for(var f of H(s))Ae.call(s,f)&&_(r,f,s[f]);return r},O=(r,s)=>Ie(r,ze(s));var m=(r,s,f)=>(_(r,typeof s!="symbol"?s+"":s,f),f);(function(r,s){typeof exports=="object"&&typeof module!="undefined"?module.exports=s(require("vue-demi"),require("vue")):typeof define=="function"&&define.amd?define(["vue-demi","vue"],s):(r=typeof globalThis!="undefined"?globalThis:r||self,r["vue3-infinite-list"]=s(r.VueDemi,r.Vue))})(this,function(r,s){"use strict";const f="auto",$="start",j="center",Y="end",P="vertical",x="horizontal",W="observed",L="requested",Q={[P]:"scrollTop",[x]:"scrollLeft"},Z={[P]:"height",[x]:"width"},J={[P]:"top",[x]:"left"},K={overflow:"auto",willChange:"transform",WebkitOverflowScrolling:"touch"},k={position:"relative",overflow:"hidden",width:"100%",minHeight:"100%"},X={position:"absolute",left:0,width:"100%",height:"100%"};class ee{constructor({itemCount:e,itemSizeGetter:n,estimatedItemSize:o}){m(this,"itemSizeGetter");m(this,"itemCount");m(this,"estimatedItemSize");m(this,"lastMeasuredIndex");m(this,"itemSizeAndPositionData");this.itemSizeGetter=n,this.itemCount=e,this.estimatedItemSize=o,this.itemSizeAndPositionData={},this.lastMeasuredIndex=-1}updateConfig({itemCount:e,estimatedItemSize:n}){this.itemCount=e,this.estimatedItemSize=n}getLastMeasuredIndex(){return this.lastMeasuredIndex}destroy(){for(let e in this.itemSizeAndPositionData)delete this.itemSizeAndPositionData[e]}getSizeAndPositionForIndex(e){if(e<0||e>=this.itemCount)throw Error(`Requested index ${e} is outside of range 0..${this.itemCount}`);if(e>this.lastMeasuredIndex){const n=this.getSizeAndPositionOfLastMeasuredItem();let o=n.offset+n.size;for(let l=this.lastMeasuredIndex+1;l<=e;l++){const d=this.itemSizeGetter(l);if(d==null||isNaN(d))throw Error(`Invalid size returned for index ${l} of value ${d}`);this.itemSizeAndPositionData[l]={offset:o,size:d},o+=d}this.lastMeasuredIndex=e}return this.itemSizeAndPositionData[e]}getSizeAndPositionOfLastMeasuredItem(){return this.lastMeasuredIndex>=0?this.itemSizeAndPositionData[this.lastMeasuredIndex]:{offset:0,size:0}}getTotalSize(){const e=this.getSizeAndPositionOfLastMeasuredItem();return e.offset+e.size+(this.itemCount-this.lastMeasuredIndex-1)*this.estimatedItemSize}getUpdatedOffsetForIndex({align:e=$,containerSize:n,currentOffset:o,targetIndex:l}){if(n<=0)return 0;const d=this.getSizeAndPositionForIndex(l),u=d.offset,S=u-n+d.size;let a;switch(e){case Y:a=S;break;case j:a=u-(n-d.size)/2;break;case $:a=u;break;default:a=Math.max(S,Math.min(u,o))}const c=this.getTotalSize();return Math.max(0,Math.min(c-n,a))}getVisibleRange({containerSize:e,offset:n,overscanCount:o}){if(this.getTotalSize()===0)return{};const d=n+e;let u=this.findNearestItem(n);if(typeof u=="undefined")throw Error(`Invalid offset ${n} specified`);const S=this.getSizeAndPositionForIndex(u);n=S.offset+S.size;let a=u;for(;n<d&&a<this.itemCount-1;)a++,n+=this.getSizeAndPositionForIndex(a).size;return o&&(u=Math.max(0,u-o),a=Math.min(a+o,this.itemCount-1)),{start:u,stop:a}}resetItem(e){this.lastMeasuredIndex=Math.min(this.lastMeasuredIndex,e-1)}findNearestItem(e){if(isNaN(e))throw Error(`Invalid offset ${e} specified`);e=Math.max(0,e);const n=this.getSizeAndPositionOfLastMeasuredItem(),o=Math.max(0,this.lastMeasuredIndex);return n.offset>=e?this.binarySearch({high:o,low:0,offset:e}):this.exponentialSearch({index:o,offset:e})}binarySearch({low:e,high:n,offset:o}){let l=0,d=0;for(;e<=n;){if(l=e+Math.floor((n-e)/2),d=this.getSizeAndPositionForIndex(l).offset,d===o)return l;d<o?e=l+1:d>o&&(n=l-1)}return e>0?e-1:0}exponentialSearch({index:e,offset:n}){let o=1;for(;e<this.itemCount&&this.getSizeAndPositionForIndex(e).offset<n;)e+=o,o*=2;return this.binarySearch({high:Math.min(e,this.itemCount-1),low:Math.floor(e/2),offset:n})}}class te{addEventListener(e,n,o){return e.addEventListener?e.addEventListener(n,o,!1):e.attachEvent?e.attachEvent(n,o):e["on"+n]=o}removeEventListener(e,n,o){return e.removeEventListener?e.removeEventListener(n,o,!1):e.detachEvent?e.detachEvent(n,o):e["on"+n]=null}isArray(e){return Object.prototype.toString.call(e)==="[object Array]"}randomColor(){return"#"+("00000"+(Math.random()*16777216<<0).toString(16)).slice(-6)}isPureNumber(e){return typeof e=="number"||!e}}class ne{constructor(){m(this,"items",[]);m(this,"offset",0);m(this,"data",null);m(this,"start",0);m(this,"stop",0);m(this,"total",0)}toString(){return`start:${this.start} stop:${this.stop} total:${this.total} offset:${this.offset}`}}var ie=(t,e)=>{const n=t.__vccOpts||t;for(const[o,l]of e)n[o]=l;return n};const se=r.defineComponent({name:"InfiniteList",props:{scrollDirection:{type:String,default:P},scrollToAlignment:{type:String,default:f},overscanCount:{type:Number,default:4},itemSize:{type:null,required:!0},data:{type:[Array,null],default:[],required:!0},unit:{type:String,default:"px"},width:{type:[Number,String]},height:{type:[Number,String]},debug:{type:Boolean,default:!1},scrollOffset:Number,scrollToIndex:Number,estimatedItemSize:Number},setup(t,{attrs:e,slots:n,emit:o}){let l=r.ref(null),d=r.ref(null),u=r.ref(null),S=r.ref(null),a=[],c,b,M,g,v={};const{itemSize:I,scrollDirection:F,scrollToIndex:Ee}=r.toRefs(t),C=new te,z=r.reactive(new ne),le=i=>{i+=z.start;const h=v[i];if(h)return h;const{size:y,offset:me}=g.getSizeAndPositionForIndex(i),Se=t.debug?{backgroundColor:C.randomColor()}:null;return v[i]=O(E(E({},X),Se),{[w()]:A(y),[J[t.scrollDirection]]:A(me)})},ae=()=>{ue(),C.addEventListener(l.value,"scroll",G),c=t.scrollOffset||t.scrollToIndex!=null&&V(t.scrollToIndex)||0,M=L,setTimeout(()=>{t.scrollOffset!=null?R(t.scrollOffset):t.scrollToIndex!=null&&R(V(t.scrollToIndex))},0),q(),T()},G=i=>{const h=fe();h<0||c===h||i.target!==l.value||(c=h,M=W,T())},T=()=>{const{start:i,stop:h}=g.getVisibleRange({containerSize:B()||0,offset:c||0,overscanCount:t.overscanCount});if(typeof i!="undefined"&&typeof h!="undefined"){a.length=0;for(let y=i;y<=h;y++)a.push(t.data[y]);z.start=i,z.stop=h,z.offset=c,z.items=a,z.total=N(),C.isPureNumber(I.value)||(S.value=O(E({},k),{[w()]:A(g.getTotalSize())})),t.debug&&console.log(z.toString())}de()},R=i=>{l.value[U()]=i,b=i},de=()=>{b!==c&&M===L&&R(c)},ue=()=>(g||(g=new ee({itemCount:N(),itemSizeGetter:i=>ce(i),estimatedItemSize:p()})),g),fe=()=>l.value[U()],w=()=>Z[F.value],B=()=>t[w()],U=()=>Q[F.value],V=(i,h=t.scrollToAlignment,y=N())=>((i<0||i>=y)&&(i=0),g.getUpdatedOffsetForIndex({align:t.scrollToAlignment,containerSize:B(),currentOffset:c||0,targetIndex:i})),ce=i=>typeof I.value=="function"?I.value(i):C.isArray(I.value)?I.value[i]:I.value,N=()=>t.data?t.data.length:0,p=()=>t.estimatedItemSize||typeof I.value=="number"&&I.value||50,he=(i=0)=>{v={},g.resetItem(i)},A=i=>typeof i=="string"?i:i+t.unit,q=()=>{u.value=O(E({},K),{height:A(t.height),width:A(t.width)}),S.value=O(E({},k),{[w()]:A(g.getTotalSize())})},D=()=>{for(let i in v)delete v[i]};return r.onMounted(()=>setTimeout(ae)),r.onBeforeUnmount(()=>{D(),g.destroy(),C.removeEventListener(l.value,"scroll",G)}),r.watch(()=>t.debug,(i,h)=>D()),r.watch(()=>t.data,(i,h)=>{g.updateConfig({itemCount:N(),estimatedItemSize:p()}),b=null,he(),q(),setTimeout(T,0)}),r.watch(()=>t.scrollOffset,(i,h)=>{c=t.scrollOffset||0,M=L,T()}),r.watch(()=>t.scrollToIndex,(i,h)=>{c=V(t.scrollToIndex,t.scrollToAlignment,N()),M=L,T()}),{rootNode:l,innerNode:d,warpStyle:u,innerStyle:S,getItemStyle:le,event:z}}});function re(t,e,n,o,l,d){var u;return s.openBlock(),s.createElementBlock("div",{ref:"rootNode",style:s.normalizeStyle(t.warpStyle)},[s.createElementVNode("div",{ref:"innerNode",style:s.normalizeStyle(t.innerStyle)},[(s.openBlock(!0),s.createElementBlock(s.Fragment,null,s.renderList((u=t.event)==null?void 0:u.items,(S,a)=>{var c;return s.openBlock(),s.createElementBlock("div",{style:s.normalizeStyle(t.getItemStyle(a)),key:((c=t.event)==null?void 0:c.start)+a,class:"vue3-infinite-list"},[s.renderSlot(t.$slots,"default",{event:t.event,item:S,index:t.event.start+a})],4)}),128))],4)],4)}var oe=ie(se,[["render",re]]);return oe});