virtua 0.36.0 → 0.36.2

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.
@@ -0,0 +1,140 @@
1
+ <script lang="ts" generics="T">
2
+ import { onMount, onDestroy } from "svelte";
3
+ import {
4
+ SCROLL_IDLE,
5
+ type StateVersion,
6
+ getOverscanedRange,
7
+ CHANGE_ITEM_LENGTH,
8
+ createWindowVirtualizer,
9
+ FIX_SCROLL_JUMP,
10
+ GET_ITEM_OFFSET,
11
+ GET_JUMP_COUNT,
12
+ GET_RANGE,
13
+ GET_SCROLL_DIRECTION,
14
+ GET_TOTAL_SIZE,
15
+ IS_ITEM_HIDDEN,
16
+ OBSERVE_ITEM_RESIZE,
17
+ ON_MOUNT,
18
+ ON_UN_MOUNT,
19
+ GET_ITEMS_LENGTH,
20
+ } from "./core";
21
+ import { defaultGetKey, styleToString } from "./utils";
22
+ import ListItem from "./ListItem.svelte";
23
+ import type { WindowVirtualizerProps } from "./WindowVirtualizer.type";
24
+
25
+ interface Props extends WindowVirtualizerProps<T> {}
26
+
27
+ let {
28
+ data,
29
+ getKey = defaultGetKey,
30
+ overscan = 4,
31
+ itemSize,
32
+ shift = false,
33
+ horizontal = false,
34
+ children,
35
+ onscrollend,
36
+ onrangechange,
37
+ }: Props = $props();
38
+
39
+ const virtualizer = createWindowVirtualizer(
40
+ data.length,
41
+ itemSize,
42
+ horizontal,
43
+ (v) => {
44
+ rerender = v;
45
+ },
46
+ () => {
47
+ onscrollend && onscrollend();
48
+ }
49
+ );
50
+
51
+ let containerRef: HTMLDivElement | undefined = $state();
52
+
53
+ let rerender: StateVersion = $state([]);
54
+
55
+ let range = $derived(rerender && virtualizer[GET_RANGE]());
56
+ let scrollDirection = $derived(
57
+ rerender && virtualizer[GET_SCROLL_DIRECTION]()
58
+ );
59
+ let totalSize = $derived(rerender && virtualizer[GET_TOTAL_SIZE]());
60
+ let jumpCount = $derived(rerender && virtualizer[GET_JUMP_COUNT]());
61
+ let extendedRange = $derived(
62
+ getOverscanedRange(
63
+ range[0],
64
+ range[1],
65
+ overscan,
66
+ scrollDirection,
67
+ data.length
68
+ )
69
+ );
70
+
71
+ onMount(() => {
72
+ virtualizer[ON_MOUNT](containerRef!);
73
+ });
74
+ onDestroy(() => {
75
+ virtualizer[ON_UN_MOUNT]();
76
+ });
77
+
78
+ $effect.pre(() => {
79
+ if (data.length !== virtualizer[GET_ITEMS_LENGTH]()) {
80
+ virtualizer[CHANGE_ITEM_LENGTH](data.length, shift);
81
+ }
82
+ });
83
+
84
+ let prevJumpCount: number | undefined;
85
+ $effect(() => {
86
+ if (prevJumpCount === jumpCount) return;
87
+ prevJumpCount = jumpCount;
88
+ virtualizer[FIX_SCROLL_JUMP]();
89
+ });
90
+
91
+ let prevRange: typeof range | undefined;
92
+ $effect(() => {
93
+ if (prevRange && prevRange[0] === range[0] && prevRange[1] === range[1])
94
+ return;
95
+ prevRange = range;
96
+ onrangechange && onrangechange(range[0], range[1]);
97
+ });
98
+
99
+ let items = $derived.by(() => {
100
+ const [startIndex, endIndex] = extendedRange;
101
+ const newItems: T[] = [];
102
+ for (let i = startIndex, j = endIndex; i <= j; i++) {
103
+ newItems.push(data[i]!);
104
+ }
105
+ return newItems;
106
+ });
107
+
108
+ let containerStyle = $derived(
109
+ styleToString({
110
+ // contain: "content",
111
+ "overflow-anchor": "none", // opt out browser's scroll anchoring because it will conflict to scroll anchoring of virtualizer
112
+ flex: "none", // flex style can break layout
113
+ position: "relative",
114
+ visibility: "hidden", // TODO replace with other optimization methods
115
+ width: horizontal ? totalSize + "px" : "100%",
116
+ height: horizontal ? "100%" : totalSize + "px",
117
+ "pointer-events": scrollDirection !== SCROLL_IDLE ? "none" : undefined,
118
+ })
119
+ );
120
+ </script>
121
+
122
+ <!--
123
+ @component
124
+ {@link Virtualizer} controlled by the window scrolling. See {@link WindowVirtualizerProps} and {@link WindowVirtualizerHandle}.
125
+ -->
126
+ <div bind:this={containerRef} style={containerStyle}>
127
+ {#each items as item, i (getKey(item, i + extendedRange[0]))}
128
+ {@const index = i + extendedRange[0]}
129
+ <ListItem
130
+ {children}
131
+ {item}
132
+ {index}
133
+ as={"div"}
134
+ offset={rerender && virtualizer[GET_ITEM_OFFSET](index)}
135
+ hide={rerender && virtualizer[IS_ITEM_HIDDEN](index)}
136
+ {horizontal}
137
+ resizer={virtualizer[OBSERVE_ITEM_RESIZE]}
138
+ />
139
+ {/each}
140
+ </div>
@@ -0,0 +1,19 @@
1
+ import type { WindowVirtualizerProps } from "./WindowVirtualizer.type";
2
+ declare class __sveltets_Render<T> {
3
+ props(): WindowVirtualizerProps<T>;
4
+ events(): {};
5
+ slots(): {};
6
+ bindings(): "";
7
+ exports(): {};
8
+ }
9
+ interface $$IsomorphicComponent {
10
+ new <T>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
11
+ $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
12
+ } & ReturnType<__sveltets_Render<T>['exports']>;
13
+ <T>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
14
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
15
+ }
16
+ /** {@link Virtualizer} controlled by the window scrolling. See {@link WindowVirtualizerProps} and {@link WindowVirtualizerHandle}. */
17
+ declare const WindowVirtualizer: $$IsomorphicComponent;
18
+ type WindowVirtualizer<T> = InstanceType<typeof WindowVirtualizer<T>>;
19
+ export default WindowVirtualizer;
@@ -0,0 +1,50 @@
1
+ // @ts-nocheck
2
+ import { type Snippet } from "svelte";
3
+ /**
4
+ * Props of {@link WindowVirtualizer}.
5
+ */
6
+ export interface WindowVirtualizerProps<T> {
7
+ /**
8
+ * The data items rendered by this component.
9
+ */
10
+ data: T[];
11
+ /**
12
+ * The elements renderer snippet.
13
+ */
14
+ children: Snippet<[item: T, index: number]>;
15
+ /**
16
+ * Function that returns the key of an item in the list. It's recommended to specify whenever possible for performance.
17
+ * @default defaultGetKey (returns index of item)
18
+ */
19
+ getKey?: (data: T, index: number) => string | number;
20
+ /**
21
+ * Number of items to render above/below the visible bounds of the list. You can increase to avoid showing blank items in fast scrolling.
22
+ * @defaultValue 4
23
+ */
24
+ overscan?: number;
25
+ /**
26
+ * Item size hint for unmeasured items. It will help to reduce scroll jump when items are measured if used properly.
27
+ *
28
+ * - If not set, initial item sizes will be automatically estimated from measured sizes. This is recommended for most cases.
29
+ * - If set, you can opt out estimation and use the value as initial item size.
30
+ */
31
+ itemSize?: number;
32
+ /**
33
+ * While true is set, scroll position will be maintained from the end not usual start when items are added to/removed from start. It's recommended to set false if you add to/remove from mid/end of the list because it can cause unexpected behavior. This prop is useful for reverse infinite scrolling.
34
+ */
35
+ shift?: boolean;
36
+ /**
37
+ * If true, rendered as a horizontally scrollable list. Otherwise rendered as a vertically scrollable list.
38
+ */
39
+ horizontal?: boolean;
40
+ /**
41
+ * Callback invoked when scrolling stops.
42
+ */
43
+ onscrollend?: () => void;
44
+ /**
45
+ * Callback invoked when visible items range changes.
46
+ * @param startIndex The start index of viewable items.
47
+ * @param endIndex The end index of viewable items.
48
+ */
49
+ onrangechange?: (startIndex: number, endIndex: number) => void;
50
+ }
@@ -0,0 +1,10 @@
1
+ export {};
2
+ // /**
3
+ // * Methods of {@link WindowVirtualizer}.
4
+ // */
5
+ // export interface WindowVirtualizerHandle {
6
+ // /**
7
+ // * Get current {@link CacheSnapshot}.
8
+ // */
9
+ // readonly cache: CacheSnapshot;
10
+ // }
@@ -49,3 +49,23 @@ export declare const createVirtualizer: (count: number, itemSize: number | undef
49
49
  18: (offset: number) => void;
50
50
  19: (index: number, opts?: import("..").ScrollToIndexOpts) => void;
51
51
  };
52
+ /**
53
+ * This function is workaround for terser minification.
54
+ * Svelte doesn't seem to have a good way to modify and print its AST.
55
+ */
56
+ export declare const createWindowVirtualizer: (count: number, itemSize: number | undefined, horizontal: boolean, onUpdate: (v: StateVersion) => void, onScrollEnd: () => void) => {
57
+ 0: (scrollable: HTMLElement) => void;
58
+ 1: () => void;
59
+ 2: () => import("../core/types").ItemsRange;
60
+ 3: () => number;
61
+ 4: () => number;
62
+ 5: () => number;
63
+ 6: () => import("../core/store").ScrollDirection;
64
+ 7: () => number;
65
+ 8: (index: number) => number;
66
+ 9: (index: number) => boolean;
67
+ 10: () => number;
68
+ 12: import("./core").ItemResizeObserver;
69
+ 13: () => void;
70
+ 14: (len: number, shift?: boolean) => void;
71
+ };
@@ -1 +1 @@
1
- const e=null,{min:t,max:r,abs:o,floor:n}=Math,s=setTimeout,c=(e,o,n)=>t(n,r(o,e)),i="function"==typeof queueMicrotask?queueMicrotask:e=>{Promise.resolve().then(e)},a=e=>{let t,r;return(...o)=>(t||(t=!0,r=e(...o)),r)},l=-1,u=(e,t,r)=>{const o=r?"unshift":"push";for(let r=0;r<t;r++)e[o](l);return e},f=(e,t)=>{const r=e.t[t];return r===l?e.o:r},_=(e,r,o)=>{const n=e.t[r]===l;return e.t[r]=o,e.i=t(r,e.i),n},d=(e,t)=>{if(!e.l)return 0;if(e.i>=t)return e.u[t];e.i<0&&(e.u[0]=0,e.i=0);let r=e.i,o=e.u[r];for(;r<t;)o+=f(e,r),e.u[++r]=o;return e.i=t,o},h=(e,t,r=0,o=e.l-1)=>{for(;r<=o;){const s=n((r+o)/2),c=d(e,s);if(c<=t){if(c+f(e,s)>t)return s;r=s+1}else o=s-1}return c(r,0,e.l-1)},m=(e,r,o)=>{const n=r-e.l;return e.i=o?-1:t(r-1,e.i),e.l=r,n>0?(u(e.u,n),u(e.t,n,o),e.o*n):(e.u.splice(n),(o?e.t.splice(0,-n):e.t.splice(n)).reduce(((t,r)=>t-(r===l?e.o:r)),0))},p="undefined"!=typeof window,g=()=>document.documentElement,v=/*#__PURE__*/a((()=>!!p&&"rtl"===getComputedStyle(g()).direction)),b=/*#__PURE__*/a((()=>/iP(hone|od|ad)/.test(navigator.userAgent))),w=/*#__PURE__*/a((()=>"scrollBehavior"in g().style)),S=0,k=(e,o,n,s,c)=>(1!==s&&(e-=r(0,n)),2!==s&&(o+=r(0,n)),[r(e,0),t(o,c-1)]),I=(e,t)=>t&&v()?-e:e,y=0,z=1,x=2,T=3,J=4,M=5,R=6,C=7,O=8,P=9,q=10,B=11,D=12,L=13,U=14,V=15,F=16,W=17,X=18,Y=19,j=(n,a,p,g,v,S)=>{const k=((n,s=40,c=0,i,a=!1)=>{let p=!!c,g=[],v=0,w=0,S=0,k=0,I=0,y=0,z=0,x=0,T=0,J=p?[0,r(c-1,0)]:e,M=[0,0],R=0;const C=((e,t)=>({o:t,t:u([],e),l:e,i:-1,u:u([],e)}))(n,s),O=new Set,P=()=>S-w,q=e=>((e,r,o,n)=>{if(n=t(n,e.l-1),d(e,n)<=r){const t=h(e,r+o,n);return[h(e,r,n,t),t]}{const t=h(e,r,void 0,n);return[t,h(e,r+o,t)]}})(C,e,v,M[0]),B=()=>(e=>e.l?d(e,e.l-1)+f(e,e.l-1):0)(C),D=e=>d(C,e)-y,L=e=>f(C,e),U=e=>{e&&(b()&&0!==x?y+=e:(I+=e,k++))};return{_:()=>g,h:()=>(e=>[e.t.slice(),e.o])(C),m:()=>z?M:(M=q(r(0,P()+y+I)),J?[t(M[0],J[0]),r(M[1],J[1])]:M),p:e=>C.t[e]===l,v:()=>!!J&&C.t.slice(r(0,J[0]-1),t(C.l-1,J[1]+1)+1).includes(l),S:D,k:L,I:()=>C.l,T:()=>S,J:()=>x,M:()=>v,R:()=>w,C:B,O:()=>k,P:()=>(z=I,I=0,[z,2===T||P()+v>=B()]),q(e,t){const r=[e,t];return O.add(r),()=>{O.delete(r)}},B(t,n){let s,c,i=0;switch(t){case 1:{const t=z;z=0;const r=n-S,s=o(r);t&&s<o(t)+1||0!==T||(x=r<0?2:1),p&&(J=e,p=!1),S=n,i=4;const a=P();a>=-v&&a<=B()&&(i+=1,c=s>v);break}case 2:i=8,0!==x&&(s=!0,i+=1),x=0,T=0,J=e;break;case 3:{const e=n.filter((([e,t])=>C.t[e]!==t));if(!e.length)break;U(e.reduce(((e,[t,r])=>((2===T||(J?t<J[0]:D(t)+(0===x&&0===T?L(t):0)<P()))&&(e+=r-L(t)),e)),0));for(const[t,r]of e){const e=L(t),o=_(C,t,r);a&&(R+=o?r:r-e)}a&&v&&R>v&&(U(((e,t)=>{let o=0;const n=e.t.filter(((e,r)=>{const n=e!==l;return n&&r<t&&o++,n})),s=e.o;return e.i=-1,((e.o=(e=>{const t=(e=>[...e].sort(((e,t)=>e-t)))(e),r=e.length/2|0;return t.length%2==0?(t[r-1]+t[r])/2:t[r]})(n))-s)*r(t-o,0)})(C,M[0])),a=!1),i=3,c=!0;break}case 4:v!==n&&(v=n,i=3);break;case 5:n[1]?(U(m(C,n[0],!0)),T=2,i=1):m(C,n[0]);break;case 6:w=n;break;case 7:T=1;break;case 8:J=q(n),i=1}i&&(g=[],s&&y&&(I+=y,y=0,k++),O.forEach((([e,t])=>{i&e&&t(c)})))}}})(n,null!=a?a:40,void 0,0,!a),j=((t,r)=>{let o;const n=r?"width":"height",s=new WeakMap,c=(e=>{let t;return{D(r){var o,n;(t||(t=new(n=r,o=n.ownerDocument,o.defaultView).ResizeObserver(e))).observe(r)},L(e){t.unobserve(e)},U(){t&&t.disconnect()}}})((r=>{const c=[];for(const{target:i,contentRect:a}of r)if(i.offsetParent)if(i===o)t.B(4,a[n]);else{const t=s.get(i);t!=e&&c.push([t,a[n]])}c.length&&t.B(3,c)}));return{V(e){c.D(o=e)},F:(e,t)=>(s.set(e,t),c.D(e),()=>{s.delete(e),c.L(e)}),U:c.U}})(k,p),A=((t,r)=>{let o,n,a;const l=r?"scrollLeft":"scrollTop",u=r?"overflowX":"overflowY",f=async(e,n)=>{if(!o)return void i((()=>f(e,n)));a&&a();const c=()=>{let e;return[new Promise(((r,o)=>{e=r,a=o,(e=>!!e.M())(t)&&s(o,150)})),t.q(2,(()=>{e&&e()}))]};if(n&&w()){for(;t.B(8,e()),t.v();){const[e,t]=c();try{await e}catch(e){return}finally{t()}}o.scrollTo({[r?"left":"top"]:I(e(),r),behavior:"smooth"})}else for(;;){const[n,s]=c();try{o[l]=I(e(),r),t.B(7),await n}catch(e){return}finally{s()}}};return{D(c){o=c,n=((t,r,o,n,c)=>{const i=Date.now;let a=0,l=!1,u=!1,f=!1,_=!1;const d=(()=>{let r;const o=()=>{r!=e&&clearTimeout(r)},n=()=>{o(),r=s((()=>{r=e,(()=>{if(l||u)return l=!1,void d();f=!1,t.B(2)})()}),150)};return n.W=o,n})(),h=()=>{a=i(),f&&(_=!0),t.B(1,n()),d()},m=e=>{if(l||0===t.J()||e.ctrlKey)return;const r=i()-a;150>r&&50<r&&(o?e.deltaX:e.deltaY)&&(l=!0)},p=()=>{u=!0,f=_=!1},g=()=>{u=!1,b()&&(f=!0)};return r.addEventListener("scroll",h),r.addEventListener("wheel",m,{passive:!0}),r.addEventListener("touchstart",p,{passive:!0}),r.addEventListener("touchend",g,{passive:!0}),{U:()=>{r.removeEventListener("scroll",h),r.removeEventListener("wheel",m),r.removeEventListener("touchstart",p),r.removeEventListener("touchend",g),d.W()},X:()=>{const[e,r]=t.P();e&&(c(I(e,o),r,_),_=!1,r&&t.M()>t.C()&&t.B(1,n()))}}})(t,c,r,(()=>I(c[l],r)),((e,r,o)=>{if(o){const e=c.style,t=e[u];e[u]="hidden",s((()=>{e[u]=t}))}r?(c[l]=t.T()+e,a&&a()):c[l]+=e}))},U(){n&&n.U()},Y(e){f((()=>e))},j(e){e+=t.T(),f((()=>e))},A(e,{align:r,smooth:o,offset:n=0}={}){if(e=c(e,0,t.I()-1),"nearest"===r){const o=t.S(e),n=t.T();if(o<n)r="start";else{if(!(o+t.k(e)>n+t.M()))return;r="end"}}f((()=>n+t.R()+t.S(e)+("end"===r?t.k(e)-t.M():"center"===r?(t.k(e)-t.M())/2:0)),o)},X:()=>{n&&n.X()}}})(k,p),E=k.q(1,(()=>{g(k._())})),G=k.q(4,(()=>{v(k.T())})),H=k.q(8,(()=>{S()}));return{[y]:e=>{j.V(e),A.D(e)},[z]:()=>{E(),G(),H(),j.U(),A.U()},[x]:k.m,[T]:k.C,[J]:k.M,[M]:k.T,[R]:k.J,[C]:k.O,[O]:k.S,[P]:k.p,[q]:k.I,[B]:k.R,[D]:j.F,[L]:A.X,[U]:(e,t)=>{k.B(5,[e,t])},[V]:e=>{k.B(6,e)},[F]:()=>(e=>r(e.C(),e.M()))(k),[W]:A.Y,[X]:A.j,[Y]:A.A}};export{U as CHANGE_ITEM_LENGTH,V as CHANGE_START_MARGIN,L as FIX_SCROLL_JUMP,q as GET_ITEMS_LENGTH,O as GET_ITEM_OFFSET,C as GET_JUMP_COUNT,x as GET_RANGE,R as GET_SCROLL_DIRECTION,M as GET_SCROLL_OFFSET,F as GET_SCROLL_SIZE,B as GET_START_SPACER_SIZE,T as GET_TOTAL_SIZE,J as GET_VIEWPORT_SIZE,P as IS_ITEM_HIDDEN,D as OBSERVE_ITEM_RESIZE,y as ON_MOUNT,z as ON_UN_MOUNT,X as SCROLL_BY,S as SCROLL_IDLE,W as SCROLL_TO,Y as SCROLL_TO_INDEX,j as createVirtualizer,k as getOverscanedRange,v as isRTLDocument};
1
+ const e=null,{min:t,max:o,abs:r,floor:n}=Math,s=setTimeout,c=(e,r,n)=>t(n,o(r,e)),i="function"==typeof queueMicrotask?queueMicrotask:e=>{Promise.resolve().then(e)},l=e=>{let t,o;return(...r)=>(t||(t=!0,o=e(...r)),o)},u=-1,a=(e,t,o)=>{const r=o?"unshift":"push";for(let o=0;o<t;o++)e[r](u);return e},f=(e,t)=>{const o=e.t[t];return o===u?e.o:o},_=(e,o,r)=>{const n=e.t[o]===u;return e.t[o]=r,e.i=t(o,e.i),n},d=(e,t)=>{if(!e.l)return 0;if(e.i>=t)return e.u[t];e.i<0&&(e.u[0]=0,e.i=0);let o=e.i,r=e.u[o];for(;o<t;)r+=f(e,o),e.u[++o]=r;return e.i=t,r},h=(e,t,o=0,r=e.l-1)=>{for(;o<=r;){const s=n((o+r)/2),c=d(e,s);if(c<=t){if(c+f(e,s)>t)return s;o=s+1}else r=s-1}return c(o,0,e.l-1)},p=(e,o,r)=>{const n=o-e.l;return e.i=r?-1:t(o-1,e.i),e.l=o,n>0?(a(e.u,n),a(e.t,n,r),e.o*n):(e.u.splice(n),(r?e.t.splice(0,-n):e.t.splice(n)).reduce(((t,o)=>t-(o===u?e.o:o)),0))},m="undefined"!=typeof window,g=()=>document.documentElement,v=e=>e.ownerDocument,b=e=>e.defaultView,w=/*#__PURE__*/l((()=>!!m&&"rtl"===getComputedStyle(g()).direction)),S=/*#__PURE__*/l((()=>/iP(hone|od|ad)/.test(navigator.userAgent))),k=/*#__PURE__*/l((()=>"scrollBehavior"in g().style)),I=0,y=(e,r,n,s,c)=>(1!==s&&(e-=o(0,n)),2!==s&&(r+=o(0,n)),[o(e,0),t(r,c-1)]),z=(n,s=40,c=0,i,l=!1)=>{let m=!!c,g=[],v=0,b=0,w=0,k=0,I=0,y=0,z=0,x=0,T=0,R=m?[0,o(c-1,0)]:e,J=[0,0],M=0;const C=((e,t)=>({o:t,t:a([],e),l:e,i:-1,u:a([],e)}))(n,s),L=new Set,O=()=>w-b,P=e=>((e,o,r,n)=>{if(n=t(n,e.l-1),d(e,n)<=o){const t=h(e,o+r,n);return[h(e,o,n,t),t]}{const t=h(e,o,void 0,n);return[t,h(e,o+r,t)]}})(C,e,v,J[0]),W=()=>(e=>e.l?d(e,e.l-1)+f(e,e.l-1):0)(C),q=e=>d(C,e)-y,B=e=>f(C,e),D=e=>{e&&(S()&&0!==x?y+=e:(I+=e,k++))};return{_:()=>g,h:()=>(e=>[e.t.slice(),e.o])(C),p:()=>z?J:(J=P(o(0,O()+y+I)),R?[t(J[0],R[0]),o(J[1],R[1])]:J),m:e=>C.t[e]===u,v:()=>!!R&&C.t.slice(o(0,R[0]-1),t(C.l-1,R[1]+1)+1).includes(u),S:q,k:B,I:()=>C.l,T:()=>w,R:()=>x,J:()=>v,M:()=>b,C:W,L:()=>k,O:()=>(z=I,I=0,[z,2===T||O()+v>=W()]),P(e,t){const o=[e,t];return L.add(o),()=>{L.delete(o)}},W(t,n){let s,c,i=0;switch(t){case 1:{const t=z;z=0;const o=n-w,s=r(o);t&&s<r(t)+1||0!==T||(x=o<0?2:1),m&&(R=e,m=!1),w=n,i=4;const l=O();l>=-v&&l<=W()&&(i+=1,c=s>v);break}case 2:i=8,0!==x&&(s=!0,i+=1),x=0,T=0,R=e;break;case 3:{const e=n.filter((([e,t])=>C.t[e]!==t));if(!e.length)break;D(e.reduce(((e,[t,o])=>((2===T||(R?t<R[0]:q(t)+(0===x&&0===T?B(t):0)<O()))&&(e+=o-B(t)),e)),0));for(const[t,o]of e){const e=B(t),r=_(C,t,o);l&&(M+=r?o:o-e)}l&&v&&M>v&&(D(((e,t)=>{let r=0;const n=e.t.filter(((e,o)=>{const n=e!==u;return n&&o<t&&r++,n})),s=e.o;return e.i=-1,((e.o=(e=>{const t=(e=>[...e].sort(((e,t)=>e-t)))(e),o=e.length/2|0;return t.length%2==0?(t[o-1]+t[o])/2:t[o]})(n))-s)*o(t-r,0)})(C,J[0])),l=!1),i=3,c=!0;break}case 4:v!==n&&(v=n,i=3);break;case 5:n[1]?(D(p(C,n[0],!0)),T=2,i=1):p(C,n[0]);break;case 6:b=n;break;case 7:T=1;break;case 8:R=P(n),i=1}i&&(g=[],s&&y&&(I+=y,y=0,k++),L.forEach((([e,t])=>{i&e&&t(c)})))}}},x=e=>{let t;return{q(o){(t||(t=new(b(v(o)).ResizeObserver)(e))).observe(o)},B(e){t.unobserve(e)},D(){t&&t.disconnect()}}},T=(e,t)=>t&&w()?-e:e,R=(t,o,r,n,c,i)=>{const l=Date.now;let u=0,a=!1,f=!1,_=!1,d=!1;const h=(()=>{let o;const r=()=>{o!=e&&clearTimeout(o)},n=()=>{r(),o=s((()=>{o=e,(()=>{if(a||f)return a=!1,void h();_=!1,t.W(2)})()}),150)};return n.U=r,n})(),p=()=>{u=l(),_&&(d=!0),i&&t.W(6,i()),t.W(1,n()),h()},m=e=>{if(a||0===t.R()||e.ctrlKey)return;const o=l()-u;150>o&&50<o&&(r?e.deltaX:e.deltaY)&&(a=!0)},g=()=>{f=!0,_=d=!1},v=()=>{f=!1,S()&&(_=!0)};return o.addEventListener("scroll",p),o.addEventListener("wheel",m,{passive:!0}),o.addEventListener("touchstart",g,{passive:!0}),o.addEventListener("touchend",v,{passive:!0}),{D:()=>{o.removeEventListener("scroll",p),o.removeEventListener("wheel",m),o.removeEventListener("touchstart",g),o.removeEventListener("touchend",v),h.U()},V:()=>{const[e,o]=t.O();e&&(c(T(e,r),o,d),d=!1,o&&t.J()>t.C()&&t.W(1,n()))}}},J=0,M=1,C=2,L=3,O=4,P=5,W=6,q=7,B=8,D=9,U=10,V=11,X=12,Y=13,F=14,H=15,j=16,A=17,E=18,G=19,K=(t,r,n,l,u,a)=>{const f=z(t,null!=r?r:40,void 0,0,!r),_=((t,o)=>{let r;const n=o?"width":"height",s=new WeakMap,c=x((o=>{const c=[];for(const{target:i,contentRect:l}of o)if(i.offsetParent)if(i===r)t.W(4,l[n]);else{const t=s.get(i);t!=e&&c.push([t,l[n]])}c.length&&t.W(3,c)}));return{X(e){c.q(r=e)},Y:(e,t)=>(s.set(e,t),c.q(e),()=>{s.delete(e),c.B(e)}),D:c.D}})(f,n),d=((e,t)=>{let o,r,n;const l=t?"scrollLeft":"scrollTop",u=t?"overflowX":"overflowY",a=async(r,c)=>{if(!o)return void i((()=>a(r,c)));n&&n();const u=()=>{let t;return[new Promise(((o,r)=>{t=o,n=r,(e=>!!e.J())(e)&&s(r,150)})),e.P(2,(()=>{t&&t()}))]};if(c&&k()){for(;e.W(8,r()),e.v();){const[e,t]=u();try{await e}catch(e){return}finally{t()}}o.scrollTo({[t?"left":"top"]:T(r(),t),behavior:"smooth"})}else for(;;){const[n,s]=u();try{o[l]=T(r(),t),e.W(7),await n}catch(e){return}finally{s()}}};return{q(c){o=c,r=R(e,c,t,(()=>T(c[l],t)),((t,o,r)=>{if(r){const e=c.style,t=e[u];e[u]="hidden",s((()=>{e[u]=t}))}o?(c[l]=e.T()+t,n&&n()):c[l]+=t}))},D(){r&&r.D()},F(e){a((()=>e))},H(t){t+=e.T(),a((()=>t))},j(t,{align:o,smooth:r,offset:n=0}={}){if(t=c(t,0,e.I()-1),"nearest"===o){const r=e.S(t),n=e.T();if(r<n)o="start";else{if(!(r+e.k(t)>n+e.J()))return;o="end"}}a((()=>n+e.M()+e.S(t)+("end"===o?e.k(t)-e.J():"center"===o?(e.k(t)-e.J())/2:0)),r)},V:()=>{r&&r.V()}}})(f,n),h=f.P(1,(()=>{l(f._())})),p=f.P(4,(()=>{u(f.T())})),m=f.P(8,(()=>{a()}));return{[J]:e=>{_.X(e),d.q(e)},[M]:()=>{h(),p(),m(),_.D(),d.D()},[C]:f.p,[L]:f.C,[O]:f.J,[P]:f.T,[W]:f.R,[q]:f.L,[B]:f.S,[D]:f.m,[U]:f.I,[V]:f.M,[X]:_.Y,[Y]:d.V,[F]:(e,t)=>{f.W(5,[e,t])},[H]:e=>{f.W(6,e)},[j]:()=>(e=>o(e.C(),e.J()))(f),[A]:d.F,[E]:d.H,[G]:d.j}},N=(t,o,r,n,s)=>{const c=z(t,null!=o?o:40,void 0,0,!o),i=((t,o)=>{const r=o?"width":"height",n=o?"innerWidth":"innerHeight",s=new WeakMap,c=x((o=>{const n=[];for(const{target:t,contentRect:c}of o){if(!t.offsetParent)continue;const o=s.get(t);o!=e&&n.push([o,c[r]])}n.length&&t.W(3,n)}));let i;return{X(e){const o=b(v(e)),r=()=>{t.W(4,o[n])};o.addEventListener("resize",r),r(),i=()=>{o.removeEventListener("resize",r)}},Y:(e,t)=>(s.set(e,t),c.q(e),()=>{s.delete(e),c.B(e)}),D(){i&&i(),c.D()}}})(c,r),l=((e,t)=>{let o;return{q(r){const n=t?"scrollX":"scrollY",s=v(r),c=b(s),i=s.body,l=(e,t,o,r=0)=>{const n=o?"offsetLeft":"offsetTop",s=r+(o&&w()?c.innerWidth-e[n]-e.offsetWidth:e[n]),i=e.offsetParent;return e!==t&&i?l(i,t,o,s):s};o=R(e,c,t,(()=>T(c[n],t)),((o,r)=>{r?c.scroll({[t?"left":"top"]:e.T()+o}):c.scrollBy(t?o:0,t?0:o)}),(()=>l(r,i,t)))},D(){o&&o.D()},V:()=>{o&&o.V()}}})(c,r),u=c.P(1,(()=>{n(c._())})),a=c.P(8,(()=>{s()}));return{[J]:e=>{i.X(e),l.q(e)},[M]:()=>{u(),a(),i.D(),l.D()},[C]:c.p,[L]:c.C,[O]:c.J,[P]:c.T,[W]:c.R,[q]:c.L,[B]:c.S,[D]:c.m,[U]:c.I,[X]:i.Y,[Y]:l.V,[F]:(e,t)=>{c.W(5,[e,t])}}};export{F as CHANGE_ITEM_LENGTH,H as CHANGE_START_MARGIN,Y as FIX_SCROLL_JUMP,U as GET_ITEMS_LENGTH,B as GET_ITEM_OFFSET,q as GET_JUMP_COUNT,C as GET_RANGE,W as GET_SCROLL_DIRECTION,P as GET_SCROLL_OFFSET,j as GET_SCROLL_SIZE,V as GET_START_SPACER_SIZE,L as GET_TOTAL_SIZE,O as GET_VIEWPORT_SIZE,D as IS_ITEM_HIDDEN,X as OBSERVE_ITEM_RESIZE,J as ON_MOUNT,M as ON_UN_MOUNT,E as SCROLL_BY,I as SCROLL_IDLE,A as SCROLL_TO,G as SCROLL_TO_INDEX,K as createVirtualizer,N as createWindowVirtualizer,y as getOverscanedRange,w as isRTLDocument};
@@ -5,3 +5,5 @@ export { default as VList } from "./VList.svelte";
5
5
  export type { VListProps, VListHandle } from "./VList.type";
6
6
  export { default as Virtualizer } from "./Virtualizer.svelte";
7
7
  export type { VirtualizerProps, VirtualizerHandle } from "./Virtualizer.type";
8
+ export { default as WindowVirtualizer } from "./WindowVirtualizer.svelte";
9
+ export type { WindowVirtualizerProps } from "./WindowVirtualizer.type";
@@ -3,3 +3,4 @@
3
3
  */
4
4
  export { default as VList } from "./VList.svelte";
5
5
  export { default as Virtualizer } from "./Virtualizer.svelte";
6
+ export { default as WindowVirtualizer } from "./WindowVirtualizer.svelte";
@@ -41,7 +41,7 @@ export declare const VList: import("vue").DefineComponent<{
41
41
  }, VListHandle, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
42
42
  /**
43
43
  * Callback invoked whenever scroll offset changes.
44
- * @param offset Current scrollTop or scrollLeft.
44
+ * @param offset Current scrollTop, or scrollLeft if horizontal: true.
45
45
  */
46
46
  scroll: (offset: number) => void;
47
47
  /**
@@ -50,16 +50,10 @@ export declare const VList: import("vue").DefineComponent<{
50
50
  scrollEnd: () => void;
51
51
  /**
52
52
  * Callback invoked when visible items range changes.
53
+ * @param startIndex The start index of viewable items.
54
+ * @param endIndex The end index of viewable items.
53
55
  */
54
- rangeChange: (
55
- /**
56
- * The start index of viewable items.
57
- */
58
- startIndex: number,
59
- /**
60
- * The end index of viewable items.
61
- */
62
- endIndex: number) => void;
56
+ rangeChange: (startIndex: number, endIndex: number) => void;
63
57
  }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
64
58
  /**
65
59
  * The data items rendered by this component.
@@ -3,15 +3,15 @@ import { VNode, ComponentOptionsMixin, SlotsType, PropType, NativeElements } fro
3
3
  import { ScrollToIndexOpts } from "../core/types";
4
4
  export interface VirtualizerHandle {
5
5
  /**
6
- * Get current scrollTop or scrollLeft.
6
+ * Get current scrollTop, or scrollLeft if horizontal: true.
7
7
  */
8
8
  readonly scrollOffset: number;
9
9
  /**
10
- * Get current scrollHeight or scrollWidth.
10
+ * Get current scrollHeight, or scrollWidth if horizontal: true.
11
11
  */
12
12
  readonly scrollSize: number;
13
13
  /**
14
- * Get current offsetHeight or offsetWidth.
14
+ * Get current offsetHeight, or offsetWidth if horizontal: true.
15
15
  */
16
16
  readonly viewportSize: number;
17
17
  /**
@@ -79,7 +79,7 @@ export declare const Virtualizer: import("vue").DefineComponent<{
79
79
  */
80
80
  ssrCount: NumberConstructor;
81
81
  /**
82
- * Reference to the scrollable element. The default will get the parent element of virtualizer.
82
+ * Reference to the scrollable element. The default will get the direct parent element of virtualizer.
83
83
  */
84
84
  scrollRef: PropType<HTMLElement>;
85
85
  /**
@@ -101,7 +101,7 @@ export declare const Virtualizer: import("vue").DefineComponent<{
101
101
  }, VirtualizerHandle, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
102
102
  /**
103
103
  * Callback invoked whenever scroll offset changes.
104
- * @param offset Current scrollTop or scrollLeft.
104
+ * @param offset Current scrollTop, or scrollLeft if horizontal: true.
105
105
  */
106
106
  scroll: (offset: number) => void;
107
107
  /**
@@ -110,16 +110,10 @@ export declare const Virtualizer: import("vue").DefineComponent<{
110
110
  scrollEnd: () => void;
111
111
  /**
112
112
  * Callback invoked when visible items range changes.
113
+ * @param startIndex The start index of viewable items.
114
+ * @param endIndex The end index of viewable items.
113
115
  */
114
- rangeChange: (
115
- /**
116
- * The start index of viewable items.
117
- */
118
- startIndex: number,
119
- /**
120
- * The end index of viewable items.
121
- */
122
- endIndex: number) => void;
116
+ rangeChange: (startIndex: number, endIndex: number) => void;
123
117
  }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
124
118
  /**
125
119
  * The data items rendered by this component.
@@ -163,7 +157,7 @@ export declare const Virtualizer: import("vue").DefineComponent<{
163
157
  */
164
158
  ssrCount: NumberConstructor;
165
159
  /**
166
- * Reference to the scrollable element. The default will get the parent element of virtualizer.
160
+ * Reference to the scrollable element. The default will get the direct parent element of virtualizer.
167
161
  */
168
162
  scrollRef: PropType<HTMLElement>;
169
163
  /**
@@ -54,16 +54,10 @@ export declare const WindowVirtualizer: import("vue").DefineComponent<{
54
54
  scrollEnd: () => void;
55
55
  /**
56
56
  * Callback invoked when visible items range changes.
57
+ * @param startIndex The start index of viewable items.
58
+ * @param endIndex The end index of viewable items.
57
59
  */
58
- rangeChange: (
59
- /**
60
- * The start index of viewable items.
61
- */
62
- startIndex: number,
63
- /**
64
- * The end index of viewable items.
65
- */
66
- endIndex: number) => void;
60
+ rangeChange: (startIndex: number, endIndex: number) => void;
67
61
  }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
68
62
  /**
69
63
  * The data items rendered by this component.