@dot-present/virtual-list 1.0.4-alpha.0 → 1.0.5-alpha.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/dist/index.cjs.js +2 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/{index.js → index.esm.js} +1 -0
- package/dist/index.esm.js.map +1 -0
- package/package.json +7 -4
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("react/jsx-runtime"),t=require("react");const r=t.forwardRef((r,n)=>{const{data:c,itemKey:o,estimatedItemHeight:s=50,itemHeight:i,containerHeight:u="100%",bufferSize:l=3,overscanCount:h,onScroll:a,onReachEnd:f,renderItem:g}=r,d=h??l,m=void 0!==i,x=t.useRef(null),p=t.useRef(new Map),M=t.useRef(new Map),v=t.useRef(!1),[R,I]=t.useState(0),[b,H]=t.useState(0),[w,y]=t.useReducer(e=>e+1,0),T=t.useMemo(()=>{if("number"==typeof u)return u;if("string"==typeof u){const e=u.trim().match(/^(\d+(?:\.\d+)?)px$/i);if(e)return Number(e[1])}return 0},[u]),C=t.useRef([]);t.useEffect(()=>{if(m)return;c.length;let e=0;C.current=c.map((t,r)=>{const n={index:r,height:s,offset:e};return e+=s,n})},[c,s,m]),t.useEffect(()=>()=>{M.current.forEach(e=>e.disconnect()),M.current.clear()},[]);const E=t.useCallback((e,t)=>{if(m)return;const r=C.current[e];if(!r||r.height===t)return;const n=r.height;r.height=t;let c=t-n;for(let t=e+1;t<C.current.length;t++){const e=C.current[t];e&&(e.offset+=c)}y()},[m]);t.useLayoutEffect(()=>{if(!x.current)return;const e=x.current.clientHeight;e>0&&H(e)},[]),t.useEffect(()=>{if(!x.current)return;const e=new ResizeObserver(e=>{if(e.length>0){const t=e[0].contentRect.height;H(t)}});return e.observe(x.current),()=>e.disconnect()},[]);const{startIndex:S,endIndex:j,totalHeight:k}=t.useMemo(()=>{if(0===c.length)return{startIndex:0,endIndex:-1,totalHeight:0};const e=b>0?b:T>0?T:8*s;if(m){const t=i,r=Math.max(0,Math.floor(R/t)-d),n=Math.max(1,Math.ceil(e/t));return{startIndex:r,endIndex:Math.min(c.length-1,r+n+d),totalHeight:c.length*t}}{const t=(e=>{let t=0,r=c.length-1,n=0;for(;t<=r;){const c=Math.floor((t+r)/2);(C.current[c]?.offset??0)<=e?(n=c,t=c+1):r=c-1}return n})(R);let r=t;const n=C.current[t];let o=(n?.offset??0)+(n?.height??0);for(;r<c.length-1&&o-R<e;){r++;const e=C.current[r];o=(e?.offset??0)+(e?.height??0)}return{startIndex:Math.max(0,t-d),endIndex:Math.min(c.length-1,r+d),totalHeight:C.current.length>0?(()=>{const e=C.current[C.current.length-1];return(e?.offset??0)+(e?.height??0)})():0}}},[R,b,c.length,d,i,m,w,T,s]),z=t.useCallback(e=>{const t=e.currentTarget,r=t.scrollTop;I(r),a?.(e);const n=t.scrollHeight-t.scrollTop-t.clientHeight<5;f&&n&&!v.current?(v.current=!0,f()):n||(v.current=!1)},[a,f]);t.useImperativeHandle(n,()=>({scrollTo:e=>{if(!x.current)return;const t=Math.max(0,e);x.current.scrollTop=t,I(t)},scrollToIndex:(e,t="start")=>{if(!x.current||0===c.length)return;const r=Math.min(Math.max(0,e),c.length-1);let n=0;n=m?r*i:C.current[r]?.offset??0;const o=m?i:C.current[r]?.height??s;"center"===t?n-=(b-o)/2:"end"===t&&(n-=b-o);const u=Math.max(0,n);x.current.scrollTop=u,I(u)},getCurrentRange:()=>({start:S,end:j})}),[S,j,b,i,m,c.length,s]);const $=t.useCallback((e,t)=>"function"==typeof o?o(e,t):e[o]?.toString()??`item_${t}`,[o]),q=t.useMemo(()=>{const t=[];for(let r=S;r<=j&&r<c.length;r++){const n=c[r];if(void 0===n)continue;const o=$(n,r);let s=0;s=m?r*i:C.current[r]?.offset??0,t.push(e.jsx("div",{ref:e=>{if(m)return;if(!e){const e=M.current.get(o);return e&&(e.disconnect(),M.current.delete(o)),void p.current.delete(o)}const t=e;p.current.set(o,t);const n=M.current.get(o);n&&n.disconnect();const c=new ResizeObserver(e=>{const t=e[0]?.contentRect.height;t&&t>0&&E(r,t)});c.observe(e),M.current.set(o,c);const s=t.getBoundingClientRect().height;s&&C.current[r]?.height!==s&&E(r,s)},style:{position:"absolute",top:0,left:0,width:"100%",transform:`translateY(${s}px)`},children:g(n,r)},o))}return t},[S,j,c,$,m,i,g,E,w]),L={height:u,overflowY:"auto",position:"relative"},O={position:"relative",height:k,width:"100%"};return e.jsx("div",{ref:x,style:L,onScroll:z,children:e.jsx("div",{style:O,children:q})})});exports.VirtualList=r;
|
|
2
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
interface VirtualListRef {
|
|
4
|
+
scrollTo: (scrollTop: number) => void;
|
|
5
|
+
scrollToIndex: (index: number, align?: "start" | "center" | "end") => void;
|
|
6
|
+
getCurrentRange: () => {
|
|
7
|
+
start: number;
|
|
8
|
+
end: number;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
interface VirtualListProps<T> {
|
|
12
|
+
data: T[];
|
|
13
|
+
itemKey: keyof T | ((item: T, index: number) => string);
|
|
14
|
+
estimatedItemHeight?: number;
|
|
15
|
+
itemHeight?: number;
|
|
16
|
+
containerHeight?: number | string;
|
|
17
|
+
bufferSize?: number;
|
|
18
|
+
overscanCount?: number;
|
|
19
|
+
onScroll?: (e: React.UIEvent<HTMLDivElement>) => void;
|
|
20
|
+
onReachEnd?: () => void;
|
|
21
|
+
renderItem: (item: T, index: number) => React.ReactNode;
|
|
22
|
+
}
|
|
23
|
+
declare const VirtualList: React.ForwardRefExoticComponent<VirtualListProps<unknown> & React.RefAttributes<VirtualListRef>>;
|
|
24
|
+
|
|
25
|
+
export { VirtualList };
|
|
26
|
+
export type { VirtualListRef };
|
|
@@ -1 +1,2 @@
|
|
|
1
1
|
import{jsx as t}from"react/jsx-runtime";import{forwardRef as e,useRef as n,useState as r,useReducer as o,useMemo as c,useEffect as i,useCallback as s,useLayoutEffect as h,useImperativeHandle as l}from"react";const u=e((e,u)=>{const{data:f,itemKey:a,estimatedItemHeight:g=50,itemHeight:d,containerHeight:m="100%",bufferSize:p=3,overscanCount:x,onScroll:v,onReachEnd:M,renderItem:I}=e,H=x??p,b=void 0!==d,w=n(null),y=n(new Map),R=n(new Map),T=n(!1),[S,z]=r(0),[C,$]=r(0),[E,O]=o(t=>t+1,0),Y=c(()=>{if("number"==typeof m)return m;if("string"==typeof m){const t=m.trim().match(/^(\d+(?:\.\d+)?)px$/i);if(t)return Number(t[1])}return 0},[m]),j=n([]);i(()=>{if(b)return;f.length;let t=0;j.current=f.map((e,n)=>{const r={index:n,height:g,offset:t};return t+=g,r})},[f,g,b]),i(()=>()=>{R.current.forEach(t=>t.disconnect()),R.current.clear()},[]);const B=s((t,e)=>{if(b)return;const n=j.current[t];if(!n||n.height===e)return;const r=n.height;n.height=e;let o=e-r;for(let e=t+1;e<j.current.length;e++){const t=j.current[e];t&&(t.offset+=o)}O()},[b]);h(()=>{if(!w.current)return;const t=w.current.clientHeight;t>0&&$(t)},[]),i(()=>{if(!w.current)return;const t=new ResizeObserver(t=>{if(t.length>0){const e=t[0].contentRect.height;$(e)}});return t.observe(w.current),()=>t.disconnect()},[]);const{startIndex:K,endIndex:N,totalHeight:_}=c(()=>{if(0===f.length)return{startIndex:0,endIndex:-1,totalHeight:0};const t=C>0?C:Y>0?Y:8*g;if(b){const e=d,n=Math.max(0,Math.floor(S/e)-H),r=Math.max(1,Math.ceil(t/e));return{startIndex:n,endIndex:Math.min(f.length-1,n+r+H),totalHeight:f.length*e}}{const e=(t=>{let e=0,n=f.length-1,r=0;for(;e<=n;){const o=Math.floor((e+n)/2);(j.current[o]?.offset??0)<=t?(r=o,e=o+1):n=o-1}return r})(S);let n=e;const r=j.current[e];let o=(r?.offset??0)+(r?.height??0);for(;n<f.length-1&&o-S<t;){n++;const t=j.current[n];o=(t?.offset??0)+(t?.height??0)}return{startIndex:Math.max(0,e-H),endIndex:Math.min(f.length-1,n+H),totalHeight:j.current.length>0?(()=>{const t=j.current[j.current.length-1];return(t?.offset??0)+(t?.height??0)})():0}}},[S,C,f.length,H,d,b,E,Y,g]),k=s(t=>{const e=t.currentTarget,n=e.scrollTop;z(n),v?.(t);const r=e.scrollHeight-e.scrollTop-e.clientHeight<5;M&&r&&!T.current?(T.current=!0,M()):r||(T.current=!1)},[v,M]);l(u,()=>({scrollTo:t=>{if(!w.current)return;const e=Math.max(0,t);w.current.scrollTop=e,z(e)},scrollToIndex:(t,e="start")=>{if(!w.current||0===f.length)return;const n=Math.min(Math.max(0,t),f.length-1);let r=0;r=b?n*d:j.current[n]?.offset??0;const o=b?d:j.current[n]?.height??g;"center"===e?r-=(C-o)/2:"end"===e&&(r-=C-o);const c=Math.max(0,r);w.current.scrollTop=c,z(c)},getCurrentRange:()=>({start:K,end:N})}),[K,N,C,d,b,f.length,g]);const q=s((t,e)=>"function"==typeof a?a(t,e):t[a]?.toString()??`item_${e}`,[a]),A=c(()=>{const e=[];for(let n=K;n<=N&&n<f.length;n++){const r=f[n];if(void 0===r)continue;const o=q(r,n);let c=0;c=b?n*d:j.current[n]?.offset??0,e.push(t("div",{ref:t=>{if(b)return;if(!t){const t=R.current.get(o);return t&&(t.disconnect(),R.current.delete(o)),void y.current.delete(o)}const e=t;y.current.set(o,e);const r=R.current.get(o);r&&r.disconnect();const c=new ResizeObserver(t=>{const e=t[0]?.contentRect.height;e&&e>0&&B(n,e)});c.observe(t),R.current.set(o,c);const i=e.getBoundingClientRect().height;i&&j.current[n]?.height!==i&&B(n,i)},style:{position:"absolute",top:0,left:0,width:"100%",transform:`translateY(${c}px)`},children:I(r,n)},o))}return e},[K,N,f,q,b,d,I,B,E]);return t("div",{ref:w,style:{height:m,overflowY:"auto",position:"relative"},onScroll:k,children:t("div",{style:{position:"relative",height:_,width:"100%"},children:A})})});export{u as VirtualList};
|
|
2
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dot-present/virtual-list",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5-alpha.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"module": "./src/index.
|
|
7
|
-
"types": "./src/
|
|
6
|
+
"module": "./src/index.ts",
|
|
7
|
+
"types": "./src/index.ts",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
10
10
|
},
|
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
],
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"publishConfig": {
|
|
18
|
+
"main": "./dist/index.cjs.js",
|
|
19
|
+
"module": "./dist/index.esm.js",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
18
21
|
"access": "public"
|
|
19
22
|
},
|
|
20
23
|
"keywords": [],
|
|
@@ -24,5 +27,5 @@
|
|
|
24
27
|
"react": ">=18",
|
|
25
28
|
"react-dom": ">=18"
|
|
26
29
|
},
|
|
27
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "d7572c80741931a4e6b0cda5e635878b2062bfed"
|
|
28
31
|
}
|