virtua 0.2.3 → 0.3.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.
- package/README.md +31 -4
- package/lib/core/resizer.d.ts +1 -1
- package/lib/core/scroller.d.ts +1 -1
- package/lib/core/store.d.ts +4 -4
- package/lib/core/utils.d.ts +1 -0
- package/lib/index.d.ts +3 -3
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +2 -1
- package/lib/index.mjs.map +1 -1
- package/lib/react/DefaultWindow.d.ts +29 -0
- package/lib/react/VGrid.d.ts +33 -15
- package/lib/react/VList.d.ts +7 -14
- package/lib/react/useStore.d.ts +2 -0
- package/package.json +14 -17
- package/lib/react/types.d.ts +0 -2
- package/lib/react/useSyncExternalStore.d.ts +0 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
   [](https://github.com/inokawa/virtua/actions/workflows/check.yml) [](https://github.com/inokawa/virtua/actions/workflows/demo.yml)
|
|
4
4
|
|
|
5
|
-
A zero-config, fast and small (3kB) virtual list and grid component for [React](https://github.com/facebook/react).
|
|
5
|
+
A zero-config, fast and small (~3kB) virtual list and grid component for [React](https://github.com/facebook/react).
|
|
6
6
|
|
|
7
7
|
If you want to check the difference with the alternatives right away, [see comparison section](#comparison).
|
|
8
8
|
|
|
@@ -12,7 +12,7 @@ This project is a challenge to rethink virtualization. The goals are...
|
|
|
12
12
|
|
|
13
13
|
- **Minimal setup:** This library is designed to give the best performance with no configuration, not like alternatives, and also it handles common hard things in the real world (dynamic size measurement, scroll position adjustment in bottom-up scrolling and imperative scrolling, etc).
|
|
14
14
|
- **Fast:** Scrolling without frame drop needs optimization in many aspects (reduce CPU usage, reduce GC, [reduce layout recalculation](https://gist.github.com/paulirish/5d52fb081b3570c81e3a), optimize for frameworks, etc). We are trying to combine the best of them.
|
|
15
|
-
- **Small:** Its bundle size should be small as much as possible to be friendly with modern web development. Currently
|
|
15
|
+
- **Small:** Its bundle size should be small as much as possible to be friendly with modern web development. Currently each components are ~3kB gzipped and the total is [~4kB gzipped](https://bundlephobia.com/package/virtua).
|
|
16
16
|
- **Flexible:** Aiming to support many usecases - fixed size, dynamic size, horizontal scrolling, reverse scrolling, rtl direction, sticky, infinite scrolling, placeholder, scrollTo, dnd, table, and more. See [live demo](#demo).
|
|
17
17
|
- **Framework agnostic (WIP):** Currently only for [React](https://react.dev/) but we could support [Vue](https://vuejs.org/), [Svelte](https://svelte.dev/), [Solid](https://www.solidjs.com/), [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components) and more in the future.
|
|
18
18
|
|
|
@@ -32,6 +32,8 @@ npm install virtua
|
|
|
32
32
|
|
|
33
33
|
If you use ESM and webpack 5, use react >= 18 to avoid [Can't resolve `react/jsx-runtime` error](https://github.com/facebook/react/issues/20235).
|
|
34
34
|
|
|
35
|
+
If you use this lib in [legacy browsers which does not have ResizeObserver](https://caniuse.com/?search=resizeobserver), you should use [polyfill](https://github.com/juggle/resize-observer#switching-between-native-and-polyfilled-versions).
|
|
36
|
+
|
|
35
37
|
## Usage
|
|
36
38
|
|
|
37
39
|
### Vertical scroll
|
|
@@ -108,6 +110,30 @@ export const App = () => {
|
|
|
108
110
|
};
|
|
109
111
|
```
|
|
110
112
|
|
|
113
|
+
### React Server Components (RSC) support
|
|
114
|
+
|
|
115
|
+
This library is marked as a Client Component. You can render RSC as children of VList.
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
// page.tsx in App Router of Next.js
|
|
119
|
+
import { VList } from "virtua";
|
|
120
|
+
|
|
121
|
+
export default async () => {
|
|
122
|
+
return (
|
|
123
|
+
<div>
|
|
124
|
+
<div>This is Server Component</div>
|
|
125
|
+
<VList style={{ height: 300 }}>
|
|
126
|
+
{Array.from({ length: 1000 }).map((_, i) => (
|
|
127
|
+
<div key={i} style={{ border: "solid 1px gray", height: 80 }}>
|
|
128
|
+
{i}
|
|
129
|
+
</div>
|
|
130
|
+
))}
|
|
131
|
+
</VList>
|
|
132
|
+
</div>
|
|
133
|
+
);
|
|
134
|
+
};
|
|
135
|
+
```
|
|
136
|
+
|
|
111
137
|
And see [examples](./stories) for more usages.
|
|
112
138
|
|
|
113
139
|
## Documentation
|
|
@@ -124,10 +150,10 @@ WIP
|
|
|
124
150
|
|
|
125
151
|
| | [virtua](https://github.com/inokawa/virtua) | [react-virtuoso](https://github.com/petyosi/react-virtuoso) | [react-window](https://github.com/bvaughn/react-window) | [react-virtualized](https://github.com/bvaughn/react-virtualized) | [@tanstack/react-virtual](https://github.com/TanStack/virtual) | [react-cool-virtual](https://github.com/wellyshen/react-cool-virtual) |
|
|
126
152
|
| :------------------------------------------------- | :------------------------------------------------------- | :---------------------------------------------------------------- | :------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------ | :-------------------------------------------------------------------- |
|
|
127
|
-
| Bundle size | [
|
|
153
|
+
| Bundle size | [4.2kB gzipped](https://bundlephobia.com/package/virtua) | [16.3kB gzipped](https://bundlephobia.com/package/react-virtuoso) | [6.4kB gzipped](https://bundlephobia.com/package/react-window) | [27.3kB gzipped](https://bundlephobia.com/package/react-virtualized) | [2.3kB gzipped](https://bundlephobia.com/package/@tanstack/react-virtual) | [3.1kB gzipped](https://bundlephobia.com/package/react-cool-virtual) |
|
|
128
154
|
| Vertical scroll | ✅ | ✅ | ✅ | ✅ | 🟠 (needs customization) | 🟠 (needs customization) |
|
|
129
155
|
| Horizontal scroll | ✅ | ✅ | ✅ | ✅ | 🟠 (needs customization) | 🟠 (needs customization) |
|
|
130
|
-
| Grid (Virtualization for
|
|
156
|
+
| Grid (Virtualization for two dimension) | ✅ | ❌ | ✅ (FixedSizeGrid / VariableSizeGrid) | ✅ ([Grid](https://github.com/bvaughn/react-virtualized/blob/master/docs/Grid.md)) | 🟠 (needs customization) | 🟠 (needs customization) |
|
|
131
157
|
| Table | 🟠 (needs customization) | ✅ (TableVirtuoso) | 🟠 (needs customization) | ✅ ([Table](https://github.com/bvaughn/react-virtualized/blob/master/docs/Table.md)) | 🟠 (needs customization) | 🟠 (needs customization) |
|
|
132
158
|
| Window scroller | ❌ | ✅ | ❌ | ✅ ([WindowScroller](https://github.com/bvaughn/react-virtualized/blob/master/docs/WindowScroller.md)) | ✅ | ❌ |
|
|
133
159
|
| Dynamic list size | ✅ | ✅ | 🟠 (needs [AutoSizer](https://github.com/bvaughn/react-virtualized/blob/master/docs/AutoSizer.md)) | 🟠 (needs [AutoSizer](https://github.com/bvaughn/react-virtualized/blob/master/docs/AutoSizer.md)) | ✅ | ✅ |
|
|
@@ -136,6 +162,7 @@ WIP
|
|
|
136
162
|
| Infinite scroll | ✅ | ✅ | 🟠 (needs [react-window-infinite-loader](https://github.com/bvaughn/react-window-infinite-loader)) | 🟠 (needs [InfiniteLoader](https://github.com/bvaughn/react-virtualized/blob/master/docs/InfiniteLoader.md)) | ✅ | ✅ |
|
|
137
163
|
| RTL | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
|
|
138
164
|
| SSR support | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
165
|
+
| React Server Components (RSC) support | ✅ | ? | ? | ? | ✅ (hook) | ✅ (hook) |
|
|
139
166
|
| Display exceeding browser's max element size limit | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
|
|
140
167
|
|
|
141
168
|
- ✅ - Built-in supported
|
package/lib/core/resizer.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { VirtualStore } from "./store";
|
|
2
|
-
export declare const createResizer: (store: VirtualStore) => {
|
|
2
|
+
export declare const createResizer: (store: VirtualStore, isHorizontal: boolean) => {
|
|
3
3
|
_observeRoot(root: HTMLElement): () => void;
|
|
4
4
|
_observeItem(el: HTMLElement, i: number): () => void;
|
|
5
5
|
_isJustResized(): boolean;
|
package/lib/core/scroller.d.ts
CHANGED
|
@@ -6,4 +6,4 @@ export type Scroller = {
|
|
|
6
6
|
_scrollToIndex: (index: number, count: number) => void;
|
|
7
7
|
_fixScrollJump: (jump: ScrollJump, startIndex: number) => void;
|
|
8
8
|
};
|
|
9
|
-
export declare const createScroller: (store: VirtualStore, isJustResized: () => boolean) => Scroller;
|
|
9
|
+
export declare const createScroller: (store: VirtualStore, isHorizontal: boolean, isRtl: boolean, isJustResized: () => boolean) => Scroller;
|
package/lib/core/store.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export declare const ACTION_WINDOW_RESIZE = 2;
|
|
|
12
12
|
export declare const ACTION_SCROLL = 3;
|
|
13
13
|
export declare const ACTION_MANUAL_SCROLL = 4;
|
|
14
14
|
type Actions = [type: typeof ACTION_ITEM_RESIZE, entries: ItemResize[]] | [type: typeof ACTION_WINDOW_RESIZE, size: number] | [type: typeof ACTION_SCROLL, offset: number] | [type: typeof ACTION_MANUAL_SCROLL, offset: number];
|
|
15
|
+
type Subscriber = (sync?: boolean) => void;
|
|
15
16
|
export type VirtualStore = {
|
|
16
17
|
_getRange(): ItemsRange;
|
|
17
18
|
_isUnmeasuredItem(index: number): boolean;
|
|
@@ -21,16 +22,15 @@ export type VirtualStore = {
|
|
|
21
22
|
_getScrollOffset(): number;
|
|
22
23
|
_getViewportSize(): number;
|
|
23
24
|
_getScrollSize(): number;
|
|
25
|
+
_getScrollableDomSize(): number;
|
|
24
26
|
_getJump(): ScrollJump;
|
|
25
|
-
_isHorizontal(): boolean;
|
|
26
|
-
_isRtl(): boolean;
|
|
27
27
|
_getItemIndexForScrollTo(offset: number): number;
|
|
28
28
|
_waitForScrollDestinationItemsMeasured(): Promise<void>;
|
|
29
|
-
_subscribe(cb:
|
|
29
|
+
_subscribe(cb: Subscriber): () => void;
|
|
30
30
|
_update(...action: Actions): void;
|
|
31
31
|
_getScrollDirection(): ScrollDirection;
|
|
32
32
|
_setScrollDirection(direction: ScrollDirection): void;
|
|
33
33
|
_updateCacheLength(length: number): void;
|
|
34
34
|
};
|
|
35
|
-
export declare const createVirtualStore: (itemCount: number, itemSize: number,
|
|
35
|
+
export declare const createVirtualStore: (itemCount: number, itemSize: number, initialItemCount: number | undefined, isReverse: boolean, onScrollStateChange: (scrolling: boolean) => void, onScrollOffsetChange: (offset: number) => void) => VirtualStore;
|
|
36
36
|
export {};
|
package/lib/core/utils.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare const min: (...values: number[]) => number;
|
|
2
2
|
export declare const max: (...values: number[]) => number;
|
|
3
|
+
export declare const abs: (x: number) => number;
|
|
3
4
|
export declare const now: () => number;
|
|
4
5
|
export declare const exists: <T>(v: T) => v is Exclude<T, null | undefined>;
|
|
5
6
|
export declare const range: <T>(length: number, cb: (i: number) => T) => T[];
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { VList } from "./react/VList";
|
|
2
|
-
export type { VListProps, VListHandle, CustomItemComponent, CustomItemComponentProps,
|
|
2
|
+
export type { VListProps, VListHandle, CustomItemComponent, CustomItemComponentProps, ScrollMode, } from "./react/VList";
|
|
3
3
|
export { VGrid } from "./react/VGrid";
|
|
4
|
-
export type { VGridProps, VGridHandle, CustomCellComponent, CustomCellComponentProps,
|
|
5
|
-
export type { WindowComponentAttributes } from "./react/
|
|
4
|
+
export type { VGridProps, VGridHandle, CustomCellComponent, CustomCellComponentProps, } from "./react/VGrid";
|
|
5
|
+
export type { WindowComponentAttributes, CustomWindowComponent, CustomWindowComponentProps, } from "./react/DefaultWindow";
|
package/lib/index.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
var e=require("react/jsx-runtime"),t=require("react"),r=require("react-dom");const n=Math.min,o=Math.max,i=Math.abs,l=Date.now,s=e=>null!=e,c=(e,t)=>Array.from({length:e},((e,r)=>t(r))),u=e=>{let t,r;return(...n)=>(t||(t=!0,r=e(...n)),r)},_=(e,t)=>{const r=e.t[t];return-1===r?e.o:r},a=(e,t,r)=>{if(!e.i)return 0;if(e.l>=t)return r?e.u[t]+_(e,t):e.u[t];let n=e.l,o=e.u[n];for(;n<=t&&(e.u[n]=o,n!==t||r);)o+=_(e,n),n++;return e.l=t,o},d=(e,t)=>a(e,t),h=(e,t,r)=>{let i=0;if(r>=0)for(;t<e.i-1;){const n=_(e,t++);if((i+=n)>=r){i-n/2>=r&&t--;break}}else for(;t>0;){const n=_(e,--t);if((i-=n)<=r){i+n/2<r&&t++;break}}return n(o(t,0),e.i-1)},f=(e,t,r,n)=>h(e,r,t-n),g=h,m=(e,t,r)=>({o:t,i:e,l:r?n(r.l,e-1):0,t:c(e,(e=>{const t=r&&r.t[e];return s(t)?t:-1})),u:c(e,(e=>{if(0===e)return 0;const t=r&&r.u[e];return s(t)?t:-1}))}),w=(e,t,r=0,l,s,c)=>{let u,h=t*o(r-1,0),w=0,S=[],v=m(e,t),p=0,z=[0,r];const I=new Set,b=()=>(e=>a(e,e.i-1,!0))(v);return{_(){const[e,t]=z,r=d(v,e),n=f(v,w,e,r),o=g(v,n,h);return e===n&&t===o?z:z=[n,o]},h:e=>-1===v.t[e],g:e=>((e,t,r)=>{for(let n=t;n<=r;n++)if(-1===e.t[n])return!0;return!1})(v,e,g(v,e,h)),m(e){const t=d(v,e);return l?t+o(0,h-b()):t},S:e=>_(v,e),v:()=>w,p:()=>h,I:()=>b(),R:()=>o(b(),h),T:()=>S,M:e=>f(v,e,0,0),O:()=>(u&&u[1](),new Promise(((e,t)=>{u=[()=>{Promise.resolve().then((()=>{e(),u=void 0}))},t]}))),C:e=>(I.add(e),()=>{I.delete(e)}),H(e,t){let r;const o=(()=>{switch(e){case 1:{const e=t.filter((([e,t])=>v.t[e]!==t));return!!e.length&&(S=[],e.forEach((([e,t])=>{S.push([t-_(v,e),e]),((e,t,r)=>{e.t[t]=r,e.l=n(t,e.l)})(v,e,t)})),r=!0,!0)}case 2:return h!==t&&(h=t,!0);case 3:case 4:{const n=w,o=(w=t)!==n;return o&&3===e&&(r=i(n-t)>h),o}}})();o&&(I.forEach((e=>{e(r)})),3===e?c(w):u&&1===e&&u[0]())},D:()=>p,k(e){const t=p;p=e,0===p?s(!1):0!==t||1!==p&&2!==p||s(!0)},J(e){v.i!==e&&(v=m(e,t,v))}}},S="undefined"!=typeof window?t.useLayoutEffect:t.useEffect,v="current",p=e=>{const r=t.useRef(e);return S((()=>{r[v]=e}),[e]),r},z=(e,n,o)=>{const[i,l]=t.useState(n),s=p(n);if(t.useLayoutEffect((()=>{const t=()=>{l((()=>s[v]()))};return e.C((e=>{e?r.flushSync(t):t()}))}),[]),o){const e=n();i!==e&&l(e)}return i},I=u((e=>{const t="scrollLeft",r=e[t];e[t]=1;const n=e[t]<1;return e[t]=r,n})),b=(e,t,r,i)=>{let c;const u=t?"scrollLeft":"scrollTop",_=()=>c?t?c.scrollWidth:c.scrollHeight:0,a=(t,r)=>I(c)||r?-t:e.I()-e.p()-t,d=(n,o)=>{c&&(t&&r&&(n=a(n,o)),o?c[u]+=n:(c[u]=n,e.k(3)))},h=async(t,r)=>{const n=()=>{let t=r();const n=_(),o=e.p();return n-(t+o)<=0&&(t=n-o),t};if(e.g(t)){do{e.H(4,n());try{await e.O()}catch(e){return}}while(e.g(t));d(n())}else{const t=n();d(t),e.H(4,t)}},f=e=>e.reduce(((e,[t])=>e+t),0);return{W(n){c=n;const o=()=>{let o=n[u];t&&r&&(o=a(o));const l=e.v();if(l===o)return;const s=e.D(),c=i();0!==s&&c||3===s||e.k(l>o?2:1),e.H(3,o)},_=(()=>{let t;const r=()=>{s(t)&&clearTimeout(t)},n=()=>{r(),t=setTimeout((()=>{t=null,o(),e.k(0)}),150)};return n.$=r,n})(),d=()=>{o(),_()},h=(()=>{let r=l()-50;return(...n)=>{const o=l();r+50<o&&(r=o,(r=>{if(0!==e.D()&&!r.ctrlKey&&(t?r.deltaX:r.deltaY)){const t=e.v();t>0&&t<e.I()-e.p()&&_()}})(...n))}})();return n.addEventListener("scroll",d),n.addEventListener("wheel",h,{passive:!0}),()=>{n.removeEventListener("scroll",d),n.removeEventListener("wheel",h),_.$()}},q:_,L(t){t=o(t,0),h(e.M(t),(()=>t))},A(t,r){t=o(n(t,r-1),0),h(t,(()=>e.m(t)))},B:(t,r)=>{const n=e.D();if(2===n){const e=f(t);e&&d(e,!0)}else if(3===n){const n=e.v();if(0===n);else{const o=f(t);if(e.I()-(n+e.p()+o)<=0)o&&d(n+o);else{const e=t.reduce(((e,[t,n])=>(n<r&&(e+=t),e)),0);e&&d(e,!0)}}}}}},x=e=>{const r=t.useRef();return r[v]||(r[v]=e())},R=t.forwardRef((({children:r,attrs:n,width:o,height:i,scrolling:l},s)=>e.jsx("div",{ref:s,...n,children:e.jsx("div",{style:t.useMemo((()=>({position:"relative",visibility:"hidden",width:null!=o?o:"100%",height:null!=i?i:"100%",pointerEvents:l?"none":"auto"})),[o,i,l]),children:r})}))),y=t.memo((({F:r,P:n,U:o,j:i,V:l,G:s,K:c})=>{const u=t.useRef(null),_=z(o,(()=>o.m(i)),!0),a=z(o,(()=>o.h(i)),!0);return S((()=>n.N(u[v],i)),[i]),e.jsx(l,{ref:u,style:t.useMemo((()=>{const e=c?"right":"left",t={margin:0,padding:0,position:"absolute",[s?"height":"width"]:"100%",[s?"top":e]:0,[s?e:"top"]:_,visibility:a?"hidden":"visible"};return s&&(t.display="flex"),t}),[_,a]),children:r})})),T=({F:r,X:n,U:o,V:i,Y:l,Z:s,G:c})=>{const u=z(o,o.I);return e.jsx(i,{ref:n,width:c?u:void 0,height:c?void 0:u,scrolling:l,attrs:t.useMemo((()=>({...s,style:{overflow:c?"auto hidden":"hidden auto",contain:"strict",width:"100%",height:"100%",padding:0,margin:0,...s.style}})),[s]),children:r})},M=t.forwardRef((({children:r,itemSize:i=40,overscan:l=4,initialItemCount:c,horizontal:_,mode:a,element:d=R,itemElement:h="div",onScroll:f,onScrollStop:g,onRangeChange:m,...I},M)=>{const O=t.useMemo((()=>{const e=[];return t.Children.forEach(r,(t=>{(e=>!s(e)||"boolean"==typeof e)(t)||e.push(t)})),e}),[r]),C=O.length,H=p(f),D=p(g),[k,J]=t.useState(!1),[W,$,q,E,L]=x((()=>{const e=!!_,t="rtl"===a,r=w(C,i,c,"reverse"===a,(e=>{J(e),e||D[v]&&D[v]()}),(e=>{H[v]&&H[v](e)})),n=((e,t)=>{let r,n=!1;const o=t?"width":"height",i=new WeakMap,l=u((()=>new ResizeObserver((t=>{const l=[];for(const{target:n,contentRect:c}of t)if(n===r)e.H(2,c[o]);else{const e=i.get(n);s(e)&&l.push([e,c[o]])}l.length&&(e.H(1,l),n=!0)}))));return{ee(e){r=e;const t=l();return t.observe(e),()=>{t.disconnect()}},N(e,t){const r=l();return i.set(e,t),r.observe(e),()=>{i.delete(e),r.unobserve(e)}},te(){const e=n;return n=!1,e}}})(r,e);return[r,n,b(r,e,t,n.te),e,t]}));W.J(C);const[A,B]=z(W,W._),F=z(W,W.T),P=t.useRef(null);S((()=>{const e=P[v],t=$.ee(e),r=q.W(e);return()=>{t(),r()}}),[]),S((()=>{F.length&&q.B(F,A)}),[F]),t.useEffect((()=>{m&&m({start:A,end:B,count:C})}),[A,B]),t.useImperativeHandle(M,(()=>({get scrollOffset(){return W.v()},get scrollSize(){return q.q()},get viewportSize(){return W.p()},scrollToIndex(e){q.A(e,C)},scrollTo:q.L,scrollBy(e){q.L(W.v()+e)}})),[C]);const U=o(A-l,0),j=n(B+l,C-1),V=t.useMemo((()=>{const t=[];for(let r=U;r<=j;r++){const n=O[r];s(n)&&t.push(e.jsx(y,{P:$,U:W,j:r,V:h,F:n,G:E,K:L},(null==n?void 0:n.key)||r))}return t}),[O,U,j]);return e.jsx(T,{X:P,U:W,V:d,Y:k,F:V,Z:I,G:E})})),O=(e,t)=>`${e}-${t}`,C=t.memo((({F:r,P:n,re:o,ne:i,oe:l,ie:s,V:c,K:u})=>{const _=t.useRef(null),a=z(o,(()=>o.m(l)),!0),d=z(i,(()=>i.m(s)),!0),h=z(o,(()=>o.h(l)),!0),f=z(i,(()=>i.h(s)),!0),g=z(o,(()=>o.S(l)),!0),m=z(i,(()=>i.S(s)),!0);return S((()=>n.N(_[v],l,s)),[s,l]),e.jsx(c,{ref:_,style:t.useMemo((()=>({display:"grid",margin:0,padding:0,position:"absolute",top:a,[u?"right":"left"]:d,visibility:h||f?"hidden":"visible",minHeight:g,minWidth:m})),[a,d,m,g,h,f]),children:r})})),H=({F:r,X:n,le:o,se:i,V:l,Y:s,Z:c})=>{const u=z(o,o.I),_=z(i,i.I);return e.jsx(l,{ref:n,width:_,height:u,scrolling:s,attrs:t.useMemo((()=>({...c,style:{overflow:"auto",contain:"strict",width:"100%",height:"100%",padding:0,margin:0,...c.style}})),[c]),children:r})},D=t.forwardRef((({children:r,row:i,col:l,cellHeight:s=40,cellWidth:c=100,overscan:_=2,initialRowCount:a,initialColCount:d,rtl:h,element:f=R,cellElement:g="div",...m},p)=>{const[I,y]=t.useState(!1),[T,M]=t.useState(!1),[D,k,J,W,$,q]=x((()=>{const e=!!h,t=()=>{},r=w(i,s,a,!1,y,t),n=w(l,c,d,!1,M,t),_=((e,t)=>{let r,n=!1,i=!1;const l="height",s="width",c=new WeakMap,_=new Set,a=new Set,d=new Map,h=(e,t)=>`${e}-${t}`,f=u((()=>new ResizeObserver((u=>{const f=new Set,g=new Set;for(const{target:n,contentRect:o}of u)if(n===r)e.H(2,o[l]),t.H(2,o[s]);else{const e=c.get(n);if(e){const[t,r]=e,n=h(t,r),i=d.get(n),c=[o[l],o[s]];let u,_;i?(i[0]!==c[0]&&(u=!0),i[1]!==c[1]&&(_=!0)):u=_=!0,u&&f.add(t),_&&g.add(r),(u||_)&&d.set(n,c)}}if(f.size){const t=[];f.forEach((e=>{let r=0;a.forEach((t=>{const n=d.get(h(e,t));n&&(r=o(r,n[0]))})),r&&t.push([e,r])})),e.H(1,t),n=!0}if(g.size){const e=[];g.forEach((t=>{let r=0;_.forEach((e=>{const n=d.get(h(e,t));n&&(r=o(r,n[1]))})),r&&e.push([t,r])})),t.H(1,e),i=!0}}))));return{ee(e){r=e;const t=f();return t.observe(e),()=>{t.disconnect()}},N(e,t,r){const n=f();return c.set(e,[t,r]),_.add(t),a.add(r),n.observe(e),()=>{c.delete(e),n.unobserve(e)}},te(e){const t=e?i:n;return e?i=!1:n=!1,t}}})(r,n);return[r,n,_,b(r,!1,e,(()=>_.te())),b(n,!0,e,(()=>_.te(!0))),e]}));D.J(i),k.J(l);const[E,L]=z(D,D._),[A,B]=z(k,k._),F=z(D,D.T),P=z(k,k.T),U=t.useRef(null);S((()=>{const e=U[v],t=J.ee(e),r=W.W(e),n=$.W(e);return()=>{t(),r(),n()}}),[]),S((()=>{F.length&&W.B(F,E)}),[F]),S((()=>{P.length&&$.B(P,A)}),[P]),t.useImperativeHandle(p,(()=>({get scrollOffset(){return[k.v(),D.v()]},get scrollSize(){return[$.q(),W.q()]},get viewportSize(){return[k.p(),D.p()]},scrollToIndex(e,t){$.A(e,l),W.A(t,i)},scrollTo(e,t){$.L(e),W.L(t)},scrollBy(e,t){$.L(k.v()+e),W.L(D.v()+t)}})),[i,l]);const j=t.useMemo((()=>{const e=new Map;return(t,n)=>{let o=e.get(O(t,n));return o||e.set(O(t,n),o=r({rowIndex:t,colIndex:n})),o}}),[r]),V=o(E-_,0),G=n(L+_,i-1),K=o(A-_,0),N=n(B+_,l-1),Q=t.useMemo((()=>{const t=[];for(let r=V;r<=G;r++)for(let n=K;n<=N;n++)t.push(e.jsx(C,{P:J,re:D,ne:k,oe:r,ie:n,V:g,F:j(r,n),K:q},O(r,n)));return t}),[j,V,G,K,N]);return e.jsx(H,{X:U,le:D,se:k,V:f,Y:I||T,F:Q,Z:m})}));exports.VGrid=D,exports.VList=M;
|
|
2
3
|
//# sourceMappingURL=index.js.map
|