react-anchorlist 0.2.3 → 0.2.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"VirtualItem.d.ts","sourceRoot":"","sources":["../../src/components/VirtualItem.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE3C,UAAU,gBAAgB;IACxB,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IACjC,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACzD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,WAAW,EACX,WAAW,EACX,QAAQ,GACT,EAAE,gBAAgB,2CA6BlB"}
1
+ {"version":3,"file":"VirtualItem.d.ts","sourceRoot":"","sources":["../../src/components/VirtualItem.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE3C,UAAU,gBAAgB;IACxB,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IACjC,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACzD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,WAAW,EACX,WAAW,EACX,QAAQ,GACT,EAAE,gBAAgB,2CAsClB"}
@@ -1 +1 @@
1
- {"version":3,"file":"useChatVirtualizer.d.ts","sourceRoot":"","sources":["../../src/hooks/useChatVirtualizer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAqB,wBAAwB,EAAE,MAAM,UAAU,CAAA;AAE3E;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,EAAE;IAC7C,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAAA;IACnD,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAA;IACxC,gBAAgB,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAA;IACnC,cAAc,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3C,YAAY,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzC,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,kBAAkB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAC3C,yBAAyB,CAAC,EAAE,MAAM,IAAI,CAAA;CACvC,GAAG,wBAAwB,CAAC,CAAC,CAAC,CAmI9B"}
1
+ {"version":3,"file":"useChatVirtualizer.d.ts","sourceRoot":"","sources":["../../src/hooks/useChatVirtualizer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAqB,wBAAwB,EAAE,MAAM,UAAU,CAAA;AAE3E;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,EAAE;IAC7C,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAAA;IACnD,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAA;IACxC,gBAAgB,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAA;IACnC,cAAc,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3C,YAAY,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzC,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,kBAAkB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAC3C,yBAAyB,CAAC,EAAE,MAAM,IAAI,CAAA;CACvC,GAAG,wBAAwB,CAAC,CAAC,CAAC,CAwI9B"}
@@ -4,7 +4,7 @@
4
4
  * This hook performs restoration in multiple phases (layout + raf + timeout)
5
5
  * to absorb late height measurements (ResizeObserver) and avoid flicker/jumps.
6
6
  */
7
- export declare function useScrollAnchor(scrollerRef: React.RefObject<HTMLDivElement>, itemCount: number): {
7
+ export declare function useScrollAnchor(scrollerRef: React.RefObject<HTMLDivElement>, itemCount: number, onRestored?: () => void): {
8
8
  prepareAnchor: () => void;
9
9
  };
10
10
  //# sourceMappingURL=useScrollAnchor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useScrollAnchor.d.ts","sourceRoot":"","sources":["../../src/hooks/useScrollAnchor.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,EAC5C,SAAS,EAAE,MAAM,GAChB;IAAE,aAAa,EAAE,MAAM,IAAI,CAAA;CAAE,CA8D/B"}
1
+ {"version":3,"file":"useScrollAnchor.d.ts","sourceRoot":"","sources":["../../src/hooks/useScrollAnchor.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,EAC5C,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,IAAI,GACtB;IAAE,aAAa,EAAE,MAAM,IAAI,CAAA;CAAE,CAmE/B"}
@@ -1 +1 @@
1
- {"version":3,"file":"useVirtualEngine.d.ts","sourceRoot":"","sources":["../../src/hooks/useVirtualEngine.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,sBAAsB,EAAe,MAAM,UAAU,CAAA;AAEnE;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE;IAC3C,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAAA;IACnD,iBAAiB,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,gBAAgB,EAAE,KAAK,GAAG,QAAQ,CAAA;CACnC,GAAG,sBAAsB,CAAC,CAAC,CAAC,CAqN5B"}
1
+ {"version":3,"file":"useVirtualEngine.d.ts","sourceRoot":"","sources":["../../src/hooks/useVirtualEngine.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,sBAAsB,EAAe,MAAM,UAAU,CAAA;AAEnE;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE;IAC3C,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAAA;IACnD,iBAAiB,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,gBAAgB,EAAE,KAAK,GAAG,QAAQ,CAAA;CACnC,GAAG,sBAAsB,CAAC,CAAC,CAAC,CAsQ5B"}
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const j=require("react/jsx-runtime"),r=require("react");function U(i){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(i){for(const t in i)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(i,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>i[t]})}}return e.default=i,Object.freeze(e)}const _=U(r);class ${constructor(e,t){this.defaultSize=t,this.sizes=e>0?Array(e).fill(t):[],this.offsets=e>0?Array(e).fill(0):[],e>0&&this._recalcFrom(0)}_recalcFrom(e){for(let t=e;t<this.sizes.length;t++)this.offsets[t]=t===0?0:(this.offsets[t-1]??0)+(this.sizes[t-1]??this.defaultSize)}getOffset(e){return this.offsets[e]??0}getSize(e){return this.sizes[e]??this.defaultSize}setSize(e,t){return this.sizes[e]===t?!1:(this.sizes[e]=t,this._recalcFrom(e+1),!0)}prepend(e){const t=Array(e).fill(this.defaultSize);this.sizes=[...t,...this.sizes],this.offsets=Array(this.sizes.length).fill(0),this._recalcFrom(0)}append(e){const t=this.sizes.length;for(let n=0;n<e;n++)this.sizes.push(this.defaultSize),this.offsets.push(0);this._recalcFrom(t)}resize(e){const t=this.sizes.length;e>t?this.append(e-t):e<t&&(this.sizes=this.sizes.slice(0,e),this.offsets=this.offsets.slice(0,e))}totalSize(){if(this.sizes.length===0)return 0;const e=this.sizes.length-1;return(this.offsets[e]??0)+(this.sizes[e]??this.defaultSize)}get count(){return this.sizes.length}getOffsets(){return this.offsets}getSizes(){return this.sizes}}class G{constructor(){this.cache=new Map}get(e){return this.cache.get(e)}set(e,t){this.cache.set(e,t)}has(e){return this.cache.has(e)}delete(e){this.cache.delete(e)}clear(){this.cache.clear()}applyToOffsetMap(e,t){for(const[n,l]of this.cache){const s=t.get(n);s!==void 0&&e.setSize(s,l)}}}function J(i,e){if(i.length===0)return 0;let t=0,n=i.length-1;for(;t<n;){const l=t+n>>1;(i[l]??0)<e?t=l+1:n=l}return Math.max(0,t>0&&(i[t]??0)>e?t-1:t)}function Q(i,e,t){if(i.length===0)return 0;for(let n=i.length-1;n>=0;n--)if((i[n]??0)<t)return n;return 0}function W(i){const{firstVisible:e,lastVisible:t,itemCount:n,overscan:l}=i;return n===0?{start:0,end:-1}:{start:Math.max(0,e-l),end:Math.min(n-1,t+l)}}function X(i,e,t){return r.useCallback((n,l)=>{var k;const s=i.current,o=e.current;if(!s||!o)return;let p,c;if(typeof n=="object"&&n!==null?(p=n.index,c={align:n.align,behavior:n.behavior,offset:n.offset}):(p=n,c=l),!Number.isFinite(p))return;const g=Math.max(0,Math.min(Math.floor(p),o.count-1)),h=((k=t==null?void 0:t.current)==null?void 0:k.offsetTop)??0,I=o.getOffset(g),R=o.getSize(g),b=(c==null?void 0:c.align)??"start",f=(c==null?void 0:c.behavior)??"auto",E=(c==null?void 0:c.offset)??0;let y;b==="start"?y=h+I+E:b==="center"?y=h+I-s.clientHeight/2+R/2+E:y=h+I-s.clientHeight+R+E,s.scrollTo({top:Math.max(0,y),behavior:f})},[i,e,t])}function q(i){var V;const{items:e,getKey:t,estimatedItemSize:n,overscan:l,initialAlignment:s}=i,o=r.useRef(null),p=r.useRef(null),c=r.useRef(null),g=r.useRef(new G),h=r.useRef([]),I=r.useRef(!1),R=r.useRef(0),b=r.useRef(0),f=r.useRef(null),[,E]=r.useState(0),y=r.useCallback(()=>E(a=>a+1),[]);c.current||(c.current=new $(e.length,n));const k=r.useRef(e.length);if(e.length!==k.current||e.some((a,d)=>{const z=t(a,d);return h.current[d]!==z})){const a=c.current,d=e.map((N,O)=>t(N,O)),z=h.current,M=z.length,w=d.length;w===0?a.resize(0):M===0?a.resize(w):w>M?z.length>0&&d[w-M]===z[0]?a.prepend(w-M):a.resize(w):w<M&&a.resize(w);const H=new Map;d.forEach((N,O)=>H.set(N,O)),g.current.applyToOffsetMap(a,H),h.current=d,k.current=e.length}r.useEffect(()=>{const a=o.current;if(!a)return;const d=()=>{f.current===null&&(f.current=requestAnimationFrame(()=>{f.current=null,R.current=a.scrollTop,b.current=a.clientHeight,y()}))};return a.addEventListener("scroll",d,{passive:!0}),()=>{a.removeEventListener("scroll",d),f.current!==null&&(cancelAnimationFrame(f.current),f.current=null)}},[y]),r.useEffect(()=>{const a=o.current;if(!a)return;b.current=a.clientHeight,R.current=a.scrollTop;const d=new ResizeObserver(([z])=>{z&&(b.current=z.contentRect.height,y())});return d.observe(a),()=>d.disconnect()},[y]),r.useLayoutEffect(()=>{if(I.current||e.length===0)return;const a=o.current;a&&(s==="bottom"&&(a.scrollTop=a.scrollHeight,R.current=a.scrollTop),I.current=!0)},[s,e.length]),r.useEffect(()=>{e.length===0&&(I.current=!1)},[e.length]);const C=r.useCallback((a,d)=>{const z=c.current;if(!z||g.current.get(a)===d)return;g.current.set(a,d);const w=h.current.indexOf(a);if(w===-1)return;z.setSize(w,d)&&y()},[y]),x=r.useCallback((a,d="auto")=>{var z;(z=o.current)==null||z.scrollTo({top:a,behavior:d})},[]),K=X(o,c,p),A=c.current,L=A?A.totalSize():0,F=o.current,v=(F==null?void 0:F.scrollTop)??R.current,u=(F==null?void 0:F.clientHeight)??b.current,m=((V=p.current)==null?void 0:V.offsetTop)??0,T=Math.max(0,v-m);let P=[];if(A&&A.count>0&&u>0){const a=A.getOffsets(),d=A.getSizes(),z=J(a,T),M=Q(a,d,T+u),w=W({firstVisible:z,lastVisible:M,itemCount:A.count,overscan:l});for(let H=w.start;H<=w.end&&H<e.length;H++)P.push({key:h.current[H]??t(e[H],H),index:H,start:A.getOffset(H),size:A.getSize(H),data:e[H]})}else if(A&&A.count>0){const a=Math.min(e.length-1,l*2);for(let d=0;d<=a;d++)P.push({key:h.current[d]??t(e[d],d),index:d,start:A.getOffset(d),size:A.getSize(d),data:e[d]})}const B=F?F.scrollHeight-F.scrollTop-F.clientHeight:1/0;return{scrollerRef:o,innerRef:p,virtualItems:P,totalSize:L,measureItem:C,scrollToIndex:K,scrollToOffset:x,isAtTop:v<=1,isAtBottom:B<=1,scrollTop:v}}function Z(i,e){const t=r.useRef(0),n=r.useRef(0),l=r.useRef(!1),s=r.useRef({first:null,second:null,timeout:null}),o=r.useCallback(()=>{const{first:c,second:g,timeout:h}=s.current;c&&cancelAnimationFrame(c),g&&cancelAnimationFrame(g),h&&clearTimeout(h),s.current={first:null,second:null,timeout:null}},[]),p=r.useCallback(()=>{const c=i.current;c&&(t.current=c.scrollTop,n.current=c.scrollHeight,l.current=!0)},[i]);return r.useLayoutEffect(()=>{if(!l.current)return;const c=i.current;if(!c)return;l.current=!1;const g=()=>{const h=t.current+(c.scrollHeight-n.current);Number.isFinite(h)&&Math.abs(c.scrollTop-h)>1&&(c.scrollTop=h)};return o(),g(),s.current.first=requestAnimationFrame(()=>{s.current.first=null,g(),s.current.second=requestAnimationFrame(()=>{s.current.second=null,g()})}),s.current.timeout=setTimeout(()=>{s.current.timeout=null,g()},90),()=>o()},[e,i,o]),{prepareAnchor:p}}function ee(i,e){const[t,n]=r.useState(!0),l=r.useRef(null);return r.useEffect(()=>{const s=i.current;if(!s)return;const o=()=>{const c=s.scrollHeight-s.scrollTop-s.clientHeight;n(c<=e)},p=()=>{l.current!==null&&cancelAnimationFrame(l.current),l.current=requestAnimationFrame(o)};return s.addEventListener("scroll",p,{passive:!0}),o(),()=>{s.removeEventListener("scroll",p),l.current!==null&&cancelAnimationFrame(l.current)}},[i,e]),t}function te(i){const{itemCount:e,firstKey:t,lastKey:n,isAtBottom:l,scrollToIndex:s,mode:o}=i,p=r.useRef(e),c=r.useRef(t),g=r.useRef(n);r.useLayoutEffect(()=>{if(!o){p.current=e,c.current=t,g.current=n;return}const h=p.current,I=c.current,R=g.current;e>h&&t===I&&n!==R&&l&&e>0&&s(e-1,{align:"end",behavior:o==="smooth"?"smooth":"auto"}),p.current=e,c.current=t,g.current=n},[e,t,n,l,s,o])}function D(i){const{items:e,getKey:t,estimatedItemSize:n=80,overscan:l=20,atBottomThreshold:s=200,followOutput:o="auto",initialAlignment:p="bottom",onStartReached:c,onEndReached:g,startReachedThreshold:h=300,endReachedThreshold:I=300,scrollToMessageKey:R,onScrollToMessageComplete:b}=i,f=q({items:e,getKey:t,estimatedItemSize:n,overscan:l,initialAlignment:p}),E=ee(f.scrollerRef,s),{prepareAnchor:y}=Z(f.scrollerRef,e.length),k=e.length>0?t(e[0],0):null,S=e.length>0?t(e[e.length-1],e.length-1):null;te({itemCount:e.length,firstKey:k,lastKey:S,isAtBottom:E,scrollToIndex:f.scrollToIndex,mode:o??!1});const C=r.useRef(!1),x=r.useRef(p==="top");r.useEffect(()=>{const v=f.scrollerRef.current;if(!v||!c)return;const u=()=>{const m=v.scrollTop;!x.current&&m>h&&(x.current=!0),x.current&&m<=h&&!C.current&&(C.current=!0,Promise.resolve(c()).finally(()=>{C.current=!1}))};return v.addEventListener("scroll",u,{passive:!0}),()=>v.removeEventListener("scroll",u)},[f.scrollerRef,c,h,p]);const K=r.useRef(!1);r.useEffect(()=>{const v=f.scrollerRef.current;if(!v||!g)return;const u=()=>{v.scrollHeight-v.scrollTop-v.clientHeight<=I&&!K.current&&(K.current=!0,Promise.resolve(g()).finally(()=>{K.current=!1}))};return v.addEventListener("scroll",u,{passive:!0}),()=>v.removeEventListener("scroll",u)},[f.scrollerRef,g,I]);const A=r.useRef(null);r.useEffect(()=>{if(!R||A.current===R)return;const v=e.findIndex((u,m)=>t(u,m)===R);v!==-1&&(A.current=R,f.scrollToIndex(v,{align:"center",behavior:"smooth"}),b==null||b())},[R,e,t,f,b]);const L=r.useCallback((v="auto")=>{e.length!==0&&f.scrollToIndex(e.length-1,{align:"end",behavior:v})},[e.length,f]),F=r.useCallback((v,u)=>{const m=e.findIndex((T,P)=>t(T,P)===v);m!==-1&&f.scrollToIndex(m,u)},[e,t,f]);return{scrollerRef:f.scrollerRef,innerRef:f.innerRef,virtualItems:f.virtualItems,totalSize:f.totalSize,measureItem:f.measureItem,scrollToIndex:f.scrollToIndex,scrollToBottom:L,scrollToKey:F,isAtBottom:E,prepareAnchor:y}}function Y({virtualItem:i,measureItem:e,children:t}){const n=r.useRef(null);return r.useEffect(()=>{const l=n.current;if(!l)return;const s=new ResizeObserver(([o])=>{o&&e(i.key,o.contentRect.height)});return s.observe(l),()=>s.disconnect()},[i.key,e]),j.jsx("div",{ref:n,style:{position:"absolute",top:0,transform:`translateY(${i.start}px)`,width:"100%",minHeight:i.size},children:t})}function re(i,e){const{data:t,itemContent:n,computeItemKey:l,estimatedItemSize:s=80,overscan:o=20,followOutput:p="auto",atBottomThreshold:c=200,initialAlignment:g="bottom",onStartReached:h,onEndReached:I,startReachedThreshold:R=300,endReachedThreshold:b=300,scrollToMessageKey:f,onScrollToMessageComplete:E,onAtBottomChange:y,components:k={},className:S,style:C}=i,{scrollerRef:x,innerRef:K,virtualItems:A,totalSize:L,measureItem:F,scrollToIndex:v,scrollToBottom:u,scrollToKey:m,isAtBottom:T,prepareAnchor:P}=D({items:t,getKey:(z,M)=>l(M,z),estimatedItemSize:s,overscan:o,atBottomThreshold:c,followOutput:p,initialAlignment:g,onStartReached:h,onEndReached:I,startReachedThreshold:R,endReachedThreshold:b,scrollToMessageKey:f,onScrollToMessageComplete:E}),B=_.useRef(T);_.useEffect(()=>{B.current!==T&&(B.current=T,y==null||y(T))},[T,y]),r.useImperativeHandle(e,()=>({scrollToBottom:u,scrollToIndex:v,scrollToKey:m,getScrollTop:()=>{var z;return((z=x.current)==null?void 0:z.scrollTop)??0},isAtBottom:()=>T,prepareAnchor:P}),[u,v,m,x,T,P]);const{Header:V,Footer:a,EmptyPlaceholder:d}=k;return t.length===0&&d?j.jsx(d,{}):j.jsxs("div",{ref:x,className:S,style:{overflow:"auto",height:"100%",position:"relative",overscrollBehaviorY:"contain",...C},children:[V&&j.jsx(V,{}),j.jsx("div",{ref:K,style:{height:L,position:"relative",width:"100%"},children:A.map(z=>j.jsx(Y,{virtualItem:z,measureItem:F,children:n(z.index,z.data)},z.key))}),a&&j.jsx(a,{})]})}const ne=r.forwardRef(re);function se({data:i,itemContent:e,computeItemKey:t,estimatedItemSize:n=60,overscan:l=20,onEndReached:s,endReachedThreshold:o=300,components:p={},className:c,style:g}){const{scrollerRef:h,innerRef:I,virtualItems:R,totalSize:b,measureItem:f}=q({items:i,getKey:(S,C)=>t(C,S),estimatedItemSize:n,overscan:l,initialAlignment:"top"});_.useEffect(()=>{const S=h.current;if(!S||!s)return;let C=!1;const x=()=>{S.scrollHeight-S.scrollTop-S.clientHeight<=o&&!C&&(C=!0,Promise.resolve(s()).finally(()=>{C=!1}))};return S.addEventListener("scroll",x,{passive:!0}),()=>S.removeEventListener("scroll",x)},[h,s,o]);const{Header:E,Footer:y,EmptyPlaceholder:k}=p;return i.length===0&&k?j.jsx(k,{}):j.jsxs("div",{ref:h,className:c,style:{overflow:"auto",height:"100%",position:"relative",overscrollBehaviorY:"contain",...g},children:[E&&j.jsx(E,{}),j.jsx("div",{ref:I,style:{height:b,position:"relative",width:"100%"},children:R.map(S=>j.jsx(Y,{virtualItem:S,measureItem:f,children:e(S.index,S.data)},S.key))}),y&&j.jsx(y,{})]})}function ce(i){const{fetcher:e,initialPage:t=1,direction:n="append",getKey:l,onPageLoaded:s,onError:o}=i,[p,c]=r.useState([]),[g,h]=r.useState(t),[I,R]=r.useState(!0),[b,f]=r.useState(!1),[E,y]=r.useState(!1),[k,S]=r.useState(!1),C=r.useRef(new Set),x=r.useRef(!1),K=r.useCallback(u=>l?u.filter(m=>{const T=l(m);return C.current.has(T)?!1:(C.current.add(T),!0)}):u,[l]),A=r.useCallback(async()=>{if(!(x.current||!I)){x.current=!0,S(!0);try{const u=g+1,m=await e(u),T=K(m.data);c(P=>n==="prepend"?[...T,...P]:[...P,...T]),h(u),R(m.hasNextPage),f(m.hasPrevPage),s==null||s(u,T)}catch(u){o==null||o(u instanceof Error?u:new Error(String(u)))}finally{S(!1),x.current=!1}}},[g,I,e,K,n,s,o]),L=r.useCallback(async()=>{if(!(x.current||!b)){x.current=!0,S(!0);try{const u=g-1,m=await e(u),T=K(m.data);c(P=>[...T,...P]),h(u),f(m.hasPrevPage),R(m.hasNextPage),s==null||s(u,T)}catch(u){o==null||o(u instanceof Error?u:new Error(String(u)))}finally{S(!1),x.current=!1}}},[g,b,e,K,s,o]),F=r.useCallback(async()=>{if(!x.current){x.current=!0,y(!0);try{const u=await e(t),m=u.data;if(l){const T=new Set(m.map(l));m.forEach(P=>C.current.add(l(P))),c(P=>{const B=P.filter(V=>!T.has(l(V)));return n==="prepend"?[...m,...B]:[...B,...m]})}else c(m);h(t),R(u.hasNextPage),f(u.hasPrevPage),s==null||s(t,m)}catch(u){o==null||o(u instanceof Error?u:new Error(String(u)))}finally{y(!1),x.current=!1}}},[e,t,l,n,s,o]),v=r.useCallback(()=>{c([]),h(t),R(!0),f(!1),y(!1),S(!1),C.current.clear(),x.current=!1},[t]);return{items:p,loadNextPage:A,loadPrevPage:L,hasNextPage:I,hasPrevPage:b,loading:E,loadingMore:k,refresh:F,reset:v,currentPage:g}}exports.ChatVirtualList=ne;exports.VirtualList=se;exports.useChatVirtualizer=D;exports.usePagination=ce;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const M=require("react/jsx-runtime"),r=require("react");function Q(i){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(i){for(const t in i)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(i,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>i[t]})}}return e.default=i,Object.freeze(e)}const D=Q(r);class W{constructor(e,t){this.defaultSize=t,this.sizes=e>0?Array(e).fill(t):[],this.offsets=e>0?Array(e).fill(0):[],e>0&&this._recalcFrom(0)}_recalcFrom(e){for(let t=e;t<this.sizes.length;t++)this.offsets[t]=t===0?0:(this.offsets[t-1]??0)+(this.sizes[t-1]??this.defaultSize)}getOffset(e){return this.offsets[e]??0}getSize(e){return this.sizes[e]??this.defaultSize}setSize(e,t){return this.sizes[e]===t?!1:(this.sizes[e]=t,this._recalcFrom(e+1),!0)}prepend(e){const t=Array(e).fill(this.defaultSize);this.sizes=[...t,...this.sizes],this.offsets=Array(this.sizes.length).fill(0),this._recalcFrom(0)}append(e){const t=this.sizes.length;for(let n=0;n<e;n++)this.sizes.push(this.defaultSize),this.offsets.push(0);this._recalcFrom(t)}resize(e){const t=this.sizes.length;e>t?this.append(e-t):e<t&&(this.sizes=this.sizes.slice(0,e),this.offsets=this.offsets.slice(0,e))}totalSize(){if(this.sizes.length===0)return 0;const e=this.sizes.length-1;return(this.offsets[e]??0)+(this.sizes[e]??this.defaultSize)}get count(){return this.sizes.length}getOffsets(){return this.offsets}getSizes(){return this.sizes}}class Z{constructor(){this.cache=new Map}get(e){return this.cache.get(e)}set(e,t){this.cache.set(e,t)}has(e){return this.cache.has(e)}delete(e){this.cache.delete(e)}clear(){this.cache.clear()}applyToOffsetMap(e,t){for(const[n,l]of this.cache){const o=t.get(n);o!==void 0&&e.setSize(o,l)}}}function ee(i,e){if(i.length===0)return 0;let t=0,n=i.length-1;for(;t<n;){const l=t+n>>1;(i[l]??0)<e?t=l+1:n=l}return Math.max(0,t>0&&(i[t]??0)>e?t-1:t)}function te(i,e,t){if(i.length===0)return 0;for(let n=i.length-1;n>=0;n--)if((i[n]??0)<t)return n;return 0}function re(i){const{firstVisible:e,lastVisible:t,itemCount:n,overscan:l}=i;return n===0?{start:0,end:-1}:{start:Math.max(0,e-l),end:Math.min(n-1,t+l)}}function ne(i,e,t){return r.useCallback((n,l)=>{var H;const o=i.current,s=e.current;if(!o||!s)return;let m,f;if(typeof n=="object"&&n!==null?(m=n.index,f={align:n.align,behavior:n.behavior,offset:n.offset}):(m=n,f=l),!Number.isFinite(m))return;const d=Math.max(0,Math.min(Math.floor(m),s.count-1)),g=((H=t==null?void 0:t.current)==null?void 0:H.offsetTop)??0,z=s.getOffset(d),S=s.getSize(d),T=(f==null?void 0:f.align)??"start",h=(f==null?void 0:f.behavior)??"auto",I=(f==null?void 0:f.offset)??0;let y;T==="start"?y=g+z+I:T==="center"?y=g+z-o.clientHeight/2+S/2+I:y=g+z-o.clientHeight+S+I,o.scrollTo({top:Math.max(0,y),behavior:h})},[i,e,t])}function X(i){var O;const{items:e,getKey:t,estimatedItemSize:n,overscan:l,initialAlignment:o}=i,s=r.useRef(null),m=r.useRef(null),f=r.useRef(null),d=r.useRef(new Z),g=r.useRef([]),z=r.useRef(!1),S=r.useRef(0),T=r.useRef(0),h=r.useRef(null),I=r.useRef(!1),y=r.useRef(null),[,H]=r.useState(0),v=r.useCallback(()=>H(c=>c+1),[]);f.current||(f.current=new W(e.length,n));const E=r.useRef(e.length);if(e.length!==E.current||e.some((c,R)=>{const b=t(c,R);return g.current[R]!==b})){const c=f.current,R=e.map((_,N)=>t(_,N)),b=g.current,A=b.length,k=R.length;k===0?c.resize(0):A===0?c.resize(k):k>A?b.length>0&&R[k-A]===b[0]?c.prepend(k-A):c.resize(k):k<A&&c.resize(k);const P=new Map;R.forEach((_,N)=>P.set(_,N)),d.current.applyToOffsetMap(c,P),g.current=R,E.current=e.length}r.useEffect(()=>{const c=s.current;if(!c)return;const R=()=>{h.current===null&&(h.current=requestAnimationFrame(()=>{h.current=null,S.current=c.scrollTop,T.current=c.clientHeight,v()}))};return c.addEventListener("scroll",R,{passive:!0}),()=>{c.removeEventListener("scroll",R),h.current!==null&&(cancelAnimationFrame(h.current),h.current=null)}},[v]),r.useEffect(()=>{const c=s.current;if(!c)return;T.current=c.clientHeight,S.current=c.scrollTop;const R=new ResizeObserver(([b])=>{b&&(T.current=b.contentRect.height,v())});return R.observe(c),()=>R.disconnect()},[v]),r.useLayoutEffect(()=>{if(z.current||e.length===0)return;const c=s.current;if(c){if(o==="bottom"){c.scrollTop=c.scrollHeight,S.current=c.scrollTop,T.current=c.clientHeight,I.current=!0,y.current!==null&&cancelAnimationFrame(y.current);let R=0;const b=30,A=()=>{if(!I.current||R>=b){I.current=!1,y.current=null;return}R++,c.scrollTop=c.scrollHeight,S.current=c.scrollTop,y.current=requestAnimationFrame(A)};y.current=requestAnimationFrame(A)}z.current=!0}},[o,e.length]),r.useEffect(()=>{e.length===0&&(z.current=!1,I.current=!1,y.current!==null&&(cancelAnimationFrame(y.current),y.current=null))},[e.length]);const w=r.useCallback((c,R)=>{var N;const b=f.current;if(!b||d.current.get(c)===R)return;d.current.set(c,R);const k=g.current.indexOf(c);if(k===-1)return;const P=s.current;if(P&&!I.current){const Y=b.getSize(k),U=R-Y,J=b.getOffset(k)+Y+(((N=m.current)==null?void 0:N.offsetTop)??0);U!==0&&J<P.scrollTop&&(P.scrollTop+=U,S.current=P.scrollTop)}b.setSize(k,R)&&v()},[v]),L=r.useCallback((c,R="auto")=>{var b;(b=s.current)==null||b.scrollTo({top:c,behavior:R})},[]),B=ne(s,f,m),F=f.current,V=F?F.totalSize():0,a=s.current,u=(a==null?void 0:a.scrollTop)??S.current,p=(a==null?void 0:a.clientHeight)??T.current,x=((O=m.current)==null?void 0:O.offsetTop)??0,K=Math.max(0,u-x);let j=[];if(F&&F.count>0&&p>0){const c=F.getOffsets(),R=F.getSizes(),b=ee(c,K),A=te(c,R,K+p),k=re({firstVisible:b,lastVisible:A,itemCount:F.count,overscan:l});for(let P=k.start;P<=k.end&&P<e.length;P++)j.push({key:g.current[P]??t(e[P],P),index:P,start:F.getOffset(P),size:F.getSize(P),data:e[P]})}else if(F&&F.count>0){const c=Math.min(e.length,l*2+1),R=o==="bottom"?Math.max(0,e.length-c):0,b=R+c-1;for(let A=R;A<=b;A++)j.push({key:g.current[A]??t(e[A],A),index:A,start:F.getOffset(A),size:F.getSize(A),data:e[A]})}const q=a?a.scrollHeight-a.scrollTop-a.clientHeight:1/0;return{scrollerRef:s,innerRef:m,virtualItems:j,totalSize:V,measureItem:w,scrollToIndex:B,scrollToOffset:L,isAtTop:u<=1,isAtBottom:q<=1,scrollTop:u}}function se(i,e,t){const n=r.useRef(0),l=r.useRef(0),o=r.useRef(!1),s=r.useRef({first:null,second:null,timeout:null}),m=r.useCallback(()=>{const{first:d,second:g,timeout:z}=s.current;d&&cancelAnimationFrame(d),g&&cancelAnimationFrame(g),z&&clearTimeout(z),s.current={first:null,second:null,timeout:null}},[]),f=r.useCallback(()=>{const d=i.current;d&&(n.current=d.scrollTop,l.current=d.scrollHeight,o.current=!0)},[i]);return r.useLayoutEffect(()=>{if(!o.current)return;const d=i.current;if(!d)return;o.current=!1;const g=()=>{const z=n.current+(d.scrollHeight-l.current);Number.isFinite(z)&&Math.abs(d.scrollTop-z)>1&&(d.scrollTop=z)};return m(),g(),t==null||t(),s.current.first=requestAnimationFrame(()=>{s.current.first=null,g(),s.current.second=requestAnimationFrame(()=>{s.current.second=null,g()})}),s.current.timeout=setTimeout(()=>{s.current.timeout=null,g()},90),()=>m()},[e,i,m,t]),{prepareAnchor:f}}function ce(i,e){const[t,n]=r.useState(!0),l=r.useRef(null);return r.useEffect(()=>{const o=i.current;if(!o)return;const s=()=>{const f=o.scrollHeight-o.scrollTop-o.clientHeight;n(f<=e)},m=()=>{l.current!==null&&cancelAnimationFrame(l.current),l.current=requestAnimationFrame(s)};return o.addEventListener("scroll",m,{passive:!0}),s(),()=>{o.removeEventListener("scroll",m),l.current!==null&&cancelAnimationFrame(l.current)}},[i,e]),t}function oe(i){const{itemCount:e,firstKey:t,lastKey:n,isAtBottom:l,scrollToIndex:o,mode:s}=i,m=r.useRef(e),f=r.useRef(t),d=r.useRef(n);r.useLayoutEffect(()=>{if(!s){m.current=e,f.current=t,d.current=n;return}const g=m.current,z=f.current,S=d.current;e>g&&t===z&&n!==S&&l&&e>0&&o(e-1,{align:"end",behavior:s==="smooth"?"smooth":"auto"}),m.current=e,f.current=t,d.current=n},[e,t,n,l,o,s])}function $(i){const{items:e,getKey:t,estimatedItemSize:n=80,overscan:l=20,atBottomThreshold:o=200,followOutput:s="auto",initialAlignment:m="bottom",onStartReached:f,onEndReached:d,startReachedThreshold:g=300,endReachedThreshold:z=300,scrollToMessageKey:S,onScrollToMessageComplete:T}=i,h=X({items:e,getKey:t,estimatedItemSize:n,overscan:l,initialAlignment:m}),I=ce(h.scrollerRef,o),[,y]=r.useState(0),H=r.useCallback(()=>y(u=>u+1),[]),{prepareAnchor:v}=se(h.scrollerRef,e.length,H),E=e.length>0?t(e[0],0):null,C=e.length>0?t(e[e.length-1],e.length-1):null;oe({itemCount:e.length,firstKey:E,lastKey:C,isAtBottom:I,scrollToIndex:h.scrollToIndex,mode:s??!1});const w=r.useRef(!1),L=r.useRef(m==="top");r.useEffect(()=>{const u=h.scrollerRef.current;if(!u||!f)return;const p=()=>{const x=u.scrollTop;!L.current&&x>g&&(L.current=!0),L.current&&x<=g&&!w.current&&(w.current=!0,Promise.resolve(f()).finally(()=>{w.current=!1}))};return u.addEventListener("scroll",p,{passive:!0}),()=>u.removeEventListener("scroll",p)},[h.scrollerRef,f,g,m]);const B=r.useRef(!1);r.useEffect(()=>{const u=h.scrollerRef.current;if(!u||!d)return;const p=()=>{u.scrollHeight-u.scrollTop-u.clientHeight<=z&&!B.current&&(B.current=!0,Promise.resolve(d()).finally(()=>{B.current=!1}))};return u.addEventListener("scroll",p,{passive:!0}),()=>u.removeEventListener("scroll",p)},[h.scrollerRef,d,z]);const F=r.useRef(null);r.useEffect(()=>{if(!S||F.current===S)return;const u=e.findIndex((p,x)=>t(p,x)===S);u!==-1&&(F.current=S,h.scrollToIndex(u,{align:"center",behavior:"smooth"}),T==null||T())},[S,e,t,h,T]);const V=r.useCallback((u="auto")=>{e.length!==0&&h.scrollToIndex(e.length-1,{align:"end",behavior:u})},[e.length,h]),a=r.useCallback((u,p)=>{const x=e.findIndex((K,j)=>t(K,j)===u);x!==-1&&h.scrollToIndex(x,p)},[e,t,h]);return{scrollerRef:h.scrollerRef,innerRef:h.innerRef,virtualItems:h.virtualItems,totalSize:h.totalSize,measureItem:h.measureItem,scrollToIndex:h.scrollToIndex,scrollToBottom:V,scrollToKey:a,isAtBottom:I,prepareAnchor:v}}function G({virtualItem:i,measureItem:e,children:t}){const n=r.useRef(null),l=r.useRef(!1);return r.useEffect(()=>{const o=n.current;if(!o)return;l.current=!1;const s=new ResizeObserver(([m])=>{m&&(l.current=!0,e(i.key,m.contentRect.height))});return s.observe(o),()=>s.disconnect()},[i.key,e]),M.jsx("div",{ref:n,style:{position:"absolute",top:0,transform:`translateY(${i.start}px)`,width:"100%",minHeight:l.current?void 0:i.size},children:t})}function ie(i,e){const{data:t,itemContent:n,computeItemKey:l,estimatedItemSize:o=80,overscan:s=20,followOutput:m="auto",atBottomThreshold:f=200,initialAlignment:d="bottom",onStartReached:g,onEndReached:z,startReachedThreshold:S=300,endReachedThreshold:T=300,scrollToMessageKey:h,onScrollToMessageComplete:I,onAtBottomChange:y,components:H={},className:v,style:E}=i,{scrollerRef:C,innerRef:w,virtualItems:L,totalSize:B,measureItem:F,scrollToIndex:V,scrollToBottom:a,scrollToKey:u,isAtBottom:p,prepareAnchor:x}=$({items:t,getKey:(c,R)=>l(R,c),estimatedItemSize:o,overscan:s,atBottomThreshold:f,followOutput:m,initialAlignment:d,onStartReached:g,onEndReached:z,startReachedThreshold:S,endReachedThreshold:T,scrollToMessageKey:h,onScrollToMessageComplete:I}),K=D.useRef(p);D.useEffect(()=>{K.current!==p&&(K.current=p,y==null||y(p))},[p,y]),r.useImperativeHandle(e,()=>({scrollToBottom:a,scrollToIndex:V,scrollToKey:u,getScrollTop:()=>{var c;return((c=C.current)==null?void 0:c.scrollTop)??0},isAtBottom:()=>p,prepareAnchor:x}),[a,V,u,C,p,x]);const{Header:j,Footer:q,EmptyPlaceholder:O}=H;return t.length===0&&O?M.jsx(O,{}):M.jsxs("div",{ref:C,className:v,style:{overflow:"auto",height:"100%",position:"relative",overscrollBehaviorY:"contain",...E},children:[j&&M.jsx(j,{}),M.jsx("div",{ref:w,style:{height:B,position:"relative",width:"100%"},children:L.map(c=>M.jsx(G,{virtualItem:c,measureItem:F,children:n(c.index,c.data)},c.key))}),q&&M.jsx(q,{})]})}const le=r.forwardRef(ie);function ue({data:i,itemContent:e,computeItemKey:t,estimatedItemSize:n=60,overscan:l=20,onEndReached:o,endReachedThreshold:s=300,components:m={},className:f,style:d}){const{scrollerRef:g,innerRef:z,virtualItems:S,totalSize:T,measureItem:h}=X({items:i,getKey:(v,E)=>t(E,v),estimatedItemSize:n,overscan:l,initialAlignment:"top"});D.useEffect(()=>{const v=g.current;if(!v||!o)return;let E=!1;const C=()=>{v.scrollHeight-v.scrollTop-v.clientHeight<=s&&!E&&(E=!0,Promise.resolve(o()).finally(()=>{E=!1}))};return v.addEventListener("scroll",C,{passive:!0}),()=>v.removeEventListener("scroll",C)},[g,o,s]);const{Header:I,Footer:y,EmptyPlaceholder:H}=m;return i.length===0&&H?M.jsx(H,{}):M.jsxs("div",{ref:g,className:f,style:{overflow:"auto",height:"100%",position:"relative",overscrollBehaviorY:"contain",...d},children:[I&&M.jsx(I,{}),M.jsx("div",{ref:z,style:{height:T,position:"relative",width:"100%"},children:S.map(v=>M.jsx(G,{virtualItem:v,measureItem:h,children:e(v.index,v.data)},v.key))}),y&&M.jsx(y,{})]})}function ae(i){const{fetcher:e,initialPage:t=1,direction:n="append",getKey:l,onPageLoaded:o,onError:s}=i,[m,f]=r.useState([]),[d,g]=r.useState(t),[z,S]=r.useState(!0),[T,h]=r.useState(!1),[I,y]=r.useState(!1),[H,v]=r.useState(!1),E=r.useRef(new Set),C=r.useRef(!1),w=r.useCallback(a=>l?a.filter(u=>{const p=l(u);return E.current.has(p)?!1:(E.current.add(p),!0)}):a,[l]),L=r.useCallback(async()=>{if(!(C.current||!z)){C.current=!0,v(!0);try{const a=d+1,u=await e(a),p=w(u.data);f(x=>n==="prepend"?[...p,...x]:[...x,...p]),g(a),S(u.hasNextPage),h(u.hasPrevPage),o==null||o(a,p)}catch(a){s==null||s(a instanceof Error?a:new Error(String(a)))}finally{v(!1),C.current=!1}}},[d,z,e,w,n,o,s]),B=r.useCallback(async()=>{if(!(C.current||!T)){C.current=!0,v(!0);try{const a=d-1,u=await e(a),p=w(u.data);f(x=>[...p,...x]),g(a),h(u.hasPrevPage),S(u.hasNextPage),o==null||o(a,p)}catch(a){s==null||s(a instanceof Error?a:new Error(String(a)))}finally{v(!1),C.current=!1}}},[d,T,e,w,o,s]),F=r.useCallback(async()=>{if(!C.current){C.current=!0,y(!0);try{const a=await e(t),u=a.data;if(l){const p=new Set(u.map(l));u.forEach(x=>E.current.add(l(x))),f(x=>{const K=x.filter(j=>!p.has(l(j)));return n==="prepend"?[...u,...K]:[...K,...u]})}else f(u);g(t),S(a.hasNextPage),h(a.hasPrevPage),o==null||o(t,u)}catch(a){s==null||s(a instanceof Error?a:new Error(String(a)))}finally{y(!1),C.current=!1}}},[e,t,l,n,o,s]),V=r.useCallback(()=>{f([]),g(t),S(!0),h(!1),y(!1),v(!1),E.current.clear(),C.current=!1},[t]);return{items:m,loadNextPage:L,loadPrevPage:B,hasNextPage:z,hasPrevPage:T,loading:I,loadingMore:H,refresh:F,reset:V,currentPage:d}}exports.ChatVirtualList=le;exports.VirtualList=ue;exports.useChatVirtualizer=$;exports.usePagination=ae;
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { jsx as B, jsxs as $ } from "react/jsx-runtime";
2
- import * as U from "react";
3
- import { useCallback as L, useRef as y, useState as V, useEffect as N, useLayoutEffect as D, forwardRef as Q, useImperativeHandle as W } from "react";
4
- class X {
1
+ import { jsx as B, jsxs as Q } from "react/jsx-runtime";
2
+ import * as X from "react";
3
+ import { useCallback as M, useRef as T, useState as _, useEffect as j, useLayoutEffect as $, forwardRef as te, useImperativeHandle as re } from "react";
4
+ class ne {
5
5
  constructor(e, t) {
6
6
  this.defaultSize = t, this.sizes = e > 0 ? Array(e).fill(t) : [], this.offsets = e > 0 ? Array(e).fill(0) : [], e > 0 && this._recalcFrom(0);
7
7
  }
@@ -25,7 +25,7 @@ class X {
25
25
  }
26
26
  append(e) {
27
27
  const t = this.sizes.length;
28
- for (let n = 0; n < e; n++)
28
+ for (let s = 0; s < e; s++)
29
29
  this.sizes.push(this.defaultSize), this.offsets.push(0);
30
30
  this._recalcFrom(t);
31
31
  }
@@ -48,7 +48,7 @@ class X {
48
48
  return this.sizes;
49
49
  }
50
50
  }
51
- class Z {
51
+ class se {
52
52
  constructor() {
53
53
  this.cache = /* @__PURE__ */ new Map();
54
54
  }
@@ -69,557 +69,582 @@ class Z {
69
69
  }
70
70
  /** Re-applies all cached sizes to the OffsetMap using a key→index map */
71
71
  applyToOffsetMap(e, t) {
72
- for (const [n, i] of this.cache) {
73
- const r = t.get(n);
74
- r !== void 0 && e.setSize(r, i);
72
+ for (const [s, o] of this.cache) {
73
+ const c = t.get(s);
74
+ c !== void 0 && e.setSize(c, o);
75
75
  }
76
76
  }
77
77
  }
78
- function ee(l, e) {
79
- if (l.length === 0) return 0;
80
- let t = 0, n = l.length - 1;
81
- for (; t < n; ) {
82
- const i = t + n >> 1;
83
- (l[i] ?? 0) < e ? t = i + 1 : n = i;
78
+ function ce(a, e) {
79
+ if (a.length === 0) return 0;
80
+ let t = 0, s = a.length - 1;
81
+ for (; t < s; ) {
82
+ const o = t + s >> 1;
83
+ (a[o] ?? 0) < e ? t = o + 1 : s = o;
84
84
  }
85
- return Math.max(0, t > 0 && (l[t] ?? 0) > e ? t - 1 : t);
85
+ return Math.max(0, t > 0 && (a[t] ?? 0) > e ? t - 1 : t);
86
86
  }
87
- function te(l, e, t) {
88
- if (l.length === 0) return 0;
89
- for (let n = l.length - 1; n >= 0; n--)
90
- if ((l[n] ?? 0) < t) return n;
87
+ function oe(a, e, t) {
88
+ if (a.length === 0) return 0;
89
+ for (let s = a.length - 1; s >= 0; s--)
90
+ if ((a[s] ?? 0) < t) return s;
91
91
  return 0;
92
92
  }
93
- function re(l) {
94
- const { firstVisible: e, lastVisible: t, itemCount: n, overscan: i } = l;
95
- return n === 0 ? { start: 0, end: -1 } : {
96
- start: Math.max(0, e - i),
97
- end: Math.min(n - 1, t + i)
93
+ function ie(a) {
94
+ const { firstVisible: e, lastVisible: t, itemCount: s, overscan: o } = a;
95
+ return s === 0 ? { start: 0, end: -1 } : {
96
+ start: Math.max(0, e - o),
97
+ end: Math.min(s - 1, t + o)
98
98
  };
99
99
  }
100
- function ne(l, e, t) {
101
- return L(
102
- (n, i) => {
103
- var K;
104
- const r = l.current, o = e.current;
105
- if (!r || !o) return;
106
- let m, s;
107
- if (typeof n == "object" && n !== null ? (m = n.index, s = {
108
- align: n.align,
109
- behavior: n.behavior,
110
- offset: n.offset
111
- }) : (m = n, s = i), !Number.isFinite(m)) return;
112
- const d = Math.max(0, Math.min(Math.floor(m), o.count - 1)), f = ((K = t == null ? void 0 : t.current) == null ? void 0 : K.offsetTop) ?? 0, A = o.getOffset(d), T = o.getSize(d), R = (s == null ? void 0 : s.align) ?? "start", u = (s == null ? void 0 : s.behavior) ?? "auto", H = (s == null ? void 0 : s.offset) ?? 0;
113
- let v;
114
- R === "start" ? v = f + A + H : R === "center" ? v = f + A - r.clientHeight / 2 + T / 2 + H : v = f + A - r.clientHeight + T + H, r.scrollTo({ top: Math.max(0, v), behavior: u });
100
+ function le(a, e, t) {
101
+ return M(
102
+ (s, o) => {
103
+ var E;
104
+ const c = a.current, r = e.current;
105
+ if (!c || !r) return;
106
+ let m, u;
107
+ if (typeof s == "object" && s !== null ? (m = s.index, u = {
108
+ align: s.align,
109
+ behavior: s.behavior,
110
+ offset: s.offset
111
+ }) : (m = s, u = o), !Number.isFinite(m)) return;
112
+ const h = Math.max(0, Math.min(Math.floor(m), r.count - 1)), d = ((E = t == null ? void 0 : t.current) == null ? void 0 : E.offsetTop) ?? 0, y = r.getOffset(h), S = r.getSize(h), x = (u == null ? void 0 : u.align) ?? "start", f = (u == null ? void 0 : u.behavior) ?? "auto", F = (u == null ? void 0 : u.offset) ?? 0;
113
+ let z;
114
+ x === "start" ? z = d + y + F : x === "center" ? z = d + y - c.clientHeight / 2 + S / 2 + F : z = d + y - c.clientHeight + S + F, c.scrollTo({ top: Math.max(0, z), behavior: f });
115
115
  },
116
- [l, e, t]
116
+ [a, e, t]
117
117
  );
118
118
  }
119
- function G(l) {
120
- var q;
121
- const { items: e, getKey: t, estimatedItemSize: n, overscan: i, initialAlignment: r } = l, o = y(null), m = y(null), s = y(null), d = y(new Z()), f = y([]), A = y(!1), T = y(0), R = y(0), u = y(null), [, H] = V(0), v = L(() => H((a) => a + 1), []);
122
- s.current || (s.current = new X(e.length, n));
123
- const K = y(e.length);
124
- if (e.length !== K.current || e.some((a, h) => {
125
- const z = t(a, h);
126
- return f.current[h] !== z;
119
+ function W(a) {
120
+ var Y;
121
+ const { items: e, getKey: t, estimatedItemSize: s, overscan: o, initialAlignment: c } = a, r = T(null), m = T(null), u = T(null), h = T(new se()), d = T([]), y = T(!1), S = T(0), x = T(0), f = T(null), F = T(!1), z = T(null), [, E] = _(0), p = M(() => E((n) => n + 1), []);
122
+ u.current || (u.current = new ne(e.length, s));
123
+ const w = T(e.length);
124
+ if (e.length !== w.current || e.some((n, v) => {
125
+ const I = t(n, v);
126
+ return d.current[v] !== I;
127
127
  })) {
128
- const a = s.current, h = e.map((O, Y) => t(O, Y)), z = f.current, k = z.length, E = h.length;
129
- E === 0 ? a.resize(0) : k === 0 ? a.resize(E) : E > k ? z.length > 0 && h[E - k] === z[0] ? a.prepend(E - k) : a.resize(E) : E < k && a.resize(E);
130
- const M = /* @__PURE__ */ new Map();
131
- h.forEach((O, Y) => M.set(O, Y)), d.current.applyToOffsetMap(a, M), f.current = h, K.current = e.length;
128
+ const n = u.current, v = e.map((U, O) => t(U, O)), I = d.current, R = I.length, K = v.length;
129
+ K === 0 ? n.resize(0) : R === 0 ? n.resize(K) : K > R ? I.length > 0 && v[K - R] === I[0] ? n.prepend(K - R) : n.resize(K) : K < R && n.resize(K);
130
+ const P = /* @__PURE__ */ new Map();
131
+ v.forEach((U, O) => P.set(U, O)), h.current.applyToOffsetMap(n, P), d.current = v, w.current = e.length;
132
132
  }
133
- N(() => {
134
- const a = o.current;
135
- if (!a) return;
136
- const h = () => {
137
- u.current === null && (u.current = requestAnimationFrame(() => {
138
- u.current = null, T.current = a.scrollTop, R.current = a.clientHeight, v();
133
+ j(() => {
134
+ const n = r.current;
135
+ if (!n) return;
136
+ const v = () => {
137
+ f.current === null && (f.current = requestAnimationFrame(() => {
138
+ f.current = null, S.current = n.scrollTop, x.current = n.clientHeight, p();
139
139
  }));
140
140
  };
141
- return a.addEventListener("scroll", h, { passive: !0 }), () => {
142
- a.removeEventListener("scroll", h), u.current !== null && (cancelAnimationFrame(u.current), u.current = null);
141
+ return n.addEventListener("scroll", v, { passive: !0 }), () => {
142
+ n.removeEventListener("scroll", v), f.current !== null && (cancelAnimationFrame(f.current), f.current = null);
143
143
  };
144
- }, [v]), N(() => {
145
- const a = o.current;
146
- if (!a) return;
147
- R.current = a.clientHeight, T.current = a.scrollTop;
148
- const h = new ResizeObserver(([z]) => {
149
- z && (R.current = z.contentRect.height, v());
144
+ }, [p]), j(() => {
145
+ const n = r.current;
146
+ if (!n) return;
147
+ x.current = n.clientHeight, S.current = n.scrollTop;
148
+ const v = new ResizeObserver(([I]) => {
149
+ I && (x.current = I.contentRect.height, p());
150
150
  });
151
- return h.observe(a), () => h.disconnect();
152
- }, [v]), D(() => {
153
- if (A.current || e.length === 0) return;
154
- const a = o.current;
155
- a && (r === "bottom" && (a.scrollTop = a.scrollHeight, T.current = a.scrollTop), A.current = !0);
156
- }, [r, e.length]), N(() => {
157
- e.length === 0 && (A.current = !1);
151
+ return v.observe(n), () => v.disconnect();
152
+ }, [p]), $(() => {
153
+ if (y.current || e.length === 0) return;
154
+ const n = r.current;
155
+ if (n) {
156
+ if (c === "bottom") {
157
+ n.scrollTop = n.scrollHeight, S.current = n.scrollTop, x.current = n.clientHeight, F.current = !0, z.current !== null && cancelAnimationFrame(z.current);
158
+ let v = 0;
159
+ const I = 30, R = () => {
160
+ if (!F.current || v >= I) {
161
+ F.current = !1, z.current = null;
162
+ return;
163
+ }
164
+ v++, n.scrollTop = n.scrollHeight, S.current = n.scrollTop, z.current = requestAnimationFrame(R);
165
+ };
166
+ z.current = requestAnimationFrame(R);
167
+ }
168
+ y.current = !0;
169
+ }
170
+ }, [c, e.length]), j(() => {
171
+ e.length === 0 && (y.current = !1, F.current = !1, z.current !== null && (cancelAnimationFrame(z.current), z.current = null));
158
172
  }, [e.length]);
159
- const F = L((a, h) => {
160
- const z = s.current;
161
- if (!z || d.current.get(a) === h) return;
162
- d.current.set(a, h);
163
- const E = f.current.indexOf(a);
164
- if (E === -1) return;
165
- z.setSize(E, h) && v();
166
- }, [v]), I = L(
167
- (a, h = "auto") => {
168
- var z;
169
- (z = o.current) == null || z.scrollTo({ top: a, behavior: h });
173
+ const C = M((n, v) => {
174
+ var O;
175
+ const I = u.current;
176
+ if (!I || h.current.get(n) === v) return;
177
+ h.current.set(n, v);
178
+ const K = d.current.indexOf(n);
179
+ if (K === -1) return;
180
+ const P = r.current;
181
+ if (P && !F.current) {
182
+ const G = I.getSize(K), J = v - G, ee = I.getOffset(K) + G + (((O = m.current) == null ? void 0 : O.offsetTop) ?? 0);
183
+ J !== 0 && ee < P.scrollTop && (P.scrollTop += J, S.current = P.scrollTop);
184
+ }
185
+ I.setSize(K, v) && p();
186
+ }, [p]), V = M(
187
+ (n, v = "auto") => {
188
+ var I;
189
+ (I = r.current) == null || I.scrollTo({ top: n, behavior: v });
170
190
  },
171
191
  []
172
- ), C = ne(o, s, m), b = s.current, _ = b ? b.totalSize() : 0, w = o.current, p = (w == null ? void 0 : w.scrollTop) ?? T.current, c = (w == null ? void 0 : w.clientHeight) ?? R.current, g = ((q = m.current) == null ? void 0 : q.offsetTop) ?? 0, x = Math.max(0, p - g);
173
- let P = [];
174
- if (b && b.count > 0 && c > 0) {
175
- const a = b.getOffsets(), h = b.getSizes(), z = ee(a, x), k = te(
176
- a,
177
- h,
178
- x + c
179
- ), E = re({
180
- firstVisible: z,
181
- lastVisible: k,
182
- itemCount: b.count,
183
- overscan: i
192
+ ), N = le(r, u, m), H = u.current, q = H ? H.totalSize() : 0, l = r.current, i = (l == null ? void 0 : l.scrollTop) ?? S.current, g = (l == null ? void 0 : l.clientHeight) ?? x.current, A = ((Y = m.current) == null ? void 0 : Y.offsetTop) ?? 0, L = Math.max(0, i - A);
193
+ let k = [];
194
+ if (H && H.count > 0 && g > 0) {
195
+ const n = H.getOffsets(), v = H.getSizes(), I = ce(n, L), R = oe(
196
+ n,
197
+ v,
198
+ L + g
199
+ ), K = ie({
200
+ firstVisible: I,
201
+ lastVisible: R,
202
+ itemCount: H.count,
203
+ overscan: o
184
204
  });
185
- for (let M = E.start; M <= E.end && M < e.length; M++)
186
- P.push({
187
- key: f.current[M] ?? t(e[M], M),
188
- index: M,
189
- start: b.getOffset(M),
190
- size: b.getSize(M),
191
- data: e[M]
205
+ for (let P = K.start; P <= K.end && P < e.length; P++)
206
+ k.push({
207
+ key: d.current[P] ?? t(e[P], P),
208
+ index: P,
209
+ start: H.getOffset(P),
210
+ size: H.getSize(P),
211
+ data: e[P]
192
212
  });
193
- } else if (b && b.count > 0) {
194
- const a = Math.min(e.length - 1, i * 2);
195
- for (let h = 0; h <= a; h++)
196
- P.push({
197
- key: f.current[h] ?? t(e[h], h),
198
- index: h,
199
- start: b.getOffset(h),
200
- size: b.getSize(h),
201
- data: e[h]
213
+ } else if (H && H.count > 0) {
214
+ const n = Math.min(e.length, o * 2 + 1), v = c === "bottom" ? Math.max(0, e.length - n) : 0, I = v + n - 1;
215
+ for (let R = v; R <= I; R++)
216
+ k.push({
217
+ key: d.current[R] ?? t(e[R], R),
218
+ index: R,
219
+ start: H.getOffset(R),
220
+ size: H.getSize(R),
221
+ data: e[R]
202
222
  });
203
223
  }
204
- const j = w ? w.scrollHeight - w.scrollTop - w.clientHeight : 1 / 0;
224
+ const D = l ? l.scrollHeight - l.scrollTop - l.clientHeight : 1 / 0;
205
225
  return {
206
- scrollerRef: o,
226
+ scrollerRef: r,
207
227
  innerRef: m,
208
- virtualItems: P,
209
- totalSize: _,
210
- measureItem: F,
211
- scrollToIndex: C,
212
- scrollToOffset: I,
213
- isAtTop: p <= 1,
214
- isAtBottom: j <= 1,
215
- scrollTop: p
228
+ virtualItems: k,
229
+ totalSize: q,
230
+ measureItem: C,
231
+ scrollToIndex: N,
232
+ scrollToOffset: V,
233
+ isAtTop: i <= 1,
234
+ isAtBottom: D <= 1,
235
+ scrollTop: i
216
236
  };
217
237
  }
218
- function se(l, e) {
219
- const t = y(0), n = y(0), i = y(!1), r = y({
238
+ function ae(a, e, t) {
239
+ const s = T(0), o = T(0), c = T(!1), r = T({
220
240
  first: null,
221
241
  second: null,
222
242
  timeout: null
223
- }), o = L(() => {
224
- const { first: s, second: d, timeout: f } = r.current;
225
- s && cancelAnimationFrame(s), d && cancelAnimationFrame(d), f && clearTimeout(f), r.current = { first: null, second: null, timeout: null };
226
- }, []), m = L(() => {
227
- const s = l.current;
228
- s && (t.current = s.scrollTop, n.current = s.scrollHeight, i.current = !0);
229
- }, [l]);
230
- return D(() => {
231
- if (!i.current) return;
232
- const s = l.current;
233
- if (!s) return;
234
- i.current = !1;
243
+ }), m = M(() => {
244
+ const { first: h, second: d, timeout: y } = r.current;
245
+ h && cancelAnimationFrame(h), d && cancelAnimationFrame(d), y && clearTimeout(y), r.current = { first: null, second: null, timeout: null };
246
+ }, []), u = M(() => {
247
+ const h = a.current;
248
+ h && (s.current = h.scrollTop, o.current = h.scrollHeight, c.current = !0);
249
+ }, [a]);
250
+ return $(() => {
251
+ if (!c.current) return;
252
+ const h = a.current;
253
+ if (!h) return;
254
+ c.current = !1;
235
255
  const d = () => {
236
- const f = t.current + (s.scrollHeight - n.current);
237
- Number.isFinite(f) && Math.abs(s.scrollTop - f) > 1 && (s.scrollTop = f);
256
+ const y = s.current + (h.scrollHeight - o.current);
257
+ Number.isFinite(y) && Math.abs(h.scrollTop - y) > 1 && (h.scrollTop = y);
238
258
  };
239
- return o(), d(), r.current.first = requestAnimationFrame(() => {
259
+ return m(), d(), t == null || t(), r.current.first = requestAnimationFrame(() => {
240
260
  r.current.first = null, d(), r.current.second = requestAnimationFrame(() => {
241
261
  r.current.second = null, d();
242
262
  });
243
263
  }), r.current.timeout = setTimeout(() => {
244
264
  r.current.timeout = null, d();
245
- }, 90), () => o();
246
- }, [e, l, o]), { prepareAnchor: m };
265
+ }, 90), () => m();
266
+ }, [e, a, m, t]), { prepareAnchor: u };
247
267
  }
248
- function oe(l, e) {
249
- const [t, n] = V(!0), i = y(null);
250
- return N(() => {
251
- const r = l.current;
252
- if (!r) return;
253
- const o = () => {
254
- const s = r.scrollHeight - r.scrollTop - r.clientHeight;
255
- n(s <= e);
268
+ function ue(a, e) {
269
+ const [t, s] = _(!0), o = T(null);
270
+ return j(() => {
271
+ const c = a.current;
272
+ if (!c) return;
273
+ const r = () => {
274
+ const u = c.scrollHeight - c.scrollTop - c.clientHeight;
275
+ s(u <= e);
256
276
  }, m = () => {
257
- i.current !== null && cancelAnimationFrame(i.current), i.current = requestAnimationFrame(o);
277
+ o.current !== null && cancelAnimationFrame(o.current), o.current = requestAnimationFrame(r);
258
278
  };
259
- return r.addEventListener("scroll", m, { passive: !0 }), o(), () => {
260
- r.removeEventListener("scroll", m), i.current !== null && cancelAnimationFrame(i.current);
279
+ return c.addEventListener("scroll", m, { passive: !0 }), r(), () => {
280
+ c.removeEventListener("scroll", m), o.current !== null && cancelAnimationFrame(o.current);
261
281
  };
262
- }, [l, e]), t;
282
+ }, [a, e]), t;
263
283
  }
264
- function ie(l) {
265
- const { itemCount: e, firstKey: t, lastKey: n, isAtBottom: i, scrollToIndex: r, mode: o } = l, m = y(e), s = y(t), d = y(n);
266
- D(() => {
267
- if (!o) {
268
- m.current = e, s.current = t, d.current = n;
284
+ function fe(a) {
285
+ const { itemCount: e, firstKey: t, lastKey: s, isAtBottom: o, scrollToIndex: c, mode: r } = a, m = T(e), u = T(t), h = T(s);
286
+ $(() => {
287
+ if (!r) {
288
+ m.current = e, u.current = t, h.current = s;
269
289
  return;
270
290
  }
271
- const f = m.current, A = s.current, T = d.current;
272
- e > f && t === A && n !== T && i && e > 0 && r(e - 1, {
291
+ const d = m.current, y = u.current, S = h.current;
292
+ e > d && t === y && s !== S && o && e > 0 && c(e - 1, {
273
293
  align: "end",
274
- behavior: o === "smooth" ? "smooth" : "auto"
275
- }), m.current = e, s.current = t, d.current = n;
276
- }, [e, t, n, i, r, o]);
294
+ behavior: r === "smooth" ? "smooth" : "auto"
295
+ }), m.current = e, u.current = t, h.current = s;
296
+ }, [e, t, s, o, c, r]);
277
297
  }
278
- function ce(l) {
298
+ function he(a) {
279
299
  const {
280
300
  items: e,
281
301
  getKey: t,
282
- estimatedItemSize: n = 80,
283
- overscan: i = 20,
284
- atBottomThreshold: r = 200,
285
- followOutput: o = "auto",
302
+ estimatedItemSize: s = 80,
303
+ overscan: o = 20,
304
+ atBottomThreshold: c = 200,
305
+ followOutput: r = "auto",
286
306
  initialAlignment: m = "bottom",
287
- onStartReached: s,
288
- onEndReached: d,
289
- startReachedThreshold: f = 300,
290
- endReachedThreshold: A = 300,
291
- scrollToMessageKey: T,
292
- onScrollToMessageComplete: R
293
- } = l, u = G({
307
+ onStartReached: u,
308
+ onEndReached: h,
309
+ startReachedThreshold: d = 300,
310
+ endReachedThreshold: y = 300,
311
+ scrollToMessageKey: S,
312
+ onScrollToMessageComplete: x
313
+ } = a, f = W({
294
314
  items: e,
295
315
  getKey: t,
296
- estimatedItemSize: n,
297
- overscan: i,
316
+ estimatedItemSize: s,
317
+ overscan: o,
298
318
  initialAlignment: m
299
- }), H = oe(u.scrollerRef, r), { prepareAnchor: v } = se(u.scrollerRef, e.length), K = e.length > 0 ? t(e[0], 0) : null, S = e.length > 0 ? t(e[e.length - 1], e.length - 1) : null;
300
- ie({
319
+ }), F = ue(f.scrollerRef, c), [, z] = _(0), E = M(() => z((i) => i + 1), []), { prepareAnchor: p } = ae(f.scrollerRef, e.length, E), w = e.length > 0 ? t(e[0], 0) : null, b = e.length > 0 ? t(e[e.length - 1], e.length - 1) : null;
320
+ fe({
301
321
  itemCount: e.length,
302
- firstKey: K,
303
- lastKey: S,
304
- isAtBottom: H,
305
- scrollToIndex: u.scrollToIndex,
306
- mode: o ?? !1
322
+ firstKey: w,
323
+ lastKey: b,
324
+ isAtBottom: F,
325
+ scrollToIndex: f.scrollToIndex,
326
+ mode: r ?? !1
307
327
  });
308
- const F = y(!1), I = y(m === "top");
309
- N(() => {
310
- const p = u.scrollerRef.current;
311
- if (!p || !s) return;
312
- const c = () => {
313
- const g = p.scrollTop;
314
- !I.current && g > f && (I.current = !0), I.current && g <= f && !F.current && (F.current = !0, Promise.resolve(s()).finally(() => {
315
- F.current = !1;
328
+ const C = T(!1), V = T(m === "top");
329
+ j(() => {
330
+ const i = f.scrollerRef.current;
331
+ if (!i || !u) return;
332
+ const g = () => {
333
+ const A = i.scrollTop;
334
+ !V.current && A > d && (V.current = !0), V.current && A <= d && !C.current && (C.current = !0, Promise.resolve(u()).finally(() => {
335
+ C.current = !1;
316
336
  }));
317
337
  };
318
- return p.addEventListener("scroll", c, { passive: !0 }), () => p.removeEventListener("scroll", c);
319
- }, [u.scrollerRef, s, f, m]);
320
- const C = y(!1);
321
- N(() => {
322
- const p = u.scrollerRef.current;
323
- if (!p || !d) return;
324
- const c = () => {
325
- p.scrollHeight - p.scrollTop - p.clientHeight <= A && !C.current && (C.current = !0, Promise.resolve(d()).finally(() => {
326
- C.current = !1;
338
+ return i.addEventListener("scroll", g, { passive: !0 }), () => i.removeEventListener("scroll", g);
339
+ }, [f.scrollerRef, u, d, m]);
340
+ const N = T(!1);
341
+ j(() => {
342
+ const i = f.scrollerRef.current;
343
+ if (!i || !h) return;
344
+ const g = () => {
345
+ i.scrollHeight - i.scrollTop - i.clientHeight <= y && !N.current && (N.current = !0, Promise.resolve(h()).finally(() => {
346
+ N.current = !1;
327
347
  }));
328
348
  };
329
- return p.addEventListener("scroll", c, { passive: !0 }), () => p.removeEventListener("scroll", c);
330
- }, [u.scrollerRef, d, A]);
331
- const b = y(null);
332
- N(() => {
333
- if (!T || b.current === T) return;
334
- const p = e.findIndex((c, g) => t(c, g) === T);
335
- p !== -1 && (b.current = T, u.scrollToIndex(p, { align: "center", behavior: "smooth" }), R == null || R());
336
- }, [T, e, t, u, R]);
337
- const _ = L(
338
- (p = "auto") => {
339
- e.length !== 0 && u.scrollToIndex(e.length - 1, { align: "end", behavior: p });
349
+ return i.addEventListener("scroll", g, { passive: !0 }), () => i.removeEventListener("scroll", g);
350
+ }, [f.scrollerRef, h, y]);
351
+ const H = T(null);
352
+ j(() => {
353
+ if (!S || H.current === S) return;
354
+ const i = e.findIndex((g, A) => t(g, A) === S);
355
+ i !== -1 && (H.current = S, f.scrollToIndex(i, { align: "center", behavior: "smooth" }), x == null || x());
356
+ }, [S, e, t, f, x]);
357
+ const q = M(
358
+ (i = "auto") => {
359
+ e.length !== 0 && f.scrollToIndex(e.length - 1, { align: "end", behavior: i });
340
360
  },
341
- [e.length, u]
342
- ), w = L(
343
- (p, c) => {
344
- const g = e.findIndex((x, P) => t(x, P) === p);
345
- g !== -1 && u.scrollToIndex(g, c);
361
+ [e.length, f]
362
+ ), l = M(
363
+ (i, g) => {
364
+ const A = e.findIndex((L, k) => t(L, k) === i);
365
+ A !== -1 && f.scrollToIndex(A, g);
346
366
  },
347
- [e, t, u]
367
+ [e, t, f]
348
368
  );
349
369
  return {
350
- scrollerRef: u.scrollerRef,
351
- innerRef: u.innerRef,
352
- virtualItems: u.virtualItems,
353
- totalSize: u.totalSize,
354
- measureItem: u.measureItem,
355
- scrollToIndex: u.scrollToIndex,
356
- scrollToBottom: _,
357
- scrollToKey: w,
358
- isAtBottom: H,
359
- prepareAnchor: v
370
+ scrollerRef: f.scrollerRef,
371
+ innerRef: f.innerRef,
372
+ virtualItems: f.virtualItems,
373
+ totalSize: f.totalSize,
374
+ measureItem: f.measureItem,
375
+ scrollToIndex: f.scrollToIndex,
376
+ scrollToBottom: q,
377
+ scrollToKey: l,
378
+ isAtBottom: F,
379
+ prepareAnchor: p
360
380
  };
361
381
  }
362
- function J({
363
- virtualItem: l,
382
+ function Z({
383
+ virtualItem: a,
364
384
  measureItem: e,
365
385
  children: t
366
386
  }) {
367
- const n = y(null);
368
- return N(() => {
369
- const i = n.current;
370
- if (!i) return;
371
- const r = new ResizeObserver(([o]) => {
372
- o && e(l.key, o.contentRect.height);
387
+ const s = T(null), o = T(!1);
388
+ return j(() => {
389
+ const c = s.current;
390
+ if (!c) return;
391
+ o.current = !1;
392
+ const r = new ResizeObserver(([m]) => {
393
+ m && (o.current = !0, e(a.key, m.contentRect.height));
373
394
  });
374
- return r.observe(i), () => r.disconnect();
375
- }, [l.key, e]), /* @__PURE__ */ B(
395
+ return r.observe(c), () => r.disconnect();
396
+ }, [a.key, e]), /* @__PURE__ */ B(
376
397
  "div",
377
398
  {
378
- ref: n,
399
+ ref: s,
379
400
  style: {
380
401
  position: "absolute",
381
402
  top: 0,
382
403
  // transform instead of top: avoids reflow, uses GPU compositor layer
383
- transform: `translateY(${l.start}px)`,
404
+ transform: `translateY(${a.start}px)`,
384
405
  width: "100%",
385
- // Reserve estimated height to prevent layout collapse before first measure
386
- minHeight: l.size
406
+ // Only reserve estimated height before first measurement.
407
+ // After measurement, let the item take its natural height so
408
+ // ResizeObserver can accurately report the real size.
409
+ // Without this, items can never be smaller than estimatedItemSize,
410
+ // which distorts offsets and total height.
411
+ minHeight: o.current ? void 0 : a.size
387
412
  },
388
413
  children: t
389
414
  }
390
415
  );
391
416
  }
392
- function le(l, e) {
417
+ function de(a, e) {
393
418
  const {
394
419
  data: t,
395
- itemContent: n,
396
- computeItemKey: i,
397
- estimatedItemSize: r = 80,
398
- overscan: o = 20,
420
+ itemContent: s,
421
+ computeItemKey: o,
422
+ estimatedItemSize: c = 80,
423
+ overscan: r = 20,
399
424
  followOutput: m = "auto",
400
- atBottomThreshold: s = 200,
401
- initialAlignment: d = "bottom",
402
- onStartReached: f,
403
- onEndReached: A,
404
- startReachedThreshold: T = 300,
405
- endReachedThreshold: R = 300,
406
- scrollToMessageKey: u,
407
- onScrollToMessageComplete: H,
408
- onAtBottomChange: v,
409
- components: K = {},
410
- className: S,
411
- style: F
412
- } = l, {
413
- scrollerRef: I,
425
+ atBottomThreshold: u = 200,
426
+ initialAlignment: h = "bottom",
427
+ onStartReached: d,
428
+ onEndReached: y,
429
+ startReachedThreshold: S = 300,
430
+ endReachedThreshold: x = 300,
431
+ scrollToMessageKey: f,
432
+ onScrollToMessageComplete: F,
433
+ onAtBottomChange: z,
434
+ components: E = {},
435
+ className: p,
436
+ style: w
437
+ } = a, {
438
+ scrollerRef: b,
414
439
  innerRef: C,
415
- virtualItems: b,
416
- totalSize: _,
417
- measureItem: w,
418
- scrollToIndex: p,
419
- scrollToBottom: c,
420
- scrollToKey: g,
421
- isAtBottom: x,
422
- prepareAnchor: P
423
- } = ce({
440
+ virtualItems: V,
441
+ totalSize: N,
442
+ measureItem: H,
443
+ scrollToIndex: q,
444
+ scrollToBottom: l,
445
+ scrollToKey: i,
446
+ isAtBottom: g,
447
+ prepareAnchor: A
448
+ } = he({
424
449
  items: t,
425
- getKey: (z, k) => i(k, z),
426
- estimatedItemSize: r,
427
- overscan: o,
428
- atBottomThreshold: s,
450
+ getKey: (n, v) => o(v, n),
451
+ estimatedItemSize: c,
452
+ overscan: r,
453
+ atBottomThreshold: u,
429
454
  followOutput: m,
430
- initialAlignment: d,
431
- onStartReached: f,
432
- onEndReached: A,
433
- startReachedThreshold: T,
434
- endReachedThreshold: R,
435
- scrollToMessageKey: u,
436
- onScrollToMessageComplete: H
437
- }), j = U.useRef(x);
438
- U.useEffect(() => {
439
- j.current !== x && (j.current = x, v == null || v(x));
440
- }, [x, v]), W(
455
+ initialAlignment: h,
456
+ onStartReached: d,
457
+ onEndReached: y,
458
+ startReachedThreshold: S,
459
+ endReachedThreshold: x,
460
+ scrollToMessageKey: f,
461
+ onScrollToMessageComplete: F
462
+ }), L = X.useRef(g);
463
+ X.useEffect(() => {
464
+ L.current !== g && (L.current = g, z == null || z(g));
465
+ }, [g, z]), re(
441
466
  e,
442
467
  () => ({
443
- scrollToBottom: c,
444
- scrollToIndex: p,
445
- scrollToKey: g,
468
+ scrollToBottom: l,
469
+ scrollToIndex: q,
470
+ scrollToKey: i,
446
471
  getScrollTop: () => {
447
- var z;
448
- return ((z = I.current) == null ? void 0 : z.scrollTop) ?? 0;
472
+ var n;
473
+ return ((n = b.current) == null ? void 0 : n.scrollTop) ?? 0;
449
474
  },
450
- isAtBottom: () => x,
451
- prepareAnchor: P
475
+ isAtBottom: () => g,
476
+ prepareAnchor: A
452
477
  }),
453
- [c, p, g, I, x, P]
478
+ [l, q, i, b, g, A]
454
479
  );
455
- const { Header: q, Footer: a, EmptyPlaceholder: h } = K;
456
- return t.length === 0 && h ? /* @__PURE__ */ B(h, {}) : /* @__PURE__ */ $(
480
+ const { Header: k, Footer: D, EmptyPlaceholder: Y } = E;
481
+ return t.length === 0 && Y ? /* @__PURE__ */ B(Y, {}) : /* @__PURE__ */ Q(
457
482
  "div",
458
483
  {
459
- ref: I,
460
- className: S,
484
+ ref: b,
485
+ className: p,
461
486
  style: {
462
487
  overflow: "auto",
463
488
  height: "100%",
464
489
  position: "relative",
465
490
  overscrollBehaviorY: "contain",
466
- ...F
491
+ ...w
467
492
  },
468
493
  children: [
469
- q && /* @__PURE__ */ B(q, {}),
470
- /* @__PURE__ */ B("div", { ref: C, style: { height: _, position: "relative", width: "100%" }, children: b.map((z) => /* @__PURE__ */ B(
471
- J,
494
+ k && /* @__PURE__ */ B(k, {}),
495
+ /* @__PURE__ */ B("div", { ref: C, style: { height: N, position: "relative", width: "100%" }, children: V.map((n) => /* @__PURE__ */ B(
496
+ Z,
472
497
  {
473
- virtualItem: z,
474
- measureItem: w,
475
- children: n(z.index, z.data)
498
+ virtualItem: n,
499
+ measureItem: H,
500
+ children: s(n.index, n.data)
476
501
  },
477
- z.key
502
+ n.key
478
503
  )) }),
479
- a && /* @__PURE__ */ B(a, {})
504
+ D && /* @__PURE__ */ B(D, {})
480
505
  ]
481
506
  }
482
507
  );
483
508
  }
484
- const fe = Q(le);
485
- function he({
486
- data: l,
509
+ const pe = te(de);
510
+ function ve({
511
+ data: a,
487
512
  itemContent: e,
488
513
  computeItemKey: t,
489
- estimatedItemSize: n = 60,
490
- overscan: i = 20,
491
- onEndReached: r,
492
- endReachedThreshold: o = 300,
514
+ estimatedItemSize: s = 60,
515
+ overscan: o = 20,
516
+ onEndReached: c,
517
+ endReachedThreshold: r = 300,
493
518
  components: m = {},
494
- className: s,
495
- style: d
519
+ className: u,
520
+ style: h
496
521
  }) {
497
- const { scrollerRef: f, innerRef: A, virtualItems: T, totalSize: R, measureItem: u } = G({
498
- items: l,
499
- getKey: (S, F) => t(F, S),
500
- estimatedItemSize: n,
501
- overscan: i,
522
+ const { scrollerRef: d, innerRef: y, virtualItems: S, totalSize: x, measureItem: f } = W({
523
+ items: a,
524
+ getKey: (p, w) => t(w, p),
525
+ estimatedItemSize: s,
526
+ overscan: o,
502
527
  initialAlignment: "top"
503
528
  });
504
- U.useEffect(() => {
505
- const S = f.current;
506
- if (!S || !r) return;
507
- let F = !1;
508
- const I = () => {
509
- S.scrollHeight - S.scrollTop - S.clientHeight <= o && !F && (F = !0, Promise.resolve(r()).finally(() => {
510
- F = !1;
529
+ X.useEffect(() => {
530
+ const p = d.current;
531
+ if (!p || !c) return;
532
+ let w = !1;
533
+ const b = () => {
534
+ p.scrollHeight - p.scrollTop - p.clientHeight <= r && !w && (w = !0, Promise.resolve(c()).finally(() => {
535
+ w = !1;
511
536
  }));
512
537
  };
513
- return S.addEventListener("scroll", I, { passive: !0 }), () => S.removeEventListener("scroll", I);
514
- }, [f, r, o]);
515
- const { Header: H, Footer: v, EmptyPlaceholder: K } = m;
516
- return l.length === 0 && K ? /* @__PURE__ */ B(K, {}) : /* @__PURE__ */ $(
538
+ return p.addEventListener("scroll", b, { passive: !0 }), () => p.removeEventListener("scroll", b);
539
+ }, [d, c, r]);
540
+ const { Header: F, Footer: z, EmptyPlaceholder: E } = m;
541
+ return a.length === 0 && E ? /* @__PURE__ */ B(E, {}) : /* @__PURE__ */ Q(
517
542
  "div",
518
543
  {
519
- ref: f,
520
- className: s,
544
+ ref: d,
545
+ className: u,
521
546
  style: {
522
547
  overflow: "auto",
523
548
  height: "100%",
524
549
  position: "relative",
525
550
  overscrollBehaviorY: "contain",
526
- ...d
551
+ ...h
527
552
  },
528
553
  children: [
529
- H && /* @__PURE__ */ B(H, {}),
530
- /* @__PURE__ */ B("div", { ref: A, style: { height: R, position: "relative", width: "100%" }, children: T.map((S) => /* @__PURE__ */ B(
531
- J,
554
+ F && /* @__PURE__ */ B(F, {}),
555
+ /* @__PURE__ */ B("div", { ref: y, style: { height: x, position: "relative", width: "100%" }, children: S.map((p) => /* @__PURE__ */ B(
556
+ Z,
532
557
  {
533
- virtualItem: S,
534
- measureItem: u,
535
- children: e(S.index, S.data)
558
+ virtualItem: p,
559
+ measureItem: f,
560
+ children: e(p.index, p.data)
536
561
  },
537
- S.key
562
+ p.key
538
563
  )) }),
539
- v && /* @__PURE__ */ B(v, {})
564
+ z && /* @__PURE__ */ B(z, {})
540
565
  ]
541
566
  }
542
567
  );
543
568
  }
544
- function de(l) {
569
+ function ze(a) {
545
570
  const {
546
571
  fetcher: e,
547
572
  initialPage: t = 1,
548
- direction: n = "append",
549
- getKey: i,
550
- onPageLoaded: r,
551
- onError: o
552
- } = l, [m, s] = V([]), [d, f] = V(t), [A, T] = V(!0), [R, u] = V(!1), [H, v] = V(!1), [K, S] = V(!1), F = y(/* @__PURE__ */ new Set()), I = y(!1), C = L(
553
- (c) => i ? c.filter((g) => {
554
- const x = i(g);
555
- return F.current.has(x) ? !1 : (F.current.add(x), !0);
556
- }) : c,
557
- [i]
558
- ), b = L(async () => {
559
- if (!(I.current || !A)) {
560
- I.current = !0, S(!0);
573
+ direction: s = "append",
574
+ getKey: o,
575
+ onPageLoaded: c,
576
+ onError: r
577
+ } = a, [m, u] = _([]), [h, d] = _(t), [y, S] = _(!0), [x, f] = _(!1), [F, z] = _(!1), [E, p] = _(!1), w = T(/* @__PURE__ */ new Set()), b = T(!1), C = M(
578
+ (l) => o ? l.filter((i) => {
579
+ const g = o(i);
580
+ return w.current.has(g) ? !1 : (w.current.add(g), !0);
581
+ }) : l,
582
+ [o]
583
+ ), V = M(async () => {
584
+ if (!(b.current || !y)) {
585
+ b.current = !0, p(!0);
561
586
  try {
562
- const c = d + 1, g = await e(c), x = C(g.data);
563
- s(
564
- (P) => n === "prepend" ? [...x, ...P] : [...P, ...x]
565
- ), f(c), T(g.hasNextPage), u(g.hasPrevPage), r == null || r(c, x);
566
- } catch (c) {
567
- o == null || o(c instanceof Error ? c : new Error(String(c)));
587
+ const l = h + 1, i = await e(l), g = C(i.data);
588
+ u(
589
+ (A) => s === "prepend" ? [...g, ...A] : [...A, ...g]
590
+ ), d(l), S(i.hasNextPage), f(i.hasPrevPage), c == null || c(l, g);
591
+ } catch (l) {
592
+ r == null || r(l instanceof Error ? l : new Error(String(l)));
568
593
  } finally {
569
- S(!1), I.current = !1;
594
+ p(!1), b.current = !1;
570
595
  }
571
596
  }
572
- }, [d, A, e, C, n, r, o]), _ = L(async () => {
573
- if (!(I.current || !R)) {
574
- I.current = !0, S(!0);
597
+ }, [h, y, e, C, s, c, r]), N = M(async () => {
598
+ if (!(b.current || !x)) {
599
+ b.current = !0, p(!0);
575
600
  try {
576
- const c = d - 1, g = await e(c), x = C(g.data);
577
- s((P) => [...x, ...P]), f(c), u(g.hasPrevPage), T(g.hasNextPage), r == null || r(c, x);
578
- } catch (c) {
579
- o == null || o(c instanceof Error ? c : new Error(String(c)));
601
+ const l = h - 1, i = await e(l), g = C(i.data);
602
+ u((A) => [...g, ...A]), d(l), f(i.hasPrevPage), S(i.hasNextPage), c == null || c(l, g);
603
+ } catch (l) {
604
+ r == null || r(l instanceof Error ? l : new Error(String(l)));
580
605
  } finally {
581
- S(!1), I.current = !1;
606
+ p(!1), b.current = !1;
582
607
  }
583
608
  }
584
- }, [d, R, e, C, r, o]), w = L(async () => {
585
- if (!I.current) {
586
- I.current = !0, v(!0);
609
+ }, [h, x, e, C, c, r]), H = M(async () => {
610
+ if (!b.current) {
611
+ b.current = !0, z(!0);
587
612
  try {
588
- const c = await e(t), g = c.data;
589
- if (i) {
590
- const x = new Set(g.map(i));
591
- g.forEach((P) => F.current.add(i(P))), s((P) => {
592
- const j = P.filter((q) => !x.has(i(q)));
593
- return n === "prepend" ? [...g, ...j] : [...j, ...g];
613
+ const l = await e(t), i = l.data;
614
+ if (o) {
615
+ const g = new Set(i.map(o));
616
+ i.forEach((A) => w.current.add(o(A))), u((A) => {
617
+ const L = A.filter((k) => !g.has(o(k)));
618
+ return s === "prepend" ? [...i, ...L] : [...L, ...i];
594
619
  });
595
620
  } else
596
- s(g);
597
- f(t), T(c.hasNextPage), u(c.hasPrevPage), r == null || r(t, g);
598
- } catch (c) {
599
- o == null || o(c instanceof Error ? c : new Error(String(c)));
621
+ u(i);
622
+ d(t), S(l.hasNextPage), f(l.hasPrevPage), c == null || c(t, i);
623
+ } catch (l) {
624
+ r == null || r(l instanceof Error ? l : new Error(String(l)));
600
625
  } finally {
601
- v(!1), I.current = !1;
626
+ z(!1), b.current = !1;
602
627
  }
603
628
  }
604
- }, [e, t, i, n, r, o]), p = L(() => {
605
- s([]), f(t), T(!0), u(!1), v(!1), S(!1), F.current.clear(), I.current = !1;
629
+ }, [e, t, o, s, c, r]), q = M(() => {
630
+ u([]), d(t), S(!0), f(!1), z(!1), p(!1), w.current.clear(), b.current = !1;
606
631
  }, [t]);
607
632
  return {
608
633
  items: m,
609
- loadNextPage: b,
610
- loadPrevPage: _,
611
- hasNextPage: A,
612
- hasPrevPage: R,
613
- loading: H,
614
- loadingMore: K,
615
- refresh: w,
616
- reset: p,
617
- currentPage: d
634
+ loadNextPage: V,
635
+ loadPrevPage: N,
636
+ hasNextPage: y,
637
+ hasPrevPage: x,
638
+ loading: F,
639
+ loadingMore: E,
640
+ refresh: H,
641
+ reset: q,
642
+ currentPage: h
618
643
  };
619
644
  }
620
645
  export {
621
- fe as ChatVirtualList,
622
- he as VirtualList,
623
- ce as useChatVirtualizer,
624
- de as usePagination
646
+ pe as ChatVirtualList,
647
+ ve as VirtualList,
648
+ he as useChatVirtualizer,
649
+ ze as usePagination
625
650
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-anchorlist",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "High-performance chat virtualizer for React — no flicker, no hacks",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -13,7 +13,9 @@
13
13
  "types": "./dist/index.d.ts"
14
14
  }
15
15
  },
16
- "files": ["dist"],
16
+ "files": [
17
+ "dist"
18
+ ],
17
19
  "sideEffects": false,
18
20
  "scripts": {
19
21
  "dev": "vite build --watch",