react-anchorlist 0.2.3 → 0.2.4

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