@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.
@@ -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":""}
@@ -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.4-alpha.0",
3
+ "version": "1.0.5-alpha.0",
4
4
  "description": "",
5
5
  "type": "module",
6
- "module": "./src/index.tsx",
7
- "types": "./src/types.d.ts",
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": "33126b0d5ef1834105552afc9f693e31d1a7b5b5"
30
+ "gitHead": "d7572c80741931a4e6b0cda5e635878b2062bfed"
28
31
  }