@floor/vlist 0.5.7 → 0.6.0

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.
Files changed (108) hide show
  1. package/README.md +793 -592
  2. package/dist/async/index.js +1 -0
  3. package/dist/builder/context.d.ts +3 -3
  4. package/dist/builder/context.d.ts.map +1 -1
  5. package/dist/builder/core.d.ts +1 -1
  6. package/dist/builder/core.d.ts.map +1 -1
  7. package/dist/builder/index.js +1 -250
  8. package/dist/builder/types.d.ts +3 -3
  9. package/dist/builder/types.d.ts.map +1 -1
  10. package/dist/compression/index.js +1 -104
  11. package/dist/core/core.js +1 -0
  12. package/dist/core/full.d.ts +22 -0
  13. package/dist/core/full.d.ts.map +1 -0
  14. package/dist/core/index.js +1 -133
  15. package/dist/core/lite.d.ts +129 -0
  16. package/dist/core/lite.d.ts.map +1 -0
  17. package/dist/core/minimal.d.ts +104 -0
  18. package/dist/core/minimal.d.ts.map +1 -0
  19. package/dist/core-light.js +1 -68
  20. package/dist/data/index.js +1 -233
  21. package/dist/features/async/index.d.ts +9 -0
  22. package/dist/features/async/index.d.ts.map +1 -0
  23. package/dist/features/async/manager.d.ts +103 -0
  24. package/dist/features/async/manager.d.ts.map +1 -0
  25. package/dist/features/async/placeholder.d.ts +62 -0
  26. package/dist/features/async/placeholder.d.ts.map +1 -0
  27. package/dist/features/async/plugin.d.ts +60 -0
  28. package/dist/features/async/plugin.d.ts.map +1 -0
  29. package/dist/features/async/sparse.d.ts +91 -0
  30. package/dist/features/async/sparse.d.ts.map +1 -0
  31. package/dist/features/grid/index.d.ts +9 -0
  32. package/dist/features/grid/index.d.ts.map +1 -0
  33. package/dist/features/grid/layout.d.ts +29 -0
  34. package/dist/features/grid/layout.d.ts.map +1 -0
  35. package/dist/features/grid/plugin.d.ts +48 -0
  36. package/dist/features/grid/plugin.d.ts.map +1 -0
  37. package/dist/features/grid/renderer.d.ts +55 -0
  38. package/dist/features/grid/renderer.d.ts.map +1 -0
  39. package/dist/features/grid/types.d.ts +71 -0
  40. package/dist/features/grid/types.d.ts.map +1 -0
  41. package/dist/features/page/index.d.ts +8 -0
  42. package/dist/features/page/index.d.ts.map +1 -0
  43. package/dist/features/page/plugin.d.ts +53 -0
  44. package/dist/features/page/plugin.d.ts.map +1 -0
  45. package/dist/features/scale/index.d.ts +10 -0
  46. package/dist/features/scale/index.d.ts.map +1 -0
  47. package/dist/features/scale/plugin.d.ts +42 -0
  48. package/dist/features/scale/plugin.d.ts.map +1 -0
  49. package/dist/features/scrollbar/controller.d.ts +121 -0
  50. package/dist/features/scrollbar/controller.d.ts.map +1 -0
  51. package/dist/features/scrollbar/index.d.ts +8 -0
  52. package/dist/features/scrollbar/index.d.ts.map +1 -0
  53. package/dist/features/scrollbar/plugin.d.ts +60 -0
  54. package/dist/features/scrollbar/plugin.d.ts.map +1 -0
  55. package/dist/features/scrollbar/scrollbar.d.ts +73 -0
  56. package/dist/features/scrollbar/scrollbar.d.ts.map +1 -0
  57. package/dist/features/sections/index.d.ts +10 -0
  58. package/dist/features/sections/index.d.ts.map +1 -0
  59. package/dist/features/sections/layout.d.ts +46 -0
  60. package/dist/features/sections/layout.d.ts.map +1 -0
  61. package/dist/features/sections/plugin.d.ts +64 -0
  62. package/dist/features/sections/plugin.d.ts.map +1 -0
  63. package/dist/features/sections/sticky.d.ts +33 -0
  64. package/dist/features/sections/sticky.d.ts.map +1 -0
  65. package/dist/features/sections/types.d.ts +86 -0
  66. package/dist/features/sections/types.d.ts.map +1 -0
  67. package/dist/features/selection/index.d.ts +7 -0
  68. package/dist/features/selection/index.d.ts.map +1 -0
  69. package/dist/features/selection/plugin.d.ts +44 -0
  70. package/dist/features/selection/plugin.d.ts.map +1 -0
  71. package/dist/features/selection/state.d.ts +102 -0
  72. package/dist/features/selection/state.d.ts.map +1 -0
  73. package/dist/features/snapshots/index.d.ts +8 -0
  74. package/dist/features/snapshots/index.d.ts.map +1 -0
  75. package/dist/features/snapshots/plugin.d.ts +44 -0
  76. package/dist/features/snapshots/plugin.d.ts.map +1 -0
  77. package/dist/grid/index.js +1 -198
  78. package/dist/groups/index.js +1 -204
  79. package/dist/index.d.ts +17 -8
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +1 -1129
  82. package/dist/page/index.js +1 -0
  83. package/dist/plugins/groups/plugin.d.ts +3 -2
  84. package/dist/plugins/groups/plugin.d.ts.map +1 -1
  85. package/dist/react/index.js +1 -1024
  86. package/dist/react/react.js +1 -0
  87. package/dist/rendering/heights.d.ts +63 -0
  88. package/dist/rendering/heights.d.ts.map +1 -0
  89. package/dist/rendering/index.d.ts +9 -0
  90. package/dist/rendering/index.d.ts.map +1 -0
  91. package/dist/rendering/renderer.d.ts +103 -0
  92. package/dist/rendering/renderer.d.ts.map +1 -0
  93. package/dist/rendering/scale.d.ts +116 -0
  94. package/dist/rendering/scale.d.ts.map +1 -0
  95. package/dist/rendering/viewport.d.ts +139 -0
  96. package/dist/rendering/viewport.d.ts.map +1 -0
  97. package/dist/scale/index.js +1 -0
  98. package/dist/scroll/index.js +1 -116
  99. package/dist/scrollbar/index.js +1 -0
  100. package/dist/sections/index.js +1 -0
  101. package/dist/selection/index.js +1 -96
  102. package/dist/snapshots/index.js +1 -21
  103. package/dist/svelte/index.js +1 -1012
  104. package/dist/svelte/svelte.js +1 -0
  105. package/dist/vue/index.js +1 -1018
  106. package/dist/vue/vue.js +1 -0
  107. package/dist/window/index.js +1 -18
  108. package/package.json +1 -1
@@ -1,133 +1 @@
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))}px)`},i=(j,K)=>{let G=I.acquire();
55
- return G.className=n,G.style.height=`${A.getHeight(j)}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()}px`},P=()=>{if(y)return;
56
- if(Vj(D,E,A,_.length,h),Lj(h,U,_.length,M),M.start===C.start&&M.end===C.end)return;
57
- let j=String(_.length),K=j!==T;
58
- T=j;
59
- for(let[Z,L]of b)if(Z<M.start||Z>M.end)L.remove(),I.release(L),b.delete(Z);
60
- let G=document.createDocumentFragment(),Q=[];
61
- for(let Z=M.start;
62
- Z<=M.end;
63
- Z++){let L=_[Z];
64
- if(!L)continue;
65
- let z=b.get(Z);
66
- if(z){let H=z.dataset.id,w=String(L.id);
67
- if(H!==w)p(z,N(L,Z,f)),z.dataset.id=w,z.style.height=`${A.getHeight(Z)}px`;
68
- if(c(z,Z),K)z.setAttribute("aria-setsize",T)}
69
- else{let H=i(Z,L);
70
- G.appendChild(H),Q.push({index:Z,element:H})}}
71
- if(Q.length>0){V.items.appendChild(G);
72
- for(let{index:Z,element:L}
73
- of Q)b.set(Z,L)}
74
- 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;
75
- 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";
76
- if(!V.root.classList.contains(`${$}--scrolling`))V.root.classList.add(`${$}--scrolling`);
77
- if(D=K,P(),W.emit("scroll",{scrollTop:K,direction:G}),O)clearTimeout(O);
78
- O=setTimeout(()=>{V.root.classList.remove(`${$}--scrolling`)},150)},d=k?q:V.viewport;
79
- d.addEventListener("scroll",m,{passive:!0});
80
- let s=(j)=>{if(y)return;
81
- let G=j.target.closest("[data-index]");
82
- if(!G)return;
83
- let Q=parseInt(G.dataset.index??"-1",10);
84
- if(Q<0)return;
85
- let Z=_[Q];
86
- if(!Z)return;
87
- W.emit("item:click",{item:Z,index:Q,event:j})},e=(j)=>{if(y)return;
88
- let G=j.target.closest("[data-index]");
89
- if(!G)return;
90
- let Q=parseInt(G.dataset.index??"-1",10);
91
- if(Q<0)return;
92
- let Z=_[Q];
93
- if(!Z)return;
94
- W.emit("item:dblclick",{item:Z,index:Q,event:j})};
95
- V.items.addEventListener("click",s),V.items.addEventListener("dblclick",e);
96
- let a=new ResizeObserver((j)=>{if(y||k)return;
97
- for(let K of j){let G=K.contentRect.height;
98
- if(Math.abs(G-E)>1)E=G,v(),P(),W.emit("resize",{height:G,width:K.contentRect.width})}});
99
- a.observe(V.viewport);
100
- let u=null;
101
- if(k)u=()=>{if(y)return;
102
- let j=window.innerHeight;
103
- if(Math.abs(j-E)>1)E=j,v(),P(),W.emit("resize",{height:j,width:window.innerWidth})},window.addEventListener("resize",u);
104
- let S=()=>{if(R!==null)cancelAnimationFrame(R),R=null},jj=(j)=>{if(typeof j==="string")return{align:j,behavior:"auto",duration:300};
105
- if(j&&typeof j==="object")return{align:j.align??"start",behavior:j.behavior??"auto",duration:j.duration??300};
106
- return{align:"start",behavior:"auto",duration:300}},g=(j)=>{if(k){let G=V.viewport.getBoundingClientRect().top+window.scrollY;
107
- q.scrollTo(0,G+j)}
108
- else V.viewport.scrollTop=j},qj=(j,K,G)=>{if(S(),Math.abs(K-j)<1){g(K),D=K,P();
109
- return}
110
- let Q=performance.now(),Z=(L)=>{let z=L-Q,H=Math.min(z/G,1),w=j+(K-j)*Fj(H);
111
- if(g(w),D=w,P(),H<1)R=requestAnimationFrame(Z);
112
- else R=null};
113
- R=requestAnimationFrame(Z)},r=(j,K)=>{let{align:G,behavior:Q,duration:Z}=jj(K),L=kj(j,A,E,_.length,G);
114
- if(Q==="smooth")qj(D,L,Z);
115
- 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);
116
- if(G<0)return;
117
- _[G]={..._[G],...K};
118
- let Q=b.get(G);
119
- 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;
120
- if(y=!0,S(),d.removeEventListener("scroll",m),V.items.removeEventListener("click",s),a.disconnect(),u)window.removeEventListener("resize",u);
121
- if(O)clearTimeout(O);
122
- for(let[,j]of b)j.remove(),I.release(j);
123
- b.clear(),I.clear(),W.clear(),V.root.remove()};
124
- 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);
125
- if(G>=0)r(G,K)},cancelScroll:S,getScrollPosition:()=>D,getScrollSnapshot:()=>{if(_.length===0)return{index:0,offsetInItem:0};
126
- let j=A.indexAtOffset(D),K=Math.max(0,D-A.getOffset(j));
127
- return{index:j,offsetInItem:K}},restoreScroll:(j)=>{if(_.length===0)return;
128
- 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));
129
- if(k){let L=V.viewport.getBoundingClientRect().top+window.scrollY;
130
- window.scrollTo({top:L+Q,behavior:"auto"})}
131
- else V.viewport.scrollTo({top:Q,behavior:"auto"});
132
- D=Q,P()},on:(j,K)=>W.on(j,K),off:(j,K)=>W.off(j,K),destroy:Xj}};
133
- export{Aj as createVList};
1
+ var Yj=(B,X)=>{if(typeof B==="number"){let q=X;return{getOffset:(J)=>J*B,getHeight:()=>B,indexAtOffset:(J)=>{if(q===0||B===0)return 0;return Math.max(0,Math.min(Math.floor(J/B),q-1))},getTotalHeight:()=>q*B,getTotal:()=>q,rebuild:(J)=>{q=J}}}let Y=X,U=new Float64Array(0),$=(q)=>{Y=q,U=new Float64Array(q+1),U[0]=0;for(let J=0;J<q;J++)U[J+1]=U[J]+B(J)};return $(X),{getOffset:(q)=>{if(q<=0)return 0;if(q>=Y)return U[Y];return U[q]},getHeight:(q)=>B(q),indexAtOffset:(q)=>{if(Y===0)return 0;if(q<=0)return 0;if(q>=U[Y])return Y-1;let J=0,F=Y-1;while(J<F){let N=J+F+1>>>1;if(U[N]<=q)J=N;else F=N-1}return J},getTotalHeight:()=>U[Y]??0,getTotal:()=>Y,rebuild:(q)=>$(q)}},Zj=()=>{let B={},X=(q,J)=>{if(!B[q])B[q]=new Set;return B[q].add(J),()=>Y(q,J)},Y=(q,J)=>{B[q]?.delete(J)};return{on:X,off:Y,emit:(q,J)=>{B[q]?.forEach((F)=>{try{F(J)}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);if(!X)throw Error(`[vlist] Container not found: ${B}`);return X}return B},$j=(B,X,Y)=>{let U=document.createElement("div");if(U.className=X,U.setAttribute("role","listbox"),U.setAttribute("tabindex","0"),Y)U.setAttribute("aria-label",Y);let $=document.createElement("div");$.className=`${X}-viewport`,$.style.overflow="auto",$.style.height="100%",$.style.width="100%";let q=document.createElement("div");q.className=`${X}-content`,q.style.position="relative",q.style.width="100%";let J=document.createElement("div");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=[];return{acquire:()=>{let q=X.pop();if(q)return q;let J=document.createElement("div");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;return}let q=Y.indexAtOffset(B),J=q,F=Y.getOffset(q)-B;while(J<U-1&&F<X)F+=Y.getHeight(J),J++;$.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;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;switch($){case"center":k=J-(Y-F)/2;break;case"end":k=J-Y+F;break;default:k=J}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");if(!B.item)throw Error("[vlist] item configuration is required");if(B.item.height==null)throw Error("[vlist] item.height is required");if(typeof B.item.height==="number"&&B.item.height<=0)throw Error("[vlist] item.height must be positive");if(typeof B.item.height!=="number"&&typeof B.item.height!=="function")throw Error("[vlist] item.height must be a number or (index) => number");if(!B.item.template)throw Error("[vlist] item.template is required");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();if(k)V.root.style.overflow="visible",V.root.style.height="auto",V.viewport.style.overflow="visible",V.viewport.style.height="auto";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;else j.replaceChildren(K)},c=(j,K)=>{j.style.transform=`translateY(${Math.round(A.getOffset(K))}px)`},i=(j,K)=>{let G=I.acquire();return G.className=n,G.style.height=`${A.getHeight(j)}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()}px`},P=()=>{if(y)return;if(Vj(D,E,A,_.length,h),Lj(h,U,_.length,M),M.start===C.start&&M.end===C.end)return;let j=String(_.length),K=j!==T;T=j;for(let[Z,L]of b)if(Z<M.start||Z>M.end)L.remove(),I.release(L),b.delete(Z);let G=document.createDocumentFragment(),Q=[];for(let Z=M.start;Z<=M.end;Z++){let L=_[Z];if(!L)continue;let z=b.get(Z);if(z){let H=z.dataset.id,w=String(L.id);if(H!==w)p(z,N(L,Z,f)),z.dataset.id=w,z.style.height=`${A.getHeight(Z)}px`;if(c(z,Z),K)z.setAttribute("aria-setsize",T)}else{let H=i(Z,L);G.appendChild(H),Q.push({index:Z,element:H})}}if(Q.length>0){V.items.appendChild(G);for(let{index:Z,element:L}of Q)b.set(Z,L)}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;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";if(!V.root.classList.contains(`${$}--scrolling`))V.root.classList.add(`${$}--scrolling`);if(D=K,P(),W.emit("scroll",{scrollTop:K,direction:G}),O)clearTimeout(O);O=setTimeout(()=>{V.root.classList.remove(`${$}--scrolling`)},150)},d=k?q:V.viewport;d.addEventListener("scroll",m,{passive:!0});let s=(j)=>{if(y)return;let G=j.target.closest("[data-index]");if(!G)return;let Q=parseInt(G.dataset.index??"-1",10);if(Q<0)return;let Z=_[Q];if(!Z)return;W.emit("item:click",{item:Z,index:Q,event:j})},e=(j)=>{if(y)return;let G=j.target.closest("[data-index]");if(!G)return;let Q=parseInt(G.dataset.index??"-1",10);if(Q<0)return;let Z=_[Q];if(!Z)return;W.emit("item:dblclick",{item:Z,index:Q,event:j})};V.items.addEventListener("click",s),V.items.addEventListener("dblclick",e);let a=new ResizeObserver((j)=>{if(y||k)return;for(let K of j){let G=K.contentRect.height;if(Math.abs(G-E)>1)E=G,v(),P(),W.emit("resize",{height:G,width:K.contentRect.width})}});a.observe(V.viewport);let u=null;if(k)u=()=>{if(y)return;let j=window.innerHeight;if(Math.abs(j-E)>1)E=j,v(),P(),W.emit("resize",{height:j,width:window.innerWidth})},window.addEventListener("resize",u);let S=()=>{if(R!==null)cancelAnimationFrame(R),R=null},jj=(j)=>{if(typeof j==="string")return{align:j,behavior:"auto",duration:300};if(j&&typeof j==="object")return{align:j.align??"start",behavior:j.behavior??"auto",duration:j.duration??300};return{align:"start",behavior:"auto",duration:300}},g=(j)=>{if(k){let G=V.viewport.getBoundingClientRect().top+window.scrollY;q.scrollTo(0,G+j)}else V.viewport.scrollTop=j},qj=(j,K,G)=>{if(S(),Math.abs(K-j)<1){g(K),D=K,P();return}let Q=performance.now(),Z=(L)=>{let z=L-Q,H=Math.min(z/G,1),w=j+(K-j)*Fj(H);if(g(w),D=w,P(),H<1)R=requestAnimationFrame(Z);else R=null};R=requestAnimationFrame(Z)},r=(j,K)=>{let{align:G,behavior:Q,duration:Z}=jj(K),L=kj(j,A,E,_.length,G);if(Q==="smooth")qj(D,L,Z);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);if(G<0)return;_[G]={..._[G],...K};let Q=b.get(G);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;if(y=!0,S(),d.removeEventListener("scroll",m),V.items.removeEventListener("click",s),a.disconnect(),u)window.removeEventListener("resize",u);if(O)clearTimeout(O);for(let[,j]of b)j.remove(),I.release(j);b.clear(),I.clear(),W.clear(),V.root.remove()};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);if(G>=0)r(G,K)},cancelScroll:S,getScrollPosition:()=>D,getScrollSnapshot:()=>{if(_.length===0)return{index:0,offsetInItem:0};let j=A.indexAtOffset(D),K=Math.max(0,D-A.getOffset(j));return{index:j,offsetInItem:K}},restoreScroll:(j)=>{if(_.length===0)return;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));if(k){let L=V.viewport.getBoundingClientRect().top+window.scrollY;window.scrollTo({top:L+Q,behavior:"auto"})}else V.viewport.scrollTo({top:Q,behavior:"auto"});D=Q,P()},on:(j,K)=>W.on(j,K),off:(j,K)=>W.off(j,K),destroy:Xj}};export{Aj as createVList};
@@ -0,0 +1,129 @@
1
+ /**
2
+ * vlist/core - Lightweight Virtual List
3
+ *
4
+ * A self-contained, minimal virtual list factory for the common case:
5
+ * static or streaming lists that don't need selection, groups,
6
+ * compression, custom scrollbar, or async data adapters.
7
+ *
8
+ * ~10 KB minified vs ~42 KB for the full bundle.
9
+ *
10
+ * Supports:
11
+ * - Fixed and variable item heights
12
+ * - scrollToIndex with smooth animation
13
+ * - setItems / appendItems / prependItems / updateItem / removeItem
14
+ * - Events (scroll, item:click, range:change, resize)
15
+ * - Window (document) scrolling
16
+ * - ResizeObserver for container resize
17
+ * - DOM element pooling & DocumentFragment batching
18
+ *
19
+ * Does NOT include (use full `vlist` if needed):
20
+ * - Selection / keyboard navigation
21
+ * - Groups / sticky headers
22
+ * - Compression (lists > ~100K items)
23
+ * - Custom scrollbar
24
+ * - Async data adapter / placeholders
25
+ * - Velocity tracking / load cancellation
26
+ */
27
+ /** Base item interface — must have an id */
28
+ export interface VListItem {
29
+ id: string | number;
30
+ [key: string]: unknown;
31
+ }
32
+ /** State passed to template */
33
+ export interface ItemState {
34
+ selected: boolean;
35
+ focused: boolean;
36
+ }
37
+ /** Item template function */
38
+ export type ItemTemplate<T extends VListItem = VListItem> = (item: T, index: number, state: ItemState) => string | HTMLElement;
39
+ /** Visible range */
40
+ export interface Range {
41
+ start: number;
42
+ end: number;
43
+ }
44
+ /** Options for scrollToIndex */
45
+ export interface ScrollToOptions {
46
+ align?: "start" | "center" | "end";
47
+ behavior?: "auto" | "smooth";
48
+ duration?: number;
49
+ }
50
+ /** Scroll position snapshot for save/restore */
51
+ export interface CoreScrollSnapshot {
52
+ /** First visible item index */
53
+ index: number;
54
+ /** Pixel offset within the first visible item (how far it's scrolled off) */
55
+ offsetInItem: number;
56
+ }
57
+ /** Event handler / unsubscribe */
58
+ export type EventHandler<T> = (payload: T) => void;
59
+ export type Unsubscribe = () => void;
60
+ /** Core event map */
61
+ export interface CoreEvents<T extends VListItem = VListItem> {
62
+ "item:click": {
63
+ item: T;
64
+ index: number;
65
+ event: MouseEvent;
66
+ };
67
+ "item:dblclick": {
68
+ item: T;
69
+ index: number;
70
+ event: MouseEvent;
71
+ };
72
+ scroll: {
73
+ scrollTop: number;
74
+ direction: "up" | "down";
75
+ };
76
+ "range:change": {
77
+ range: Range;
78
+ };
79
+ resize: {
80
+ height: number;
81
+ width: number;
82
+ };
83
+ }
84
+ /** Item configuration */
85
+ export interface CoreItemConfig<T extends VListItem = VListItem> {
86
+ height: number | ((index: number) => number);
87
+ template: ItemTemplate<T>;
88
+ }
89
+ /** Core configuration */
90
+ export interface CoreConfig<T extends VListItem = VListItem> {
91
+ container: HTMLElement | string;
92
+ item: CoreItemConfig<T>;
93
+ items?: T[];
94
+ overscan?: number;
95
+ classPrefix?: string;
96
+ ariaLabel?: string;
97
+ scrollElement?: Window;
98
+ }
99
+ /** Core VList instance */
100
+ export interface VListCore<T extends VListItem = VListItem> {
101
+ readonly element: HTMLElement;
102
+ readonly items: readonly T[];
103
+ readonly total: number;
104
+ setItems(items: T[]): void;
105
+ appendItems(items: T[]): void;
106
+ prependItems(items: T[]): void;
107
+ updateItem(id: string | number, updates: Partial<T>): void;
108
+ removeItem(id: string | number): void;
109
+ scrollToIndex(index: number, alignOrOptions?: "start" | "center" | "end" | ScrollToOptions): void;
110
+ scrollToItem(id: string | number, alignOrOptions?: "start" | "center" | "end" | ScrollToOptions): void;
111
+ cancelScroll(): void;
112
+ getScrollPosition(): number;
113
+ /** Get a snapshot of the current scroll position for save/restore */
114
+ getScrollSnapshot(): CoreScrollSnapshot;
115
+ /** Restore scroll position from a snapshot */
116
+ restoreScroll(snapshot: CoreScrollSnapshot): void;
117
+ on<K extends keyof CoreEvents<T>>(event: K, handler: EventHandler<CoreEvents<T>[K]>): Unsubscribe;
118
+ off<K extends keyof CoreEvents<T>>(event: K, handler: EventHandler<CoreEvents<T>[K]>): void;
119
+ destroy(): void;
120
+ }
121
+ /**
122
+ * Create a lightweight virtual list (core).
123
+ *
124
+ * This is the minimal-footprint alternative to `createVList` from `vlist`.
125
+ * Same essential behaviour, but without selection, groups, compression,
126
+ * custom scrollbar, or async data adapter support.
127
+ */
128
+ export declare const createVList: <T extends VListItem = VListItem>(config: CoreConfig<T>) => VListCore<T>;
129
+ //# sourceMappingURL=lite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lite.d.ts","sourceRoot":"","sources":["../../src/core/lite.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * vlist/core-light - Ultra-Lightweight Virtual List (Fixed Heights Only)
3
+ *
4
+ * An even lighter variant of vlist/core that only supports fixed-height items.
5
+ * Use this when all items have the same height and you need the absolute smallest bundle.
6
+ *
7
+ * ~3-4 KB minified vs ~10 KB for vlist/core vs ~42 KB for the full bundle.
8
+ *
9
+ * Supports:
10
+ * - Fixed item heights only
11
+ * - Container scrolling only
12
+ * - Single item selection
13
+ * - Instant scrollToIndex (no animation)
14
+ * - setItems / appendItems / prependItems
15
+ * - Events (scroll, range:change, selection:change)
16
+ * - DOM element pooling & DocumentFragment batching
17
+ *
18
+ * Does NOT include (use vlist/core or full `vlist` if needed):
19
+ * - Variable item heights
20
+ * - Window scrolling
21
+ * - Smooth scroll animation
22
+ * - Single item mutations (updateItem/removeItem)
23
+ * - Click event handling
24
+ * - ResizeObserver / auto-resize
25
+ * - Validation
26
+ * - Selection / keyboard navigation
27
+ * - Groups / sticky headers
28
+ * - Compression (lists > ~100K items)
29
+ * - Custom scrollbar
30
+ * - Async data adapter / placeholders
31
+ */
32
+ /** Base item interface — must have an id */
33
+ export interface VListItem {
34
+ id: string | number;
35
+ [key: string]: unknown;
36
+ }
37
+ /** State passed to template */
38
+ export interface ItemState {
39
+ selected: boolean;
40
+ focused: boolean;
41
+ }
42
+ /** Item template function */
43
+ export type ItemTemplate<T extends VListItem = VListItem> = (item: T, index: number, state: ItemState) => string | HTMLElement;
44
+ /** Visible range */
45
+ export interface Range {
46
+ start: number;
47
+ end: number;
48
+ }
49
+ /** Event handler / unsubscribe */
50
+ export type EventHandler<T> = (payload: T) => void;
51
+ export type Unsubscribe = () => void;
52
+ /** Core event map */
53
+ export interface CoreEvents {
54
+ scroll: {
55
+ scrollTop: number;
56
+ direction: "up" | "down";
57
+ };
58
+ "range:change": {
59
+ range: Range;
60
+ };
61
+ "selection:change": {
62
+ selectedId: string | number | null;
63
+ };
64
+ }
65
+ /** Item configuration */
66
+ export interface CoreItemConfig<T extends VListItem = VListItem> {
67
+ height: number;
68
+ template: ItemTemplate<T>;
69
+ }
70
+ /** Core configuration */
71
+ export interface CoreConfig<T extends VListItem = VListItem> {
72
+ container: HTMLElement | string;
73
+ item: CoreItemConfig<T>;
74
+ items?: T[];
75
+ overscan?: number;
76
+ classPrefix?: string;
77
+ ariaLabel?: string;
78
+ }
79
+ /** Core VList instance */
80
+ export interface VListCore<T extends VListItem = VListItem> {
81
+ readonly element: HTMLElement;
82
+ readonly items: readonly T[];
83
+ readonly total: number;
84
+ setItems(items: T[]): void;
85
+ appendItems(items: T[]): void;
86
+ prependItems(items: T[]): void;
87
+ scrollToIndex(index: number, align?: "start" | "center" | "end"): void;
88
+ getScrollPosition(): number;
89
+ selectItem(id: string | number): void;
90
+ deselectItem(): void;
91
+ getSelectedId(): string | number | null;
92
+ on<K extends keyof CoreEvents>(event: K, handler: EventHandler<CoreEvents[K]>): Unsubscribe;
93
+ off<K extends keyof CoreEvents>(event: K, handler: EventHandler<CoreEvents[K]>): void;
94
+ destroy(): void;
95
+ }
96
+ /**
97
+ * Create a lightweight virtual list (core).
98
+ *
99
+ * This is the minimal-footprint alternative to `createVList` from `vlist`.
100
+ * Same essential behaviour, but without selection, groups, compression,
101
+ * custom scrollbar, or async data adapter support.
102
+ */
103
+ export declare const createVList: <T extends VListItem = VListItem>(config: CoreConfig<T>) => VListCore<T>;
104
+ //# sourceMappingURL=minimal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"minimal.d.ts","sourceRoot":"","sources":["../../src/core/minimal.ts"],"names":[],"mappings":"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"}
@@ -1,68 +1 @@
1
- var e=(B,K)=>{let W=K;
2
- return{getOffset:(J)=>J*B,getHeight:()=>B,indexAtOffset:(J)=>{if(W===0||B===0)return 0;
3
- return Math.max(0,Math.min(Math.floor(J/B),W-1))},getTotalHeight:()=>W*B,getTotal:()=>W,rebuild:(J)=>{W=J}}},jj=()=>{let B={},K=(j,Q)=>{if(!B[j])B[j]=new Set;
4
- return B[j].add(Q),()=>W(j,Q)},W=(j,Q)=>{B[j]?.delete(Q)};
5
- return{on:K,off:W,emit:(j,Q)=>{B[j]?.forEach((N)=>{try{N(Q)}
6
- catch(Z){console.error(`[vlist] Error in "${j}" handler:`,Z)}})},clear:()=>{for(let j in B)delete B[j]}}},qj=(B)=>{if(typeof B==="string"){let K=document.querySelector(B);
7
- if(!K)throw Error(`[vlist] Container not found: ${B}`);
8
- return K}
9
- return B},Bj=(B,K,W)=>{let J=document.createElement("div");
10
- if(J.className=K,J.setAttribute("role","listbox"),J.setAttribute("tabindex","0"),W)J.setAttribute("aria-label",W);
11
- let G=document.createElement("div");
12
- G.className=`${K}-viewport`,G.style.overflow="auto",G.style.height="100%",G.style.width="100%";
13
- let j=document.createElement("div");
14
- j.className=`${K}-content`,j.style.position="relative",j.style.width="100%";
15
- let Q=document.createElement("div");
16
- return Q.className=`${K}-items`,Q.style.position="relative",Q.style.width="100%",j.appendChild(Q),G.appendChild(j),J.appendChild(G),B.appendChild(J),{root:J,viewport:G,content:j,items:Q}},Gj=(B=100)=>{let K=[];
17
- return{acquire:()=>{let j=K.pop();
18
- if(j)return j;
19
- let Q=document.createElement("div");
20
- return Q.setAttribute("role","option"),Q},release:(j)=>{if(K.length<B)j.className="",j.textContent="",j.removeAttribute("style"),j.removeAttribute("data-index"),j.removeAttribute("data-id"),K.push(j)},clear:()=>{K.length=0}}},Jj=(B,K,W,J,G)=>{if(J===0){G.start=0,G.end=0;
21
- return}
22
- let j=W.indexAtOffset(B),Q=j,N=W.getOffset(j)-B;
23
- while(Q<J-1&&N<K)N+=W.getHeight(Q),Q++;
24
- G.start=j,G.end=Math.min(Q,J-1)},Kj=(B,K,W,J)=>{J.start=Math.max(0,B.start-K),J.end=Math.min(W-1,B.end+K)},Qj=0,Uj=(B)=>{let{item:K,items:W,overscan:J=3,classPrefix:G="vlist",ariaLabel:j}=B,{height:Q,template:N}=K,Z=W?[...W]:[],y=!1,H=0,O=null,h=`${G}-${Qj++}`,c=qj(B.container),$=Bj(c,G,j),D=jj(),F=e(Q,Z.length),b=Gj(),w=$.viewport.clientHeight,S={start:0,end:0},M={start:0,end:0},L={start:-1,end:-1},A=new Map,P={selected:!1,focused:!1},m=`${G}-item`,z="",v=(q,U)=>{if(typeof U==="string")q.innerHTML=U;
25
- else q.replaceChildren(U)},I=(q,U)=>{q.style.transform=`translateY(${Math.round(F.getOffset(U))}px)`},d=(q,U)=>{let X=b.acquire();
26
- X.className=m,X.style.height=`${F.getHeight(q)}px`,X.dataset.index=String(q),X.dataset.id=String(U.id),X.ariaSelected="false",X.id=`${h}-item-${q}`,z=String(Z.length),X.setAttribute("aria-setsize",z),X.setAttribute("aria-posinset",String(q+1));
27
- let V=U.id===O;
28
- if(P.selected=V,V)X.classList.add(`${G}-item--selected`);
29
- else X.classList.remove(`${G}-item--selected`);
30
- return v(X,N(U,q,P)),I(X,q),X},f=()=>{$.content.style.height=`${F.getTotalHeight()}px`},C=()=>{if(y)return;
31
- if(Jj(H,w,F,Z.length,S),Kj(S,J,Z.length,M),M.start===L.start&&M.end===L.end)return;
32
- let q=String(Z.length),U=q!==z;
33
- z=q;
34
- for(let[Y,k]of A)if(Y<M.start||Y>M.end)k.remove(),b.release(k),A.delete(Y);
35
- let X=document.createDocumentFragment(),V=[];
36
- for(let Y=M.start;
37
- Y<=M.end;
38
- Y++){let k=Z[Y];
39
- if(!k)continue;
40
- let _=A.get(Y);
41
- if(_){let T=_.dataset.id,p=String(k.id);
42
- if(T!==p)v(_,N(k,Y,P)),_.dataset.id=p,_.style.height=`${F.getHeight(Y)}px`;
43
- let g=k.id===O;
44
- if(P.selected=g,g)_.classList.add(`${G}-item--selected`);
45
- else _.classList.remove(`${G}-item--selected`);
46
- if(I(_,Y),U)_.setAttribute("aria-setsize",z)}
47
- else{let T=d(Y,k);
48
- X.appendChild(T),V.push({index:Y,element:T})}}
49
- if(V.length>0){$.items.appendChild(X);
50
- for(let{index:Y,element:k}
51
- of V)A.set(Y,k)}
52
- L.start=M.start,L.end=M.end,D.emit("range:change",{range:{start:M.start,end:M.end}})},u=()=>{L.start=-1,L.end=-1,C()},E=null,x=()=>{if(y)return;
53
- let q=$.viewport.scrollTop,U=Math.max(0,q),X=U>=H?"down":"up";
54
- if(!$.root.classList.contains(`${G}--scrolling`))$.root.classList.add(`${G}--scrolling`);
55
- if(H=U,C(),D.emit("scroll",{scrollTop:U,direction:X}),E)clearTimeout(E);
56
- E=setTimeout(()=>{$.root.classList.remove(`${G}--scrolling`)},150)};
57
- $.viewport.addEventListener("scroll",x,{passive:!0});
58
- let o=(q)=>{if(O===q)return;
59
- O=q,u(),D.emit("selection:change",{selectedId:O})},s=()=>{if(O===null)return;
60
- O=null,u(),D.emit("selection:change",{selectedId:null})},a=()=>O,r=(q,U="start")=>{let X=Math.max(0,Math.min(q,Z.length-1)),V=F.getOffset(X),Y=F.getHeight(X),k=Math.max(0,F.getTotalHeight()-w),_=V;
61
- if(U==="center")_=V-w/2+Y/2;
62
- else if(U==="end")_=V-w+Y;
63
- _=Math.max(0,Math.min(_,k)),$.viewport.scrollTop=_},R=()=>{F.rebuild(Z.length),f(),u()},l=(q)=>{Z=[...q],R()},n=(q)=>{Z=[...Z,...q],R()},i=(q)=>{Z=[...q,...Z],R()},t=()=>{if(y)return;
64
- if(y=!0,$.viewport.removeEventListener("scroll",x),E)clearTimeout(E);
65
- for(let[,q]of A)q.remove(),b.release(q);
66
- A.clear(),b.clear(),D.clear(),$.root.remove()};
67
- return f(),C(),{get element(){return $.root},get items(){return Z},get total(){return Z.length},setItems:l,appendItems:n,prependItems:i,scrollToIndex:r,getScrollPosition:()=>H,selectItem:o,deselectItem:s,getSelectedId:a,on:(q,U)=>D.on(q,U),off:(q,U)=>D.off(q,U),destroy:t}};
68
- export{Uj as createVList};
1
+ var e=(B,K)=>{let W=K;return{getOffset:(J)=>J*B,getHeight:()=>B,indexAtOffset:(J)=>{if(W===0||B===0)return 0;return Math.max(0,Math.min(Math.floor(J/B),W-1))},getTotalHeight:()=>W*B,getTotal:()=>W,rebuild:(J)=>{W=J}}},jj=()=>{let B={},K=(j,Q)=>{if(!B[j])B[j]=new Set;return B[j].add(Q),()=>W(j,Q)},W=(j,Q)=>{B[j]?.delete(Q)};return{on:K,off:W,emit:(j,Q)=>{B[j]?.forEach((N)=>{try{N(Q)}catch(Z){console.error(`[vlist] Error in "${j}" handler:`,Z)}})},clear:()=>{for(let j in B)delete B[j]}}},qj=(B)=>{if(typeof B==="string"){let K=document.querySelector(B);if(!K)throw Error(`[vlist] Container not found: ${B}`);return K}return B},Bj=(B,K,W)=>{let J=document.createElement("div");if(J.className=K,J.setAttribute("role","listbox"),J.setAttribute("tabindex","0"),W)J.setAttribute("aria-label",W);let G=document.createElement("div");G.className=`${K}-viewport`,G.style.overflow="auto",G.style.height="100%",G.style.width="100%";let j=document.createElement("div");j.className=`${K}-content`,j.style.position="relative",j.style.width="100%";let Q=document.createElement("div");return Q.className=`${K}-items`,Q.style.position="relative",Q.style.width="100%",j.appendChild(Q),G.appendChild(j),J.appendChild(G),B.appendChild(J),{root:J,viewport:G,content:j,items:Q}},Gj=(B=100)=>{let K=[];return{acquire:()=>{let j=K.pop();if(j)return j;let Q=document.createElement("div");return Q.setAttribute("role","option"),Q},release:(j)=>{if(K.length<B)j.className="",j.textContent="",j.removeAttribute("style"),j.removeAttribute("data-index"),j.removeAttribute("data-id"),K.push(j)},clear:()=>{K.length=0}}},Jj=(B,K,W,J,G)=>{if(J===0){G.start=0,G.end=0;return}let j=W.indexAtOffset(B),Q=j,N=W.getOffset(j)-B;while(Q<J-1&&N<K)N+=W.getHeight(Q),Q++;G.start=j,G.end=Math.min(Q,J-1)},Kj=(B,K,W,J)=>{J.start=Math.max(0,B.start-K),J.end=Math.min(W-1,B.end+K)},Qj=0,Uj=(B)=>{let{item:K,items:W,overscan:J=3,classPrefix:G="vlist",ariaLabel:j}=B,{height:Q,template:N}=K,Z=W?[...W]:[],y=!1,H=0,O=null,h=`${G}-${Qj++}`,c=qj(B.container),$=Bj(c,G,j),D=jj(),F=e(Q,Z.length),b=Gj(),w=$.viewport.clientHeight,S={start:0,end:0},M={start:0,end:0},L={start:-1,end:-1},A=new Map,P={selected:!1,focused:!1},m=`${G}-item`,z="",v=(q,U)=>{if(typeof U==="string")q.innerHTML=U;else q.replaceChildren(U)},I=(q,U)=>{q.style.transform=`translateY(${Math.round(F.getOffset(U))}px)`},d=(q,U)=>{let X=b.acquire();X.className=m,X.style.height=`${F.getHeight(q)}px`,X.dataset.index=String(q),X.dataset.id=String(U.id),X.ariaSelected="false",X.id=`${h}-item-${q}`,z=String(Z.length),X.setAttribute("aria-setsize",z),X.setAttribute("aria-posinset",String(q+1));let V=U.id===O;if(P.selected=V,V)X.classList.add(`${G}-item--selected`);else X.classList.remove(`${G}-item--selected`);return v(X,N(U,q,P)),I(X,q),X},f=()=>{$.content.style.height=`${F.getTotalHeight()}px`},C=()=>{if(y)return;if(Jj(H,w,F,Z.length,S),Kj(S,J,Z.length,M),M.start===L.start&&M.end===L.end)return;let q=String(Z.length),U=q!==z;z=q;for(let[Y,k]of A)if(Y<M.start||Y>M.end)k.remove(),b.release(k),A.delete(Y);let X=document.createDocumentFragment(),V=[];for(let Y=M.start;Y<=M.end;Y++){let k=Z[Y];if(!k)continue;let _=A.get(Y);if(_){let T=_.dataset.id,p=String(k.id);if(T!==p)v(_,N(k,Y,P)),_.dataset.id=p,_.style.height=`${F.getHeight(Y)}px`;let g=k.id===O;if(P.selected=g,g)_.classList.add(`${G}-item--selected`);else _.classList.remove(`${G}-item--selected`);if(I(_,Y),U)_.setAttribute("aria-setsize",z)}else{let T=d(Y,k);X.appendChild(T),V.push({index:Y,element:T})}}if(V.length>0){$.items.appendChild(X);for(let{index:Y,element:k}of V)A.set(Y,k)}L.start=M.start,L.end=M.end,D.emit("range:change",{range:{start:M.start,end:M.end}})},u=()=>{L.start=-1,L.end=-1,C()},E=null,x=()=>{if(y)return;let q=$.viewport.scrollTop,U=Math.max(0,q),X=U>=H?"down":"up";if(!$.root.classList.contains(`${G}--scrolling`))$.root.classList.add(`${G}--scrolling`);if(H=U,C(),D.emit("scroll",{scrollTop:U,direction:X}),E)clearTimeout(E);E=setTimeout(()=>{$.root.classList.remove(`${G}--scrolling`)},150)};$.viewport.addEventListener("scroll",x,{passive:!0});let o=(q)=>{if(O===q)return;O=q,u(),D.emit("selection:change",{selectedId:O})},s=()=>{if(O===null)return;O=null,u(),D.emit("selection:change",{selectedId:null})},a=()=>O,r=(q,U="start")=>{let X=Math.max(0,Math.min(q,Z.length-1)),V=F.getOffset(X),Y=F.getHeight(X),k=Math.max(0,F.getTotalHeight()-w),_=V;if(U==="center")_=V-w/2+Y/2;else if(U==="end")_=V-w+Y;_=Math.max(0,Math.min(_,k)),$.viewport.scrollTop=_},R=()=>{F.rebuild(Z.length),f(),u()},l=(q)=>{Z=[...q],R()},n=(q)=>{Z=[...Z,...q],R()},i=(q)=>{Z=[...q,...Z],R()},t=()=>{if(y)return;if(y=!0,$.viewport.removeEventListener("scroll",x),E)clearTimeout(E);for(let[,q]of A)q.remove(),b.release(q);A.clear(),b.clear(),D.clear(),$.root.remove()};return f(),C(),{get element(){return $.root},get items(){return Z},get total(){return Z.length},setItems:l,appendItems:n,prependItems:i,scrollToIndex:r,getScrollPosition:()=>H,selectItem:o,deselectItem:s,getSelectedId:a,on:(q,U)=>D.on(q,U),off:(q,U)=>D.off(q,U),destroy:t}};export{Uj as createVList};