@floor/vlist 0.5.5 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builder/index.js +259 -1
- package/dist/compression/index.js +116 -1
- package/dist/core/index.js +137 -1
- package/dist/core-light.js +72 -1
- package/dist/data/index.js +233 -1
- package/dist/grid/index.js +203 -1
- package/dist/groups/index.js +210 -1
- package/dist/index.js +1165 -1
- package/dist/react/index.js +1057 -1
- package/dist/scroll/index.js +121 -1
- package/dist/selection/index.js +104 -1
- package/dist/snapshots/index.js +21 -1
- package/dist/svelte/index.js +1045 -1
- package/dist/vue/index.js +1051 -1
- package/dist/window/index.js +18 -1
- package/package.json +2 -1
package/dist/builder/index.js
CHANGED
|
@@ -1 +1,259 @@
|
|
|
1
|
-
var QJ=0,m=5,qJ=100,Oj=2,KJ=(X=0)=>{let U=Array(m);for(let $=0;$<m;$++)U[$]={position:0,time:0};return{velocity:0,lastPosition:X,lastTime:performance.now(),samples:U,sampleIndex:0,sampleCount:0}},UJ=(X,U)=>{let $=performance.now(),Y=$-X.lastTime;if(Y===0)return X;if(Y>qJ){X.sampleCount=0,X.sampleIndex=0,X.velocity=0;let Q=X.samples[0];return Q.position=U,Q.time=$,X.sampleIndex=1,X.sampleCount=1,X.lastPosition=U,X.lastTime=$,X}let V=X.samples[X.sampleIndex];if(V.position=U,V.time=$,X.sampleIndex=(X.sampleIndex+1)%m,X.sampleCount=Math.min(X.sampleCount+1,m),X.sampleCount>=Oj){let Q=(X.sampleIndex-X.sampleCount+m)%m,K=X.samples[Q],D=U-K.position,C=$-K.time;X.velocity=C>0?Math.abs(D)/C:0}return X.lastPosition=U,X.lastTime=$,X},Sj=(X,U)=>{if(typeof X==="number"){let Q=U;return{getOffset:(K)=>K*X,getHeight:()=>X,indexAtOffset:(K)=>{if(Q===0||X===0)return 0;return Math.max(0,Math.min(Math.floor(K/X),Q-1))},getTotalHeight:()=>Q*X,getTotal:()=>Q,rebuild:(K)=>{Q=K},isVariable:()=>!1}}let $=U,Y=new Float64Array(0),V=(Q)=>{$=Q,Y=new Float64Array(Q+1),Y[0]=0;for(let K=0;K<Q;K++)Y[K+1]=Y[K]+X(K)};return V(U),{getOffset:(Q)=>{if(Q<=0)return 0;if(Q>=$)return Y[$];return Y[Q]},getHeight:(Q)=>X(Q),indexAtOffset:(Q)=>{if($===0)return 0;if(Q<=0)return 0;if(Q>=Y[$])return $-1;let K=0,D=$-1;while(K<D){let C=K+D+1>>>1;if(Y[C]<=Q)K=C;else D=C-1}return K},getTotalHeight:()=>Y[$]??0,getTotal:()=>$,rebuild:(Q)=>V(Q),isVariable:()=>!0}},YJ=()=>{let X={},U=(Q,K)=>{if(!X[Q])X[Q]=new Set;return X[Q].add(K),()=>$(Q,K)},$=(Q,K)=>{X[Q]?.delete(K)};return{on:U,off:$,emit:(Q,K)=>{X[Q]?.forEach((D)=>{try{D(K)}catch(C){console.error(`[vlist] Error in "${Q}" handler:`,C)}})},clear:()=>{for(let Q in X)delete X[Q]}}},BJ=(X)=>{if(typeof X==="string"){let U=document.querySelector(X);if(!U)throw Error(`[vlist/builder] Container not found: ${X}`);return U}return X},GJ=(X,U,$,Y)=>{let V=document.createElement("div");if(V.className=U,Y)V.classList.add(`${U}--horizontal`);if(V.setAttribute("role","listbox"),V.setAttribute("tabindex","0"),$)V.setAttribute("aria-label",$);if(Y)V.setAttribute("aria-orientation","horizontal");let Q=document.createElement("div");if(Q.className=`${U}-viewport`,Y)Q.style.overflowX="auto",Q.style.overflowY="hidden";else Q.style.overflow="auto";Q.style.height="100%",Q.style.width="100%";let K=document.createElement("div");if(K.className=`${U}-content`,K.style.position="relative",Y)K.style.height="100%";else K.style.width="100%";let D=document.createElement("div");if(D.className=`${U}-items`,D.style.position="relative",Y)D.style.height="100%";else D.style.width="100%";return K.appendChild(D),Q.appendChild(K),V.appendChild(Q),X.appendChild(V),{root:V,viewport:Q,content:K,items:D}},WJ=(X=100)=>{let U=[];return{acquire:()=>{let $=U.pop();if($)return $;let Y=document.createElement("div");return Y.setAttribute("role","option"),Y},release:($)=>{if(U.length<X)$.className="",$.textContent="",$.removeAttribute("style"),$.removeAttribute("data-index"),$.removeAttribute("data-id"),U.push($)},clear:()=>{U.length=0}}},DJ=(X,U,$,Y,V)=>{if(Y===0||U===0){V.start=0,V.end=0;return}let Q=$.indexAtOffset(X),K=$.indexAtOffset(X+U);if(K<Y-1)K++;V.start=Math.max(0,Q),V.end=Math.min(Y-1,Math.max(0,K))},VJ=(X,U,$,Y)=>{if($===0){Y.start=0,Y.end=0;return}Y.start=Math.max(0,X.start-U),Y.end=Math.min($-1,X.end+U)},_J=(X,U,$,Y,V)=>{if(Y===0)return 0;let Q=Math.max(0,Math.min(X,Y-1)),K=U.getOffset(Q),D=U.getHeight(Q),C=Math.max(0,U.getTotalHeight()-$),f;switch(V){case"center":f=K-($-D)/2;break;case"end":f=K-$+D;break;default:f=K}return Math.max(0,Math.min(f,C))},LJ=(X)=>X<0.5?2*X*X:-1+(4-2*X)*X,NJ=(X)=>{if(typeof X==="string")return{align:X,behavior:"auto",duration:300};if(X&&typeof X==="object")return{align:X.align??"start",behavior:X.behavior??"auto",duration:X.duration??300};return{align:"start",behavior:"auto",duration:300}},MJ=(X)=>{if(!X.container)throw Error("[vlist/builder] Container is required");if(!X.item)throw Error("[vlist/builder] item configuration is required");let U=X.direction==="horizontal",$=U?"width":"height",Y=U?X.item.width:X.item.height;if(Y==null)throw Error(`[vlist/builder] item.${$} is required${U?" when direction is 'horizontal'":""}`);if(typeof Y==="number"&&Y<=0)throw Error(`[vlist/builder] item.${$} must be a positive number`);if(typeof Y!=="number"&&typeof Y!=="function")throw Error(`[vlist/builder] item.${$} must be a number or a function (index) => number`);if(!X.item.template)throw Error("[vlist/builder] item.template is required");if(U&&X.reverse)throw Error("[vlist/builder] horizontal direction cannot be combined with reverse mode");let V=new Map,Q=!1,K={use(D){if(Q)throw Error("[vlist/builder] Cannot call .use() after .build()");return V.set(D.name,D),K},build(){if(Q)throw Error("[vlist/builder] .build() can only be called once");return Q=!0,AJ(X,V,U,Y)}};return K};function AJ(X,U,$,Y){let{item:V,items:Q,overscan:K=3,classPrefix:D="vlist",ariaLabel:C,reverse:f=!1,scroll:Kj}=X,Ij=Kj?.wheel??!0,Fj=Kj?.wrap??!1,c=f,Rj=`${D}-${QJ++}`,Tj=Y,yj=$?typeof V.height==="number"?V.height:void 0:typeof V.width==="number"?V.width:void 0,t=V.template,uj={overscan:K,classPrefix:D,reverse:c,wrap:Fj,horizontal:$,ariaIdPrefix:Rj},d=Array.from(U.values()).sort((j,J)=>(j.priority??50)-(J.priority??50)),s=new Set(d.map((j)=>j.name));for(let j of d)if(j.conflicts){for(let J of j.conflicts)if(s.has(J))throw Error(`[vlist/builder] ${j.name} and ${J} cannot be combined`)}if($){if(s.has("withGrid"))throw Error("[vlist/builder] withGrid cannot be used with direction: 'horizontal'");if(s.has("withGroups"))throw Error("[vlist/builder] withGroups cannot be used with direction: 'horizontal'")}if(c){if(s.has("withGrid"))throw Error("[vlist/builder] withGrid cannot be used with reverse: true");if(s.has("withGroups"))throw Error("[vlist/builder] withGroups cannot be used with reverse: true")}let fj=BJ(X.container),_=GJ(fj,D,C,$),k=YJ(),B=Q?[...Q]:[],N=Sj(Tj,B.length),e=WJ(),R=_.viewport.clientHeight,jj=_.viewport.clientWidth,l=!1,x=!1,O=0,p=null,a=null,I=KJ(0),Jj={start:0,end:0},E={start:0,end:0},h={start:-1,end:-1},H={viewportState:{scrollTop:0,containerHeight:R,totalHeight:N.getTotalHeight(),actualHeight:N.getTotalHeight(),isCompressed:!1,compressionRatio:1,visibleRange:{start:0,end:0},renderRange:{start:0,end:0}},lastRenderRange:{start:-1,end:-1},isInitialized:!1,isDestroyed:!1,cachedCompression:null},v=new Map,Uj={selected:!1,focused:!1},xj=`${D}-item`,r="",z=new Map,Yj=()=>{z.clear();for(let j=0;j<B.length;j++){let J=B[j];if(J)z.set(J.id,j)}};Yj();let F=null,P=()=>F?F.getTotal():B.length,Bj=[],Gj=[],Wj=[],Dj=[],o=[],Vj=[],L=new Map,u=()=>{return $?_.viewport.scrollLeft:_.viewport.scrollTop},S=(j)=>{if($)_.viewport.scrollLeft=j;else _.viewport.scrollTop=j},Cj=(j=2)=>{let J=N.getTotalHeight();return O+R>=J-j},pj=!1,y,T,kj=(j,J,Z,q,W)=>{DJ(j,J,Z,q,W)},Xj=(j,J,Z,q,W)=>{return _J(j,J,Z,q,W)},_j=(j,J)=>{if(typeof J==="string")j.innerHTML=J;else j.replaceChildren(J)},Lj=(j,J)=>{let Z=Math.round(N.getOffset(J));if($)j.style.transform=`translateX(${Z}px)`;else j.style.transform=`translateY(${Z}px)`},hj=(j,J)=>{let Z=e.acquire();if(Z.className=xj,$){if(Z.style.width=`${N.getHeight(j)}px`,yj!=null)Z.style.height=`${yj}px`}else Z.style.height=`${N.getHeight(j)}px`;return Z.dataset.index=String(j),Z.dataset.id=String(J.id),Z.ariaSelected="false",Z.id=`${Rj}-item-${j}`,r=String(P()),Z.setAttribute("aria-setsize",r),Z.setAttribute("aria-posinset",String(j+1)),_j(Z,t(J,j,Uj)),Lj(Z,j),Z},n=()=>{let j=`${N.getTotalHeight()}px`;if($)_.content.style.width=j;else _.content.style.height=j},Nj=new Set,Mj=-1,gj=()=>{if(l)return;let j=P();if(kj(O,R,N,j,Jj),VJ(Jj,K,j,E),E.start===h.start&&E.end===h.end)return;let J=String(j),Z=J!==r;r=J;for(let[G,A]of v)if(G<E.start||G>E.end)A.remove(),e.release(A),v.delete(G);let q=document.createDocumentFragment(),W=[];for(let G=E.start;G<=E.end;G++){let A=F?F.getItem(G):B[G];if(!A)continue;let b=v.get(G);if(b){let w=b.dataset.id,Qj=String(A.id);if(w!==Qj)if(_j(b,t(A,G,Uj)),b.dataset.id=Qj,$)b.style.width=`${N.getHeight(G)}px`;else b.style.height=`${N.getHeight(G)}px`;Lj(b,G);let qj=Nj.has(A.id),$J=G===Mj;if(b.classList.toggle(`${D}-item--selected`,qj),b.classList.toggle(`${D}-item--focused`,$J),b.ariaSelected=qj?"true":"false",Z)b.setAttribute("aria-setsize",r)}else{let w=hj(G,A),Qj=Nj.has(A.id),qj=G===Mj;if(Qj)w.classList.add(`${D}-item--selected`),w.ariaSelected="true";if(qj)w.classList.add(`${D}-item--focused`);q.appendChild(w),W.push({index:G,element:w})}}if(W.length>0){_.items.appendChild(q);for(let{index:G,element:A}of W)v.set(G,A)}h.start=E.start,h.end=E.end,H.lastRenderRange.start=E.start,H.lastRenderRange.end=E.end,H.viewportState.scrollTop=O,H.viewportState.visibleRange.start=Jj.start,H.viewportState.visibleRange.end=Jj.end,H.viewportState.renderRange.start=E.start,H.viewportState.renderRange.end=E.end,k.emit("range:change",{range:{start:E.start,end:E.end}})},mj=()=>{h.start=-1,h.end=-1,y()};y=gj,T=mj;let i=()=>{if(l)return;let j=u(),J=j>=O?"down":"up";if(I=UJ(I,j),!_.root.classList.contains(`${D}--scrolling`))_.root.classList.add(`${D}--scrolling`);O=j,y(),k.emit("scroll",{scrollTop:j,direction:J}),k.emit("velocity:change",{velocity:I.velocity,reliable:I.sampleCount>=Oj});for(let Z=0;Z<Bj.length;Z++)Bj[Z](j,J);if(a)clearTimeout(a);a=setTimeout(()=>{_.root.classList.remove(`${D}--scrolling`),I.velocity=0,I.sampleCount=0,k.emit("velocity:change",{velocity:0,reliable:!1})},Kj?.idleTimeout??150)},Zj=null,g=_.viewport;if(g.addEventListener("scroll",i,{passive:!0}),$&&Ij)Zj=(j)=>{if(j.deltaX)return;j.preventDefault(),_.viewport.scrollLeft+=j.deltaY},_.viewport.addEventListener("wheel",Zj);_.viewport.classList.add(`${D}-viewport--custom-scrollbar`);let zj=(j)=>{let Z=j.target.closest("[data-index]");if(Z){let q=parseInt(Z.dataset.index??"-1",10);if(q>=0){let W=F?.getItem(q)??B[q];if(W){if(W.__groupHeader)return;k.emit("item:click",{item:W,index:q,event:j})}}}for(let q=0;q<Gj.length;q++)Gj[q](j)},cj=(j)=>{let Z=j.target.closest("[data-index]");if(Z){let q=parseInt(Z.dataset.index??"-1",10);if(q>=0){let W=F?.getItem(q)??B[q];if(W){if(W.__groupHeader)return;k.emit("item:dblclick",{item:W,index:q,event:j})}}}},Pj=(j)=>{for(let J=0;J<Wj.length;J++)Wj[J](j)};_.items.addEventListener("click",zj),_.items.addEventListener("dblclick",cj),_.root.addEventListener("keydown",Pj);let Aj=!0,dj=()=>jj,sj=()=>R,bj=new ResizeObserver((j)=>{if(l)return;for(let J of j){let Z=J.contentRect.height,q=J.contentRect.width,W=$?q:Z;if(jj=q,Math.abs(W-R)>1){if(R=W,H.viewportState.containerHeight=W,x)n(),y(),k.emit("resize",{height:Z,width:q})}if(x)for(let G=0;G<Dj.length;G++)Dj[G](q,Z)}});if(Aj)bj.observe(_.viewport);let M={get dom(){return _},get heightCache(){return N},get emitter(){return k},get config(){return uj},get rawConfig(){return X},get renderer(){return{render:(j,J,Z,q,W)=>{Nj=Z,Mj=q,T()},updateItemClasses:(j,J,Z)=>{let q=v.get(j);if(!q)return;q.classList.toggle(`${D}-item--selected`,J),q.classList.toggle(`${D}-item--focused`,Z),q.ariaSelected=J?"true":"false"},updatePositions:()=>{},updateItem:()=>{},getElement:(j)=>v.get(j)??null,clear:()=>{},destroy:()=>{}}},set renderer(j){},get dataManager(){return F},set dataManager(j){F=j},get scrollController(){return Ej},set scrollController(j){Ej=j},state:H,getContainerWidth(){return jj},afterScroll:Bj,clickHandlers:Gj,keydownHandlers:Wj,resizeHandlers:Dj,contentSizeHandlers:o,destroyHandlers:Vj,methods:L,replaceTemplate(j){t=j},replaceRenderer(j){},replaceDataManager(j){F=j},replaceScrollController(j){Ej=j},getItemsForRange(j){let J=[];for(let Z=j.start;Z<=j.end;Z++){let q=F?F.getItem(Z):B[Z];if(q)J.push(q)}return J},getAllLoadedItems(){if(F){let j=F.getTotal(),J=[];for(let Z=0;Z<j;Z++){let q=F.getItem(Z);if(q)J.push(q)}return J}return[...B]},getVirtualTotal(){return P()},getCachedCompression(){return{isCompressed:!1,actualHeight:N.getTotalHeight(),virtualHeight:N.getTotalHeight(),ratio:1}},getCompressionContext(){return{scrollTop:O,totalItems:P(),containerHeight:R,rangeStart:E.start}},renderIfNeeded(){y()},forceRender(){T()},getRenderFns(){return{renderIfNeeded:y,forceRender:T}},setRenderFns(j,J){y=j,T=J},setVirtualTotalFn(j){P=j},rebuildHeightCache(j){N.rebuild(j??P())},setHeightConfig(j){N=Sj(j,P())},updateContentSize(j){let J=`${j}px`;if($)_.content.style.width=J;else _.content.style.height=J},updateCompressionMode(){},setVisibleRangeFn(j){kj=j},setScrollToPosFn(j){Xj=j},setPositionElementFn(j){Lj=j},setScrollFns(j,J){u=j,S=(Z)=>{J(Z),i()}},setScrollTarget(j){g.removeEventListener("scroll",i),g=j,g.addEventListener("scroll",i,{passive:!0})},getScrollTarget(){return g},setContainerDimensions(j){dj=j.width,sj=j.height,jj=j.width(),R=j.height(),H.viewportState.containerHeight=R},disableViewportResize(){if(Aj)Aj=!1,bj.unobserve(_.viewport)}};F={getState:()=>({total:B.length,cached:B.length,isLoading:!1,pendingRanges:[],error:void 0,hasMore:!1,cursor:void 0}),getTotal:()=>B.length,getCached:()=>B.length,getIsLoading:()=>!1,getHasMore:()=>!1,getStorage:()=>null,getPlaceholders:()=>null,getItem:(j)=>B[j],getItemById:(j)=>{let J=z.get(j);return J!==void 0?B[J]:void 0},getIndexById:(j)=>z.get(j)??-1,isItemLoaded:(j)=>j>=0&&j<B.length&&B[j]!==void 0,getItemsInRange:(j,J)=>{let Z=[],q=Math.max(0,j),W=Math.min(J,B.length-1);for(let G=q;G<=W;G++)Z.push(B[G]);return Z},setTotal:(j)=>{},setItems:(j,J=0,Z)=>{if(J===0&&(Z!==void 0||B.length===0))B=[...j];else{let q=J+j.length;if(B.length<q)B.length=q;for(let W=0;W<j.length;W++)B[J+W]=j[W]}if(Yj(),x){N.rebuild(P()),n(),M.updateCompressionMode();for(let q=0;q<o.length;q++)o[q]();T()}},updateItem:(j,J)=>{let Z=z.get(j);if(Z===void 0)return!1;let q=B[Z];if(!q)return!1;if(B[Z]={...q,...J},J.id!==void 0&&J.id!==j)z.delete(j),z.set(J.id,Z);let W=v.get(Z);if(W)_j(W,t(B[Z],Z,Uj)),W.dataset.id=String(B[Z].id);return!0},removeItem:(j)=>{let J=z.get(j);if(J===void 0)return!1;if(B.splice(J,1),Yj(),x){N.rebuild(P()),n(),M.updateCompressionMode();for(let Z=0;Z<o.length;Z++)o[Z]();T()}return!0},loadRange:async()=>{},ensureRange:async()=>{},loadInitial:async()=>{},loadMore:async()=>!1,reload:async()=>{},evictDistant:()=>{},clear:()=>{B=[],z.clear()},reset:()=>{if(B=[],z.clear(),x)N.rebuild(0),n(),T()}};let Ej={getScrollTop:()=>u(),scrollTo:(j)=>{S(j),O=j,y()},scrollBy:(j)=>{let J=u()+j;S(J),O=J,y()},isAtTop:()=>O<=2,isAtBottom:(j=2)=>Cj(j),getScrollPercentage:()=>{let j=N.getTotalHeight(),J=Math.max(0,j-R);return J>0?O/J:0},getVelocity:()=>I.velocity,isTracking:()=>I.sampleCount>=Oj,isScrolling:()=>_.root.classList.contains(`${D}--scrolling`),updateConfig:()=>{},enableCompression:()=>{},disableCompression:()=>{},isCompressed:()=>pj,isWindowMode:()=>!1,updateContainerHeight:(j)=>{R=j},destroy:()=>{}},Hj=new Map;for(let j of d)if(j.methods)for(let J of j.methods){let Z=Hj.get(J);if(Z)throw Error(`[vlist/builder] Method "${J}" is registered by both "${Z}" and "${j.name}"`);Hj.set(J,j.name)}for(let j of d)j.setup(M);if(x=!0,M.state.isInitialized=!0,n(),y(),c&&B.length>0){let j=Xj(B.length-1,N,R,B.length,"end");S(j),O=j,y()}let lj=(j)=>{M.dataManager.setItems(j,0,j.length)},aj=c?(j)=>{let J=Cj(2),Z=B.length;if(M.dataManager.setItems(j,Z),J&&B.length>0){let q=Xj(B.length-1,N,R,B.length,"end");S(q),O=q,y()}}:(j)=>{let J=B.length;M.dataManager.setItems(j,J)},rj=c?(j)=>{let J=u(),Z=N.getTotalHeight(),q=[...B];M.dataManager.clear(),M.dataManager.setItems([...j,...q],0);let G=N.getTotalHeight()-Z;if(G>0)S(J+G),O=J+G}:(j)=>{let J=[...B];M.dataManager.clear(),M.dataManager.setItems([...j,...J],0)},oj=(j,J)=>{M.dataManager.updateItem(j,J)},nj=(j)=>{M.dataManager.removeItem(j)},ij=async()=>{if(M.dataManager.reload)await M.dataManager.reload()},$j=()=>{if(p!==null)cancelAnimationFrame(p),p=null},tj=(j,J,Z)=>{if($j(),Math.abs(J-j)<1){S(J),O=J,y();return}let q=performance.now(),W=(G)=>{let A=G-q,b=Math.min(A/Z,1),w=j+(J-j)*LJ(b);if(S(w),O=w,y(),b<1)p=requestAnimationFrame(W);else p=null};p=requestAnimationFrame(W)},wj=(j,J)=>{let{align:Z,behavior:q,duration:W}=NJ(J),G=P(),A=j;if(Fj&&G>0)A=(A%G+G)%G;let b=Xj(A,N,R,G,Z);if(q==="smooth")tj(u(),b,W);else $j(),S(b)},ej=(j,J)=>{let Z=z.get(j)??M.dataManager.getIndexById(j);if(Z>=0)wj(Z,J)},jJ=()=>u(),JJ=(j,J)=>{return k.on(j,J)},XJ=(j,J)=>{k.off(j,J)},ZJ=()=>{if(l)return;if(l=!0,M.state.isDestroyed=!0,_.items.removeEventListener("click",zj),_.root.removeEventListener("keydown",Pj),g.removeEventListener("scroll",i),bj.disconnect(),Zj)_.viewport.removeEventListener("wheel",Zj);if(a)clearTimeout(a);for(let j=0;j<Vj.length;j++)Vj[j]();for(let j of d)if(j.destroy)j.destroy();$j();for(let[,j]of v)j.remove(),e.release(j);v.clear(),e.clear(),k.clear(),_.root.remove()},vj={get element(){return _.root},get items(){if(L.has("_getItems"))return L.get("_getItems")();return B},get total(){if(L.has("_getTotal"))return L.get("_getTotal")();return P()},setItems:L.has("setItems")?L.get("setItems"):lj,appendItems:L.has("appendItems")?L.get("appendItems"):aj,prependItems:L.has("prependItems")?L.get("prependItems"):rj,updateItem:L.has("updateItem")?L.get("updateItem"):oj,removeItem:L.has("removeItem")?L.get("removeItem"):nj,reload:L.has("reload")?L.get("reload"):ij,scrollToIndex:L.has("scrollToIndex")?L.get("scrollToIndex"):wj,scrollToItem:L.has("scrollToItem")?L.get("scrollToItem"):ej,cancelScroll:L.has("cancelScroll")?L.get("cancelScroll"):$j,getScrollPosition:L.has("getScrollPosition")?L.get("getScrollPosition"):jJ,on:JJ,off:XJ,destroy:ZJ};for(let[j,J]of L){if(j==="setItems"||j==="appendItems"||j==="prependItems"||j==="updateItem"||j==="removeItem"||j==="reload"||j==="scrollToIndex"||j==="scrollToItem"||j==="cancelScroll"||j==="getScrollPosition")continue;vj[j]=J}return vj}export{MJ as vlist};
|
|
1
|
+
var QJ=0,m=5,qJ=100,Oj=2,KJ=(X=0)=>{let U=Array(m);
|
|
2
|
+
for(let $=0;
|
|
3
|
+
$<m;
|
|
4
|
+
$++)U[$]={position:0,time:0};
|
|
5
|
+
return{velocity:0,lastPosition:X,lastTime:performance.now(),samples:U,sampleIndex:0,sampleCount:0}},UJ=(X,U)=>{let $=performance.now(),Y=$-X.lastTime;
|
|
6
|
+
if(Y===0)return X;
|
|
7
|
+
if(Y>qJ){X.sampleCount=0,X.sampleIndex=0,X.velocity=0;
|
|
8
|
+
let Q=X.samples[0];
|
|
9
|
+
return Q.position=U,Q.time=$,X.sampleIndex=1,X.sampleCount=1,X.lastPosition=U,X.lastTime=$,X}
|
|
10
|
+
let V=X.samples[X.sampleIndex];
|
|
11
|
+
if(V.position=U,V.time=$,X.sampleIndex=(X.sampleIndex+1)%m,X.sampleCount=Math.min(X.sampleCount+1,m),X.sampleCount>=Oj){let Q=(X.sampleIndex-X.sampleCount+m)%m,K=X.samples[Q],D=U-K.position,C=$-K.time;
|
|
12
|
+
X.velocity=C>0?Math.abs(D)/C:0}
|
|
13
|
+
return X.lastPosition=U,X.lastTime=$,X},Sj=(X,U)=>{if(typeof X==="number"){let Q=U;
|
|
14
|
+
return{getOffset:(K)=>K*X,getHeight:()=>X,indexAtOffset:(K)=>{if(Q===0||X===0)return 0;
|
|
15
|
+
return Math.max(0,Math.min(Math.floor(K/X),Q-1))},getTotalHeight:()=>Q*X,getTotal:()=>Q,rebuild:(K)=>{Q=K},isVariable:()=>!1}}
|
|
16
|
+
let $=U,Y=new Float64Array(0),V=(Q)=>{$=Q,Y=new Float64Array(Q+1),Y[0]=0;
|
|
17
|
+
for(let K=0;
|
|
18
|
+
K<Q;
|
|
19
|
+
K++)Y[K+1]=Y[K]+X(K)};
|
|
20
|
+
return V(U),{getOffset:(Q)=>{if(Q<=0)return 0;
|
|
21
|
+
if(Q>=$)return Y[$];
|
|
22
|
+
return Y[Q]},getHeight:(Q)=>X(Q),indexAtOffset:(Q)=>{if($===0)return 0;
|
|
23
|
+
if(Q<=0)return 0;
|
|
24
|
+
if(Q>=Y[$])return $-1;
|
|
25
|
+
let K=0,D=$-1;
|
|
26
|
+
while(K<D){let C=K+D+1>>>1;
|
|
27
|
+
if(Y[C]<=Q)K=C;
|
|
28
|
+
else D=C-1}
|
|
29
|
+
return K},getTotalHeight:()=>Y[$]??0,getTotal:()=>$,rebuild:(Q)=>V(Q),isVariable:()=>!0}},YJ=()=>{let X={},U=(Q,K)=>{if(!X[Q])X[Q]=new Set;
|
|
30
|
+
return X[Q].add(K),()=>$(Q,K)},$=(Q,K)=>{X[Q]?.delete(K)};
|
|
31
|
+
return{on:U,off:$,emit:(Q,K)=>{X[Q]?.forEach((D)=>{try{D(K)}
|
|
32
|
+
catch(C){console.error(`[vlist] Error in "${Q}" handler:`,C)}})},clear:()=>{for(let Q in X)delete X[Q]}}},BJ=(X)=>{if(typeof X==="string"){let U=document.querySelector(X);
|
|
33
|
+
if(!U)throw Error(`[vlist/builder] Container not found: ${X}`);
|
|
34
|
+
return U}
|
|
35
|
+
return X},GJ=(X,U,$,Y)=>{let V=document.createElement("div");
|
|
36
|
+
if(V.className=U,Y)V.classList.add(`${U}--horizontal`);
|
|
37
|
+
if(V.setAttribute("role","listbox"),V.setAttribute("tabindex","0"),$)V.setAttribute("aria-label",$);
|
|
38
|
+
if(Y)V.setAttribute("aria-orientation","horizontal");
|
|
39
|
+
let Q=document.createElement("div");
|
|
40
|
+
if(Q.className=`${U}-viewport`,Y)Q.style.overflowX="auto",Q.style.overflowY="hidden";
|
|
41
|
+
else Q.style.overflow="auto";
|
|
42
|
+
Q.style.height="100%",Q.style.width="100%";
|
|
43
|
+
let K=document.createElement("div");
|
|
44
|
+
if(K.className=`${U}-content`,K.style.position="relative",Y)K.style.height="100%";
|
|
45
|
+
else K.style.width="100%";
|
|
46
|
+
let D=document.createElement("div");
|
|
47
|
+
if(D.className=`${U}-items`,D.style.position="relative",Y)D.style.height="100%";
|
|
48
|
+
else D.style.width="100%";
|
|
49
|
+
return K.appendChild(D),Q.appendChild(K),V.appendChild(Q),X.appendChild(V),{root:V,viewport:Q,content:K,items:D}},WJ=(X=100)=>{let U=[];
|
|
50
|
+
return{acquire:()=>{let $=U.pop();
|
|
51
|
+
if($)return $;
|
|
52
|
+
let Y=document.createElement("div");
|
|
53
|
+
return Y.setAttribute("role","option"),Y},release:($)=>{if(U.length<X)$.className="",$.textContent="",$.removeAttribute("style"),$.removeAttribute("data-index"),$.removeAttribute("data-id"),U.push($)},clear:()=>{U.length=0}}},DJ=(X,U,$,Y,V)=>{if(Y===0||U===0){V.start=0,V.end=0;
|
|
54
|
+
return}
|
|
55
|
+
let Q=$.indexAtOffset(X),K=$.indexAtOffset(X+U);
|
|
56
|
+
if(K<Y-1)K++;
|
|
57
|
+
V.start=Math.max(0,Q),V.end=Math.min(Y-1,Math.max(0,K))},VJ=(X,U,$,Y)=>{if($===0){Y.start=0,Y.end=0;
|
|
58
|
+
return}
|
|
59
|
+
Y.start=Math.max(0,X.start-U),Y.end=Math.min($-1,X.end+U)},_J=(X,U,$,Y,V)=>{if(Y===0)return 0;
|
|
60
|
+
let Q=Math.max(0,Math.min(X,Y-1)),K=U.getOffset(Q),D=U.getHeight(Q),C=Math.max(0,U.getTotalHeight()-$),f;
|
|
61
|
+
switch(V){case"center":f=K-($-D)/2;
|
|
62
|
+
break;
|
|
63
|
+
case"end":f=K-$+D;
|
|
64
|
+
break;
|
|
65
|
+
default:f=K}
|
|
66
|
+
return Math.max(0,Math.min(f,C))},LJ=(X)=>X<0.5?2*X*X:-1+(4-2*X)*X,NJ=(X)=>{if(typeof X==="string")return{align:X,behavior:"auto",duration:300};
|
|
67
|
+
if(X&&typeof X==="object")return{align:X.align??"start",behavior:X.behavior??"auto",duration:X.duration??300};
|
|
68
|
+
return{align:"start",behavior:"auto",duration:300}},MJ=(X)=>{if(!X.container)throw Error("[vlist/builder] Container is required");
|
|
69
|
+
if(!X.item)throw Error("[vlist/builder] item configuration is required");
|
|
70
|
+
let U=X.direction==="horizontal",$=U?"width":"height",Y=U?X.item.width:X.item.height;
|
|
71
|
+
if(Y==null)throw Error(`[vlist/builder] item.${$} is required${U?" when direction is 'horizontal'":""}`);
|
|
72
|
+
if(typeof Y==="number"&&Y<=0)throw Error(`[vlist/builder] item.${$} must be a positive number`);
|
|
73
|
+
if(typeof Y!=="number"&&typeof Y!=="function")throw Error(`[vlist/builder] item.${$} must be a number or a function (index) => number`);
|
|
74
|
+
if(!X.item.template)throw Error("[vlist/builder] item.template is required");
|
|
75
|
+
if(U&&X.reverse)throw Error("[vlist/builder] horizontal direction cannot be combined with reverse mode");
|
|
76
|
+
let V=new Map,Q=!1,K={use(D){if(Q)throw Error("[vlist/builder] Cannot call .use() after .build()");
|
|
77
|
+
return V.set(D.name,D),K},build(){if(Q)throw Error("[vlist/builder] .build() can only be called once");
|
|
78
|
+
return Q=!0,AJ(X,V,U,Y)}};
|
|
79
|
+
return K};
|
|
80
|
+
function AJ(X,U,$,Y){let{item:V,items:Q,overscan:K=3,classPrefix:D="vlist",ariaLabel:C,reverse:f=!1,scroll:Kj}=X,Ij=Kj?.wheel??!0,Fj=Kj?.wrap??!1,c=f,Rj=`${D}-${QJ++}`,Tj=Y,yj=$?typeof V.height==="number"?V.height:void 0:typeof V.width==="number"?V.width:void 0,t=V.template,uj={overscan:K,classPrefix:D,reverse:c,wrap:Fj,horizontal:$,ariaIdPrefix:Rj},d=Array.from(U.values()).sort((j,J)=>(j.priority??50)-(J.priority??50)),s=new Set(d.map((j)=>j.name));
|
|
81
|
+
for(let j of d)if(j.conflicts){for(let J of j.conflicts)if(s.has(J))throw Error(`[vlist/builder] ${j.name} and ${J} cannot be combined`)}
|
|
82
|
+
if($){if(s.has("withGrid"))throw Error("[vlist/builder] withGrid cannot be used with direction: 'horizontal'");
|
|
83
|
+
if(s.has("withGroups"))throw Error("[vlist/builder] withGroups cannot be used with direction: 'horizontal'")}
|
|
84
|
+
if(c){if(s.has("withGrid"))throw Error("[vlist/builder] withGrid cannot be used with reverse: true");
|
|
85
|
+
if(s.has("withGroups"))throw Error("[vlist/builder] withGroups cannot be used with reverse: true")}
|
|
86
|
+
let fj=BJ(X.container),_=GJ(fj,D,C,$),k=YJ(),B=Q?[...Q]:[],N=Sj(Tj,B.length),e=WJ(),R=_.viewport.clientHeight,jj=_.viewport.clientWidth,l=!1,x=!1,O=0,p=null,a=null,I=KJ(0),Jj={start:0,end:0},E={start:0,end:0},h={start:-1,end:-1},H={viewportState:{scrollTop:0,containerHeight:R,totalHeight:N.getTotalHeight(),actualHeight:N.getTotalHeight(),isCompressed:!1,compressionRatio:1,visibleRange:{start:0,end:0},renderRange:{start:0,end:0}},lastRenderRange:{start:-1,end:-1},isInitialized:!1,isDestroyed:!1,cachedCompression:null},v=new Map,Uj={selected:!1,focused:!1},xj=`${D}-item`,r="",z=new Map,Yj=()=>{z.clear();
|
|
87
|
+
for(let j=0;
|
|
88
|
+
j<B.length;
|
|
89
|
+
j++){let J=B[j];
|
|
90
|
+
if(J)z.set(J.id,j)}};
|
|
91
|
+
Yj();
|
|
92
|
+
let F=null,P=()=>F?F.getTotal():B.length,Bj=[],Gj=[],Wj=[],Dj=[],o=[],Vj=[],L=new Map,u=()=>{return $?_.viewport.scrollLeft:_.viewport.scrollTop},S=(j)=>{if($)_.viewport.scrollLeft=j;
|
|
93
|
+
else _.viewport.scrollTop=j},Cj=(j=2)=>{let J=N.getTotalHeight();
|
|
94
|
+
return O+R>=J-j},pj=!1,y,T,kj=(j,J,Z,q,W)=>{DJ(j,J,Z,q,W)},Xj=(j,J,Z,q,W)=>{return _J(j,J,Z,q,W)},_j=(j,J)=>{if(typeof J==="string")j.innerHTML=J;
|
|
95
|
+
else j.replaceChildren(J)},Lj=(j,J)=>{let Z=Math.round(N.getOffset(J));
|
|
96
|
+
if($)j.style.transform=`translateX(${Z}
|
|
97
|
+
px)`;
|
|
98
|
+
else j.style.transform=`translateY(${Z}
|
|
99
|
+
px)`},hj=(j,J)=>{let Z=e.acquire();
|
|
100
|
+
if(Z.className=xj,$){if(Z.style.width=`${N.getHeight(j)}
|
|
101
|
+
px`,yj!=null)Z.style.height=`${yj}
|
|
102
|
+
px`}
|
|
103
|
+
else Z.style.height=`${N.getHeight(j)}
|
|
104
|
+
px`;
|
|
105
|
+
return Z.dataset.index=String(j),Z.dataset.id=String(J.id),Z.ariaSelected="false",Z.id=`${Rj}-item-${j}`,r=String(P()),Z.setAttribute("aria-setsize",r),Z.setAttribute("aria-posinset",String(j+1)),_j(Z,t(J,j,Uj)),Lj(Z,j),Z},n=()=>{let j=`${N.getTotalHeight()}
|
|
106
|
+
px`;
|
|
107
|
+
if($)_.content.style.width=j;
|
|
108
|
+
else _.content.style.height=j},Nj=new Set,Mj=-1,gj=()=>{if(l)return;
|
|
109
|
+
let j=P();
|
|
110
|
+
if(kj(O,R,N,j,Jj),VJ(Jj,K,j,E),E.start===h.start&&E.end===h.end)return;
|
|
111
|
+
let J=String(j),Z=J!==r;
|
|
112
|
+
r=J;
|
|
113
|
+
for(let[G,A]of v)if(G<E.start||G>E.end)A.remove(),e.release(A),v.delete(G);
|
|
114
|
+
let q=document.createDocumentFragment(),W=[];
|
|
115
|
+
for(let G=E.start;
|
|
116
|
+
G<=E.end;
|
|
117
|
+
G++){let A=F?F.getItem(G):B[G];
|
|
118
|
+
if(!A)continue;
|
|
119
|
+
let b=v.get(G);
|
|
120
|
+
if(b){let w=b.dataset.id,Qj=String(A.id);
|
|
121
|
+
if(w!==Qj)if(_j(b,t(A,G,Uj)),b.dataset.id=Qj,$)b.style.width=`${N.getHeight(G)}
|
|
122
|
+
px`;
|
|
123
|
+
else b.style.height=`${N.getHeight(G)}
|
|
124
|
+
px`;
|
|
125
|
+
Lj(b,G);
|
|
126
|
+
let qj=Nj.has(A.id),$J=G===Mj;
|
|
127
|
+
if(b.classList.toggle(`${D}-item--selected`,qj),b.classList.toggle(`${D}-item--focused`,$J),b.ariaSelected=qj?"true":"false",Z)b.setAttribute("aria-setsize",r)}
|
|
128
|
+
else{let w=hj(G,A),Qj=Nj.has(A.id),qj=G===Mj;
|
|
129
|
+
if(Qj)w.classList.add(`${D}-item--selected`),w.ariaSelected="true";
|
|
130
|
+
if(qj)w.classList.add(`${D}-item--focused`);
|
|
131
|
+
q.appendChild(w),W.push({index:G,element:w})}}
|
|
132
|
+
if(W.length>0){_.items.appendChild(q);
|
|
133
|
+
for(let{index:G,element:A}
|
|
134
|
+
of W)v.set(G,A)}
|
|
135
|
+
h.start=E.start,h.end=E.end,H.lastRenderRange.start=E.start,H.lastRenderRange.end=E.end,H.viewportState.scrollTop=O,H.viewportState.visibleRange.start=Jj.start,H.viewportState.visibleRange.end=Jj.end,H.viewportState.renderRange.start=E.start,H.viewportState.renderRange.end=E.end,k.emit("range:change",{range:{start:E.start,end:E.end}})},mj=()=>{h.start=-1,h.end=-1,y()};
|
|
136
|
+
y=gj,T=mj;
|
|
137
|
+
let i=()=>{if(l)return;
|
|
138
|
+
let j=u(),J=j>=O?"down":"up";
|
|
139
|
+
if(I=UJ(I,j),!_.root.classList.contains(`${D}--scrolling`))_.root.classList.add(`${D}--scrolling`);
|
|
140
|
+
O=j,y(),k.emit("scroll",{scrollTop:j,direction:J}),k.emit("velocity:change",{velocity:I.velocity,reliable:I.sampleCount>=Oj});
|
|
141
|
+
for(let Z=0;
|
|
142
|
+
Z<Bj.length;
|
|
143
|
+
Z++)Bj[Z](j,J);
|
|
144
|
+
if(a)clearTimeout(a);
|
|
145
|
+
a=setTimeout(()=>{_.root.classList.remove(`${D}--scrolling`),I.velocity=0,I.sampleCount=0,k.emit("velocity:change",{velocity:0,reliable:!1})},Kj?.idleTimeout??150)},Zj=null,g=_.viewport;
|
|
146
|
+
if(g.addEventListener("scroll",i,{passive:!0}),$&&Ij)Zj=(j)=>{if(j.deltaX)return;
|
|
147
|
+
j.preventDefault(),_.viewport.scrollLeft+=j.deltaY},_.viewport.addEventListener("wheel",Zj);
|
|
148
|
+
_.viewport.classList.add(`${D}-viewport--custom-scrollbar`);
|
|
149
|
+
let zj=(j)=>{let Z=j.target.closest("[data-index]");
|
|
150
|
+
if(Z){let q=parseInt(Z.dataset.index??"-1",10);
|
|
151
|
+
if(q>=0){let W=F?.getItem(q)??B[q];
|
|
152
|
+
if(W){if(W.__groupHeader)return;
|
|
153
|
+
k.emit("item:click",{item:W,index:q,event:j})}}}
|
|
154
|
+
for(let q=0;
|
|
155
|
+
q<Gj.length;
|
|
156
|
+
q++)Gj[q](j)},cj=(j)=>{let Z=j.target.closest("[data-index]");
|
|
157
|
+
if(Z){let q=parseInt(Z.dataset.index??"-1",10);
|
|
158
|
+
if(q>=0){let W=F?.getItem(q)??B[q];
|
|
159
|
+
if(W){if(W.__groupHeader)return;
|
|
160
|
+
k.emit("item:dblclick",{item:W,index:q,event:j})}}}},Pj=(j)=>{for(let J=0;
|
|
161
|
+
J<Wj.length;
|
|
162
|
+
J++)Wj[J](j)};
|
|
163
|
+
_.items.addEventListener("click",zj),_.items.addEventListener("dblclick",cj),_.root.addEventListener("keydown",Pj);
|
|
164
|
+
let Aj=!0,dj=()=>jj,sj=()=>R,bj=new ResizeObserver((j)=>{if(l)return;
|
|
165
|
+
for(let J of j){let Z=J.contentRect.height,q=J.contentRect.width,W=$?q:Z;
|
|
166
|
+
if(jj=q,Math.abs(W-R)>1){if(R=W,H.viewportState.containerHeight=W,x)n(),y(),k.emit("resize",{height:Z,width:q})}
|
|
167
|
+
if(x)for(let G=0;
|
|
168
|
+
G<Dj.length;
|
|
169
|
+
G++)Dj[G](q,Z)}});
|
|
170
|
+
if(Aj)bj.observe(_.viewport);
|
|
171
|
+
let M={get dom(){return _},get heightCache(){return N},get emitter(){return k},get config(){return uj},get rawConfig(){return X},get renderer(){return{render:(j,J,Z,q,W)=>{Nj=Z,Mj=q,T()},updateItemClasses:(j,J,Z)=>{let q=v.get(j);
|
|
172
|
+
if(!q)return;
|
|
173
|
+
q.classList.toggle(`${D}-item--selected`,J),q.classList.toggle(`${D}-item--focused`,Z),q.ariaSelected=J?"true":"false"},updatePositions:()=>{},updateItem:()=>{},getElement:(j)=>v.get(j)??null,clear:()=>{},destroy:()=>{}}},set renderer(j){},get dataManager(){return F},set dataManager(j){F=j},get scrollController(){return Ej},set scrollController(j){Ej=j},state:H,getContainerWidth(){return jj},afterScroll:Bj,clickHandlers:Gj,keydownHandlers:Wj,resizeHandlers:Dj,contentSizeHandlers:o,destroyHandlers:Vj,methods:L,replaceTemplate(j){t=j},replaceRenderer(j){},replaceDataManager(j){F=j},replaceScrollController(j){Ej=j},getItemsForRange(j){let J=[];
|
|
174
|
+
for(let Z=j.start;
|
|
175
|
+
Z<=j.end;
|
|
176
|
+
Z++){let q=F?F.getItem(Z):B[Z];
|
|
177
|
+
if(q)J.push(q)}
|
|
178
|
+
return J},getAllLoadedItems(){if(F){let j=F.getTotal(),J=[];
|
|
179
|
+
for(let Z=0;
|
|
180
|
+
Z<j;
|
|
181
|
+
Z++){let q=F.getItem(Z);
|
|
182
|
+
if(q)J.push(q)}
|
|
183
|
+
return J}
|
|
184
|
+
return[...B]},getVirtualTotal(){return P()},getCachedCompression(){return{isCompressed:!1,actualHeight:N.getTotalHeight(),virtualHeight:N.getTotalHeight(),ratio:1}},getCompressionContext(){return{scrollTop:O,totalItems:P(),containerHeight:R,rangeStart:E.start}},renderIfNeeded(){y()},forceRender(){T()},getRenderFns(){return{renderIfNeeded:y,forceRender:T}},setRenderFns(j,J){y=j,T=J},setVirtualTotalFn(j){P=j},rebuildHeightCache(j){N.rebuild(j??P())},setHeightConfig(j){N=Sj(j,P())},updateContentSize(j){let J=`${j}
|
|
185
|
+
px`;
|
|
186
|
+
if($)_.content.style.width=J;
|
|
187
|
+
else _.content.style.height=J},updateCompressionMode(){},setVisibleRangeFn(j){kj=j},setScrollToPosFn(j){Xj=j},setPositionElementFn(j){Lj=j},setScrollFns(j,J){u=j,S=(Z)=>{J(Z),i()}},setScrollTarget(j){g.removeEventListener("scroll",i),g=j,g.addEventListener("scroll",i,{passive:!0})},getScrollTarget(){return g},setContainerDimensions(j){dj=j.width,sj=j.height,jj=j.width(),R=j.height(),H.viewportState.containerHeight=R},disableViewportResize(){if(Aj)Aj=!1,bj.unobserve(_.viewport)}};
|
|
188
|
+
F={getState:()=>({total:B.length,cached:B.length,isLoading:!1,pendingRanges:[],error:void 0,hasMore:!1,cursor:void 0}),getTotal:()=>B.length,getCached:()=>B.length,getIsLoading:()=>!1,getHasMore:()=>!1,getStorage:()=>null,getPlaceholders:()=>null,getItem:(j)=>B[j],getItemById:(j)=>{let J=z.get(j);
|
|
189
|
+
return J!==void 0?B[J]:void 0},getIndexById:(j)=>z.get(j)??-1,isItemLoaded:(j)=>j>=0&&j<B.length&&B[j]!==void 0,getItemsInRange:(j,J)=>{let Z=[],q=Math.max(0,j),W=Math.min(J,B.length-1);
|
|
190
|
+
for(let G=q;
|
|
191
|
+
G<=W;
|
|
192
|
+
G++)Z.push(B[G]);
|
|
193
|
+
return Z},setTotal:(j)=>{},setItems:(j,J=0,Z)=>{if(J===0&&(Z!==void 0||B.length===0))B=[...j];
|
|
194
|
+
else{let q=J+j.length;
|
|
195
|
+
if(B.length<q)B.length=q;
|
|
196
|
+
for(let W=0;
|
|
197
|
+
W<j.length;
|
|
198
|
+
W++)B[J+W]=j[W]}
|
|
199
|
+
if(Yj(),x){N.rebuild(P()),n(),M.updateCompressionMode();
|
|
200
|
+
for(let q=0;
|
|
201
|
+
q<o.length;
|
|
202
|
+
q++)o[q]();
|
|
203
|
+
T()}},updateItem:(j,J)=>{let Z=z.get(j);
|
|
204
|
+
if(Z===void 0)return!1;
|
|
205
|
+
let q=B[Z];
|
|
206
|
+
if(!q)return!1;
|
|
207
|
+
if(B[Z]={...q,...J},J.id!==void 0&&J.id!==j)z.delete(j),z.set(J.id,Z);
|
|
208
|
+
let W=v.get(Z);
|
|
209
|
+
if(W)_j(W,t(B[Z],Z,Uj)),W.dataset.id=String(B[Z].id);
|
|
210
|
+
return!0},removeItem:(j)=>{let J=z.get(j);
|
|
211
|
+
if(J===void 0)return!1;
|
|
212
|
+
if(B.splice(J,1),Yj(),x){N.rebuild(P()),n(),M.updateCompressionMode();
|
|
213
|
+
for(let Z=0;
|
|
214
|
+
Z<o.length;
|
|
215
|
+
Z++)o[Z]();
|
|
216
|
+
T()}
|
|
217
|
+
return!0},loadRange:async()=>{},ensureRange:async()=>{},loadInitial:async()=>{},loadMore:async()=>!1,reload:async()=>{},evictDistant:()=>{},clear:()=>{B=[],z.clear()},reset:()=>{if(B=[],z.clear(),x)N.rebuild(0),n(),T()}};
|
|
218
|
+
let Ej={getScrollTop:()=>u(),scrollTo:(j)=>{S(j),O=j,y()},scrollBy:(j)=>{let J=u()+j;
|
|
219
|
+
S(J),O=J,y()},isAtTop:()=>O<=2,isAtBottom:(j=2)=>Cj(j),getScrollPercentage:()=>{let j=N.getTotalHeight(),J=Math.max(0,j-R);
|
|
220
|
+
return J>0?O/J:0},getVelocity:()=>I.velocity,isTracking:()=>I.sampleCount>=Oj,isScrolling:()=>_.root.classList.contains(`${D}--scrolling`),updateConfig:()=>{},enableCompression:()=>{},disableCompression:()=>{},isCompressed:()=>pj,isWindowMode:()=>!1,updateContainerHeight:(j)=>{R=j},destroy:()=>{}},Hj=new Map;
|
|
221
|
+
for(let j of d)if(j.methods)for(let J of j.methods){let Z=Hj.get(J);
|
|
222
|
+
if(Z)throw Error(`[vlist/builder] Method "${J}" is registered by both "${Z}" and "${j.name}"`);
|
|
223
|
+
Hj.set(J,j.name)}
|
|
224
|
+
for(let j of d)j.setup(M);
|
|
225
|
+
if(x=!0,M.state.isInitialized=!0,n(),y(),c&&B.length>0){let j=Xj(B.length-1,N,R,B.length,"end");
|
|
226
|
+
S(j),O=j,y()}
|
|
227
|
+
let lj=(j)=>{M.dataManager.setItems(j,0,j.length)},aj=c?(j)=>{let J=Cj(2),Z=B.length;
|
|
228
|
+
if(M.dataManager.setItems(j,Z),J&&B.length>0){let q=Xj(B.length-1,N,R,B.length,"end");
|
|
229
|
+
S(q),O=q,y()}}:(j)=>{let J=B.length;
|
|
230
|
+
M.dataManager.setItems(j,J)},rj=c?(j)=>{let J=u(),Z=N.getTotalHeight(),q=[...B];
|
|
231
|
+
M.dataManager.clear(),M.dataManager.setItems([...j,...q],0);
|
|
232
|
+
let G=N.getTotalHeight()-Z;
|
|
233
|
+
if(G>0)S(J+G),O=J+G}:(j)=>{let J=[...B];
|
|
234
|
+
M.dataManager.clear(),M.dataManager.setItems([...j,...J],0)},oj=(j,J)=>{M.dataManager.updateItem(j,J)},nj=(j)=>{M.dataManager.removeItem(j)},ij=async()=>{if(M.dataManager.reload)await M.dataManager.reload()},$j=()=>{if(p!==null)cancelAnimationFrame(p),p=null},tj=(j,J,Z)=>{if($j(),Math.abs(J-j)<1){S(J),O=J,y();
|
|
235
|
+
return}
|
|
236
|
+
let q=performance.now(),W=(G)=>{let A=G-q,b=Math.min(A/Z,1),w=j+(J-j)*LJ(b);
|
|
237
|
+
if(S(w),O=w,y(),b<1)p=requestAnimationFrame(W);
|
|
238
|
+
else p=null};
|
|
239
|
+
p=requestAnimationFrame(W)},wj=(j,J)=>{let{align:Z,behavior:q,duration:W}=NJ(J),G=P(),A=j;
|
|
240
|
+
if(Fj&&G>0)A=(A%G+G)%G;
|
|
241
|
+
let b=Xj(A,N,R,G,Z);
|
|
242
|
+
if(q==="smooth")tj(u(),b,W);
|
|
243
|
+
else $j(),S(b)},ej=(j,J)=>{let Z=z.get(j)??M.dataManager.getIndexById(j);
|
|
244
|
+
if(Z>=0)wj(Z,J)},jJ=()=>u(),JJ=(j,J)=>{return k.on(j,J)},XJ=(j,J)=>{k.off(j,J)},ZJ=()=>{if(l)return;
|
|
245
|
+
if(l=!0,M.state.isDestroyed=!0,_.items.removeEventListener("click",zj),_.root.removeEventListener("keydown",Pj),g.removeEventListener("scroll",i),bj.disconnect(),Zj)_.viewport.removeEventListener("wheel",Zj);
|
|
246
|
+
if(a)clearTimeout(a);
|
|
247
|
+
for(let j=0;
|
|
248
|
+
j<Vj.length;
|
|
249
|
+
j++)Vj[j]();
|
|
250
|
+
for(let j of d)if(j.destroy)j.destroy();
|
|
251
|
+
$j();
|
|
252
|
+
for(let[,j]of v)j.remove(),e.release(j);
|
|
253
|
+
v.clear(),e.clear(),k.clear(),_.root.remove()},vj={get element(){return _.root},get items(){if(L.has("_getItems"))return L.get("_getItems")();
|
|
254
|
+
return B},get total(){if(L.has("_getTotal"))return L.get("_getTotal")();
|
|
255
|
+
return P()},setItems:L.has("setItems")?L.get("setItems"):lj,appendItems:L.has("appendItems")?L.get("appendItems"):aj,prependItems:L.has("prependItems")?L.get("prependItems"):rj,updateItem:L.has("updateItem")?L.get("updateItem"):oj,removeItem:L.has("removeItem")?L.get("removeItem"):nj,reload:L.has("reload")?L.get("reload"):ij,scrollToIndex:L.has("scrollToIndex")?L.get("scrollToIndex"):wj,scrollToItem:L.has("scrollToItem")?L.get("scrollToItem"):ej,cancelScroll:L.has("cancelScroll")?L.get("cancelScroll"):$j,getScrollPosition:L.has("getScrollPosition")?L.get("getScrollPosition"):jJ,on:JJ,off:XJ,destroy:ZJ};
|
|
256
|
+
for(let[j,J]of L){if(j==="setItems"||j==="appendItems"||j==="prependItems"||j==="updateItem"||j==="removeItem"||j==="reload"||j==="scrollToIndex"||j==="scrollToItem"||j==="cancelScroll"||j==="getScrollPosition")continue;
|
|
257
|
+
vj[j]=J}
|
|
258
|
+
return vj}
|
|
259
|
+
export{MJ as vlist};
|
|
@@ -1 +1,116 @@
|
|
|
1
|
-
var F=16000000;
|
|
1
|
+
var F=16000000;
|
|
2
|
+
var Ny=(j,K,J,y)=>{if(y===0)return 0;
|
|
3
|
+
if(!j.isVariable())return Math.ceil(J/j.getHeight(0));
|
|
4
|
+
let N=0,Q=0,q=K;
|
|
5
|
+
while(q<y&&Q<J)Q+=j.getHeight(q),N++,q++;
|
|
6
|
+
return Math.max(1,N)},n=(j,K,J)=>{if(J===0)return 0;
|
|
7
|
+
if(!j.isVariable())return Math.floor(K/j.getHeight(0));
|
|
8
|
+
let y=0,N=0;
|
|
9
|
+
for(let Q=J-1;
|
|
10
|
+
Q>=0;
|
|
11
|
+
Q--){let q=j.getHeight(Q);
|
|
12
|
+
if(N+q>K)break;
|
|
13
|
+
N+=q,y++}
|
|
14
|
+
return Math.max(y,1)},l=(j,K,J)=>{if(J===0)return 0;
|
|
15
|
+
let y=Math.floor(K),N=K-y,Q=Math.max(0,Math.min(y,J-1));
|
|
16
|
+
return j.getOffset(Q)+N*j.getHeight(Q)};
|
|
17
|
+
var w=(j,K)=>{let J=K.getTotalHeight(),y=J>F,N=y?F:J,Q=J>0?N/J:1;
|
|
18
|
+
return{isCompressed:y,actualHeight:J,virtualHeight:N,ratio:Q}},c=(j,K,J,y,N,Q)=>{if(y===0||K===0)return Q.start=0,Q.end=-1,Q;
|
|
19
|
+
if(!N.isCompressed){let X=J.indexAtOffset(j),$=J.indexAtOffset(j+K);
|
|
20
|
+
if($<y-1)$++;
|
|
21
|
+
return Q.start=Math.max(0,X),Q.end=Math.min(y-1,Math.max(0,$)),Q}
|
|
22
|
+
let{virtualHeight:q}=N,B=j/q*y,E=Math.floor(B),L=Ny(J,Math.max(0,E),K,y),Y=Math.ceil(B)+L,G=q-K-j;
|
|
23
|
+
if(G<=K&&G>=-1){let X=n(J,K,y),$=Math.max(0,y-X),D=Math.max(0,Math.min(1,1-G/K));
|
|
24
|
+
E=Math.floor(E+($-E)*D),Y=G<=1?y-1:Math.min(y-1,E+L)}
|
|
25
|
+
return Q.start=Math.max(0,E),Q.end=Math.min(y-1,Math.max(0,Y)),Q},Gy=(j,K,J,y)=>{if(J===0)return y.start=0,y.end=-1,y;
|
|
26
|
+
return y.start=Math.max(0,j.start-K),y.end=Math.min(J-1,j.end+K),y},r=(j,K,J,y,N,Q,q)=>{if(!Q.isCompressed||y===0)return J.getOffset(j);
|
|
27
|
+
let{virtualHeight:V}=Q,B=V-N,E=B-K;
|
|
28
|
+
if(E<=N&&E>=-1){if(K>=B-1){let b=J.getTotalHeight()-J.getOffset(j);
|
|
29
|
+
return N-b}
|
|
30
|
+
let W=n(J,N,y),G=Math.max(0,y-W),$=K/V*y,D=Math.max(0,Math.min(1,1-E/N)),z=J.getOffset(j)-J.getOffset(G),M=J.getOffset(j)-l(J,$,y);
|
|
31
|
+
return M+(z-M)*D}
|
|
32
|
+
let Y=K/V*y;
|
|
33
|
+
return J.getOffset(j)-l(J,Y,y)},a=(j,K,J,y,N,Q="start")=>{if(y===0)return 0;
|
|
34
|
+
let q;
|
|
35
|
+
if(N.isCompressed){if(Q==="end"&&j===y-1)return Math.max(0,N.virtualHeight-J);
|
|
36
|
+
q=j/y*N.virtualHeight}
|
|
37
|
+
else q=K.getOffset(j);
|
|
38
|
+
let V=K.getHeight(j);
|
|
39
|
+
switch(Q){case"center":q-=(J-V)/2;
|
|
40
|
+
break;
|
|
41
|
+
case"end":q-=J-V;
|
|
42
|
+
break}
|
|
43
|
+
let B=N.virtualHeight-J;
|
|
44
|
+
return Math.max(0,Math.min(q,B))},Uy=(j,K,J,y)=>{if(J===0)return 0;
|
|
45
|
+
if(y.isCompressed){let N=j/y.virtualHeight;
|
|
46
|
+
return Math.floor(N*J)}
|
|
47
|
+
return K.indexAtOffset(j)},Dy=(j,K)=>{if(typeof K==="number")return j*K>F;
|
|
48
|
+
return K.getTotalHeight()>F},_y=(j)=>{if(j<=0)return 0;
|
|
49
|
+
return Math.floor(F/j)},Ey=(j,K)=>{let J=w(j,K);
|
|
50
|
+
if(!J.isCompressed)return`No compression needed (${j} items, ${(J.actualHeight/1e6).toFixed(2)}
|
|
51
|
+
M px)`;
|
|
52
|
+
return`Compressed to ${(J.ratio*100).toFixed(1)}% (${j} items, ${(J.actualHeight/1e6).toFixed(1)}
|
|
53
|
+
M px → ${(J.virtualHeight/1e6).toFixed(1)}
|
|
54
|
+
M px virtual)`};
|
|
55
|
+
var i=(j,K,J={},y="vlist",N=!1)=>{let{autoHide:Q=!0,autoHideDelay:q=1000,minThumbSize:V=30,showOnHover:B=!0,hoverZoneWidth:E=16,showOnViewportEnter:L=!0}=J,Y=0,W=0,G=0,X=0,$=!1,D=!1,z=0,M=0,b=0,f=null,T=!1,Z=null,P=null,Qy=N?"width":"height",o=N?"translateX":"translateY",u=N?(_)=>_.clientX:(_)=>_.clientY,Yy=N?"left":"top",U=document.createElement("div"),R=document.createElement("div"),O=B?document.createElement("div"):null,$y=()=>{if(U.className=`${y}-scrollbar`,R.className=`${y}-scrollbar-thumb`,N)U.classList.add(`${y}-scrollbar--horizontal`);
|
|
56
|
+
if(U.appendChild(R),j.appendChild(U),O){if(O.className=`${y}-scrollbar-hover`,N)O.classList.add(`${y}-scrollbar-hover--horizontal`),O.style.height=`${E}
|
|
57
|
+
px`;
|
|
58
|
+
else O.style.width=`${E}
|
|
59
|
+
px`;
|
|
60
|
+
j.appendChild(O)}},S=()=>{if(f)clearTimeout(f),f=null},v=()=>{if(!Q)return;
|
|
61
|
+
S(),f=setTimeout(d,q)},H=()=>{if(Y<=W)return;
|
|
62
|
+
if(S(),!T)U.classList.add(`${y}-scrollbar--visible`),T=!0;
|
|
63
|
+
if(Q&&!$&&!D)v()},d=()=>{if($||D)return;
|
|
64
|
+
U.classList.remove(`${y}-scrollbar--visible`),T=!1},Wy=(_,A)=>{Y=_,W=A;
|
|
65
|
+
let C=Y>W;
|
|
66
|
+
if(U.style.display=C?"":"none",!C){d();
|
|
67
|
+
return}
|
|
68
|
+
let k=W/Y;
|
|
69
|
+
G=Math.max(V,k*W),R.style[Qy]=`${G}
|
|
70
|
+
px`,X=W-G,e(b)},e=(_)=>{if(b=_,Y<=W||X<=0)return;
|
|
71
|
+
let A=Y-W,k=Math.min(1,Math.max(0,_/A))*X;
|
|
72
|
+
R.style.transform=`${o}(${k}
|
|
73
|
+
px)`},t=(_)=>{if(_.target===R)return;
|
|
74
|
+
let A=U.getBoundingClientRect(),m=u(_)-A[Yy]-G/2,Ky=Math.max(0,Math.min(m,X))/X,h=Y-W,qy=Ky*h;
|
|
75
|
+
K(qy),H()},yy=(_)=>{_.preventDefault(),_.stopPropagation(),$=!0,z=u(_),M=b,S(),U.classList.add(`${y}-scrollbar--dragging`),document.addEventListener("mousemove",x),document.addEventListener("mouseup",g)},x=(_)=>{if(!$)return;
|
|
76
|
+
let A=u(_)-z,C=X>0?A/X:0,k=Y-W,m=C*k,s=Math.max(0,Math.min(M+m,k)),h=s/k*X;
|
|
77
|
+
if(R.style.transform=`${o}(${h}
|
|
78
|
+
px)`,P=s,Z===null)Z=requestAnimationFrame(()=>{if(P!==null)K(P);
|
|
79
|
+
Z=null})},g=()=>{if($=!1,Z!==null)cancelAnimationFrame(Z),Z=null;
|
|
80
|
+
if(P!==null)K(P),P=null;
|
|
81
|
+
if(U.classList.remove(`${y}-scrollbar--dragging`),Q&&!D)v();
|
|
82
|
+
document.removeEventListener("mousemove",x),document.removeEventListener("mouseup",g)},jy=()=>{if(L)H()},Jy=()=>{if(!$){if(D=!1,Q)v()}},p=()=>{D=!0,S(),H()},I=()=>{if(D=!1,!$&&Q)v()},Xy=()=>{if(S(),Z!==null)cancelAnimationFrame(Z),Z=null;
|
|
83
|
+
if(U.removeEventListener("click",t),U.removeEventListener("mouseenter",p),U.removeEventListener("mouseleave",I),R.removeEventListener("mousedown",yy),j.removeEventListener("mouseenter",jy),j.removeEventListener("mouseleave",Jy),document.removeEventListener("mousemove",x),document.removeEventListener("mouseup",g),O){if(O.removeEventListener("mouseenter",p),O.removeEventListener("mouseleave",I),O.parentNode)O.parentNode.removeChild(O)}
|
|
84
|
+
if(U.parentNode)U.parentNode.removeChild(U)};
|
|
85
|
+
if($y(),U.addEventListener("click",t),U.addEventListener("mouseenter",p),U.addEventListener("mouseleave",I),R.addEventListener("mousedown",yy),j.addEventListener("mouseenter",jy),j.addEventListener("mouseleave",Jy),O)O.addEventListener("mouseenter",p),O.addEventListener("mouseleave",I);
|
|
86
|
+
return{show:H,hide:d,updateBounds:Wy,updatePosition:e,isVisible:()=>T,destroy:Xy}};
|
|
87
|
+
var Ly=()=>{let j=null,K=0,J=!1;
|
|
88
|
+
return{name:"withCompression",priority:20,setup(y){let{dom:N,config:Q}=y,{classPrefix:q,horizontal:V}=Q,B=()=>{let L=y.getVirtualTotal(),Y=w(L,y.heightCache);
|
|
89
|
+
if(Y.isCompressed&&!J){J=!0,y.scrollController.enableCompression(Y),y.updateContentSize(Y.virtualHeight),y.setScrollFns(()=>K,($)=>{K=$});
|
|
90
|
+
let W=N.viewport,G=($)=>{$.preventDefault();
|
|
91
|
+
let D=Y.virtualHeight-y.state.viewportState.containerHeight;
|
|
92
|
+
K=Math.max(0,Math.min(K+$.deltaY,D)),y.scrollController.scrollTo(K)};
|
|
93
|
+
if(W.addEventListener("wheel",G,{passive:!1}),y.destroyHandlers.push(()=>{W.removeEventListener("wheel",G)}),!N.viewport.querySelector(`.${q}-scrollbar-track`)){if(j=i(N.viewport,(D)=>y.scrollController.scrollTo(D),{},q,V),!N.viewport.classList.contains(`${q}-viewport--custom-scrollbar`))N.viewport.classList.add(`${q}-viewport--custom-scrollbar`);
|
|
94
|
+
j.updateBounds(Y.virtualHeight,y.state.viewportState.containerHeight);
|
|
95
|
+
let $=j;
|
|
96
|
+
y.afterScroll.push((D,z)=>{if($)$.updatePosition(D),$.show()}),y.resizeHandlers.push((D,z)=>{if($){let M=y.getCachedCompression();
|
|
97
|
+
$.updateBounds(M.virtualHeight,y.state.viewportState.containerHeight)}})}}
|
|
98
|
+
else if(!Y.isCompressed&&J)J=!1,y.scrollController.disableCompression(),y.updateContentSize(Y.actualHeight);
|
|
99
|
+
else if(Y.isCompressed)y.scrollController.updateConfig({compression:Y}),y.updateContentSize(Y.virtualHeight);
|
|
100
|
+
if(j)j.updateBounds(Y.virtualHeight,y.state.viewportState.containerHeight);
|
|
101
|
+
y.state.cachedCompression={state:Y,totalItems:L}};
|
|
102
|
+
y.updateCompressionMode=B;
|
|
103
|
+
let E=y.getCachedCompression.bind(y);
|
|
104
|
+
y.getCachedCompression=()=>{if(y.state.cachedCompression)return y.state.cachedCompression.state;
|
|
105
|
+
return E()},y.setVisibleRangeFn((L,Y,W,G,X)=>{let $=w(G,W);
|
|
106
|
+
c(L,Y,W,G,$,X)}),y.setScrollToPosFn((L,Y,W,G,X)=>{let $=w(G,Y);
|
|
107
|
+
return a(L,Y,W,G,$,X)}),y.setPositionElementFn((L,Y)=>{let W=y.getVirtualTotal(),G=w(W,y.heightCache);
|
|
108
|
+
if(G.isCompressed){let X=Math.round(r(Y,y.scrollController.getScrollTop(),y.heightCache,W,y.state.viewportState.containerHeight,G)),$=y.config.horizontal;
|
|
109
|
+
L.style.transform=$?`translateX(${X}
|
|
110
|
+
px)`:`translateY(${X}
|
|
111
|
+
px)`}
|
|
112
|
+
else{let X=Math.round(y.heightCache.getOffset(Y)),$=y.config.horizontal;
|
|
113
|
+
L.style.transform=$?`translateX(${X}
|
|
114
|
+
px)`:`translateY(${X}
|
|
115
|
+
px)`}}),B(),y.destroyHandlers.push(()=>{if(j)j.destroy(),j=null})},destroy(){if(j)j.destroy(),j=null}}};
|
|
116
|
+
export{Ly as withCompression,Dy as needsCompression,_y as getMaxItemsWithoutCompression,w as getCompressionState,Ey as getCompressionInfo,Uy as calculateIndexFromScrollPosition,c as calculateCompressedVisibleRange,a as calculateCompressedScrollToIndex,Gy as calculateCompressedRenderRange,r as calculateCompressedItemPosition,F as MAX_VIRTUAL_HEIGHT};
|
package/dist/core/index.js
CHANGED
|
@@ -1 +1,137 @@
|
|
|
1
|
-
var Yj=(B,X)=>{if(typeof B==="number"){let q=X;
|
|
1
|
+
var Yj=(B,X)=>{if(typeof B==="number"){let q=X;
|
|
2
|
+
return{getOffset:(J)=>J*B,getHeight:()=>B,indexAtOffset:(J)=>{if(q===0||B===0)return 0;
|
|
3
|
+
return Math.max(0,Math.min(Math.floor(J/B),q-1))},getTotalHeight:()=>q*B,getTotal:()=>q,rebuild:(J)=>{q=J}}}
|
|
4
|
+
let Y=X,U=new Float64Array(0),$=(q)=>{Y=q,U=new Float64Array(q+1),U[0]=0;
|
|
5
|
+
for(let J=0;
|
|
6
|
+
J<q;
|
|
7
|
+
J++)U[J+1]=U[J]+B(J)};
|
|
8
|
+
return $(X),{getOffset:(q)=>{if(q<=0)return 0;
|
|
9
|
+
if(q>=Y)return U[Y];
|
|
10
|
+
return U[q]},getHeight:(q)=>B(q),indexAtOffset:(q)=>{if(Y===0)return 0;
|
|
11
|
+
if(q<=0)return 0;
|
|
12
|
+
if(q>=U[Y])return Y-1;
|
|
13
|
+
let J=0,F=Y-1;
|
|
14
|
+
while(J<F){let N=J+F+1>>>1;
|
|
15
|
+
if(U[N]<=q)J=N;
|
|
16
|
+
else F=N-1}
|
|
17
|
+
return J},getTotalHeight:()=>U[Y]??0,getTotal:()=>Y,rebuild:(q)=>$(q)}},Zj=()=>{let B={},X=(q,J)=>{if(!B[q])B[q]=new Set;
|
|
18
|
+
return B[q].add(J),()=>Y(q,J)},Y=(q,J)=>{B[q]?.delete(J)};
|
|
19
|
+
return{on:X,off:Y,emit:(q,J)=>{B[q]?.forEach((F)=>{try{F(J)}
|
|
20
|
+
catch(N){console.error(`[vlist] Error in "${q}" handler:`,N)}})},clear:()=>{for(let q in B)delete B[q]}}},_j=(B)=>{if(typeof B==="string"){let X=document.querySelector(B);
|
|
21
|
+
if(!X)throw Error(`[vlist] Container not found: ${B}`);
|
|
22
|
+
return X}
|
|
23
|
+
return B},$j=(B,X,Y)=>{let U=document.createElement("div");
|
|
24
|
+
if(U.className=X,U.setAttribute("role","listbox"),U.setAttribute("tabindex","0"),Y)U.setAttribute("aria-label",Y);
|
|
25
|
+
let $=document.createElement("div");
|
|
26
|
+
$.className=`${X}-viewport`,$.style.overflow="auto",$.style.height="100%",$.style.width="100%";
|
|
27
|
+
let q=document.createElement("div");
|
|
28
|
+
q.className=`${X}-content`,q.style.position="relative",q.style.width="100%";
|
|
29
|
+
let J=document.createElement("div");
|
|
30
|
+
return J.className=`${X}-items`,J.style.position="relative",J.style.width="100%",q.appendChild(J),$.appendChild(q),U.appendChild($),B.appendChild(U),{root:U,viewport:$,content:q,items:J}},Qj=(B=100)=>{let X=[];
|
|
31
|
+
return{acquire:()=>{let q=X.pop();
|
|
32
|
+
if(q)return q;
|
|
33
|
+
let J=document.createElement("div");
|
|
34
|
+
return J.setAttribute("role","option"),J},release:(q)=>{if(X.length<B)q.className="",q.textContent="",q.removeAttribute("style"),q.removeAttribute("data-index"),q.removeAttribute("data-id"),X.push(q)},clear:()=>{X.length=0}}},Vj=(B,X,Y,U,$)=>{if(U===0){$.start=0,$.end=0;
|
|
35
|
+
return}
|
|
36
|
+
let q=Y.indexAtOffset(B),J=q,F=Y.getOffset(q)-B;
|
|
37
|
+
while(J<U-1&&F<X)F+=Y.getHeight(J),J++;
|
|
38
|
+
$.start=q,$.end=Math.min(J,U-1)},Lj=(B,X,Y,U)=>{U.start=Math.max(0,B.start-X),U.end=Math.min(Y-1,B.end+X)},kj=(B,X,Y,U,$)=>{if(U===0)return 0;
|
|
39
|
+
let q=Math.max(0,Math.min(B,U-1)),J=X.getOffset(q),F=X.getHeight(q),N=Math.max(0,X.getTotalHeight()-Y),k;
|
|
40
|
+
switch($){case"center":k=J-(Y-F)/2;
|
|
41
|
+
break;
|
|
42
|
+
case"end":k=J-Y+F;
|
|
43
|
+
break;
|
|
44
|
+
default:k=J}
|
|
45
|
+
return Math.max(0,Math.min(k,N))},Fj=(B)=>B<0.5?2*B*B:-1+(4-2*B)*B,Nj=0,Aj=(B)=>{if(!B.container)throw Error("[vlist] container is required");
|
|
46
|
+
if(!B.item)throw Error("[vlist] item configuration is required");
|
|
47
|
+
if(B.item.height==null)throw Error("[vlist] item.height is required");
|
|
48
|
+
if(typeof B.item.height==="number"&&B.item.height<=0)throw Error("[vlist] item.height must be positive");
|
|
49
|
+
if(typeof B.item.height!=="number"&&typeof B.item.height!=="function")throw Error("[vlist] item.height must be a number or (index) => number");
|
|
50
|
+
if(!B.item.template)throw Error("[vlist] item.template is required");
|
|
51
|
+
let{item:X,items:Y,overscan:U=3,classPrefix:$="vlist",scrollElement:q,ariaLabel:J}=B,{height:F,template:N}=X,k=!!q,_=Y?[...Y]:[],y=!1,R=null,D=0,l=`${$}-${Nj++}`,o=_j(B.container),V=$j(o,$,J),W=Zj(),A=Yj(F,_.length),I=Qj();
|
|
52
|
+
if(k)V.root.style.overflow="visible",V.root.style.height="auto",V.viewport.style.overflow="visible",V.viewport.style.height="auto";
|
|
53
|
+
let E=k?window.innerHeight:V.viewport.clientHeight,h={start:0,end:0},M={start:0,end:0},C={start:-1,end:-1},b=new Map,f={selected:!1,focused:!1},n=`${$}-item`,T="",p=(j,K)=>{if(typeof K==="string")j.innerHTML=K;
|
|
54
|
+
else j.replaceChildren(K)},c=(j,K)=>{j.style.transform=`translateY(${Math.round(A.getOffset(K))}
|
|
55
|
+
px)`},i=(j,K)=>{let G=I.acquire();
|
|
56
|
+
return G.className=n,G.style.height=`${A.getHeight(j)}
|
|
57
|
+
px`,G.dataset.index=String(j),G.dataset.id=String(K.id),G.ariaSelected="false",G.id=`${l}-item-${j}`,T=String(_.length),G.setAttribute("aria-setsize",T),G.setAttribute("aria-posinset",String(j+1)),p(G,N(K,j,f)),c(G,j),G},v=()=>{V.content.style.height=`${A.getTotalHeight()}
|
|
58
|
+
px`},P=()=>{if(y)return;
|
|
59
|
+
if(Vj(D,E,A,_.length,h),Lj(h,U,_.length,M),M.start===C.start&&M.end===C.end)return;
|
|
60
|
+
let j=String(_.length),K=j!==T;
|
|
61
|
+
T=j;
|
|
62
|
+
for(let[Z,L]of b)if(Z<M.start||Z>M.end)L.remove(),I.release(L),b.delete(Z);
|
|
63
|
+
let G=document.createDocumentFragment(),Q=[];
|
|
64
|
+
for(let Z=M.start;
|
|
65
|
+
Z<=M.end;
|
|
66
|
+
Z++){let L=_[Z];
|
|
67
|
+
if(!L)continue;
|
|
68
|
+
let z=b.get(Z);
|
|
69
|
+
if(z){let H=z.dataset.id,w=String(L.id);
|
|
70
|
+
if(H!==w)p(z,N(L,Z,f)),z.dataset.id=w,z.style.height=`${A.getHeight(Z)}
|
|
71
|
+
px`;
|
|
72
|
+
if(c(z,Z),K)z.setAttribute("aria-setsize",T)}
|
|
73
|
+
else{let H=i(Z,L);
|
|
74
|
+
G.appendChild(H),Q.push({index:Z,element:H})}}
|
|
75
|
+
if(Q.length>0){V.items.appendChild(G);
|
|
76
|
+
for(let{index:Z,element:L}
|
|
77
|
+
of Q)b.set(Z,L)}
|
|
78
|
+
C.start=M.start,C.end=M.end,W.emit("range:change",{range:{start:M.start,end:M.end}})},t=()=>{C.start=-1,C.end=-1,P()},O=null,m=()=>{if(y)return;
|
|
79
|
+
let j=k?Math.max(0,q.scrollY-V.viewport.getBoundingClientRect().top-q.scrollY+window.scrollY):V.viewport.scrollTop,K=k?Math.max(0,q.scrollY+V.viewport.getBoundingClientRect().top*-1):j,G=K>=D?"down":"up";
|
|
80
|
+
if(!V.root.classList.contains(`${$}--scrolling`))V.root.classList.add(`${$}--scrolling`);
|
|
81
|
+
if(D=K,P(),W.emit("scroll",{scrollTop:K,direction:G}),O)clearTimeout(O);
|
|
82
|
+
O=setTimeout(()=>{V.root.classList.remove(`${$}--scrolling`)},150)},d=k?q:V.viewport;
|
|
83
|
+
d.addEventListener("scroll",m,{passive:!0});
|
|
84
|
+
let s=(j)=>{if(y)return;
|
|
85
|
+
let G=j.target.closest("[data-index]");
|
|
86
|
+
if(!G)return;
|
|
87
|
+
let Q=parseInt(G.dataset.index??"-1",10);
|
|
88
|
+
if(Q<0)return;
|
|
89
|
+
let Z=_[Q];
|
|
90
|
+
if(!Z)return;
|
|
91
|
+
W.emit("item:click",{item:Z,index:Q,event:j})},e=(j)=>{if(y)return;
|
|
92
|
+
let G=j.target.closest("[data-index]");
|
|
93
|
+
if(!G)return;
|
|
94
|
+
let Q=parseInt(G.dataset.index??"-1",10);
|
|
95
|
+
if(Q<0)return;
|
|
96
|
+
let Z=_[Q];
|
|
97
|
+
if(!Z)return;
|
|
98
|
+
W.emit("item:dblclick",{item:Z,index:Q,event:j})};
|
|
99
|
+
V.items.addEventListener("click",s),V.items.addEventListener("dblclick",e);
|
|
100
|
+
let a=new ResizeObserver((j)=>{if(y||k)return;
|
|
101
|
+
for(let K of j){let G=K.contentRect.height;
|
|
102
|
+
if(Math.abs(G-E)>1)E=G,v(),P(),W.emit("resize",{height:G,width:K.contentRect.width})}});
|
|
103
|
+
a.observe(V.viewport);
|
|
104
|
+
let u=null;
|
|
105
|
+
if(k)u=()=>{if(y)return;
|
|
106
|
+
let j=window.innerHeight;
|
|
107
|
+
if(Math.abs(j-E)>1)E=j,v(),P(),W.emit("resize",{height:j,width:window.innerWidth})},window.addEventListener("resize",u);
|
|
108
|
+
let S=()=>{if(R!==null)cancelAnimationFrame(R),R=null},jj=(j)=>{if(typeof j==="string")return{align:j,behavior:"auto",duration:300};
|
|
109
|
+
if(j&&typeof j==="object")return{align:j.align??"start",behavior:j.behavior??"auto",duration:j.duration??300};
|
|
110
|
+
return{align:"start",behavior:"auto",duration:300}},g=(j)=>{if(k){let G=V.viewport.getBoundingClientRect().top+window.scrollY;
|
|
111
|
+
q.scrollTo(0,G+j)}
|
|
112
|
+
else V.viewport.scrollTop=j},qj=(j,K,G)=>{if(S(),Math.abs(K-j)<1){g(K),D=K,P();
|
|
113
|
+
return}
|
|
114
|
+
let Q=performance.now(),Z=(L)=>{let z=L-Q,H=Math.min(z/G,1),w=j+(K-j)*Fj(H);
|
|
115
|
+
if(g(w),D=w,P(),H<1)R=requestAnimationFrame(Z);
|
|
116
|
+
else R=null};
|
|
117
|
+
R=requestAnimationFrame(Z)},r=(j,K)=>{let{align:G,behavior:Q,duration:Z}=jj(K),L=kj(j,A,E,_.length,G);
|
|
118
|
+
if(Q==="smooth")qj(D,L,Z);
|
|
119
|
+
else S(),g(L)},x=()=>{A.rebuild(_.length),v(),t()},Bj=(j)=>{_=[...j],x()},Gj=(j)=>{_=[..._,...j],x()},Jj=(j)=>{_=[...j,..._],x()},Kj=(j,K)=>{let G=_.findIndex((Z)=>Z.id===j);
|
|
120
|
+
if(G<0)return;
|
|
121
|
+
_[G]={..._[G],...K};
|
|
122
|
+
let Q=b.get(G);
|
|
123
|
+
if(Q)p(Q,N(_[G],G,f)),Q.dataset.id=String(_[G].id)},Uj=(j)=>{_=_.filter((K)=>K.id!==j),x()},Xj=()=>{if(y)return;
|
|
124
|
+
if(y=!0,S(),d.removeEventListener("scroll",m),V.items.removeEventListener("click",s),a.disconnect(),u)window.removeEventListener("resize",u);
|
|
125
|
+
if(O)clearTimeout(O);
|
|
126
|
+
for(let[,j]of b)j.remove(),I.release(j);
|
|
127
|
+
b.clear(),I.clear(),W.clear(),V.root.remove()};
|
|
128
|
+
return v(),P(),{get element(){return V.root},get items(){return _},get total(){return _.length},setItems:Bj,appendItems:Gj,prependItems:Jj,updateItem:Kj,removeItem:Uj,scrollToIndex:r,scrollToItem:(j,K)=>{let G=_.findIndex((Q)=>Q.id===j);
|
|
129
|
+
if(G>=0)r(G,K)},cancelScroll:S,getScrollPosition:()=>D,getScrollSnapshot:()=>{if(_.length===0)return{index:0,offsetInItem:0};
|
|
130
|
+
let j=A.indexAtOffset(D),K=Math.max(0,D-A.getOffset(j));
|
|
131
|
+
return{index:j,offsetInItem:K}},restoreScroll:(j)=>{if(_.length===0)return;
|
|
132
|
+
let K=Math.max(0,Math.min(j.index,_.length-1)),G=Math.max(0,A.getTotalHeight()-E),Q=Math.max(0,Math.min(A.getOffset(K)+j.offsetInItem,G));
|
|
133
|
+
if(k){let L=V.viewport.getBoundingClientRect().top+window.scrollY;
|
|
134
|
+
window.scrollTo({top:L+Q,behavior:"auto"})}
|
|
135
|
+
else V.viewport.scrollTo({top:Q,behavior:"auto"});
|
|
136
|
+
D=Q,P()},on:(j,K)=>W.on(j,K),off:(j,K)=>W.off(j,K),destroy:Xj}};
|
|
137
|
+
export{Aj as createVList};
|