react-anchorlist 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,206 @@
1
+ # react-anchorlist
2
+
3
+ **High-performance virtualized list for React — built for chat.**
4
+
5
+ Zero flicker on prepend. Smooth scroll. Native pagination support. Drop-in replacement for react-virtuoso.
6
+
7
+ ```bash
8
+ npm install react-anchorlist
9
+ ```
10
+
11
+ ---
12
+
13
+ ## Why not react-virtuoso?
14
+
15
+ | Problem | react-virtuoso | react-anchorlist |
16
+ |---|---|---|
17
+ | Flicker when loading older messages | ✗ Yes | ✓ Zero — scroll anchor via `useLayoutEffect` |
18
+ | Prepend hack | `firstItemIndex=10000` | Native prepend detection |
19
+ | `scrollToIndex` needs double-RAF | ✗ Yes | ✓ No — direct offset calculation |
20
+ | Overscan as flicker band-aid | 3000px+ needed | 5 items (no pixels) |
21
+ | Bundle size | 88 kB | ~17 kB |
22
+ | Pagination built-in | ✗ No | ✓ Yes — `usePagination` hook |
23
+
24
+ ---
25
+
26
+ ## Quick start
27
+
28
+ ### Simple list (tickets, contacts, feeds)
29
+
30
+ ```tsx
31
+ import { VirtualList } from 'react-anchorlist'
32
+
33
+ <VirtualList
34
+ data={tickets}
35
+ computeItemKey={(index, item) => item.id}
36
+ itemContent={(index, item) => <TicketRow ticket={item} />}
37
+ onEndReached={loadMore}
38
+ style={{ height: '100%' }}
39
+ />
40
+ ```
41
+
42
+ ### Chat list (messages with pagination)
43
+
44
+ ```tsx
45
+ import { ChatVirtualList } from 'react-anchorlist'
46
+ import type { ChatVirtualListHandle } from 'react-anchorlist'
47
+
48
+ const listRef = useRef<ChatVirtualListHandle>(null)
49
+
50
+ <ChatVirtualList
51
+ ref={listRef}
52
+ data={messages}
53
+ computeItemKey={(index, item) => item._id}
54
+ itemContent={(index, item) => <Message data={item} />}
55
+ // Pagination — fires when scroll reaches top
56
+ onStartReached={loadOlderMessages}
57
+ // Stick to bottom when new messages arrive
58
+ followOutput="auto"
59
+ // Notify parent of bottom state (for scroll button)
60
+ onAtBottomChange={setIsAtBottom}
61
+ components={{
62
+ Header: () => loading ? <Spinner /> : null,
63
+ Footer: () => <QueueMessages />,
64
+ }}
65
+ style={{ height: '100%' }}
66
+ />
67
+ ```
68
+
69
+ ---
70
+
71
+ ## ChatVirtualList props
72
+
73
+ | Prop | Type | Default | Description |
74
+ |---|---|---|---|
75
+ | `data` | `T[]` | required | Array of items |
76
+ | `itemContent` | `(index, item) => ReactNode` | required | Render function |
77
+ | `computeItemKey` | `(index, item) => string \| number` | required | Stable key per item |
78
+ | `estimatedItemSize` | `number` | `80` | Initial height estimate (px) |
79
+ | `overscan` | `number` | `5` | Items to render beyond visible area |
80
+ | `followOutput` | `"auto" \| "smooth" \| false` | `"auto"` | Stick to bottom on new items |
81
+ | `atBottomThreshold` | `number` | `200` | px from bottom to consider "at bottom" |
82
+ | `initialAlignment` | `"top" \| "bottom"` | `"bottom"` | Initial scroll position |
83
+ | `onStartReached` | `() => void \| Promise<void>` | — | Fires when scroll nears top |
84
+ | `onEndReached` | `() => void \| Promise<void>` | — | Fires when scroll nears bottom |
85
+ | `startReachedThreshold` | `number` | `300` | px from top to trigger `onStartReached` |
86
+ | `endReachedThreshold` | `number` | `300` | px from bottom to trigger `onEndReached` |
87
+ | `onAtBottomChange` | `(isAtBottom: boolean) => void` | — | Called when bottom state changes |
88
+ | `scrollToMessageKey` | `string \| number \| null` | — | Scroll to item by key |
89
+ | `onScrollToMessageComplete` | `() => void` | — | Fires after scroll-to-key completes |
90
+ | `components` | `{ Header, Footer, EmptyPlaceholder }` | — | Slot components |
91
+ | `className` | `string` | — | CSS class for the scroller |
92
+ | `style` | `CSSProperties` | — | Inline style for the scroller |
93
+
94
+ ---
95
+
96
+ ## VirtualList props
97
+
98
+ | Prop | Type | Default | Description |
99
+ |---|---|---|---|
100
+ | `data` | `T[]` | required | Array of items |
101
+ | `itemContent` | `(index, item) => ReactNode` | required | Render function |
102
+ | `computeItemKey` | `(index, item) => string \| number` | required | Stable key per item |
103
+ | `estimatedItemSize` | `number` | `80` | Initial height estimate (px) |
104
+ | `overscan` | `number` | `5` | Items to render beyond visible area |
105
+ | `onEndReached` | `() => void \| Promise<void>` | — | Fires when scroll nears bottom |
106
+ | `endReachedThreshold` | `number` | `300` | px from bottom to trigger callback |
107
+ | `components` | `{ Header, Footer, EmptyPlaceholder }` | — | Slot components |
108
+ | `className` | `string` | — | CSS class for the scroller |
109
+ | `style` | `CSSProperties` | — | Inline style for the scroller |
110
+
111
+ ---
112
+
113
+ ## Ref handle (ChatVirtualList)
114
+
115
+ ```tsx
116
+ const listRef = useRef<ChatVirtualListHandle>(null)
117
+
118
+ listRef.current?.scrollToBottom()
119
+ listRef.current?.scrollToIndex(42, { align: 'center', behavior: 'smooth' })
120
+ listRef.current?.scrollToKey('msg-123', { align: 'center' })
121
+ listRef.current?.getScrollTop() // → number
122
+ listRef.current?.isAtBottom() // → boolean
123
+ listRef.current?.prepareAnchor() // call before manually prepending items
124
+ ```
125
+
126
+ | Method | Description |
127
+ |---|---|
128
+ | `scrollToBottom(behavior?)` | Scroll to last item |
129
+ | `scrollToIndex(index, opts?)` | Scroll to item by index |
130
+ | `scrollToKey(key, opts?)` | Scroll to item by key |
131
+ | `getScrollTop()` | Current scroll position |
132
+ | `isAtBottom()` | Whether list is at bottom |
133
+ | `prepareAnchor()` | Save scroll position before external prepend |
134
+
135
+ ---
136
+
137
+ ## usePagination hook
138
+
139
+ For back-end driven pagination with automatic deduplication:
140
+
141
+ ```tsx
142
+ import { usePagination, ChatVirtualList } from 'react-anchorlist'
143
+
144
+ const { items, loadPrevPage, hasPrevPage, loadingMore } = usePagination({
145
+ fetcher: async (page) => {
146
+ const res = await api.get(`/messages?page=${page}&per_page=50`)
147
+ return {
148
+ data: res.messages,
149
+ hasNextPage: res.pagination.current_page < res.pagination.last_page,
150
+ hasPrevPage: res.pagination.current_page > 1,
151
+ currentPage: res.pagination.current_page,
152
+ }
153
+ },
154
+ direction: 'prepend', // new pages go to the top (chat pattern)
155
+ getKey: (msg) => msg._id, // deduplication key
156
+ })
157
+
158
+ <ChatVirtualList
159
+ data={items}
160
+ computeItemKey={(_, item) => item._id}
161
+ itemContent={(_, item) => <Message data={item} />}
162
+ onStartReached={hasPrevPage ? loadPrevPage : undefined}
163
+ components={{
164
+ Header: () => loadingMore ? <Spinner /> : null,
165
+ }}
166
+ />
167
+ ```
168
+
169
+ ---
170
+
171
+ ## Migrating from react-virtuoso
172
+
173
+ | react-virtuoso | react-anchorlist |
174
+ |---|---|
175
+ | `<Virtuoso data={} itemContent={} />` | `<ChatVirtualList data={} itemContent={} />` |
176
+ | `computeItemKey={(_index, item) => item.id}` | `computeItemKey={(_index, item) => item.id}` ✓ same |
177
+ | `firstItemIndex={10000}` | Not needed — automatic |
178
+ | `initialTopMostItemIndex={n}` | Not needed — `initialAlignment="bottom"` |
179
+ | `alignToBottom` | `initialAlignment="bottom"` (default) |
180
+ | `followOutput={isAtBottom ? 'auto' : false}` | `followOutput="auto"` (default) |
181
+ | `atBottomStateChange={setIsAtBottom}` | `onAtBottomChange={setIsAtBottom}` |
182
+ | `atBottomThreshold={200}` | `atBottomThreshold={200}` ✓ same |
183
+ | `startReached={fn}` | `onStartReached={fn}` |
184
+ | `endReached={fn}` | `onEndReached={fn}` |
185
+ | `overscan={{ main: 3000, reverse: 3000 }}` | `overscan={5}` (items, not pixels) |
186
+ | `increaseViewportBy={{ top: 2200, bottom: 1100 }}` | Not needed |
187
+ | `components={{ Header, Footer }}` | `components={{ Header, Footer }}` ✓ same |
188
+ | `ref.scrollToIndex({ index, align, behavior })` | `ref.scrollToIndex(index, { align, behavior })` |
189
+
190
+ ---
191
+
192
+ ## How it works
193
+
194
+ **OffsetMap** — maintains cumulative Y offsets for all items. When an item is measured, only downstream offsets are recalculated (O(n−i), not O(n)).
195
+
196
+ **Scroll Anchor** — before prepending items, saves `scrollTop` and `scrollHeight`. After the DOM updates, `useLayoutEffect` adjusts `scrollTop` by the delta — synchronously, before the browser paints. Zero flicker.
197
+
198
+ **ResizeObserver per item** — each rendered item has its own observer. Real heights are measured as soon as the item enters the DOM and reported back to the engine. No estimation loops, no layout thrashing.
199
+
200
+ **Binary search** — given `scrollTop`, finds the first visible item in O(log n) using the offset array.
201
+
202
+ ---
203
+
204
+ ## License
205
+
206
+ MIT
@@ -1 +1 @@
1
- {"version":3,"file":"ChatVirtualList.d.ts","sourceRoot":"","sources":["../../src/components/ChatVirtualList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAe,MAAM,UAAU,CAAA;AA6FxF,eAAO,MAAM,eAAe,EAAuC,CAAC,CAAC,EACnE,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAA;CAAE,KACxE,KAAK,CAAC,YAAY,CAAA"}
1
+ {"version":3,"file":"ChatVirtualList.d.ts","sourceRoot":"","sources":["../../src/components/ChatVirtualList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAe,MAAM,UAAU,CAAA;AAuGxF,eAAO,MAAM,eAAe,EAAuC,CAAC,CAAC,EACnE,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAA;CAAE,KACxE,KAAK,CAAC,YAAY,CAAA"}
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const A=require("react/jsx-runtime"),l=require("react");function _(s){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const t in s)if(t!=="default"){const r=Object.getOwnPropertyDescriptor(s,t);Object.defineProperty(e,t,r.get?r:{enumerable:!0,get:()=>s[t]})}}return e.default=s,Object.freeze(e)}const D=_(l);class q{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 r=0;r<e;r++)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[r,i]of this.cache){const a=t.get(r);a!==void 0&&e.setSize(a,i)}}}function U(s,e){if(s.length===0)return 0;let t=0,r=s.length-1;for(;t<r;){const i=t+r>>1;(s[i]??0)<e?t=i+1:r=i}return Math.max(0,t>0&&(s[t]??0)>e?t-1:t)}function Z(s,e,t){if(s.length===0)return 0;for(let r=s.length-1;r>=0;r--)if((s[r]??0)<t)return r;return 0}function Y(s){const{firstVisible:e,lastVisible:t,itemCount:r,overscan:i}=s;return r===0?{start:0,end:-1}:{start:Math.max(0,e-i),end:Math.min(r-1,t+i)}}function $(s,e){return l.useCallback((t,r)=>{const i=s.current,a=e.current;if(!i||!a)return;const c=a.getOffset(t),d=a.getSize(t),S=(r==null?void 0:r.align)??"start",y=(r==null?void 0:r.behavior)??"auto",v=(r==null?void 0:r.offset)??0;let T;S==="start"?T=c+v:S==="center"?T=c-i.clientHeight/2+d/2+v:T=c-i.clientHeight+d+v,i.scrollTo({top:Math.max(0,T),behavior:y})},[s,e])}function J(s,e){switch(e.type){case"SCROLL":return{...s,scrollTop:e.scrollTop,totalSize:e.totalSize,renderRange:e.renderRange};case"RESIZE_CONTAINER":return{...s,containerHeight:e.height,totalSize:e.totalSize,renderRange:e.renderRange};case"MEASURE":return{...s,totalSize:e.totalSize};case"ITEMS_CHANGED":return{...s,renderRange:e.renderRange,totalSize:e.totalSize}}}function F(s){const{items:e,getKey:t,estimatedItemSize:r,overscan:i,initialAlignment:a}=s,c=l.useRef(null),d=l.useRef(null),S=l.useRef(new G),y=l.useRef([]),v=l.useRef(!1),T=l.useRef(i);T.current=i,d.current||(d.current=new q(e.length,r));const z=l.useCallback((o,m)=>{const n=d.current;if(!n||n.count===0)return{start:0,end:-1};const u=n.getOffsets(),h=n.getSizes(),x=U(u,o),P=Z(u,h,o+m);return Y({firstVisible:x,lastVisible:P,itemCount:n.count,overscan:T.current})},[]),[b,f]=l.useReducer(J,{renderRange:{start:0,end:Math.min(e.length-1,i*2)},scrollTop:0,containerHeight:0,totalSize:d.current.totalSize()});l.useEffect(()=>{const o=d.current,m=e.map((k,L)=>t(k,L)),n=y.current,u=n.length,h=m.length;h===0?o.resize(0):u===0?o.resize(h):h>u?n.length>0&&m[h-u]===n[0]?o.prepend(h-u):o.resize(h):h<u&&o.resize(h);const x=new Map;m.forEach((k,L)=>x.set(k,L)),S.current.applyToOffsetMap(o,x),y.current=m;const P=c.current,H=(P==null?void 0:P.scrollTop)??0,M=(P==null?void 0:P.clientHeight)??0,B=z(H,M);f({type:"ITEMS_CHANGED",renderRange:B,totalSize:o.totalSize()})},[e,t,z]),l.useEffect(()=>{const o=c.current;if(!o)return;const m=()=>{const n=d.current,u=o.scrollTop,h=o.clientHeight,x=z(u,h);f({type:"SCROLL",scrollTop:u,totalSize:n.totalSize(),renderRange:x})};return o.addEventListener("scroll",m,{passive:!0}),()=>o.removeEventListener("scroll",m)},[z]),l.useEffect(()=>{const o=c.current;if(!o)return;const m=new ResizeObserver(([n])=>{if(!n)return;const u=n.contentRect.height,h=d.current,x=o.scrollTop,P=z(x,u);f({type:"RESIZE_CONTAINER",height:u,totalSize:h.totalSize(),renderRange:P})});return m.observe(o),()=>m.disconnect()},[z]),l.useEffect(()=>{if(v.current||e.length===0)return;const o=c.current;o&&(a==="bottom"&&(o.scrollTop=o.scrollHeight),v.current=!0)},[a,e.length]);const w=l.useCallback((o,m)=>{const n=d.current;if(!n)return;S.current.set(o,m);const u=y.current.indexOf(o);if(u===-1)return;n.setSize(u,m)&&f({type:"MEASURE",totalSize:n.totalSize()})},[]),O=l.useCallback((o,m="auto")=>{var n;(n=c.current)==null||n.scrollTo({top:o,behavior:m})},[]),p=$(c,d),R=d.current,{start:I,end:E}=b.renderRange,j=[];if(R&&E>=I)for(let o=I;o<=E&&o<e.length;o++)j.push({key:y.current[o]??t(e[o],o),index:o,start:R.getOffset(o),size:R.getSize(o),data:e[o]});const g=c.current,C=g?g.scrollHeight-g.scrollTop-g.clientHeight:1/0;return{scrollerRef:c,virtualItems:j,totalSize:b.totalSize,measureItem:w,scrollToIndex:p,scrollToOffset:O,isAtTop:b.scrollTop<=0,isAtBottom:C<=0,scrollTop:b.scrollTop}}function Q(s,e){const t=l.useRef(0),r=l.useRef(0),i=l.useRef(!1),a=l.useCallback(()=>{const c=s.current;c&&(t.current=c.scrollTop,r.current=c.scrollHeight,i.current=!0)},[s]);return l.useLayoutEffect(()=>{if(!i.current)return;const c=s.current;if(!c)return;const d=c.scrollHeight-r.current;d>0&&(c.scrollTop=t.current+d),i.current=!1},[e,s]),{prepareAnchor:a}}function W(s,e){const[t,r]=l.useState(!0),i=l.useRef(null);return l.useEffect(()=>{const a=s.current;if(!a)return;const c=()=>{const S=a.scrollHeight-a.scrollTop-a.clientHeight;r(S<=e)},d=()=>{i.current!==null&&cancelAnimationFrame(i.current),i.current=requestAnimationFrame(c)};return a.addEventListener("scroll",d,{passive:!0}),c(),()=>{a.removeEventListener("scroll",d),i.current!==null&&cancelAnimationFrame(i.current)}},[s,e]),t}function X(s){const{itemCount:e,isAtBottom:t,scrollToIndex:r,mode:i}=s,a=l.useRef(e);l.useLayoutEffect(()=>{i&&(e>a.current&&t&&e>0&&r(e-1,{align:"end",behavior:i==="smooth"?"smooth":"auto"}),a.current=e)},[e,t,r,i])}function K(s){const{items:e,getKey:t,estimatedItemSize:r=80,overscan:i=5,atBottomThreshold:a=200,followOutput:c="auto",initialAlignment:d="bottom",onStartReached:S,onEndReached:y,startReachedThreshold:v=300,endReachedThreshold:T=300,scrollToMessageKey:z,onScrollToMessageComplete:b}=s,f=F({items:e,getKey:t,estimatedItemSize:r,overscan:i,initialAlignment:d}),w=W(f.scrollerRef,a),{prepareAnchor:O}=Q(f.scrollerRef,e.length);X({itemCount:e.length,isAtBottom:w,scrollToIndex:f.scrollToIndex,mode:c??!1});const p=l.useRef(!1);l.useEffect(()=>{const g=f.scrollerRef.current;if(!g||!S)return;const C=()=>{g.scrollTop<=v&&!p.current&&(p.current=!0,Promise.resolve(S()).finally(()=>{p.current=!1}))};return g.addEventListener("scroll",C,{passive:!0}),()=>g.removeEventListener("scroll",C)},[f.scrollerRef,S,v]);const R=l.useRef(!1);l.useEffect(()=>{const g=f.scrollerRef.current;if(!g||!y)return;const C=()=>{g.scrollHeight-g.scrollTop-g.clientHeight<=T&&!R.current&&(R.current=!0,Promise.resolve(y()).finally(()=>{R.current=!1}))};return g.addEventListener("scroll",C,{passive:!0}),()=>g.removeEventListener("scroll",C)},[f.scrollerRef,y,T]);const I=l.useRef(null);l.useEffect(()=>{if(!z||I.current===z)return;const g=e.findIndex((C,o)=>t(C,o)===z);g!==-1&&(I.current=z,f.scrollToIndex(g,{align:"center",behavior:"smooth"}),b==null||b())},[z,e,t,f,b]);const E=l.useCallback((g="auto")=>{e.length!==0&&f.scrollToIndex(e.length-1,{align:"end",behavior:g})},[e.length,f]),j=l.useCallback((g,C)=>{const o=e.findIndex((m,n)=>t(m,n)===g);o!==-1&&f.scrollToIndex(o,C)},[e,t,f]);return{scrollerRef:f.scrollerRef,virtualItems:f.virtualItems,totalSize:f.totalSize,measureItem:f.measureItem,scrollToIndex:f.scrollToIndex,scrollToBottom:E,scrollToKey:j,isAtBottom:w,prepareAnchor:O}}function N({scrollerRef:s,totalSize:e,children:t,className:r,style:i}){return A.jsx("div",{ref:s,className:r,style:{overflow:"auto",height:"100%",position:"relative",...i},children:A.jsx("div",{style:{height:e,position:"relative",width:"100%"},children:t})})}function V({virtualItem:s,measureItem:e,children:t}){const r=l.useRef(null);return l.useEffect(()=>{const i=r.current;if(!i)return;const a=new ResizeObserver(([c])=>{c&&e(s.key,c.contentRect.height)});return a.observe(i),()=>a.disconnect()},[s.key,e]),A.jsx("div",{ref:r,style:{position:"absolute",top:0,transform:`translateY(${s.start}px)`,width:"100%",minHeight:s.size},children:t})}function ee(s,e){const{data:t,itemContent:r,computeItemKey:i,estimatedItemSize:a=80,overscan:c=5,followOutput:d="auto",atBottomThreshold:S=200,initialAlignment:y="bottom",onStartReached:v,onEndReached:T,startReachedThreshold:z=300,endReachedThreshold:b=300,scrollToMessageKey:f,onScrollToMessageComplete:w,components:O={},className:p,style:R}=s,{scrollerRef:I,virtualItems:E,totalSize:j,measureItem:g,scrollToIndex:C,scrollToBottom:o,scrollToKey:m,isAtBottom:n,prepareAnchor:u}=K({items:t,getKey:(H,M)=>i(M,H),estimatedItemSize:a,overscan:c,atBottomThreshold:S,followOutput:d,initialAlignment:y,onStartReached:v,onEndReached:T,startReachedThreshold:z,endReachedThreshold:b,scrollToMessageKey:f,onScrollToMessageComplete:w});l.useImperativeHandle(e,()=>({scrollToBottom:o,scrollToIndex:C,scrollToKey:m,getScrollTop:()=>{var H;return((H=I.current)==null?void 0:H.scrollTop)??0},isAtBottom:()=>n,prepareAnchor:u}),[o,C,m,I,n,u]);const{Header:h,Footer:x,EmptyPlaceholder:P}=O;return t.length===0&&P?A.jsx(P,{}):A.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%"},children:[h&&A.jsx(h,{}),A.jsx(N,{scrollerRef:I,totalSize:j,className:p,style:{flex:1,minHeight:0,...R},children:E.map(H=>A.jsx(V,{virtualItem:H,measureItem:g,children:r(H.index,H.data)},H.key))}),x&&A.jsx(x,{})]})}const te=l.forwardRef(ee);function re({data:s,itemContent:e,computeItemKey:t,estimatedItemSize:r=80,overscan:i=5,onEndReached:a,endReachedThreshold:c=300,components:d={},className:S,style:y}){const{scrollerRef:v,virtualItems:T,totalSize:z,measureItem:b}=F({items:s,getKey:(p,R)=>t(R,p),estimatedItemSize:r,overscan:i,initialAlignment:"top"});D.useEffect(()=>{const p=v.current;if(!p||!a)return;let R=!1;const I=()=>{p.scrollHeight-p.scrollTop-p.clientHeight<=c&&!R&&(R=!0,Promise.resolve(a()).finally(()=>{R=!1}))};return p.addEventListener("scroll",I,{passive:!0}),()=>p.removeEventListener("scroll",I)},[v,a,c]);const{Header:f,Footer:w,EmptyPlaceholder:O}=d;return s.length===0&&O?A.jsx(O,{}):A.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%"},children:[f&&A.jsx(f,{}),A.jsx(N,{scrollerRef:v,totalSize:z,className:S,style:{flex:1,minHeight:0,...y},children:T.map(p=>A.jsx(V,{virtualItem:p,measureItem:b,children:e(p.index,p.data)},p.key))}),w&&A.jsx(w,{})]})}function se(s){const{fetcher:e,initialPage:t=1,direction:r="append",getKey:i,onPageLoaded:a,onError:c}=s,[d,S]=l.useState([]),[y,v]=l.useState(t),[T,z]=l.useState(!0),[b,f]=l.useState(!1),[w,O]=l.useState(!1),[p,R]=l.useState(!1),I=l.useRef(new Set),E=l.useRef(!1),j=l.useCallback(n=>i?n.filter(u=>{const h=i(u);return I.current.has(h)?!1:(I.current.add(h),!0)}):n,[i]),g=l.useCallback(async()=>{if(!(E.current||!T)){E.current=!0,R(!0);try{const n=y+1,u=await e(n),h=j(u.data);S(x=>r==="prepend"?[...h,...x]:[...x,...h]),v(n),z(u.hasNextPage),f(u.hasPrevPage),a==null||a(n,h)}catch(n){c==null||c(n instanceof Error?n:new Error(String(n)))}finally{R(!1),E.current=!1}}},[y,T,e,j,r,a,c]),C=l.useCallback(async()=>{if(!(E.current||!b)){E.current=!0,R(!0);try{const n=y-1,u=await e(n),h=j(u.data);S(x=>[...h,...x]),v(n),f(u.hasPrevPage),z(u.hasNextPage),a==null||a(n,h)}catch(n){c==null||c(n instanceof Error?n:new Error(String(n)))}finally{R(!1),E.current=!1}}},[y,b,e,j,a,c]),o=l.useCallback(async()=>{if(!E.current){E.current=!0,O(!0);try{const n=await e(t),u=n.data;if(i){const h=new Set(u.map(i));u.forEach(x=>I.current.add(i(x))),S(x=>{const P=x.filter(H=>!h.has(i(H)));return r==="prepend"?[...u,...P]:[...P,...u]})}else S(u);v(t),z(n.hasNextPage),f(n.hasPrevPage),a==null||a(t,u)}catch(n){c==null||c(n instanceof Error?n:new Error(String(n)))}finally{O(!1),E.current=!1}}},[e,t,i,r,a,c]),m=l.useCallback(()=>{S([]),v(t),z(!0),f(!1),O(!1),R(!1),I.current.clear(),E.current=!1},[t]);return{items:d,loadNextPage:g,loadPrevPage:C,hasNextPage:T,hasPrevPage:b,loading:w,loadingMore:p,refresh:o,reset:m,currentPage:y}}exports.ChatVirtualList=te;exports.VirtualList=re;exports.useChatVirtualizer=K;exports.usePagination=se;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const H=require("react/jsx-runtime"),c=require("react");function D(s){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const t in s)if(t!=="default"){const r=Object.getOwnPropertyDescriptor(s,t);Object.defineProperty(e,t,r.get?r:{enumerable:!0,get:()=>s[t]})}}return e.default=s,Object.freeze(e)}const K=D(c);class q{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 r=0;r<e;r++)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[r,i]of this.cache){const a=t.get(r);a!==void 0&&e.setSize(a,i)}}}function U(s,e){if(s.length===0)return 0;let t=0,r=s.length-1;for(;t<r;){const i=t+r>>1;(s[i]??0)<e?t=i+1:r=i}return Math.max(0,t>0&&(s[t]??0)>e?t-1:t)}function Z(s,e,t){if(s.length===0)return 0;for(let r=s.length-1;r>=0;r--)if((s[r]??0)<t)return r;return 0}function Y(s){const{firstVisible:e,lastVisible:t,itemCount:r,overscan:i}=s;return r===0?{start:0,end:-1}:{start:Math.max(0,e-i),end:Math.min(r-1,t+i)}}function $(s,e){return c.useCallback((t,r)=>{const i=s.current,a=e.current;if(!i||!a)return;const l=a.getOffset(t),d=a.getSize(t),S=(r==null?void 0:r.align)??"start",y=(r==null?void 0:r.behavior)??"auto",v=(r==null?void 0:r.offset)??0;let E;S==="start"?E=l+v:S==="center"?E=l-i.clientHeight/2+d/2+v:E=l-i.clientHeight+d+v,i.scrollTo({top:Math.max(0,E),behavior:y})},[s,e])}function J(s,e){switch(e.type){case"SCROLL":return{...s,scrollTop:e.scrollTop,totalSize:e.totalSize,renderRange:e.renderRange};case"RESIZE_CONTAINER":return{...s,containerHeight:e.height,totalSize:e.totalSize,renderRange:e.renderRange};case"MEASURE":return{...s,totalSize:e.totalSize};case"ITEMS_CHANGED":return{...s,renderRange:e.renderRange,totalSize:e.totalSize}}}function N(s){const{items:e,getKey:t,estimatedItemSize:r,overscan:i,initialAlignment:a}=s,l=c.useRef(null),d=c.useRef(null),S=c.useRef(new G),y=c.useRef([]),v=c.useRef(!1),E=c.useRef(i);E.current=i,d.current||(d.current=new q(e.length,r));const z=c.useCallback((o,m)=>{const n=d.current;if(!n||n.count===0)return{start:0,end:-1};const u=n.getOffsets(),h=n.getSizes(),T=U(u,o),I=Z(u,h,o+m);return Y({firstVisible:T,lastVisible:I,itemCount:n.count,overscan:E.current})},[]),[b,f]=c.useReducer(J,{renderRange:{start:0,end:Math.min(e.length-1,i*2)},scrollTop:0,containerHeight:0,totalSize:d.current.totalSize()});c.useEffect(()=>{const o=d.current,m=e.map((M,F)=>t(M,F)),n=y.current,u=n.length,h=m.length;h===0?o.resize(0):u===0?o.resize(h):h>u?n.length>0&&m[h-u]===n[0]?o.prepend(h-u):o.resize(h):h<u&&o.resize(h);const T=new Map;m.forEach((M,F)=>T.set(M,F)),S.current.applyToOffsetMap(o,T),y.current=m;const I=l.current,k=(I==null?void 0:I.scrollTop)??0,L=(I==null?void 0:I.clientHeight)??0,j=z(k,L);f({type:"ITEMS_CHANGED",renderRange:j,totalSize:o.totalSize()})},[e,t,z]),c.useEffect(()=>{const o=l.current;if(!o)return;const m=()=>{const n=d.current,u=o.scrollTop,h=o.clientHeight,T=z(u,h);f({type:"SCROLL",scrollTop:u,totalSize:n.totalSize(),renderRange:T})};return o.addEventListener("scroll",m,{passive:!0}),()=>o.removeEventListener("scroll",m)},[z]),c.useEffect(()=>{const o=l.current;if(!o)return;const m=new ResizeObserver(([n])=>{if(!n)return;const u=n.contentRect.height,h=d.current,T=o.scrollTop,I=z(T,u);f({type:"RESIZE_CONTAINER",height:u,totalSize:h.totalSize(),renderRange:I})});return m.observe(o),()=>m.disconnect()},[z]),c.useEffect(()=>{if(v.current||e.length===0)return;const o=l.current;o&&(a==="bottom"&&(o.scrollTop=o.scrollHeight),v.current=!0)},[a,e.length]);const O=c.useCallback((o,m)=>{const n=d.current;if(!n)return;S.current.set(o,m);const u=y.current.indexOf(o);if(u===-1)return;n.setSize(u,m)&&f({type:"MEASURE",totalSize:n.totalSize()})},[]),P=c.useCallback((o,m="auto")=>{var n;(n=l.current)==null||n.scrollTo({top:o,behavior:m})},[]),p=$(l,d),R=d.current,{start:A,end:x}=b.renderRange,w=[];if(R&&x>=A)for(let o=A;o<=x&&o<e.length;o++)w.push({key:y.current[o]??t(e[o],o),index:o,start:R.getOffset(o),size:R.getSize(o),data:e[o]});const g=l.current,C=g?g.scrollHeight-g.scrollTop-g.clientHeight:1/0;return{scrollerRef:l,virtualItems:w,totalSize:b.totalSize,measureItem:O,scrollToIndex:p,scrollToOffset:P,isAtTop:b.scrollTop<=0,isAtBottom:C<=0,scrollTop:b.scrollTop}}function Q(s,e){const t=c.useRef(0),r=c.useRef(0),i=c.useRef(!1),a=c.useCallback(()=>{const l=s.current;l&&(t.current=l.scrollTop,r.current=l.scrollHeight,i.current=!0)},[s]);return c.useLayoutEffect(()=>{if(!i.current)return;const l=s.current;if(!l)return;const d=l.scrollHeight-r.current;d>0&&(l.scrollTop=t.current+d),i.current=!1},[e,s]),{prepareAnchor:a}}function W(s,e){const[t,r]=c.useState(!0),i=c.useRef(null);return c.useEffect(()=>{const a=s.current;if(!a)return;const l=()=>{const S=a.scrollHeight-a.scrollTop-a.clientHeight;r(S<=e)},d=()=>{i.current!==null&&cancelAnimationFrame(i.current),i.current=requestAnimationFrame(l)};return a.addEventListener("scroll",d,{passive:!0}),l(),()=>{a.removeEventListener("scroll",d),i.current!==null&&cancelAnimationFrame(i.current)}},[s,e]),t}function X(s){const{itemCount:e,isAtBottom:t,scrollToIndex:r,mode:i}=s,a=c.useRef(e);c.useLayoutEffect(()=>{i&&(e>a.current&&t&&e>0&&r(e-1,{align:"end",behavior:i==="smooth"?"smooth":"auto"}),a.current=e)},[e,t,r,i])}function V(s){const{items:e,getKey:t,estimatedItemSize:r=80,overscan:i=5,atBottomThreshold:a=200,followOutput:l="auto",initialAlignment:d="bottom",onStartReached:S,onEndReached:y,startReachedThreshold:v=300,endReachedThreshold:E=300,scrollToMessageKey:z,onScrollToMessageComplete:b}=s,f=N({items:e,getKey:t,estimatedItemSize:r,overscan:i,initialAlignment:d}),O=W(f.scrollerRef,a),{prepareAnchor:P}=Q(f.scrollerRef,e.length);X({itemCount:e.length,isAtBottom:O,scrollToIndex:f.scrollToIndex,mode:l??!1});const p=c.useRef(!1);c.useEffect(()=>{const g=f.scrollerRef.current;if(!g||!S)return;const C=()=>{g.scrollTop<=v&&!p.current&&(p.current=!0,Promise.resolve(S()).finally(()=>{p.current=!1}))};return g.addEventListener("scroll",C,{passive:!0}),()=>g.removeEventListener("scroll",C)},[f.scrollerRef,S,v]);const R=c.useRef(!1);c.useEffect(()=>{const g=f.scrollerRef.current;if(!g||!y)return;const C=()=>{g.scrollHeight-g.scrollTop-g.clientHeight<=E&&!R.current&&(R.current=!0,Promise.resolve(y()).finally(()=>{R.current=!1}))};return g.addEventListener("scroll",C,{passive:!0}),()=>g.removeEventListener("scroll",C)},[f.scrollerRef,y,E]);const A=c.useRef(null);c.useEffect(()=>{if(!z||A.current===z)return;const g=e.findIndex((C,o)=>t(C,o)===z);g!==-1&&(A.current=z,f.scrollToIndex(g,{align:"center",behavior:"smooth"}),b==null||b())},[z,e,t,f,b]);const x=c.useCallback((g="auto")=>{e.length!==0&&f.scrollToIndex(e.length-1,{align:"end",behavior:g})},[e.length,f]),w=c.useCallback((g,C)=>{const o=e.findIndex((m,n)=>t(m,n)===g);o!==-1&&f.scrollToIndex(o,C)},[e,t,f]);return{scrollerRef:f.scrollerRef,virtualItems:f.virtualItems,totalSize:f.totalSize,measureItem:f.measureItem,scrollToIndex:f.scrollToIndex,scrollToBottom:x,scrollToKey:w,isAtBottom:O,prepareAnchor:P}}function B({scrollerRef:s,totalSize:e,children:t,className:r,style:i}){return H.jsx("div",{ref:s,className:r,style:{overflow:"auto",height:"100%",position:"relative",...i},children:H.jsx("div",{style:{height:e,position:"relative",width:"100%"},children:t})})}function _({virtualItem:s,measureItem:e,children:t}){const r=c.useRef(null);return c.useEffect(()=>{const i=r.current;if(!i)return;const a=new ResizeObserver(([l])=>{l&&e(s.key,l.contentRect.height)});return a.observe(i),()=>a.disconnect()},[s.key,e]),H.jsx("div",{ref:r,style:{position:"absolute",top:0,transform:`translateY(${s.start}px)`,width:"100%",minHeight:s.size},children:t})}function ee(s,e){const{data:t,itemContent:r,computeItemKey:i,estimatedItemSize:a=80,overscan:l=5,followOutput:d="auto",atBottomThreshold:S=200,initialAlignment:y="bottom",onStartReached:v,onEndReached:E,startReachedThreshold:z=300,endReachedThreshold:b=300,scrollToMessageKey:f,onScrollToMessageComplete:O,onAtBottomChange:P,components:p={},className:R,style:A}=s,{scrollerRef:x,virtualItems:w,totalSize:g,measureItem:C,scrollToIndex:o,scrollToBottom:m,scrollToKey:n,isAtBottom:u,prepareAnchor:h}=V({items:t,getKey:(j,M)=>i(M,j),estimatedItemSize:a,overscan:l,atBottomThreshold:S,followOutput:d,initialAlignment:y,onStartReached:v,onEndReached:E,startReachedThreshold:z,endReachedThreshold:b,scrollToMessageKey:f,onScrollToMessageComplete:O}),T=K.useRef(u);K.useEffect(()=>{T.current!==u&&(T.current=u,P==null||P(u))},[u,P]),c.useImperativeHandle(e,()=>({scrollToBottom:m,scrollToIndex:o,scrollToKey:n,getScrollTop:()=>{var j;return((j=x.current)==null?void 0:j.scrollTop)??0},isAtBottom:()=>u,prepareAnchor:h}),[m,o,n,x,u,h]);const{Header:I,Footer:k,EmptyPlaceholder:L}=p;return t.length===0&&L?H.jsx(L,{}):H.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%"},children:[I&&H.jsx(I,{}),H.jsx(B,{scrollerRef:x,totalSize:g,className:R,style:{flex:1,minHeight:0,...A},children:w.map(j=>H.jsx(_,{virtualItem:j,measureItem:C,children:r(j.index,j.data)},j.key))}),k&&H.jsx(k,{})]})}const te=c.forwardRef(ee);function re({data:s,itemContent:e,computeItemKey:t,estimatedItemSize:r=80,overscan:i=5,onEndReached:a,endReachedThreshold:l=300,components:d={},className:S,style:y}){const{scrollerRef:v,virtualItems:E,totalSize:z,measureItem:b}=N({items:s,getKey:(p,R)=>t(R,p),estimatedItemSize:r,overscan:i,initialAlignment:"top"});K.useEffect(()=>{const p=v.current;if(!p||!a)return;let R=!1;const A=()=>{p.scrollHeight-p.scrollTop-p.clientHeight<=l&&!R&&(R=!0,Promise.resolve(a()).finally(()=>{R=!1}))};return p.addEventListener("scroll",A,{passive:!0}),()=>p.removeEventListener("scroll",A)},[v,a,l]);const{Header:f,Footer:O,EmptyPlaceholder:P}=d;return s.length===0&&P?H.jsx(P,{}):H.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%"},children:[f&&H.jsx(f,{}),H.jsx(B,{scrollerRef:v,totalSize:z,className:S,style:{flex:1,minHeight:0,...y},children:E.map(p=>H.jsx(_,{virtualItem:p,measureItem:b,children:e(p.index,p.data)},p.key))}),O&&H.jsx(O,{})]})}function se(s){const{fetcher:e,initialPage:t=1,direction:r="append",getKey:i,onPageLoaded:a,onError:l}=s,[d,S]=c.useState([]),[y,v]=c.useState(t),[E,z]=c.useState(!0),[b,f]=c.useState(!1),[O,P]=c.useState(!1),[p,R]=c.useState(!1),A=c.useRef(new Set),x=c.useRef(!1),w=c.useCallback(n=>i?n.filter(u=>{const h=i(u);return A.current.has(h)?!1:(A.current.add(h),!0)}):n,[i]),g=c.useCallback(async()=>{if(!(x.current||!E)){x.current=!0,R(!0);try{const n=y+1,u=await e(n),h=w(u.data);S(T=>r==="prepend"?[...h,...T]:[...T,...h]),v(n),z(u.hasNextPage),f(u.hasPrevPage),a==null||a(n,h)}catch(n){l==null||l(n instanceof Error?n:new Error(String(n)))}finally{R(!1),x.current=!1}}},[y,E,e,w,r,a,l]),C=c.useCallback(async()=>{if(!(x.current||!b)){x.current=!0,R(!0);try{const n=y-1,u=await e(n),h=w(u.data);S(T=>[...h,...T]),v(n),f(u.hasPrevPage),z(u.hasNextPage),a==null||a(n,h)}catch(n){l==null||l(n instanceof Error?n:new Error(String(n)))}finally{R(!1),x.current=!1}}},[y,b,e,w,a,l]),o=c.useCallback(async()=>{if(!x.current){x.current=!0,P(!0);try{const n=await e(t),u=n.data;if(i){const h=new Set(u.map(i));u.forEach(T=>A.current.add(i(T))),S(T=>{const I=T.filter(k=>!h.has(i(k)));return r==="prepend"?[...u,...I]:[...I,...u]})}else S(u);v(t),z(n.hasNextPage),f(n.hasPrevPage),a==null||a(t,u)}catch(n){l==null||l(n instanceof Error?n:new Error(String(n)))}finally{P(!1),x.current=!1}}},[e,t,i,r,a,l]),m=c.useCallback(()=>{S([]),v(t),z(!0),f(!1),P(!1),R(!1),A.current.clear(),x.current=!1},[t]);return{items:d,loadNextPage:g,loadPrevPage:C,hasNextPage:E,hasPrevPage:b,loading:O,loadingMore:p,refresh:o,reset:m,currentPage:y}}exports.ChatVirtualList=te;exports.VirtualList=re;exports.useChatVirtualizer=V;exports.usePagination=se;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { jsx as b, jsxs as _ } from "react/jsx-runtime";
2
- import * as Z from "react";
3
- import { useCallback as C, useRef as A, useReducer as q, useEffect as K, useLayoutEffect as k, useState as L, forwardRef as Y, useImperativeHandle as $ } from "react";
1
+ import { jsx as b, jsxs as D } from "react/jsx-runtime";
2
+ import * as k from "react";
3
+ import { useCallback as O, useRef as E, useReducer as q, useEffect as K, useLayoutEffect as j, useState as L, forwardRef as Y, useImperativeHandle as $ } from "react";
4
4
  class J {
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);
@@ -70,8 +70,8 @@ class Q {
70
70
  /** Re-applies all cached sizes to the OffsetMap using a key→index map */
71
71
  applyToOffsetMap(e, t) {
72
72
  for (const [n, s] of this.cache) {
73
- const c = t.get(n);
74
- c !== void 0 && e.setSize(c, s);
73
+ const l = t.get(n);
74
+ l !== void 0 && e.setSize(l, s);
75
75
  }
76
76
  }
77
77
  }
@@ -98,13 +98,13 @@ function ee(o) {
98
98
  };
99
99
  }
100
100
  function te(o, e) {
101
- return C(
101
+ return O(
102
102
  (t, n) => {
103
- const s = o.current, c = e.current;
104
- if (!s || !c) return;
105
- const l = c.getOffset(t), h = c.getSize(t), p = (n == null ? void 0 : n.align) ?? "start", v = (n == null ? void 0 : n.behavior) ?? "auto", y = (n == null ? void 0 : n.offset) ?? 0;
106
- let R;
107
- p === "start" ? R = l + y : p === "center" ? R = l - s.clientHeight / 2 + h / 2 + y : R = l - s.clientHeight + h + y, s.scrollTo({ top: Math.max(0, R), behavior: v });
103
+ const s = o.current, l = e.current;
104
+ if (!s || !l) return;
105
+ const c = l.getOffset(t), h = l.getSize(t), p = (n == null ? void 0 : n.align) ?? "start", v = (n == null ? void 0 : n.behavior) ?? "auto", y = (n == null ? void 0 : n.offset) ?? 0;
106
+ let x;
107
+ p === "start" ? x = c + y : p === "center" ? x = c - s.clientHeight / 2 + h / 2 + y : x = c - s.clientHeight + h + y, s.scrollTo({ top: Math.max(0, x), behavior: v });
108
108
  },
109
109
  [o, e]
110
110
  );
@@ -121,18 +121,18 @@ function re(o, e) {
121
121
  return { ...o, renderRange: e.renderRange, totalSize: e.totalSize };
122
122
  }
123
123
  }
124
- function D(o) {
125
- const { items: e, getKey: t, estimatedItemSize: n, overscan: s, initialAlignment: c } = o, l = A(null), h = A(null), p = A(new Q()), v = A([]), y = A(!1), R = A(s);
126
- R.current = s, h.current || (h.current = new J(e.length, n));
127
- const z = C((i, g) => {
124
+ function G(o) {
125
+ const { items: e, getKey: t, estimatedItemSize: n, overscan: s, initialAlignment: l } = o, c = E(null), h = E(null), p = E(new Q()), v = E([]), y = E(!1), x = E(s);
126
+ x.current = s, h.current || (h.current = new J(e.length, n));
127
+ const z = O((i, g) => {
128
128
  const r = h.current;
129
129
  if (!r || r.count === 0) return { start: 0, end: -1 };
130
- const a = r.getOffsets(), f = r.getSizes(), T = W(a, i), P = X(a, f, i + g);
130
+ const a = r.getOffsets(), f = r.getSizes(), R = W(a, i), A = X(a, f, i + g);
131
131
  return ee({
132
- firstVisible: T,
133
- lastVisible: P,
132
+ firstVisible: R,
133
+ lastVisible: A,
134
134
  itemCount: r.count,
135
- overscan: R.current
135
+ overscan: x.current
136
136
  });
137
137
  }, []), [I, u] = q(re, {
138
138
  renderRange: { start: 0, end: Math.min(e.length - 1, s * 2) },
@@ -141,106 +141,106 @@ function D(o) {
141
141
  totalSize: h.current.totalSize()
142
142
  });
143
143
  K(() => {
144
- const i = h.current, g = e.map((N, V) => t(N, V)), r = v.current, a = r.length, f = g.length;
144
+ const i = h.current, g = e.map((B, _) => t(B, _)), r = v.current, a = r.length, f = g.length;
145
145
  f === 0 ? i.resize(0) : a === 0 ? i.resize(f) : f > a ? r.length > 0 && g[f - a] === r[0] ? i.prepend(f - a) : i.resize(f) : f < a && i.resize(f);
146
- const T = /* @__PURE__ */ new Map();
147
- g.forEach((N, V) => T.set(N, V)), p.current.applyToOffsetMap(i, T), v.current = g;
148
- const P = l.current, w = (P == null ? void 0 : P.scrollTop) ?? 0, B = (P == null ? void 0 : P.clientHeight) ?? 0, U = z(w, B);
149
- u({ type: "ITEMS_CHANGED", renderRange: U, totalSize: i.totalSize() });
146
+ const R = /* @__PURE__ */ new Map();
147
+ g.forEach((B, _) => R.set(B, _)), p.current.applyToOffsetMap(i, R), v.current = g;
148
+ const A = c.current, N = (A == null ? void 0 : A.scrollTop) ?? 0, V = (A == null ? void 0 : A.clientHeight) ?? 0, F = z(N, V);
149
+ u({ type: "ITEMS_CHANGED", renderRange: F, totalSize: i.totalSize() });
150
150
  }, [e, t, z]), K(() => {
151
- const i = l.current;
151
+ const i = c.current;
152
152
  if (!i) return;
153
153
  const g = () => {
154
- const r = h.current, a = i.scrollTop, f = i.clientHeight, T = z(a, f);
155
- u({ type: "SCROLL", scrollTop: a, totalSize: r.totalSize(), renderRange: T });
154
+ const r = h.current, a = i.scrollTop, f = i.clientHeight, R = z(a, f);
155
+ u({ type: "SCROLL", scrollTop: a, totalSize: r.totalSize(), renderRange: R });
156
156
  };
157
157
  return i.addEventListener("scroll", g, { passive: !0 }), () => i.removeEventListener("scroll", g);
158
158
  }, [z]), K(() => {
159
- const i = l.current;
159
+ const i = c.current;
160
160
  if (!i) return;
161
161
  const g = new ResizeObserver(([r]) => {
162
162
  if (!r) return;
163
- const a = r.contentRect.height, f = h.current, T = i.scrollTop, P = z(T, a);
164
- u({ type: "RESIZE_CONTAINER", height: a, totalSize: f.totalSize(), renderRange: P });
163
+ const a = r.contentRect.height, f = h.current, R = i.scrollTop, A = z(R, a);
164
+ u({ type: "RESIZE_CONTAINER", height: a, totalSize: f.totalSize(), renderRange: A });
165
165
  });
166
166
  return g.observe(i), () => g.disconnect();
167
167
  }, [z]), K(() => {
168
168
  if (y.current || e.length === 0) return;
169
- const i = l.current;
170
- i && (c === "bottom" && (i.scrollTop = i.scrollHeight), y.current = !0);
171
- }, [c, e.length]);
172
- const M = C((i, g) => {
169
+ const i = c.current;
170
+ i && (l === "bottom" && (i.scrollTop = i.scrollHeight), y.current = !0);
171
+ }, [l, e.length]);
172
+ const M = O((i, g) => {
173
173
  const r = h.current;
174
174
  if (!r) return;
175
175
  p.current.set(i, g);
176
176
  const a = v.current.indexOf(i);
177
177
  if (a === -1) return;
178
178
  r.setSize(a, g) && u({ type: "MEASURE", totalSize: r.totalSize() });
179
- }, []), O = C(
179
+ }, []), H = O(
180
180
  (i, g = "auto") => {
181
181
  var r;
182
- (r = l.current) == null || r.scrollTo({ top: i, behavior: g });
182
+ (r = c.current) == null || r.scrollTo({ top: i, behavior: g });
183
183
  },
184
184
  []
185
- ), m = te(l, h), S = h.current, { start: E, end: x } = I.renderRange, F = [];
186
- if (S && x >= E)
187
- for (let i = E; i <= x && i < e.length; i++)
188
- F.push({
185
+ ), m = te(c, h), S = h.current, { start: P, end: T } = I.renderRange, C = [];
186
+ if (S && T >= P)
187
+ for (let i = P; i <= T && i < e.length; i++)
188
+ C.push({
189
189
  key: v.current[i] ?? t(e[i], i),
190
190
  index: i,
191
191
  start: S.getOffset(i),
192
192
  size: S.getSize(i),
193
193
  data: e[i]
194
194
  });
195
- const d = l.current, H = d ? d.scrollHeight - d.scrollTop - d.clientHeight : 1 / 0;
195
+ const d = c.current, w = d ? d.scrollHeight - d.scrollTop - d.clientHeight : 1 / 0;
196
196
  return {
197
- scrollerRef: l,
198
- virtualItems: F,
197
+ scrollerRef: c,
198
+ virtualItems: C,
199
199
  totalSize: I.totalSize,
200
200
  measureItem: M,
201
201
  scrollToIndex: m,
202
- scrollToOffset: O,
202
+ scrollToOffset: H,
203
203
  isAtTop: I.scrollTop <= 0,
204
- isAtBottom: H <= 0,
204
+ isAtBottom: w <= 0,
205
205
  scrollTop: I.scrollTop
206
206
  };
207
207
  }
208
208
  function ne(o, e) {
209
- const t = A(0), n = A(0), s = A(!1), c = C(() => {
210
- const l = o.current;
211
- l && (t.current = l.scrollTop, n.current = l.scrollHeight, s.current = !0);
209
+ const t = E(0), n = E(0), s = E(!1), l = O(() => {
210
+ const c = o.current;
211
+ c && (t.current = c.scrollTop, n.current = c.scrollHeight, s.current = !0);
212
212
  }, [o]);
213
- return k(() => {
213
+ return j(() => {
214
214
  if (!s.current) return;
215
- const l = o.current;
216
- if (!l) return;
217
- const h = l.scrollHeight - n.current;
218
- h > 0 && (l.scrollTop = t.current + h), s.current = !1;
219
- }, [e, o]), { prepareAnchor: c };
215
+ const c = o.current;
216
+ if (!c) return;
217
+ const h = c.scrollHeight - n.current;
218
+ h > 0 && (c.scrollTop = t.current + h), s.current = !1;
219
+ }, [e, o]), { prepareAnchor: l };
220
220
  }
221
221
  function se(o, e) {
222
- const [t, n] = L(!0), s = A(null);
222
+ const [t, n] = L(!0), s = E(null);
223
223
  return K(() => {
224
- const c = o.current;
225
- if (!c) return;
226
- const l = () => {
227
- const p = c.scrollHeight - c.scrollTop - c.clientHeight;
224
+ const l = o.current;
225
+ if (!l) return;
226
+ const c = () => {
227
+ const p = l.scrollHeight - l.scrollTop - l.clientHeight;
228
228
  n(p <= e);
229
229
  }, h = () => {
230
- s.current !== null && cancelAnimationFrame(s.current), s.current = requestAnimationFrame(l);
230
+ s.current !== null && cancelAnimationFrame(s.current), s.current = requestAnimationFrame(c);
231
231
  };
232
- return c.addEventListener("scroll", h, { passive: !0 }), l(), () => {
233
- c.removeEventListener("scroll", h), s.current !== null && cancelAnimationFrame(s.current);
232
+ return l.addEventListener("scroll", h, { passive: !0 }), c(), () => {
233
+ l.removeEventListener("scroll", h), s.current !== null && cancelAnimationFrame(s.current);
234
234
  };
235
235
  }, [o, e]), t;
236
236
  }
237
237
  function ie(o) {
238
- const { itemCount: e, isAtBottom: t, scrollToIndex: n, mode: s } = o, c = A(e);
239
- k(() => {
240
- s && (e > c.current && t && e > 0 && n(e - 1, {
238
+ const { itemCount: e, isAtBottom: t, scrollToIndex: n, mode: s } = o, l = E(e);
239
+ j(() => {
240
+ s && (e > l.current && t && e > 0 && n(e - 1, {
241
241
  align: "end",
242
242
  behavior: s === "smooth" ? "smooth" : "auto"
243
- }), c.current = e);
243
+ }), l.current = e);
244
244
  }, [e, t, n, s]);
245
245
  }
246
246
  function oe(o) {
@@ -249,65 +249,65 @@ function oe(o) {
249
249
  getKey: t,
250
250
  estimatedItemSize: n = 80,
251
251
  overscan: s = 5,
252
- atBottomThreshold: c = 200,
253
- followOutput: l = "auto",
252
+ atBottomThreshold: l = 200,
253
+ followOutput: c = "auto",
254
254
  initialAlignment: h = "bottom",
255
255
  onStartReached: p,
256
256
  onEndReached: v,
257
257
  startReachedThreshold: y = 300,
258
- endReachedThreshold: R = 300,
258
+ endReachedThreshold: x = 300,
259
259
  scrollToMessageKey: z,
260
260
  onScrollToMessageComplete: I
261
- } = o, u = D({
261
+ } = o, u = G({
262
262
  items: e,
263
263
  getKey: t,
264
264
  estimatedItemSize: n,
265
265
  overscan: s,
266
266
  initialAlignment: h
267
- }), M = se(u.scrollerRef, c), { prepareAnchor: O } = ne(u.scrollerRef, e.length);
267
+ }), M = se(u.scrollerRef, l), { prepareAnchor: H } = ne(u.scrollerRef, e.length);
268
268
  ie({
269
269
  itemCount: e.length,
270
270
  isAtBottom: M,
271
271
  scrollToIndex: u.scrollToIndex,
272
- mode: l ?? !1
272
+ mode: c ?? !1
273
273
  });
274
- const m = A(!1);
274
+ const m = E(!1);
275
275
  K(() => {
276
276
  const d = u.scrollerRef.current;
277
277
  if (!d || !p) return;
278
- const H = () => {
278
+ const w = () => {
279
279
  d.scrollTop <= y && !m.current && (m.current = !0, Promise.resolve(p()).finally(() => {
280
280
  m.current = !1;
281
281
  }));
282
282
  };
283
- return d.addEventListener("scroll", H, { passive: !0 }), () => d.removeEventListener("scroll", H);
283
+ return d.addEventListener("scroll", w, { passive: !0 }), () => d.removeEventListener("scroll", w);
284
284
  }, [u.scrollerRef, p, y]);
285
- const S = A(!1);
285
+ const S = E(!1);
286
286
  K(() => {
287
287
  const d = u.scrollerRef.current;
288
288
  if (!d || !v) return;
289
- const H = () => {
290
- d.scrollHeight - d.scrollTop - d.clientHeight <= R && !S.current && (S.current = !0, Promise.resolve(v()).finally(() => {
289
+ const w = () => {
290
+ d.scrollHeight - d.scrollTop - d.clientHeight <= x && !S.current && (S.current = !0, Promise.resolve(v()).finally(() => {
291
291
  S.current = !1;
292
292
  }));
293
293
  };
294
- return d.addEventListener("scroll", H, { passive: !0 }), () => d.removeEventListener("scroll", H);
295
- }, [u.scrollerRef, v, R]);
296
- const E = A(null);
294
+ return d.addEventListener("scroll", w, { passive: !0 }), () => d.removeEventListener("scroll", w);
295
+ }, [u.scrollerRef, v, x]);
296
+ const P = E(null);
297
297
  K(() => {
298
- if (!z || E.current === z) return;
299
- const d = e.findIndex((H, i) => t(H, i) === z);
300
- d !== -1 && (E.current = z, u.scrollToIndex(d, { align: "center", behavior: "smooth" }), I == null || I());
298
+ if (!z || P.current === z) return;
299
+ const d = e.findIndex((w, i) => t(w, i) === z);
300
+ d !== -1 && (P.current = z, u.scrollToIndex(d, { align: "center", behavior: "smooth" }), I == null || I());
301
301
  }, [z, e, t, u, I]);
302
- const x = C(
302
+ const T = O(
303
303
  (d = "auto") => {
304
304
  e.length !== 0 && u.scrollToIndex(e.length - 1, { align: "end", behavior: d });
305
305
  },
306
306
  [e.length, u]
307
- ), F = C(
308
- (d, H) => {
307
+ ), C = O(
308
+ (d, w) => {
309
309
  const i = e.findIndex((g, r) => t(g, r) === d);
310
- i !== -1 && u.scrollToIndex(i, H);
310
+ i !== -1 && u.scrollToIndex(i, w);
311
311
  },
312
312
  [e, t, u]
313
313
  );
@@ -317,13 +317,13 @@ function oe(o) {
317
317
  totalSize: u.totalSize,
318
318
  measureItem: u.measureItem,
319
319
  scrollToIndex: u.scrollToIndex,
320
- scrollToBottom: x,
321
- scrollToKey: F,
320
+ scrollToBottom: T,
321
+ scrollToKey: C,
322
322
  isAtBottom: M,
323
- prepareAnchor: O
323
+ prepareAnchor: H
324
324
  };
325
325
  }
326
- function j({
326
+ function U({
327
327
  scrollerRef: o,
328
328
  totalSize: e,
329
329
  children: t,
@@ -340,19 +340,19 @@ function j({
340
340
  }
341
341
  );
342
342
  }
343
- function G({
343
+ function Z({
344
344
  virtualItem: o,
345
345
  measureItem: e,
346
346
  children: t
347
347
  }) {
348
- const n = A(null);
348
+ const n = E(null);
349
349
  return K(() => {
350
350
  const s = n.current;
351
351
  if (!s) return;
352
- const c = new ResizeObserver(([l]) => {
353
- l && e(o.key, l.contentRect.height);
352
+ const l = new ResizeObserver(([c]) => {
353
+ c && e(o.key, c.contentRect.height);
354
354
  });
355
- return c.observe(s), () => c.disconnect();
355
+ return l.observe(s), () => l.disconnect();
356
356
  }, [o.key, e]), /* @__PURE__ */ b(
357
357
  "div",
358
358
  {
@@ -370,132 +370,135 @@ function G({
370
370
  }
371
371
  );
372
372
  }
373
- function le(o, e) {
373
+ function ce(o, e) {
374
374
  const {
375
375
  data: t,
376
376
  itemContent: n,
377
377
  computeItemKey: s,
378
- estimatedItemSize: c = 80,
379
- overscan: l = 5,
378
+ estimatedItemSize: l = 80,
379
+ overscan: c = 5,
380
380
  followOutput: h = "auto",
381
381
  atBottomThreshold: p = 200,
382
382
  initialAlignment: v = "bottom",
383
383
  onStartReached: y,
384
- onEndReached: R,
384
+ onEndReached: x,
385
385
  startReachedThreshold: z = 300,
386
386
  endReachedThreshold: I = 300,
387
387
  scrollToMessageKey: u,
388
388
  onScrollToMessageComplete: M,
389
- components: O = {},
390
- className: m,
391
- style: S
389
+ onAtBottomChange: H,
390
+ components: m = {},
391
+ className: S,
392
+ style: P
392
393
  } = o, {
393
- scrollerRef: E,
394
- virtualItems: x,
395
- totalSize: F,
396
- measureItem: d,
397
- scrollToIndex: H,
398
- scrollToBottom: i,
399
- scrollToKey: g,
400
- isAtBottom: r,
401
- prepareAnchor: a
394
+ scrollerRef: T,
395
+ virtualItems: C,
396
+ totalSize: d,
397
+ measureItem: w,
398
+ scrollToIndex: i,
399
+ scrollToBottom: g,
400
+ scrollToKey: r,
401
+ isAtBottom: a,
402
+ prepareAnchor: f
402
403
  } = oe({
403
404
  items: t,
404
- getKey: (w, B) => s(B, w),
405
- estimatedItemSize: c,
406
- overscan: l,
405
+ getKey: (F, B) => s(B, F),
406
+ estimatedItemSize: l,
407
+ overscan: c,
407
408
  atBottomThreshold: p,
408
409
  followOutput: h,
409
410
  initialAlignment: v,
410
411
  onStartReached: y,
411
- onEndReached: R,
412
+ onEndReached: x,
412
413
  startReachedThreshold: z,
413
414
  endReachedThreshold: I,
414
415
  scrollToMessageKey: u,
415
416
  onScrollToMessageComplete: M
416
- });
417
- $(
417
+ }), R = k.useRef(a);
418
+ k.useEffect(() => {
419
+ R.current !== a && (R.current = a, H == null || H(a));
420
+ }, [a, H]), $(
418
421
  e,
419
422
  () => ({
420
- scrollToBottom: i,
421
- scrollToIndex: H,
422
- scrollToKey: g,
423
+ scrollToBottom: g,
424
+ scrollToIndex: i,
425
+ scrollToKey: r,
423
426
  getScrollTop: () => {
424
- var w;
425
- return ((w = E.current) == null ? void 0 : w.scrollTop) ?? 0;
427
+ var F;
428
+ return ((F = T.current) == null ? void 0 : F.scrollTop) ?? 0;
426
429
  },
427
- isAtBottom: () => r,
428
- prepareAnchor: a
430
+ isAtBottom: () => a,
431
+ prepareAnchor: f
429
432
  }),
430
- [i, H, g, E, r, a]
433
+ [g, i, r, T, a, f]
431
434
  );
432
- const { Header: f, Footer: T, EmptyPlaceholder: P } = O;
433
- return t.length === 0 && P ? /* @__PURE__ */ b(P, {}) : /* @__PURE__ */ _("div", { style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
434
- f && /* @__PURE__ */ b(f, {}),
435
+ const { Header: A, Footer: N, EmptyPlaceholder: V } = m;
436
+ return t.length === 0 && V ? /* @__PURE__ */ b(V, {}) : /* @__PURE__ */ D("div", { style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
437
+ A && /* @__PURE__ */ b(A, {}),
435
438
  /* @__PURE__ */ b(
436
- j,
439
+ U,
437
440
  {
438
- scrollerRef: E,
439
- totalSize: F,
440
- className: m,
441
- style: { flex: 1, minHeight: 0, ...S },
442
- children: x.map((w) => /* @__PURE__ */ b(
443
- G,
441
+ scrollerRef: T,
442
+ totalSize: d,
443
+ className: S,
444
+ style: { flex: 1, minHeight: 0, ...P },
445
+ children: C.map((F) => /* @__PURE__ */ b(
446
+ Z,
444
447
  {
445
- virtualItem: w,
446
- measureItem: d,
447
- children: n(w.index, w.data)
448
+ virtualItem: F,
449
+ measureItem: w,
450
+ children: n(F.index, F.data)
448
451
  },
449
- w.key
452
+ F.key
450
453
  ))
451
454
  }
452
455
  ),
453
- T && /* @__PURE__ */ b(T, {})
456
+ N && /* @__PURE__ */ b(N, {})
454
457
  ] });
455
458
  }
456
- const ue = Y(le);
459
+ const ue = Y(ce);
457
460
  function fe({
458
461
  data: o,
459
462
  itemContent: e,
460
463
  computeItemKey: t,
461
464
  estimatedItemSize: n = 80,
462
465
  overscan: s = 5,
463
- onEndReached: c,
464
- endReachedThreshold: l = 300,
466
+ onEndReached: l,
467
+ endReachedThreshold: c = 300,
465
468
  components: h = {},
466
469
  className: p,
467
470
  style: v
468
471
  }) {
469
- const { scrollerRef: y, virtualItems: R, totalSize: z, measureItem: I } = D({
472
+ const { scrollerRef: y, virtualItems: x, totalSize: z, measureItem: I } = G({
470
473
  items: o,
471
474
  getKey: (m, S) => t(S, m),
472
475
  estimatedItemSize: n,
473
476
  overscan: s,
474
477
  initialAlignment: "top"
475
478
  });
476
- Z.useEffect(() => {
479
+ k.useEffect(() => {
477
480
  const m = y.current;
478
- if (!m || !c) return;
481
+ if (!m || !l) return;
479
482
  let S = !1;
480
- const E = () => {
481
- m.scrollHeight - m.scrollTop - m.clientHeight <= l && !S && (S = !0, Promise.resolve(c()).finally(() => {
483
+ const P = () => {
484
+ m.scrollHeight - m.scrollTop - m.clientHeight <= c && !S && (S = !0, Promise.resolve(l()).finally(() => {
482
485
  S = !1;
483
486
  }));
484
487
  };
485
- return m.addEventListener("scroll", E, { passive: !0 }), () => m.removeEventListener("scroll", E);
486
- }, [y, c, l]);
487
- const { Header: u, Footer: M, EmptyPlaceholder: O } = h;
488
- return o.length === 0 && O ? /* @__PURE__ */ b(O, {}) : /* @__PURE__ */ _("div", { style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
488
+ return m.addEventListener("scroll", P, { passive: !0 }), () => m.removeEventListener("scroll", P);
489
+ }, [y, l, c]);
490
+ const { Header: u, Footer: M, EmptyPlaceholder: H } = h;
491
+ return o.length === 0 && H ? /* @__PURE__ */ b(H, {}) : /* @__PURE__ */ D("div", { style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
489
492
  u && /* @__PURE__ */ b(u, {}),
490
493
  /* @__PURE__ */ b(
491
- j,
494
+ U,
492
495
  {
493
496
  scrollerRef: y,
494
497
  totalSize: z,
495
498
  className: p,
496
499
  style: { flex: 1, minHeight: 0, ...v },
497
- children: R.map((m) => /* @__PURE__ */ b(
498
- G,
500
+ children: x.map((m) => /* @__PURE__ */ b(
501
+ Z,
499
502
  {
500
503
  virtualItem: m,
501
504
  measureItem: I,
@@ -514,68 +517,68 @@ function he(o) {
514
517
  initialPage: t = 1,
515
518
  direction: n = "append",
516
519
  getKey: s,
517
- onPageLoaded: c,
518
- onError: l
519
- } = o, [h, p] = L([]), [v, y] = L(t), [R, z] = L(!0), [I, u] = L(!1), [M, O] = L(!1), [m, S] = L(!1), E = A(/* @__PURE__ */ new Set()), x = A(!1), F = C(
520
+ onPageLoaded: l,
521
+ onError: c
522
+ } = o, [h, p] = L([]), [v, y] = L(t), [x, z] = L(!0), [I, u] = L(!1), [M, H] = L(!1), [m, S] = L(!1), P = E(/* @__PURE__ */ new Set()), T = E(!1), C = O(
520
523
  (r) => s ? r.filter((a) => {
521
524
  const f = s(a);
522
- return E.current.has(f) ? !1 : (E.current.add(f), !0);
525
+ return P.current.has(f) ? !1 : (P.current.add(f), !0);
523
526
  }) : r,
524
527
  [s]
525
- ), d = C(async () => {
526
- if (!(x.current || !R)) {
527
- x.current = !0, S(!0);
528
+ ), d = O(async () => {
529
+ if (!(T.current || !x)) {
530
+ T.current = !0, S(!0);
528
531
  try {
529
- const r = v + 1, a = await e(r), f = F(a.data);
532
+ const r = v + 1, a = await e(r), f = C(a.data);
530
533
  p(
531
- (T) => n === "prepend" ? [...f, ...T] : [...T, ...f]
532
- ), y(r), z(a.hasNextPage), u(a.hasPrevPage), c == null || c(r, f);
534
+ (R) => n === "prepend" ? [...f, ...R] : [...R, ...f]
535
+ ), y(r), z(a.hasNextPage), u(a.hasPrevPage), l == null || l(r, f);
533
536
  } catch (r) {
534
- l == null || l(r instanceof Error ? r : new Error(String(r)));
537
+ c == null || c(r instanceof Error ? r : new Error(String(r)));
535
538
  } finally {
536
- S(!1), x.current = !1;
539
+ S(!1), T.current = !1;
537
540
  }
538
541
  }
539
- }, [v, R, e, F, n, c, l]), H = C(async () => {
540
- if (!(x.current || !I)) {
541
- x.current = !0, S(!0);
542
+ }, [v, x, e, C, n, l, c]), w = O(async () => {
543
+ if (!(T.current || !I)) {
544
+ T.current = !0, S(!0);
542
545
  try {
543
- const r = v - 1, a = await e(r), f = F(a.data);
544
- p((T) => [...f, ...T]), y(r), u(a.hasPrevPage), z(a.hasNextPage), c == null || c(r, f);
546
+ const r = v - 1, a = await e(r), f = C(a.data);
547
+ p((R) => [...f, ...R]), y(r), u(a.hasPrevPage), z(a.hasNextPage), l == null || l(r, f);
545
548
  } catch (r) {
546
- l == null || l(r instanceof Error ? r : new Error(String(r)));
549
+ c == null || c(r instanceof Error ? r : new Error(String(r)));
547
550
  } finally {
548
- S(!1), x.current = !1;
551
+ S(!1), T.current = !1;
549
552
  }
550
553
  }
551
- }, [v, I, e, F, c, l]), i = C(async () => {
552
- if (!x.current) {
553
- x.current = !0, O(!0);
554
+ }, [v, I, e, C, l, c]), i = O(async () => {
555
+ if (!T.current) {
556
+ T.current = !0, H(!0);
554
557
  try {
555
558
  const r = await e(t), a = r.data;
556
559
  if (s) {
557
560
  const f = new Set(a.map(s));
558
- a.forEach((T) => E.current.add(s(T))), p((T) => {
559
- const P = T.filter((w) => !f.has(s(w)));
560
- return n === "prepend" ? [...a, ...P] : [...P, ...a];
561
+ a.forEach((R) => P.current.add(s(R))), p((R) => {
562
+ const A = R.filter((N) => !f.has(s(N)));
563
+ return n === "prepend" ? [...a, ...A] : [...A, ...a];
561
564
  });
562
565
  } else
563
566
  p(a);
564
- y(t), z(r.hasNextPage), u(r.hasPrevPage), c == null || c(t, a);
567
+ y(t), z(r.hasNextPage), u(r.hasPrevPage), l == null || l(t, a);
565
568
  } catch (r) {
566
- l == null || l(r instanceof Error ? r : new Error(String(r)));
569
+ c == null || c(r instanceof Error ? r : new Error(String(r)));
567
570
  } finally {
568
- O(!1), x.current = !1;
571
+ H(!1), T.current = !1;
569
572
  }
570
573
  }
571
- }, [e, t, s, n, c, l]), g = C(() => {
572
- p([]), y(t), z(!0), u(!1), O(!1), S(!1), E.current.clear(), x.current = !1;
574
+ }, [e, t, s, n, l, c]), g = O(() => {
575
+ p([]), y(t), z(!0), u(!1), H(!1), S(!1), P.current.clear(), T.current = !1;
573
576
  }, [t]);
574
577
  return {
575
578
  items: h,
576
579
  loadNextPage: d,
577
- loadPrevPage: H,
578
- hasNextPage: R,
580
+ loadPrevPage: w,
581
+ hasNextPage: x,
579
582
  hasPrevPage: I,
580
583
  loading: M,
581
584
  loadingMore: m,
package/dist/types.d.ts CHANGED
@@ -74,6 +74,7 @@ export interface ChatVirtualListProps<T> {
74
74
  endReachedThreshold?: number;
75
75
  scrollToMessageKey?: string | number | null;
76
76
  onScrollToMessageComplete?: () => void;
77
+ onAtBottomChange?: (isAtBottom: boolean) => void;
77
78
  components?: VirtualListComponents<T>;
78
79
  className?: string;
79
80
  style?: React.CSSProperties;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-anchorlist",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "High-performance chat virtualizer for React — no flicker, no hacks",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",