virtua
Version:
A zero-config, fast and small (~3kB) virtual list (and grid) component for React, Vue, Solid and Svelte.
3 lines (2 loc) • 12 kB
JavaScript
import{createComponent as e,Dynamic as t,spread as r,mergeProps as n,insert as o,template as s,use as i,setStyleProperty as c,effect as l}from"solid-js/web";import{mergeProps as a,createEffect as u,createMemo as f,onCleanup as d,createSignal as h,onMount as g,createComputed as v,on as p,untrack as m,For as w,splitProps as $}from"solid-js";const S=null,{min:x,max:y,abs:_,floor:b}=Math,z=(e,t,r)=>x(r,y(t,e)),I=e=>[...e].sort(((e,t)=>e-t)),k="function"==typeof queueMicrotask?queueMicrotask:e=>{Promise.resolve().then(e)},T=e=>{let t;return()=>(e&&(t=e(),e=void 0),t)},M=-1,E=(e,t,r)=>{const n=r?"unshift":"push";for(let r=0;r<t;r++)e[n](M);return e},R=(e,t)=>{const r=e.o[t];return r===M?e.i:r},O=(e,t,r)=>{const n=e.o[t]===M;return e.o[t]=r,e.l=x(t,e.l),n},P=(e,t)=>{if(!e.u)return 0;if(e.l>=t)return e.h[t];e.l<0&&(e.h[0]=0,e.l=0);let r=e.l,n=e.h[r];for(;r<t;)n+=R(e,r),e.h[++r]=n;return e.l=t,n},J=(e,t,r=0,n=e.u-1)=>{for(;r<=n;){const o=b((r+n)/2),s=P(e,o);if(s<=t){if(s+R(e,o)>t)return o;r=o+1}else n=o-1}return z(r,0,e.u-1)},B=(e,t,r)=>{const n=t-e.u;return e.l=r?-1:x(t-1,e.l),e.u=t,n>0?(E(e.h,n),E(e.o,n,r),e.i*n):(e.h.splice(n),(r?e.o.splice(0,-n):e.o.splice(n)).reduce(((t,r)=>t-(r===M?e.i:r)),0))},H="undefined"!=typeof window,L=()=>document.documentElement,W=e=>e.ownerDocument,j=e=>e.defaultView,q=/*#__PURE__*/T((()=>!!H&&"rtl"===getComputedStyle(L()).direction)),C=/*#__PURE__*/T((()=>/iP(hone|od|ad)/.test(navigator.userAgent))),U=/*#__PURE__*/T((()=>"scrollBehavior"in L().style)),V=e=>!!e.v(),X=(e,t=40,r=4,n=0,o,s=!1)=>{let i=!!n,c=1,l=0,a=0,u=0,f=0,d=0,h=0,g=0,v=0,p=i?[0,y(n-1,0)]:S,m=[0,0],w=0;const $=((e,t,r)=>({i:r?r[1]:t,o:r&&r[0]?E(r[0].slice(0,x(e,r[0].length)),y(0,e-r[0].length)):E([],e),u:e,l:-1,h:E([],e)}))(e,t,o),b=new Set,z=()=>u-a,k=()=>z()+d+f,T=e=>((e,t,r,n)=>{if(n=x(n,e.u-1),P(e,n)<=t){const o=J(e,t+r,n);return[J(e,t,n,o),o]}{const o=J(e,t,void 0,n);return[o,J(e,t+r,o)]}})($,e,l,m[0]),H=()=>(e=>e.u?P(e,e.u-1)+R(e,e.u-1):0)($),L=e=>P($,e)-d,W=e=>R($,e),j=e=>{e&&(C()&&0!==g?d+=e:f+=e)};return{p:()=>c,m:()=>(e=>[e.o.slice(),e.i])($),$:()=>{let e,t;return h?[e,t]=m:([e,t]=m=T(y(0,k())),p&&(e=x(e,p[0]),t=y(t,p[1]))),1!==g&&(e-=y(0,r)),2!==g&&(t+=y(0,r)),[y(e,0),x(t,$.u-1)]},S:()=>J($,k()),_:()=>J($,k()+l),I:e=>$.o[e]===M,k:()=>!!p&&$.o.slice(y(0,p[0]-1),x($.u-1,p[1]+1)+1).includes(M),T:L,M:W,R:()=>$.u,O:()=>u,P:()=>0!==g,v:()=>l,J:()=>a,B:H,H:()=>(h=f,f=0,[h,2===v||z()+l>=H()]),L:(e,t)=>{const r=[e,t];return b.add(r),()=>{b.delete(r)}},W:(e,t)=>{let r,n,o=0;switch(e){case 1:{const e=h;h=0;const r=t-u,s=_(r);e&&s<_(e)+1||0!==v||(g=r<0?2:1),i&&(p=S,i=!1),u=t,o=4;const c=z();c>=-l&&c<=H()&&(o+=1,n=s>l);break}case 2:o=8,0!==g&&(r=!0,o+=1),g=0,v=0,p=S;break;case 3:{const e=t.filter((([e,t])=>$.o[e]!==t));if(!e.length)break;j(e.reduce(((e,[t,r])=>((2===v||(p?!i&&t<p[0]:L(t)+(0===g&&0===v?W(t):0)<z()))&&(e+=r-W(t)),e)),0));for(const[t,r]of e){const e=W(t),n=O($,t,r);s&&(w+=n?r:r-e)}s&&l&&w>l&&(j(((e,t)=>{let r=0;const n=[];e.o.forEach(((e,o)=>{e!==M&&(n.push(e),o<t&&r++)})),e.l=-1;const o=I(n),s=o.length,i=s/2|0,c=s%2==0?(o[i-1]+o[i])/2:o[i],l=e.i;return((e.i=c)-l)*y(t-r,0)})($,J($,k()))),s=!1),o=3,n=!0;break}case 4:l!==t&&(l=t,o=3);break;case 5:t[1]?(j(B($,t[0],!0)),v=2,o=1):(B($,t[0]),o=1);break;case 6:a=t;break;case 7:v=1;break;case 8:p=T(t),o=1}o&&(c=1+(2147483647&c),r&&d&&(f+=d,d=0),b.forEach((([e,t])=>{o&e&&t(n)})))}}},Y=setTimeout,D=(e,t)=>t&&q()?-e:e,F=(e,t,r,n,o,s)=>{const i=Date.now;let c=0,l=!1,a=!1,u=!1,f=!1;const d=(()=>{let t;const r=()=>{t!=S&&clearTimeout(t)},n=()=>{r(),t=Y((()=>{t=S,(()=>{if(l||a)return l=!1,void d();u=!1,e.W(2)})()}),150)};return n.j=r,n})(),h=()=>{c=i(),u&&(f=!0),s&&e.W(6,s()),e.W(1,n()),d()},g=t=>{if(l||!e.P()||t.ctrlKey)return;const n=i()-c;150>n&&50<n&&(r?t.deltaX:t.deltaY)&&(l=!0)},v=()=>{a=!0,u=f=!1},p=()=>{a=!1,C()&&(u=!0)};return t.addEventListener("scroll",h),t.addEventListener("wheel",g,{passive:!0}),t.addEventListener("touchstart",v,{passive:!0}),t.addEventListener("touchend",p,{passive:!0}),{q:()=>{t.removeEventListener("scroll",h),t.removeEventListener("wheel",g),t.removeEventListener("touchstart",v),t.removeEventListener("touchend",p),d.j()},C:()=>{const[t,s]=e.H();t&&(o(D(t,r),s,f),f=!1,s&&e.v()>e.B()&&e.W(1,n()))}}},A=e=>{let t;return{U(r){(t||(t=new(j(W(r)).ResizeObserver)(e))).observe(r)},V(e){t.unobserve(e)},q(){t&&t.disconnect()}}},G=r=>{let n;r=a({X:"div"},r),u((()=>{n&&d(r.Y(n,r.D))}));const o=f((()=>{const e=r.F,t={contain:"layout style",position:"absolute",[e?"height":"width"]:"100%",[e?"top":"left"]:"0px",[e?q()?"right":"left":"top"]:r.A+"px",visibility:r.G?"hidden":"visible"};return e&&(t.display="inline-flex"),t}));return e(t,{get component(){return r.X},get index(){return r.D},ref(e){"function"==typeof n?n(e):n=e},get style(){return o()},get children(){return r.K}})},K=(e,t)=>e[0]===t[0]&&e[1]===t[1],N=r=>{let n;const{itemSize:o,horizontal:s=!1,overscan:i,cache:c}=r;r=a({as:"div"},r);const l=X(r.data.length,o,i,void 0,c,!o),$=((e,t)=>{let r;const n=t?"width":"height",o=new WeakMap,s=A((t=>{const s=[];for(const{target:i,contentRect:c}of t)if(i.offsetParent)if(i===r)e.W(4,c[n]);else{const e=o.get(i);e!=S&&s.push([e,c[n]])}s.length&&e.W(3,s)}));return{N(e){s.U(r=e)},Z:(e,t)=>(o.set(e,t),s.U(e),()=>{o.delete(e),s.V(e)}),ee:s.q}})(l,s),x=((e,t)=>{let r,n,o;const s=t?"scrollLeft":"scrollTop",i=t?"overflowX":"overflowY",c=async(n,i)=>{if(!r)return void k((()=>c(n,i)));o&&o();const l=()=>{let t;return[new Promise(((r,n)=>{t=r,o=n,V(e)&&Y(n,150)})),e.L(2,(()=>{t&&t()}))]};if(i&&U()){for(;e.W(8,n()),e.k();){const[e,t]=l();try{await e}catch(e){return}finally{t()}}r.scrollTo({[t?"left":"top"]:D(n(),t),behavior:"smooth"})}else for(;;){const[o,i]=l();try{r[s]=D(n(),t),e.W(7),await o}catch(e){return}finally{i()}}};return{te(c){r=c,n=F(e,c,t,(()=>D(c[s],t)),((t,r,n)=>{if(n){const e=c.style,t=e[i];e[i]="hidden",Y((()=>{e[i]=t}))}r?(c[s]=e.O()+t,o&&o()):c[s]+=t}))},ee(){n&&n.q()},re(e){c((()=>e))},ne(t){t+=e.O(),c((()=>t))},oe(t,{align:r,smooth:n,offset:o=0}={}){if(t=z(t,0,e.R()-1),"nearest"===r){const n=e.T(t),o=e.O();if(n<o)r="start";else{if(!(n+e.M(t)>o+e.v()))return;r="end"}}c((()=>o+e.J()+e.T(t)+("end"===r?e.M(t)-e.v():"center"===r?(e.M(t)-e.v())/2:0)),n)},se:()=>{n&&n.C()}}})(l,s),[_,b]=h(l.p()),T=l.L(1,(()=>{b(l.p())})),M=l.L(4,(()=>{var e;null===(e=r.onScroll)||void 0===e||e.call(r,l.O())})),E=l.L(8,(()=>{var e;null===(e=r.onScrollEnd)||void 0===e||e.call(r)})),R=f((e=>{_();const t=l.$();return e&&K(e,t)?e:t})),O=f((()=>_()&&l.P())),P=f((()=>_()&&l.B()));g((()=>{r.ref&&r.ref({get cache(){return l.m()},get scrollOffset(){return l.O()},get scrollSize(){return(e=>y(e.B(),e.v()))(l)},get viewportSize(){return l.v()},findStartIndex:l.S,findEndIndex:l._,getItemOffset:l.T,getItemSize:l.M,scrollToIndex:x.oe,scrollTo:x.re,scrollBy:x.ne});const e=r.scrollRef||n.parentElement;$.N(e),x.te(e),d((()=>{r.ref&&r.ref(),T(),M(),E(),$.ee(),x.ee()}))})),v(p((()=>r.startMargin||0),(e=>{e!==l.J()&&l.W(6,e)}))),u(p(_,(()=>{x.se()})));const J=f((()=>{const e=r.data.length;m((()=>{e!==l.R()&&l.W(5,[e,r.shift])}));const[t,n]=R(),o=n>=0?r.data.slice(t,n+1):[],s=o.map(((e,r)=>t+r));if(r.keepMounted){const e=[],i=[],c=[],l=[];I(r.keepMounted).forEach((o=>{o<0||o>=r.data.length||(o<t&&(e.push(r.data[o]),i.push(o)),o>n&&(c.push(r.data[o]),l.push(o)))})),o.unshift(...e),s.unshift(...i),o.push(...c),s.push(...l)}return{ie:o,ce:s}}));return e(t,{get component(){return r.as},ref(e){"function"==typeof n?n(e):n=e},get style(){return{contain:"strict","overflow-anchor":"none",overflow:"clip",flex:"none",position:"relative",width:s?P()+"px":"100%",height:s?"100%":P()+"px","pointer-events":O()?"none":void 0}},get children(){return e(w,{get each(){return J().ie},children:(t,n)=>((t,n)=>{const o=f((()=>(_(),l.T(n())))),i=f((()=>(_(),l.I(n())))),c=f((()=>m((()=>r.children(t,n)))));return e(G,{get X(){return r.item},get D(){return n()},get Y(){return $.Z},get A(){return o()},get G(){return i()},get K(){return c()},F:s})})(t,f((()=>J().ce[n()])))})}})};var Q=/*#__PURE__*/s("<div>");const Z=t=>{const[s,i]=$(t,["ref","data","children","overscan","itemSize","shift","horizontal","keepMounted","cache","item","onScroll","onScrollEnd","style"]);return c=Q(),r(c,n(i,{get style(){return{display:s.horizontal?"inline-block":"block",[s.horizontal?"overflow-x":"overflow-y"]:"auto",contain:"strict",width:"100%",height:"100%",...s.style}}}),!1,!0),o(c,e(N,{ref(e){var t=s.ref;"function"==typeof t?t(e):s.ref=e},get data(){return s.data},get overscan(){return s.overscan},get itemSize(){return s.itemSize},get shift(){return s.shift},get horizontal(){return s.horizontal},get keepMounted(){return s.keepMounted},get cache(){return s.cache},get item(){return s.item},get onScroll(){return s.onScroll},get onScrollEnd(){return s.onScrollEnd},get children(){return s.children}})),c;var c};var ee=/*#__PURE__*/s("<div style=overflow-anchor:none>");const te=t=>{let r;const{ref:n,data:s,children:a,overscan:v,itemSize:$,shift:x,horizontal:y=!1,cache:_,onScrollEnd:b}=t,I=X(t.data.length,$,v,void 0,_,!$),T=((e,t)=>{const r=t?"width":"height",n=t?"innerWidth":"innerHeight",o=new WeakMap,s=A((t=>{const n=[];for(const{target:e,contentRect:s}of t){if(!e.offsetParent)continue;const t=o.get(e);t!=S&&n.push([t,s[r]])}n.length&&e.W(3,n)}));let i;return{N(t){const r=j(W(t)),o=()=>{e.W(4,r[n])};r.addEventListener("resize",o),o(),i=()=>{r.removeEventListener("resize",o)}},Z:(e,t)=>(o.set(e,t),s.U(e),()=>{o.delete(e),s.V(e)}),ee(){i&&i(),s.q()}}})(I,y),M=((e,t)=>{let r,n,o;const s=(e,t,r,n,o=0)=>{const i=n?"offsetLeft":"offsetTop",c=o+(n&&q()?r.innerWidth-e[i]-e.offsetWidth:e[i]),l=e.offsetParent;return e!==t&&l?s(l,t,r,n,c):c},i=async(n,s)=>{if(!r)return void k((()=>i(n,s)));o&&o();const c=()=>{let t;return[new Promise(((r,n)=>{t=r,o=n,V(e)&&Y(n,150)})),e.L(2,(()=>{t&&t()}))]},l=j(W(r));if(s&&U()){for(;e.W(8,n()),e.k();){const[e,t]=c();try{await e}catch(e){return}finally{t()}}l.scroll({[t?"left":"top"]:D(n(),t),behavior:"smooth"})}else for(;;){const[r,o]=c();try{l.scroll({[t?"left":"top"]:D(n(),t)}),e.W(7),await r}catch(e){return}finally{o()}}};return{te(o){r=o;const i=t?"scrollX":"scrollY",c=W(o),l=j(c),a=c.body;n=F(e,l,t,(()=>D(l[i],t)),((r,n)=>{n?l.scroll({[t?"left":"top"]:e.O()+r}):l.scrollBy(t?r:0,t?0:r)}),(()=>s(o,a,l,t)))},ee(){n&&n.q(),r=void 0},se:()=>{n&&n.C()},oe(n,{align:o,smooth:c,offset:l=0}={}){if(!r)return;if(n=z(n,0,e.R()-1),"nearest"===o){const t=e.T(n),r=e.O();if(t<r)o="start";else{if(!(t+e.M(n)>r+e.v()))return;o="end"}}const a=W(r),u=j(a),f=a.documentElement,d=()=>e.v()-(t?f.clientWidth:f.clientHeight);i((()=>l+s(r,a.body,u,t)+e.T(n)+("end"===o?e.M(n)-(e.v()-d()):"center"===o?(e.M(n)-(e.v()-d()))/2:0)),c)}}})(I,y),[E,R]=h(I.p()),O=I.L(1,(()=>{R(I.p())})),P=I.L(4,(()=>{var e;null===(e=t.onScroll)||void 0===e||e.call(t)})),J=I.L(8,(()=>{var e;null===(e=t.onScrollEnd)||void 0===e||e.call(t)})),B=f((e=>{E();const t=I.$();return e&&K(e,t)?e:t})),H=f((()=>E()&&I.P())),L=f((()=>E()&&I.B()));g((()=>{t.ref&&t.ref({get cache(){return I.m()},findStartIndex:I.S,findEndIndex:I._,scrollToIndex:M.oe}),T.N(r),M.te(r),d((()=>{t.ref&&t.ref(),O(),P(),J(),T.ee(),M.ee()}))})),u(p(E,(()=>{M.se()})));const C=f((()=>{const e=t.data.length;m((()=>{e!==I.R()&&I.W(5,[e,t.shift])}));const[r,n]=B();return n>=0?t.data.slice(r,n+1):[]}));return N=ee(),"function"==typeof r?i(r,N):r=N,c(N,"contain","strict"),c(N,"overflow","clip"),c(N,"flex","none"),c(N,"position","relative"),o(N,e(w,{get each(){return C()},children:(r,n)=>{const o=f((()=>B()[0]+n())),s=f((()=>(E(),I.T(o())))),i=f((()=>(E(),I.I(o())))),c=f((()=>m((()=>t.children(r,o)))));return e(G,{get D(){return o()},get Y(){return T.Z},get A(){return s()},get G(){return i()},get K(){return c()},F:y})}})),l((e=>{var t=y?L()+"px":"100%",r=y?"100%":L()+"px",n=H()?"none":void 0;return t!==e.e&&c(N,"width",e.e=t),r!==e.t&&c(N,"height",e.t=r),n!==e.a&&c(N,"pointer-events",e.a=n),e}),{e:void 0,t:void 0,a:void 0}),N;var N};export{Z as VList,N as Virtualizer,te as WindowVirtualizer};
//# sourceMappingURL=index.mjs.map