virtua 0.0.1 → 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 +9 -0
- package/lib/List.d.ts +4 -0
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +1 -1
- package/lib/index.mjs.map +1 -1
- package/lib/state.d.ts +0 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
Simple, fast, small and flexible virtual list component for [React](https://github.com/facebook/react).
|
|
6
6
|
|
|
7
|
+
- Virtualization with minimal setup.
|
|
8
|
+
- As fast as alternatives (and also faster in several cases!).
|
|
9
|
+
- Keeping bundle size small as much as possible (Currently [about 2.8kB gzipped](https://bundlephobia.com/package/virtua)).
|
|
10
|
+
- Aiming to support many usecases - fixed size, dynamic size, horizontal scrolling, reverse scrolling, rtl direction, sticky, infinite scrolling, placeholder, scrollTo, dnd, table, and more.
|
|
11
|
+
|
|
12
|
+
## Demo
|
|
13
|
+
|
|
14
|
+
https://inokawa.github.io/virtua/
|
|
15
|
+
|
|
7
16
|
## Install
|
|
8
17
|
|
|
9
18
|
```sh
|
package/lib/List.d.ts
CHANGED
|
@@ -37,6 +37,10 @@ export interface ListProps {
|
|
|
37
37
|
* If true, rendered as a horizontally scrollable list. Otherwise rendered as a vertically scrollable list.
|
|
38
38
|
*/
|
|
39
39
|
horizontal?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* You have to set true if you use this component under `direction: rtl` style.
|
|
42
|
+
*/
|
|
43
|
+
rtl?: boolean;
|
|
40
44
|
/**
|
|
41
45
|
* Number of items to be the margin from the end of the scroll. See also {@link onEndReached}.
|
|
42
46
|
* @defaultValue 0
|
package/lib/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,"t",{value:!0});var e=require("react/jsx-runtime"),t=require("react"),n=require("use-sync-external-store/shim");const r=Math.min,i=Math.max,l=(e,t)=>Array.from({length:e},((e,n)=>t(n))),
|
|
1
|
+
Object.defineProperty(exports,"t",{value:!0});var e=require("react/jsx-runtime"),t=require("react"),n=require("use-sync-external-store/shim");const r=Math.min,i=Math.max,l=Math.abs,o=(e,t)=>Array.from({length:e},((e,n)=>t(n))),s=(e,t)=>{const n=e.i[t];return-1===n?e.l:n},_=(e,t,n)=>{let l=0;if(n>=0)for(;t<e.o-1;){const r=s(e,t);if(l+=r,t++,l>=n){l-r/2>=n&&t--;break}}else for(;t>0;){t--;const r=s(e,t);if(l-=r,l<=n){l+r/2<n&&t++;break}}return r(i(t,0),e.o-1)},u=_,c=(e,t)=>{if(!e.o)return 0;if(e._>=t)return e.u[t];let n=e.u[e._];for(let r=e._;r<=t&&(e.u[r]=n,r!==t);r++)n+=s(e,r);return e._=t,n},d=(e,t,n)=>{var i;return{l:t,o:e,_:null!==(i=n&&r(n._,e-1))&&void 0!==i?i:0,i:o(e,(e=>{var t;return null!==(t=n&&n.i[e])&&void 0!==t?t:-1})),u:o(e,(e=>{var t;return 0===e?0:null!==(t=n&&n.u[e])&&void 0!==t?t:-1}))}},a="undefined"!=typeof window?t.useLayoutEffect:t.useEffect,f=(e,t)=>n.useSyncExternalStore(e,t,t),h=t.memo((({h:n,m:r,p:i,g:l,v:o,I:s,S:_})=>{const u=t.useRef(null),c=f(i.R,(()=>i.H(l))),d=f(i.R,(()=>i.M(l)));return a((()=>r.O(u.current,l)),[l]),e.jsx(o,{ref:u,style:t.useMemo((()=>{const e={margin:"0",padding:"0",position:"absolute",[s?"height":"width"]:"100%",[s?"top":_?"right":"left"]:0,[s?_?"right":"left":"top"]:c};return s&&(e.display="flex"),d&&(e.visibility="hidden"),e}),[c,s,_,d]),children:n})})),m=e=>null==e||"boolean"==typeof e,p=({h:n,T:r,v:i,j:l,I:o})=>e.jsx(i,{ref:r,style:t.useMemo((()=>({overflow:o?"auto hidden":"hidden auto",position:"relative",contain:"strict",width:"100%",height:"100%",padding:0,margin:0,...l})),[o,l]),children:n}),g=({h:n,p:r,v:i,j:l,I:o,S:s})=>{const _=f(r.R,r.k),u=f(r.R,r.q);return e.jsx(i,{style:t.useMemo((()=>{const e=_>=u?_:u,t=o?e:"100%",n=o?"100%":e;return{position:"absolute",top:0,[s?"right":"left"]:0,width:t,height:n,minWidth:t,minHeight:n,...l}}),[_,u,l,o,s]),children:n})},y=t.forwardRef((({children:n,itemSize:o=40,overscan:y=6,horizontal:v,rtl:w,endThreshold:z=0,style:I,innerStyle:x,element:S="div",innerElement:b="div",itemElement:R="div",onEndReached:H},M)=>{const O=t.useMemo((()=>{let e=0;return t.Children.forEach(n,(t=>{m(t)||e++})),e}),[n]),T=((e,n,i)=>{const l=t.useRef();return l.current||(l.current=(()=>{const t=new Set,l={P:0,W:0,D:0,U:d(e,n),A:[]},o=()=>i?l.W:l.D;let a;return{C:()=>l.P,F:()=>u(l.U,l.P,o()),M:e=>-1===l.U.i[e],J:e=>((e,t,n)=>{for(let r=t;r<=n;r++)if(-1===e.i[r])return!0;return!1})(l.U,e,u(l.U,e,o())),H:e=>c(l.U,e),q:()=>o(),k:()=>(e=>{if(!e.o)return 0;const t=e.o-1;if(e._>=t)return e.u[t]+s(e,t);let n=e.u[e._];for(let r=e._;r<=t;r++)e.u[r]=n,n+=s(e,r);return e._=t,n})(l.U),L:()=>l.U.o,V:()=>l.A,B:()=>(a&&a[1](),new Promise(((e,t)=>{a=[()=>{Promise.resolve().then((()=>{e(),a=void 0}))},t]}))),R:e=>(t.add(e),()=>{t.delete(e)}),G(e){((e,t,n)=>{switch(t.K){case 0:return e.U.o!==t.o&&(e.U=d(t.o,n,e.U),!0);case 1:{const n=t.N.filter((([t,n])=>e.U.i[t]!==n));if(!n.length)return!1;const i=[];return n.forEach((([t,n])=>{i.push([t,n-s(e.U,t)]),((e,t,n)=>{e.i[t]=n,e._=r(t,e._)})(e.U,t,n)})),e.A=i,!0}case 2:return(e.W!==t.X||e.D!==t.Y)&&(e.W=t.X,e.D=t.Y,!0);case 3:{const n=e.P,r=c(e.U,n);return r!==t.Z&&(e.P=((e,t,n,r)=>_(e,n,t-r))(e.U,t.Z,n,r))!==n}}})(l,e,n)&&(t.forEach((e=>{e()})),a&&1===e.K&&a[0]())}}})())})(O,o,v),E=f(T.R,T.C),j=f(T.R,T.F),k=f(T.R,T.V),q=t.useRef(null),P=t.useRef(-1),W=t.useRef(),D=W.current||(W.current=(()=>{if("undefined"==typeof ResizeObserver)return{};let e,t,n=-1,r=0,i=!1;const o=v?"scrollLeft":"scrollTop",s=new WeakMap,_=new ResizeObserver((e=>{const n=[];for(const r of e)if(r.target===t)T.G({K:2,X:r.contentRect.width,Y:r.contentRect.height});else{const e=s.get(r.target);null!=e&&n.push([e,r.contentRect[v?"width":"height"]])}n.length&&(T.G({K:1,N:n}),i=!0)}));return{$(e){t=e;const s=()=>{let t=e[o];w&&(t=l(t)),n!==t&&(0!==r&&i?i=!1:3!==r&&(r=n>t?2:1),T.G({K:3,Z:n=t}))},u=(()=>{let e=null;const t=()=>{null!=e&&clearTimeout(e)},n=()=>{t(),e=setTimeout((()=>{e=null,s(),r=0}),300)};return n.ee=t,n})(),c=()=>{s(),u()};return _.observe(e),e.addEventListener("scroll",c),()=>{_.disconnect(),e.removeEventListener("scroll",c),u.ee()}},O:(e,t)=>(s.set(e,t),_.observe(e),()=>{s.delete(e),_.unobserve(e)}),te:()=>r,ne(n,i){if(t){if(w){if(null==e){const n=t[o];t[o]=1,e=0===t[o],t[o]=n}e&&(n*=-1)}i?t[o]+=n:(t[o]=n,r=3)}}}})()),U=r(O,T.L()),A=i(E-y,0),C=r(j+y,U-1);a((()=>{T.G({K:0,o:O})}),[O]),a((()=>D.$(q.current)),[]),a((()=>{if(!k.length)return;const e=D.te();if(2===e){const e=k.reduce(((e,[,t])=>e+t),0);e&&D.ne(e,!0)}else if(3===e){const e=0===E,t=j-(U-1)==0,n=k.reduce(((n,[r,i])=>(r<E?e||(n+=i):!e&&t&&(n+=i),n)),0);n&&D.ne(n,!0)}}),[k]),t.useEffect((()=>{H&&(P.current>U&&(P.current=-1),U-1-j<=z&&P.current<U&&(P.current=U,H()))}),[j]),t.useImperativeHandle(M,(()=>({scrollToIndex:async e=>{const t=q.current;if(!t)return;e=i(r(e,U-1),0);const n=()=>{let n=T.H(e);const r=v?t.scrollWidth:t.scrollHeight,i=T.q();return r-(n+i)<=0&&(n=r-i),n};if(T.J(e)){do{T.G({K:3,Z:n()});try{await T.B()}catch(e){return}}while(T.J(e));D.ne(n())}else{const e=n();D.ne(e),T.G({K:3,Z:e})}}})),[U]);const F=t.useMemo((()=>{let r=-1;return t.Children.map(n,(t=>{if(!(m(t)||(r++,r<A||r>C)))return null!=t?e.jsx(h,{m:D,p:T,g:r,v:R,I:v,S:w,h:t},(null==t?void 0:t.key)||r):null}))}),[n,A,C]);return e.jsx(p,{T:q,I:v,v:S,j:I,h:e.jsx(g,{p:T,v:b,j:x,I:v,S:w,h:F})})}));exports.List=y;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/src/utils.ts","../src/src/cache.ts","../src/src/useIsomorphicLayoutEffect.ts","../src/src/useSyncExternalStore.ts","../src/src/List.tsx","../src/src/state.ts"],"sourcesContent":["export const min = Math.min;\nexport const max = Math.max;\nexport const abs = Math.abs;\n\nexport const range = <T>(length: number, cb: (i: number) => T): T[] =>\n Array.from({ length }, (_, i) => cb(i));\n\nexport const debounce = <T extends (...args: any[]) => void>(\n fn: T,\n ms: number\n) => {\n let id: NodeJS.Timeout | null = null;\n\n const cancel = () => {\n if (id != null) {\n clearTimeout(id);\n }\n };\n const debouncedFn = () => {\n cancel();\n id = setTimeout(() => {\n id = null;\n fn();\n }, ms);\n };\n debouncedFn._cancel = cancel;\n return debouncedFn;\n};\n","import type { DeepReadonly, Writeable } from \"./types\";\nimport { max, min, range } from \"./utils\";\n\nexport const UNCACHED = -1;\n\nexport type Cache = DeepReadonly<{\n _defaultItemSize: number;\n _length: number;\n _sizes: number[];\n _measuredOffsetIndex: number;\n _offsets: number[];\n}>;\n\nexport const getItemSize = (cache: Cache, index: number): number => {\n const size = cache._sizes[index]!;\n return size === UNCACHED ? cache._defaultItemSize : size;\n};\n\nexport const setItemSize = (\n cache: Writeable<Cache>,\n index: number,\n size: number\n) => {\n cache._sizes[index] = size;\n // mark as dirty\n cache._measuredOffsetIndex = min(index, cache._measuredOffsetIndex);\n};\n\nexport const computeTotalSize = (cache: Writeable<Cache>): number => {\n if (!cache._length) return 0;\n const lastIndex = cache._length - 1;\n if (cache._measuredOffsetIndex >= lastIndex) {\n return cache._offsets[lastIndex]! + getItemSize(cache, lastIndex);\n }\n\n let top = cache._offsets[cache._measuredOffsetIndex]!;\n for (let i = cache._measuredOffsetIndex; i <= lastIndex; i++) {\n cache._offsets[i] = top;\n top += getItemSize(cache, i);\n }\n\n cache._measuredOffsetIndex = lastIndex;\n return top;\n};\n\nconst findIndex = (cache: Cache, i: number, distance: number): number => {\n let sum = 0;\n if (distance >= 0) {\n // search forward\n while (i < cache._length - 1) {\n const h = getItemSize(cache, i);\n sum += h;\n i++;\n if (sum >= distance) {\n if (sum - h / 2 >= distance) {\n i--;\n }\n break;\n }\n }\n } else {\n // search backward\n while (i > 0) {\n i--;\n const h = getItemSize(cache, i);\n sum -= h;\n if (sum <= distance) {\n if (sum + h / 2 < distance) {\n i++;\n }\n break;\n }\n }\n }\n\n return min(max(i, 0), cache._length - 1);\n};\n\nexport const findStartIndexWithOffset = (\n cache: Cache,\n offset: number,\n prevStartIndex: number,\n prevOffset: number\n): number => {\n return findIndex(cache, prevStartIndex, offset - prevOffset);\n};\n\nexport const findEndIndex = findIndex;\n\nexport const hasUnmeasuredItemsInRange = (\n cache: Cache,\n startIndex: number,\n endIndex: number\n): boolean => {\n for (let i = startIndex; i <= endIndex; i++) {\n if (cache._sizes[i] === UNCACHED) {\n return true;\n }\n }\n return false;\n};\n\nexport const computeStartOffset = (\n cache: Writeable<Cache>,\n index: number\n): number => {\n if (!cache._length) return 0;\n if (cache._measuredOffsetIndex >= index) {\n return cache._offsets[index]!;\n }\n\n let top = cache._offsets[cache._measuredOffsetIndex]!;\n for (let i = cache._measuredOffsetIndex; i <= index; i++) {\n cache._offsets[i] = top;\n if (i === index) {\n break;\n }\n top += getItemSize(cache, i);\n }\n cache._measuredOffsetIndex = index;\n return top;\n};\n\nexport const resetCache = (\n length: number,\n itemSize: number,\n cache?: Cache\n): Cache => {\n return {\n _defaultItemSize: itemSize,\n _length: length,\n _measuredOffsetIndex:\n (cache && min(cache._measuredOffsetIndex, length - 1)) ?? 0,\n _sizes: range(length, (i) => (cache && cache._sizes[i]) ?? UNCACHED),\n _offsets: range(length, (i) =>\n i === 0\n ? 0 // first offset must be 0\n : (cache && cache._offsets[i]) ?? UNCACHED\n ),\n };\n};\n","import { useEffect, useLayoutEffect } from \"react\";\n\n// https://gist.github.com/gaearon/e7d97cdf38a2907924ea12e4ebdf3c85\nexport const useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n","import { useSyncExternalStore as _useSyncExternalStore } from \"use-sync-external-store/shim\";\n\nexport const useSyncExternalStore = <T>(\n subscibe: (onStoreChange: () => void) => () => void,\n getSnapShot: () => T\n): T => {\n return _useSyncExternalStore(subscibe, getSnapShot, getSnapShot);\n};\n","import {\n Children,\n memo,\n useRef,\n useMemo,\n CSSProperties,\n ReactElement,\n forwardRef,\n useImperativeHandle,\n ReactNode,\n useEffect,\n RefObject,\n} from \"react\";\nimport {\n HANDLE_SCROLL,\n UPDATE_CACHE_LENGTH,\n Store,\n UPDATE_ITEM_SIZES,\n UPDATE_VIEWPORT_SIZE,\n useVirtualStore,\n} from \"./state\";\nimport { useIsomorphicLayoutEffect } from \"./useIsomorphicLayoutEffect\";\nimport { useSyncExternalStore } from \"./useSyncExternalStore\";\nimport { debounce, max, min } from \"./utils\";\n\nconst SCROLL_STOP = 0;\nconst SCROLL_DOWN = 1;\nconst SCROLL_UP = 2;\nconst SCROLL_MANUAL = 3;\ntype ScrollDirection =\n | typeof SCROLL_STOP\n | typeof SCROLL_DOWN\n | typeof SCROLL_UP\n | typeof SCROLL_MANUAL;\n\nconst INITIAL_END_REACHED_INDEX = -1;\n\ntype ObserverHandle = {\n _init: (rootElement: HTMLElement) => () => void;\n _observe: (itemElement: HTMLElement, index: number) => () => void;\n _getScrollDirection: () => ScrollDirection;\n _startManuallScroll: () => void;\n};\n\ntype ItemProps = {\n _children: ReactNode;\n _handle: ObserverHandle;\n _store: Store;\n _index: number;\n _element: \"div\";\n _isHorizontal: boolean | undefined;\n};\n\nconst Item = memo(\n ({\n _children: children,\n _handle: handle,\n _store: store,\n _index: index,\n _element: Element,\n _isHorizontal: isHorizontal,\n }: ItemProps): ReactElement => {\n const ref = useRef<HTMLDivElement>(null);\n\n const offset = useSyncExternalStore(store._subscribe, () =>\n store._getItemOffset(index)\n );\n const hide = useSyncExternalStore(store._subscribe, () =>\n store._isUnmeasuredItem(index)\n );\n\n // The index may be changed if elements are inserted to or removed from the start of props.children\n useIsomorphicLayoutEffect(\n () => handle._observe(ref.current!, index),\n [index]\n );\n\n return (\n <Element\n ref={ref}\n style={useMemo<CSSProperties>(() => {\n const style: CSSProperties = {\n margin: \"0\",\n padding: \"0\",\n position: \"absolute\",\n [isHorizontal ? \"height\" : \"width\"]: \"100%\",\n [isHorizontal ? \"top\" : \"left\"]: 0,\n [isHorizontal ? \"left\" : \"top\"]: offset,\n // willChange: \"transform\",\n };\n if (isHorizontal) {\n style.display = \"flex\";\n }\n if (hide) {\n style.visibility = \"hidden\";\n }\n return style;\n }, [offset, isHorizontal, hide])}\n >\n {children}\n </Element>\n );\n }\n);\n\nconst isInvalidElement = <T,>(e: T) => e == null || typeof e === \"boolean\";\n\nconst Window = ({\n _children: children,\n _ref: ref,\n _element: Element,\n _style: style,\n _isHorizontal: isHorizontal,\n}: {\n _children: ReactNode;\n _ref: RefObject<HTMLDivElement>;\n _element: \"div\";\n _style: CSSProperties | undefined;\n _isHorizontal: boolean | undefined;\n}) => {\n return (\n <Element\n ref={ref}\n style={useMemo<CSSProperties>(\n () => ({\n overflow: isHorizontal ? \"auto hidden\" : \"hidden auto\",\n position: \"relative\",\n contain: \"strict\",\n // transform: \"translate3d(0px, 0px, 0px)\",\n // willChange: \"scroll-position\",\n // backfaceVisibility: \"hidden\",\n width: \"100%\",\n height: \"100%\",\n padding: 0,\n margin: 0,\n ...style,\n }),\n [isHorizontal, style]\n )}\n >\n {children}\n </Element>\n );\n};\n\nconst Inner = ({\n _children: children,\n _store: store,\n _element: Element,\n _style: style,\n _isHorizontal: isHorizontal,\n}: {\n _children: ReactNode;\n _store: Store;\n _element: \"div\";\n _style: CSSProperties | undefined;\n _isHorizontal: boolean | undefined;\n}) => {\n const scrollSize = useSyncExternalStore(\n store._subscribe,\n store._getScrollSize\n );\n const viewportSize = useSyncExternalStore(\n store._subscribe,\n store._getViewportSize\n );\n\n return (\n <Element\n style={useMemo<CSSProperties>(() => {\n const clampedScrollSize =\n scrollSize >= viewportSize ? scrollSize : viewportSize;\n const width = isHorizontal ? clampedScrollSize : \"100%\";\n const height = isHorizontal ? \"100%\" : clampedScrollSize;\n return {\n position: \"absolute\",\n top: 0,\n left: 0,\n width,\n height,\n minWidth: width,\n minHeight: height,\n ...style,\n };\n }, [scrollSize, viewportSize, style, isHorizontal])}\n >\n {children}\n </Element>\n );\n};\n\nexport interface CustomComponentProps {\n style: CSSProperties;\n children: ReactNode;\n}\n\nexport type CustomComponent = React.ForwardRefExoticComponent<\n React.PropsWithoutRef<CustomComponentProps> & React.RefAttributes<any>\n>;\n\ntype CustomElementType = keyof JSX.IntrinsicElements | CustomComponent;\n\n/**\n * Methods of {@link List}.\n */\nexport interface ListHandle {\n /**\n * Scroll to the item specified by index.\n * @param index index of item\n */\n scrollToIndex(index: number): void;\n}\n\n/**\n * Props of {@link List}.\n */\nexport interface ListProps {\n /**\n * Elements rendered by this component.\n */\n children: ReactNode;\n /**\n * Item size hint for unmeasured items. It's recommended to specify this prop if item sizes are fixed and known, or much larger than the defaultValue. It will help to reduce scroll jump when items are measured.\n * @defaultValue 40\n */\n itemSize?: number;\n /**\n * Number of items to render above/below the visible bounds of the list. You can increase to avoid showing blank items in fast scrolling.\n * @defaultValue 6\n */\n overscan?: number;\n /**\n * If true, rendered as a horizontally scrollable list. Otherwise rendered as a vertically scrollable list.\n */\n horizontal?: boolean;\n /**\n * Number of items to be the margin from the end of the scroll. See also {@link onEndReached}.\n * @defaultValue 0\n */\n endThreshold?: number;\n /**\n * Inline style prop to override style of scrollable element.\n */\n style?: CSSProperties;\n /**\n * Inline style prop to override style of inner element.\n */\n innerStyle?: CSSProperties;\n /**\n * Customized element type for scrollable element.\n * @defaultValue \"div\"\n */\n element?: CustomElementType;\n /**\n * Customized element type for inner element.\n * @defaultValue \"div\"\n */\n innerElement?: CustomElementType;\n /**\n * Customized element type for item element.\n * @defaultValue \"div\"\n */\n itemElement?: CustomElementType;\n /**\n * Callback invoked when scrolling reached to the end. The margin from the end is specified by {@link endThreshold}.\n */\n onEndReached?: () => void;\n}\n\n/**\n * Virtualized list component. See {@link ListProps} and {@link ListHandle}.\n */\nexport const List = forwardRef<ListHandle, ListProps>(\n (\n {\n children,\n itemSize = 40,\n overscan = 6,\n horizontal: isHorizontal,\n endThreshold = 0,\n style: styleProp,\n innerStyle: innerStyleProp,\n element = \"div\",\n innerElement = \"div\",\n itemElement = \"div\",\n onEndReached,\n },\n ref\n ): ReactElement => {\n const scrollToKey = isHorizontal ? \"scrollLeft\" : \"scrollTop\";\n // memoize element count\n const rawCount = useMemo(() => {\n let i = 0;\n Children.forEach(children, (e) => {\n if (isInvalidElement(e)) {\n return;\n }\n i++;\n });\n return i;\n }, [children]);\n\n const store = useVirtualStore(rawCount, itemSize, isHorizontal);\n const startIndex = useSyncExternalStore(\n store._subscribe,\n store._getStartIndex\n );\n const endIndex = useSyncExternalStore(store._subscribe, store._getEndIndex);\n const isViewportInitialized = useSyncExternalStore(\n store._subscribe,\n store._isViewportSizeInitialized\n );\n const jump = useSyncExternalStore(store._subscribe, store._getJump);\n const scrollRef = useRef<HTMLDivElement>(null);\n const onEndReachedCalledIndex = useRef<number>(INITIAL_END_REACHED_INDEX);\n\n const handleRef = useRef<ObserverHandle>();\n const handle =\n handleRef.current ||\n (handleRef.current = ((): ObserverHandle => {\n let ro: ResizeObserver;\n let prevOffset = -1;\n let scrollDirection: ScrollDirection = SCROLL_STOP;\n let resized = false;\n const mountedIndexes = new WeakMap<Element, number>();\n\n return {\n _init(root) {\n const syncViewportToScrollPosition = () => {\n const offset = root[scrollToKey];\n if (prevOffset === offset) {\n return;\n }\n // Skip scroll direction detection just after resizing because it may result in the opposite direction.\n // Scroll events are dispatched enough so it's ok to skip some of them.\n if (scrollDirection === SCROLL_STOP || !resized) {\n // Ignore until manual scrolling\n if (scrollDirection !== SCROLL_MANUAL) {\n scrollDirection =\n prevOffset > offset ? SCROLL_UP : SCROLL_DOWN;\n }\n } else {\n resized = false;\n }\n store._update({\n _type: HANDLE_SCROLL,\n _offset: (prevOffset = offset),\n });\n };\n\n const onScrollStopped = debounce(() => {\n // Check scroll position once just after scrolling stopped\n syncViewportToScrollPosition();\n scrollDirection = SCROLL_STOP;\n }, 300);\n\n const onScroll = () => {\n syncViewportToScrollPosition();\n onScrollStopped();\n };\n\n ro = new ResizeObserver((entries) => {\n const resizes: [index: number, size: number][] = [];\n for (const entry of entries) {\n if (entry.target === root) {\n store._update({\n _type: UPDATE_VIEWPORT_SIZE,\n _width: entry.contentRect.width,\n _height: entry.contentRect.height,\n });\n } else {\n const index = mountedIndexes.get(entry.target);\n if (index != null) {\n resizes.push([\n index,\n entry.contentRect[isHorizontal ? \"width\" : \"height\"],\n ]);\n }\n }\n }\n\n if (resizes.length) {\n store._update({\n _type: UPDATE_ITEM_SIZES,\n _entries: resizes,\n });\n resized = true;\n }\n });\n\n ro.observe(root);\n root.addEventListener(\"scroll\", onScroll);\n\n return () => {\n ro.disconnect();\n root.removeEventListener(\"scroll\", onScroll);\n onScrollStopped._cancel();\n };\n },\n _observe(el, i) {\n mountedIndexes.set(el, i);\n ro.observe(el);\n return () => {\n mountedIndexes.delete(el);\n ro.unobserve(el);\n };\n },\n _getScrollDirection() {\n return scrollDirection;\n },\n _startManuallScroll() {\n scrollDirection = SCROLL_MANUAL;\n },\n };\n })());\n\n // The elements length and cached items length are different just after element is added/removed.\n const count = min(rawCount, store._getItemCount());\n\n const startIndexWithMargin = max(startIndex - overscan, 0);\n const endIndexWithMargin = min(endIndex + overscan, count - 1);\n\n // So update cache length. Updating state in render will cause warn so use useEffect for now.\n useIsomorphicLayoutEffect(() => {\n store._update({\n _type: UPDATE_CACHE_LENGTH,\n _length: rawCount,\n });\n }, [rawCount]);\n\n useIsomorphicLayoutEffect(() => handle._init(scrollRef.current!), []);\n\n useIsomorphicLayoutEffect(() => {\n if (!scrollRef.current || !jump.length) return;\n\n // Compensate scroll jump\n const scrollDirection = handle._getScrollDirection();\n if (scrollDirection === SCROLL_UP) {\n const diff = jump.reduce((acc, [, j]) => acc + j, 0);\n if (diff) {\n scrollRef.current[scrollToKey] += diff;\n }\n } else if (scrollDirection === SCROLL_MANUAL) {\n const isStartInView = startIndex === 0;\n const isEndInView = endIndex - (count - 1) === 0;\n const diff = jump.reduce((acc, [index, j]) => {\n if (index < startIndex) {\n // Keep start if scroll position is not stuck to the start\n if (!isStartInView) {\n acc += j;\n }\n } else {\n // Keep end if scroll position is stuck to the end\n if (!isStartInView && isEndInView) {\n acc += j;\n }\n }\n return acc;\n }, 0);\n if (diff) {\n scrollRef.current[scrollToKey] += diff;\n }\n } else {\n // NOP\n }\n }, [jump]);\n\n useEffect(() => {\n if (!onEndReached) return;\n\n if (onEndReachedCalledIndex.current > count) {\n // Probably items have been refreshed, so reset index\n onEndReachedCalledIndex.current = INITIAL_END_REACHED_INDEX;\n }\n\n const endMargin = count - 1 - endIndex;\n if (\n endMargin <= endThreshold &&\n onEndReachedCalledIndex.current < count\n ) {\n onEndReachedCalledIndex.current = count;\n onEndReached();\n }\n }, [endIndex]);\n\n useImperativeHandle(\n ref,\n () => ({\n scrollToIndex: async (index) => {\n const el = scrollRef.current;\n if (!el) return;\n\n index = max(min(index, count - 1), 0);\n\n const getScrollDestination = (): number => {\n let offset = store._getItemOffset(index);\n // Use element's scrollHeight/scrollWidth instead of stored scrollSize.\n // This is because stored size may differ from the actual size, for example when a new item is added and not yet measured.\n const scrollSize = isHorizontal ? el.scrollWidth : el.scrollHeight;\n const viewportSize = store._getViewportSize();\n if (scrollSize - (offset + viewportSize) <= 0) {\n // Adjust if the offset is over the end, to get correct startIndex.\n offset = scrollSize - viewportSize;\n }\n return offset;\n };\n\n if (store._hasUnmeasuredItemsInRange(index)) {\n do {\n // In order to scroll to the correct position, mount the items and measure their sizes before scrolling.\n store._update({\n _type: HANDLE_SCROLL,\n _offset: getScrollDestination(),\n });\n try {\n // Wait for the scroll destination items to be measured.\n await store._waitForScrollDestinationItemsMeasured();\n } catch (e) {\n // canceled\n return;\n }\n } while (store._hasUnmeasuredItemsInRange(index));\n\n // Scroll with the updated value\n el[scrollToKey] = getScrollDestination();\n } else {\n const offset = getScrollDestination();\n el[scrollToKey] = offset;\n // Sync viewport to scroll destination\n store._update({ _type: HANDLE_SCROLL, _offset: offset });\n }\n\n handle._startManuallScroll();\n },\n }),\n [count]\n );\n\n const items = useMemo(() => {\n let i = -1;\n return Children.map(children, (e) => {\n if (isInvalidElement(e)) {\n return;\n }\n i++;\n if (i < startIndexWithMargin || i > endIndexWithMargin) {\n return;\n }\n return e != null ? (\n <Item\n key={(e as { key?: ReactElement[\"key\"] })?.key || i}\n _handle={handle}\n _store={store}\n _index={i}\n _element={itemElement as \"div\"}\n _isHorizontal={isHorizontal}\n _children={e}\n />\n ) : null;\n });\n }, [children, startIndexWithMargin, endIndexWithMargin]);\n\n return (\n <Window\n _ref={scrollRef}\n _isHorizontal={isHorizontal}\n _element={element as \"div\"}\n _style={styleProp}\n _children={\n <Inner\n _store={store}\n _element={innerElement as \"div\"}\n _style={innerStyleProp}\n _isHorizontal={isHorizontal}\n _children={isViewportInitialized && items}\n />\n }\n />\n );\n }\n);\n","import { useRef } from \"react\";\nimport {\n findStartIndexWithOffset,\n resetCache,\n getItemSize,\n computeTotalSize,\n findEndIndex,\n computeStartOffset,\n Cache,\n UNCACHED,\n setItemSize,\n hasUnmeasuredItemsInRange,\n} from \"./cache\";\nimport type { Writeable } from \"./types\";\n\nexport const UPDATE_CACHE_LENGTH = 0;\nexport const UPDATE_ITEM_SIZES = 1;\nexport const UPDATE_VIEWPORT_SIZE = 2;\nexport const HANDLE_SCROLL = 3;\n\nexport type ScrollJump = Readonly<[index: number, sizeDiff: number][]>;\n\ntype State = {\n _startIndex: number;\n _viewportWidth: number;\n _viewportHeight: number;\n _cache: Cache;\n _jump: ScrollJump;\n};\n\ntype Actions =\n | { _type: typeof UPDATE_CACHE_LENGTH; _length: number }\n | {\n _type: typeof UPDATE_ITEM_SIZES;\n _entries: [index: number, size: number][];\n }\n | { _type: typeof UPDATE_VIEWPORT_SIZE; _width: number; _height: number }\n | { _type: typeof HANDLE_SCROLL; _offset: number };\n\nconst mutate = (state: State, action: Actions, itemSize: number): boolean => {\n switch (action._type) {\n case UPDATE_CACHE_LENGTH: {\n if (state._cache._length === action._length) return false;\n state._cache = resetCache(action._length, itemSize, state._cache);\n return true;\n }\n case UPDATE_ITEM_SIZES: {\n const updated = action._entries.filter(\n ([index, size]) => state._cache._sizes[index] !== size\n );\n // Skip if all items are cached and not updated\n if (!updated.length) {\n return false;\n }\n\n const jump: [index: number, sizeDiff: number][] = [];\n updated.forEach(([index, size]) => {\n jump.push([index, size - getItemSize(state._cache, index)]);\n setItemSize(state._cache as Writeable<Cache>, index, size);\n });\n state._jump = jump;\n return true;\n }\n case UPDATE_VIEWPORT_SIZE: {\n if (\n state._viewportWidth === action._width &&\n state._viewportHeight === action._height\n ) {\n return false;\n }\n state._viewportWidth = action._width;\n state._viewportHeight = action._height;\n return true;\n }\n case HANDLE_SCROLL: {\n const prevStartIndex = state._startIndex;\n const prevOffset = computeStartOffset(\n state._cache as Writeable<Cache>,\n prevStartIndex\n );\n if (prevOffset === action._offset) {\n return false;\n }\n return (\n (state._startIndex = findStartIndexWithOffset(\n state._cache,\n action._offset,\n prevStartIndex,\n prevOffset\n )) !== prevStartIndex\n );\n }\n }\n};\n\nexport type Store = {\n _getStartIndex(): number;\n _getEndIndex(): number;\n _isUnmeasuredItem(index: number): boolean;\n _hasUnmeasuredItemsInRange(startIndex: number): boolean;\n _getItemOffset(index: number): number;\n _getViewportSize(): number;\n _isViewportSizeInitialized(): boolean;\n _getScrollSize(): number;\n _getItemCount(): number;\n _getJump(): ScrollJump;\n _waitForScrollDestinationItemsMeasured(): Promise<void>;\n _subscribe(cb: () => void): () => void;\n _update(action: Actions): void;\n};\n\n// https://github.com/facebook/react/issues/25191#issuecomment-1237456448\nexport const useVirtualStore = (\n itemCount: number,\n itemSize: number,\n isHorizontal: boolean | undefined\n): Store => {\n const ref = useRef<Store | undefined>();\n return (\n ref.current ||\n (ref.current = (() => {\n const subscribers = new Set<() => void>();\n const state: Readonly<State> = {\n _startIndex: 0,\n _viewportWidth: 0,\n _viewportHeight: 0,\n _cache: resetCache(itemCount, itemSize),\n _jump: [],\n };\n const getViewportSize = (): number =>\n isHorizontal ? state._viewportWidth : state._viewportHeight;\n\n let scrollToQueue: [() => void, () => void] | undefined;\n\n return {\n _getStartIndex() {\n return state._startIndex;\n },\n _getEndIndex() {\n return findEndIndex(\n state._cache,\n state._startIndex,\n getViewportSize()\n );\n },\n _isUnmeasuredItem(index) {\n return state._cache._sizes[index] === UNCACHED;\n },\n _hasUnmeasuredItemsInRange(startIndex) {\n return hasUnmeasuredItemsInRange(\n state._cache,\n startIndex,\n findEndIndex(state._cache, startIndex, getViewportSize())\n );\n },\n _getItemOffset(index) {\n return computeStartOffset(state._cache as Writeable<Cache>, index);\n },\n _getViewportSize() {\n return getViewportSize();\n },\n _isViewportSizeInitialized() {\n return getViewportSize() !== 0;\n },\n _getScrollSize() {\n return computeTotalSize(state._cache as Writeable<Cache>);\n },\n _getItemCount() {\n return state._cache._length;\n },\n _getJump() {\n return state._jump;\n },\n _waitForScrollDestinationItemsMeasured() {\n if (scrollToQueue) {\n // Cancel waiting scrollTo\n scrollToQueue[1]();\n }\n // The measurement will be done asynchronously and the timing is not predictable so we use promise.\n // For example, ResizeObserver may not fire when window is not visible.\n return new Promise((resolve, reject) => {\n scrollToQueue = [\n () => {\n // HACK: It should be resolved in the next microtask that is after React's render\n Promise.resolve().then(() => {\n resolve();\n scrollToQueue = undefined;\n });\n },\n reject,\n ];\n });\n },\n _subscribe(cb) {\n subscribers.add(cb);\n return () => {\n subscribers.delete(cb);\n };\n },\n _update(action) {\n const mutated = mutate(state, action, itemSize);\n if (mutated) {\n subscribers.forEach((cb) => {\n cb();\n });\n if (scrollToQueue && action._type === UPDATE_ITEM_SIZES) {\n scrollToQueue[0]();\n }\n }\n },\n };\n })())\n );\n};\n"],"names":["min","Math","max","range","length","cb","Array","from","_","i","getItemSize","cache","index","size","_sizes","_defaultItemSize","findIndex","distance","sum","_length","h","findEndIndex","computeStartOffset","_measuredOffsetIndex","_offsets","top","resetCache","itemSize","_a","useIsomorphicLayoutEffect","window","useLayoutEffect","useEffect","useSyncExternalStore","subscibe","getSnapShot","_useSyncExternalStore","Item","memo","_children","children","_handle","handle","_store","store","_index","_element","Element","_isHorizontal","isHorizontal","ref","useRef","offset","_subscribe","_getItemOffset","hide","_isUnmeasuredItem","_observe","current","_jsx","style","useMemo","margin","padding","position","display","visibility","isInvalidElement","e","Window","_ref","_style","overflow","contain","width","height","Inner","scrollSize","_getScrollSize","viewportSize","_getViewportSize","clampedScrollSize","left","minWidth","minHeight","List","forwardRef","overscan","horizontal","endThreshold","styleProp","innerStyle","innerStyleProp","element","innerElement","itemElement","onEndReached","scrollToKey","rawCount","Children","forEach","useVirtualStore","itemCount","subscribers","Set","state","_startIndex","_viewportWidth","_viewportHeight","_cache","_jump","getViewportSize","scrollToQueue","_getStartIndex","_getEndIndex","_hasUnmeasuredItemsInRange","startIndex","hasUnmeasuredItemsInRange","endIndex","_isViewportSizeInitialized","lastIndex","computeTotalSize","_getItemCount","_getJump","_waitForScrollDestinationItemsMeasured","Promise","resolve","reject","then","undefined","add","delete","_update","action","mutate","_type","updated","_entries","filter","jump","push","setItemSize","_width","_height","prevStartIndex","prevOffset","_offset","findStartIndexWithOffset","isViewportInitialized","scrollRef","onEndReachedCalledIndex","handleRef","ro","scrollDirection","resized","mountedIndexes","WeakMap","_init","root","syncViewportToScrollPosition","onScrollStopped","debounce","id","cancel","clearTimeout","debouncedFn","setTimeout","_cancel","onScroll","ResizeObserver","entries","resizes","entry","target","contentRect","get","observe","addEventListener","disconnect","removeEventListener","el","set","unobserve","_getScrollDirection","_startManuallScroll","count","startIndexWithMargin","endIndexWithMargin","diff","reduce","acc","j","isStartInView","isEndInView","useImperativeHandle","scrollToIndex","async","getScrollDestination","scrollWidth","scrollHeight","items","map","jsx","key"],"mappings":"8IAAO,MAAMA,EAAMC,KAAKD,IACXE,EAAMD,KAAKC,IAGXC,EAAQA,CAAIC,EAAgBC,IACvCC,MAAMC,KAAK,CAAEH,WAAU,CAACI,EAAGC,IAAMJ,EAAGI,KCQzBC,EAAcA,CAACC,EAAcC,KACxC,MAAMC,EAAOF,EAAMG,EAAOF,GAC1B,OAZsB,IAYfC,EAAoBF,EAAMI,EAAmBF,CAAI,EA8BpDG,EAAYA,CAACL,EAAcF,EAAWQ,KAC1C,IAAIC,EAAM,EACV,GAAID,GAAY,EAEd,KAAOR,EAAIE,EAAMQ,EAAU,GAAG,CAC5B,MAAMC,EAAIV,EAAYC,EAAOF,GAG7B,GAFAS,GAAOE,EACPX,IACIS,GAAOD,EAAU,CACfC,EAAME,EAAI,GAAKH,GACjBR,IAEF,KACD,CACF,MAGD,KAAOA,EAAI,GAAG,CACZA,IACA,MAAMW,EAAIV,EAAYC,EAAOF,GAE7B,GADAS,GAAOE,EACHF,GAAOD,EAAU,CACfC,EAAME,EAAI,EAAIH,GAChBR,IAEF,KACD,CACF,CAGH,OAAOT,EAAIE,EAAIO,EAAG,GAAIE,EAAMQ,EAAU,EAAE,EAY7BE,EAAeL,EAefM,EAAqBA,CAChCX,EACAC,KAEA,IAAKD,EAAMQ,EAAS,OAAO,EAC3B,GAAIR,EAAMY,GAAwBX,EAChC,OAAOD,EAAMa,EAASZ,GAGxB,IAAIa,EAAMd,EAAMa,EAASb,EAAMY,GAC/B,IAAK,IAAId,EAAIE,EAAMY,EAAsBd,GAAKG,IAC5CD,EAAMa,EAASf,GAAKgB,EAChBhB,IAAMG,GAFyCH,IAKnDgB,GAAOf,EAAYC,EAAOF,GAG5B,OADAE,EAAMY,EAAuBX,EACtBa,CAAG,EAGCC,EAAaA,CACxBtB,EACAuB,EACAhB,WAEA,MAAO,CACLI,EAAkBY,EAClBR,EAASf,EACTmB,UACEK,EAACjB,GAASX,EAAIW,EAAMY,EAAsBnB,EAAS,kBAAO,EAC5DU,EAAQX,EAAMC,GAASK,IAAM,IAAAmB,EAAA,OAA8B,QAA9BA,EAACjB,GAASA,EAAMG,EAAOL,UAAO,IAAAmB,EAAAA,GAlIvC,CAkI+C,IACnEJ,EAAUrB,EAAMC,GAASK,UACvB,OAAM,IAANA,EACI,EAC4B,QAA5BmB,EAACjB,GAASA,EAAMa,EAASf,UAAG,IAAAmB,EAAAA,GAtId,CAsI0B,IAE/C,ECxIUC,EACO,oBAAXC,OAAyBC,EAAeA,gBAAGC,EAASA,UCFhDC,EAAuBA,CAClCC,EACAC,IAEOC,uBAAsBF,EAAUC,EAAaA,GC+ChDE,EAAOC,EAAIA,MACf,EACEC,EAAWC,EACXC,EAASC,EACTC,EAAQC,EACRC,EAAQjC,EACRkC,EAAUC,EACVC,EAAeC,MAEf,MAAMC,EAAMC,SAAuB,MAE7BC,EAASnB,EAAqBW,EAAMS,GAAY,IACpDT,EAAMU,EAAe1C,KAEjB2C,EAAOtB,EAAqBW,EAAMS,GAAY,IAClDT,EAAMY,EAAkB5C,KAS1B,OALAiB,GACE,IAAMa,EAAOe,EAASP,EAAIQ,QAAU9C,IACpC,CAACA,IAID+C,EAAAA,IAACZ,EAAO,CACNG,IAAKA,EACLU,MAAOC,EAAAA,SAAuB,KAC5B,MAAMD,EAAuB,CAC3BE,OAAQ,IACRC,QAAS,IACTC,SAAU,WACV,CAACf,EAAe,SAAW,SAAU,OACrC,CAACA,EAAe,MAAQ,QAAS,EACjC,CAACA,EAAe,OAAS,OAAQG,GASnC,OANIH,IACFW,EAAMK,QAAU,QAEdV,IACFK,EAAMM,WAAa,UAEdN,CAAK,GACX,CAACR,EAAQH,EAAcM,IAAMf,SAE/BA,GACO,IAKV2B,EAAwBC,GAAc,MAALA,GAA0B,kBAANA,EAErDC,EAASA,EACb9B,EAAWC,EACX8B,EAAMpB,EACNJ,EAAUC,EACVwB,EAAQX,EACRZ,EAAeC,KASbU,EAAAA,IAACZ,EAAO,CACNG,IAAKA,EACLU,MAAOC,EAAAA,SACL,KAAO,CACLW,SAAUvB,EAAe,cAAgB,cACzCe,SAAU,WACVS,QAAS,SAITC,MAAO,OACPC,OAAQ,OACRZ,QAAS,EACTD,OAAQ,KACLF,KAEL,CAACX,EAAcW,IAGhBpB,SAAAA,IAKDoC,EAAQA,EACZrC,EAAWC,EACXG,EAAQC,EACRE,EAAUC,EACVwB,EAAQX,EACRZ,EAAeC,MAQf,MAAM4B,EAAa5C,EACjBW,EAAMS,EACNT,EAAMkC,GAEFC,EAAe9C,EACnBW,EAAMS,EACNT,EAAMoC,GAGR,OACErB,MAACZ,EAAO,CACNa,MAAOC,EAAOA,SAAgB,KAC5B,MAAMoB,EACJJ,GAAcE,EAAeF,EAAaE,EACtCL,EAAQzB,EAAegC,EAAoB,OAC3CN,EAAS1B,EAAe,OAASgC,EACvC,MAAO,CACLjB,SAAU,WACVvC,IAAK,EACLyD,KAAM,EACNR,QACAC,SACAQ,SAAUT,EACVU,UAAWT,KACRf,EACJ,GACA,CAACiB,EAAYE,EAAcnB,EAAOX,IAAcT,SAElDA,GACO,EAqFD6C,EAAOC,EAAUA,YAC5B,EAEI9C,WACAb,WAAW,GACX4D,WAAW,EACXC,WAAYvC,EACZwC,eAAe,EACf7B,MAAO8B,EACPC,WAAYC,EACZC,UAAU,MACVC,eAAe,MACfC,cAAc,MACdC,gBAEF9C,KAEA,MAAM+C,EAAchD,EAAe,aAAe,YAE5CiD,EAAWrC,EAAAA,SAAQ,KACvB,IAAIpD,EAAI,EAOR,OANA0F,EAAAA,SAASC,QAAQ5D,GAAW4B,IACtBD,EAAiBC,IAGrB3D,GAAG,IAEEA,CAAC,GACP,CAAC+B,IAEEI,EC9LqByD,EAC7BC,EACA3E,EACAsB,KAEA,MAAMC,EAAMC,EAAAA,SACZ,OACED,EAAIQ,UACHR,EAAIQ,QAAU,MACb,MAAM6C,EAAc,IAAIC,IAClBC,EAAyB,CAC7BC,EAAa,EACbC,EAAgB,EAChBC,EAAiB,EACjBC,EAAQnF,EAAW4E,EAAW3E,GAC9BmF,EAAO,IAEHC,EAAkBA,IACtB9D,EAAewD,EAAME,EAAiBF,EAAMG,EAE9C,IAAII,EAEJ,MAAO,CACLC,EAAcA,IACLR,EAAMC,EAEfQ,EAAYA,IACH7F,EACLoF,EAAMI,EACNJ,EAAMC,EACNK,KAGJvD,EAAkB5C,IJ9IF,II+IP6F,EAAMI,EAAO/F,EAAOF,GAE7BuG,EAA2BC,GJ3DMC,EACvC1G,EACAyG,EACAE,KAEA,IAAK,IAAI7G,EAAI2G,EAAY3G,GAAK6G,EAAU7G,IACtC,IA5FoB,IA4FhBE,EAAMG,EAAOL,GACf,OAAO,EAGX,OAAO,CAAK,EIkDG4G,CACLZ,EAAMI,EACNO,EACA/F,EAAaoF,EAAMI,EAAQO,EAAYL,MAG3CzD,EAAe1C,GACNU,EAAmBmF,EAAMI,EAA4BjG,GAE9DoE,EAAgBA,IACP+B,IAETQ,EAA0BA,IACK,IAAtBR,IAETjC,EAAcA,IJxIWnE,KAC/B,IAAKA,EAAMQ,EAAS,OAAO,EAC3B,MAAMqG,EAAY7G,EAAMQ,EAAU,EAClC,GAAIR,EAAMY,GAAwBiG,EAChC,OAAO7G,EAAMa,EAASgG,GAAc9G,EAAYC,EAAO6G,GAGzD,IAAI/F,EAAMd,EAAMa,EAASb,EAAMY,GAC/B,IAAK,IAAId,EAAIE,EAAMY,EAAsBd,GAAK+G,EAAW/G,IACvDE,EAAMa,EAASf,GAAKgB,EACpBA,GAAOf,EAAYC,EAAOF,GAI5B,OADAE,EAAMY,EAAuBiG,EACtB/F,CAAG,EI2HKgG,CAAiBhB,EAAMI,GAEhCa,EAAaA,IACJjB,EAAMI,EAAO1F,EAEtBwG,EAAQA,IACClB,EAAMK,EAEfc,EAAsCA,KAChCZ,GAEFA,EAAc,KAIT,IAAIa,SAAQ,CAACC,EAASC,KAC3Bf,EAAgB,CACd,KAEEa,QAAQC,UAAUE,MAAK,KACrBF,IACAd,OAAgBiB,CAAS,GACzB,EAEJF,EACD,KAGL1E,EAAWhD,IACTkG,EAAY2B,IAAI7H,GACT,KACLkG,EAAY4B,OAAO9H,EAAG,GAG1B+H,EAAQC,GAhKDC,EAAC7B,EAAc4B,EAAiB1G,KAC7C,OAAQ0G,EAAOE,GACb,KA1B+B,EA2B7B,OAAI9B,EAAMI,EAAO1F,IAAYkH,EAAOlH,IACpCsF,EAAMI,EAASnF,EAAW2G,EAAOlH,EAASQ,EAAU8E,EAAMI,IACnD,GAET,KA9B6B,EA8BL,CACtB,MAAM2B,EAAUH,EAAOI,EAASC,QAC9B,EAAE9H,EAAOC,KAAU4F,EAAMI,EAAO/F,EAAOF,KAAWC,IAGpD,IAAK2H,EAAQpI,OACX,OAAO,EAGT,MAAMuI,EAA4C,GAMlD,OALAH,EAAQpC,SAAQ,EAAExF,EAAOC,MACvB8H,EAAKC,KAAK,CAAChI,EAAOC,EAAOH,EAAY+F,EAAMI,EAAQjG,KJvChCiI,EACzBlI,EACAC,EACAC,KAEAF,EAAMG,EAAOF,GAASC,EAEtBF,EAAMY,EAAuBvB,EAAIY,EAAOD,EAAMY,EAAqB,EIiC7DsH,CAAYpC,EAAMI,EAA4BjG,EAAOC,EAAK,IAE5D4F,EAAMK,EAAQ6B,GACP,CACR,CACD,KA9CgC,EA+C9B,OACElC,EAAME,IAAmB0B,EAAOS,GAChCrC,EAAMG,IAAoByB,EAAOU,KAInCtC,EAAME,EAAiB0B,EAAOS,EAC9BrC,EAAMG,EAAkByB,EAAOU,GACxB,GAET,KAxDyB,EAwDL,CAClB,MAAMC,EAAiBvC,EAAMC,EACvBuC,EAAa3H,EACjBmF,EAAMI,EACNmC,GAEF,OAAIC,IAAeZ,EAAOa,IAIvBzC,EAAMC,EJNyByC,EACtCxI,EACAyC,EACA4F,EACAC,IAEOjI,EAAUL,EAAOqI,EAAgB5F,EAAS6F,GIAtBE,CACnB1C,EAAMI,EACNwB,EAAOa,EACPF,EACAC,MACKD,CAEV,EAAA,EA6GqBV,CAAO7B,EAAO4B,EAAQ1G,KAEpC4E,EAAYH,SAAS/F,IACnBA,GAAI,IAEF2G,GA7LiB,IA6LAqB,EAAOE,GAC1BvB,EAAc,KAGnB,EAEJ,EA3Fc,GA2FV,ED2FSX,CAAgBH,EAAUvE,EAAUsB,GAC5CmE,EAAanF,EACjBW,EAAMS,EACNT,EAAMqE,GAEFK,EAAWrF,EAAqBW,EAAMS,EAAYT,EAAMsE,GACxDkC,EAAwBnH,EAC5BW,EAAMS,EACNT,EAAM2E,GAEFoB,EAAO1G,EAAqBW,EAAMS,EAAYT,EAAM+E,GACpD0B,EAAYlG,SAAuB,MACnCmG,EAA0BnG,UAvRF,GAyRxBoG,EAAYpG,EAAAA,SACZT,EACJ6G,EAAU7F,UACT6F,EAAU7F,QAAU,MACnB,IAAI8F,EACAP,GAAc,EACdQ,EAzSQ,EA0SRC,GAAU,EACd,MAAMC,EAAiB,IAAIC,QAE3B,MAAO,CACLC,EAAMC,GACJ,MAAMC,EAA+BA,KACnC,MAAM3G,EAAS0G,EAAK7D,GAChBgD,IAAe7F,IAjTb,IAsTFqG,GAAoCC,EAOtCA,GAAU,EA1TJ,IAqTFD,IACFA,EACER,EAAa7F,EAxTf,EADE,GA8TNR,EAAMwF,EAAQ,CACZG,ECvUa,EDwUbW,EAAUD,EAAa7F,IACvB,EAGE4G,EJvVMC,MAItB,IAAIC,EAA4B,KAEhC,MAAMC,EAASA,KACH,MAAND,GACFE,aAAaF,EACd,EAEGG,EAAcA,KAClBF,IACAD,EAAKI,YAAW,KACdJ,EAAK,KI2UGH,IACAN,EAxUM,CJHV,GI4UK,IJ3UL,EAGR,OADAY,EAAYE,GAAUJ,EACfE,CAAW,EIoUgBJ,GAMlBO,EAAWA,KACfT,IACAC,GAAiB,EAmCnB,OAhCAR,EAAK,IAAIiB,gBAAgBC,IACvB,MAAMC,EAA2C,GACjD,IAAK,MAAMC,KAASF,EAClB,GAAIE,EAAMC,SAAWf,EACnBlH,EAAMwF,EAAQ,CACZG,EC7VgB,ED8VhBO,EAAQ8B,EAAME,YAAYpG,MAC1BqE,EAAS6B,EAAME,YAAYnG,aAExB,CACL,MAAM/D,EAAQ+I,EAAeoB,IAAIH,EAAMC,QAC1B,MAATjK,GACF+J,EAAQ/B,KAAK,CACXhI,EACAgK,EAAME,YAAY7H,EAAe,QAAU,WAGhD,CAGC0H,EAAQvK,SACVwC,EAAMwF,EAAQ,CACZG,EC/We,EDgXfE,EAAUkC,IAEZjB,GAAU,EACX,IAGHF,EAAGwB,QAAQlB,GACXA,EAAKmB,iBAAiB,SAAUT,GAEzB,KACLhB,EAAG0B,aACHpB,EAAKqB,oBAAoB,SAAUX,GACnCR,EAAgBO,IAAS,CAE5B,EACD9G,EAAQA,CAAC2H,EAAI3K,KACXkJ,EAAe0B,IAAID,EAAI3K,GACvB+I,EAAGwB,QAAQI,GACJ,KACLzB,EAAexB,OAAOiD,GACtB5B,EAAG8B,UAAUF,EAAG,GAGpBG,GAAmBA,IACV9B,EAET+B,KACE/B,EA/XU,CAgYX,EAEJ,EA/FoB,IAkGjBgC,EAAQzL,EAAIkG,EAAUtD,EAAM8E,KAE5BgE,EAAuBxL,EAAIkH,EAAa7B,EAAU,GAClDoG,EAAqB3L,EAAIsH,EAAW/B,EAAUkG,EAAQ,GAG5D5J,GAA0B,KACxBe,EAAMwF,EAAQ,CACZG,EC1Z2B,ED2Z3BpH,EAAS+E,GACT,GACD,CAACA,IAEJrE,GAA0B,IAAMa,EAAOmH,EAAMR,EAAU3F,UAAW,IAElE7B,GAA0B,KACxB,IAAKwH,EAAU3F,UAAYiF,EAAKvI,OAAQ,OAGxC,MAAMqJ,EAAkB/G,EAAO6I,KAC/B,GA1ZY,IA0ZR9B,EAA+B,CACjC,MAAMmC,EAAOjD,EAAKkD,QAAO,CAACC,GAAQC,CAAAA,KAAOD,EAAMC,GAAG,GAC9CH,IACFvC,EAAU3F,QAAQuC,IAAgB2F,EAErC,MAAM,GA9ZS,IA8ZLnC,EAAmC,CAC5C,MAAMuC,EAA+B,IAAf5E,EAChB6E,EAAc3E,GAAYmE,EAAQ,IAAO,EACzCG,EAAOjD,EAAKkD,QAAO,CAACC,GAAMlL,EAAOmL,MACjCnL,EAAQwG,EAEL4E,IACHF,GAAOC,IAIJC,GAAiBC,IACpBH,GAAOC,GAGJD,IACN,GACCF,IACFvC,EAAU3F,QAAQuC,IAAgB2F,EAErC,CAAM,GAGN,CAACjD,IAEJ3G,EAAAA,WAAU,KACHgE,IAEDsD,EAAwB5F,QAAU+H,IAEpCnC,EAAwB5F,SArbE,GAwbV+H,EAAQ,EAAInE,GAEf7B,GACb6D,EAAwB5F,QAAU+H,IAElCnC,EAAwB5F,QAAU+H,EAClCzF,KACD,GACA,CAACsB,IAEJ4E,EAAmBA,oBACjBhJ,GACA,KAAO,CACLiJ,cAAeC,UACb,MAAMhB,EAAK/B,EAAU3F,QACrB,IAAK0H,EAAI,OAETxK,EAAQV,EAAIF,EAAIY,EAAO6K,EAAQ,GAAI,GAEnC,MAAMY,EAAuBA,KAC3B,IAAIjJ,EAASR,EAAMU,EAAe1C,GAGlC,MAAMiE,EAAa5B,EAAemI,EAAGkB,YAAclB,EAAGmB,aAChDxH,EAAenC,EAAMoC,IAK3B,OAJIH,GAAczB,EAAS2B,IAAiB,IAE1C3B,EAASyB,EAAaE,GAEjB3B,CAAM,EAGf,GAAIR,EAAMuE,EAA2BvG,GAAQ,CAC3C,EAAG,CAEDgC,EAAMwF,EAAQ,CACZG,EC7ea,ED8ebW,EAASmD,MAEX,UAEQzJ,EAAMgF,GACb,CAAC,MAAOxD,GAEP,MACD,CACF,OAAQxB,EAAMuE,EAA2BvG,IAG1CwK,EAAGnF,GAAeoG,GACnB,KAAM,CACL,MAAMjJ,EAASiJ,IACfjB,EAAGnF,GAAe7C,EAElBR,EAAMwF,EAAQ,CAAEG,EC/fC,ED+fqBW,EAAS9F,GAChD,CAEDV,EAAO8I,IAAqB,KAGhC,CAACC,IAGH,MAAMe,EAAQ3I,EAAAA,SAAQ,KACpB,IAAIpD,GAAK,EACT,OAAO0F,WAASsG,IAAIjK,GAAW4B,IAC7B,KAAID,EAAiBC,KAGrB3D,IACIA,EAAIiL,GAAwBjL,EAAIkL,IAGpC,OAAY,MAALvH,EACLT,EAAC+I,IAAArK,EAEC,CAAAI,EAASC,EACTC,EAAQC,EACRC,EAAQpC,EACRqC,EAAUiD,EACV/C,EAAeC,EACfV,EAAW6B,IANLA,eAAAA,EAAqCuI,MAAOlM,GAQlD,IAAI,GACR,GACD,CAAC+B,EAAUkJ,EAAsBC,IAEpC,OACEhI,MAACU,EAAM,CACLC,EAAM+E,EACNrG,EAAeC,EACfH,EAAU+C,EACVtB,EAAQmB,EACRnD,EACEoB,EAAAA,IAACiB,GACCjC,EAAQC,EACRE,EAAUgD,EACVvB,EAAQqB,EACR5C,EAAeC,EACfV,EAAW6G,GAAyBoD,KAGxC"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/src/utils.ts","../src/src/cache.ts","../src/src/useIsomorphicLayoutEffect.ts","../src/src/useSyncExternalStore.ts","../src/src/List.tsx","../src/src/state.ts"],"sourcesContent":["export const min = Math.min;\nexport const max = Math.max;\nexport const abs = Math.abs;\n\nexport const range = <T>(length: number, cb: (i: number) => T): T[] =>\n Array.from({ length }, (_, i) => cb(i));\n\nexport const debounce = <T extends (...args: any[]) => void>(\n fn: T,\n ms: number\n) => {\n let id: NodeJS.Timeout | null = null;\n\n const cancel = () => {\n if (id != null) {\n clearTimeout(id);\n }\n };\n const debouncedFn = () => {\n cancel();\n id = setTimeout(() => {\n id = null;\n fn();\n }, ms);\n };\n debouncedFn._cancel = cancel;\n return debouncedFn;\n};\n","import type { DeepReadonly, Writeable } from \"./types\";\nimport { max, min, range } from \"./utils\";\n\nexport const UNCACHED = -1;\n\nexport type Cache = DeepReadonly<{\n _defaultItemSize: number;\n _length: number;\n _sizes: number[];\n _measuredOffsetIndex: number;\n _offsets: number[];\n}>;\n\nexport const getItemSize = (cache: Cache, index: number): number => {\n const size = cache._sizes[index]!;\n return size === UNCACHED ? cache._defaultItemSize : size;\n};\n\nexport const setItemSize = (\n cache: Writeable<Cache>,\n index: number,\n size: number\n) => {\n cache._sizes[index] = size;\n // mark as dirty\n cache._measuredOffsetIndex = min(index, cache._measuredOffsetIndex);\n};\n\nexport const computeTotalSize = (cache: Writeable<Cache>): number => {\n if (!cache._length) return 0;\n const lastIndex = cache._length - 1;\n if (cache._measuredOffsetIndex >= lastIndex) {\n return cache._offsets[lastIndex]! + getItemSize(cache, lastIndex);\n }\n\n let top = cache._offsets[cache._measuredOffsetIndex]!;\n for (let i = cache._measuredOffsetIndex; i <= lastIndex; i++) {\n cache._offsets[i] = top;\n top += getItemSize(cache, i);\n }\n\n cache._measuredOffsetIndex = lastIndex;\n return top;\n};\n\nconst findIndex = (cache: Cache, i: number, distance: number): number => {\n let sum = 0;\n if (distance >= 0) {\n // search forward\n while (i < cache._length - 1) {\n const h = getItemSize(cache, i);\n sum += h;\n i++;\n if (sum >= distance) {\n if (sum - h / 2 >= distance) {\n i--;\n }\n break;\n }\n }\n } else {\n // search backward\n while (i > 0) {\n i--;\n const h = getItemSize(cache, i);\n sum -= h;\n if (sum <= distance) {\n if (sum + h / 2 < distance) {\n i++;\n }\n break;\n }\n }\n }\n\n return min(max(i, 0), cache._length - 1);\n};\n\nexport const findStartIndexWithOffset = (\n cache: Cache,\n offset: number,\n prevStartIndex: number,\n prevOffset: number\n): number => {\n return findIndex(cache, prevStartIndex, offset - prevOffset);\n};\n\nexport const findEndIndex = findIndex;\n\nexport const hasUnmeasuredItemsInRange = (\n cache: Cache,\n startIndex: number,\n endIndex: number\n): boolean => {\n for (let i = startIndex; i <= endIndex; i++) {\n if (cache._sizes[i] === UNCACHED) {\n return true;\n }\n }\n return false;\n};\n\nexport const computeStartOffset = (\n cache: Writeable<Cache>,\n index: number\n): number => {\n if (!cache._length) return 0;\n if (cache._measuredOffsetIndex >= index) {\n return cache._offsets[index]!;\n }\n\n let top = cache._offsets[cache._measuredOffsetIndex]!;\n for (let i = cache._measuredOffsetIndex; i <= index; i++) {\n cache._offsets[i] = top;\n if (i === index) {\n break;\n }\n top += getItemSize(cache, i);\n }\n cache._measuredOffsetIndex = index;\n return top;\n};\n\nexport const resetCache = (\n length: number,\n itemSize: number,\n cache?: Cache\n): Cache => {\n return {\n _defaultItemSize: itemSize,\n _length: length,\n _measuredOffsetIndex:\n (cache && min(cache._measuredOffsetIndex, length - 1)) ?? 0,\n _sizes: range(length, (i) => (cache && cache._sizes[i]) ?? UNCACHED),\n _offsets: range(length, (i) =>\n i === 0\n ? 0 // first offset must be 0\n : (cache && cache._offsets[i]) ?? UNCACHED\n ),\n };\n};\n","import { useEffect, useLayoutEffect } from \"react\";\n\n// https://gist.github.com/gaearon/e7d97cdf38a2907924ea12e4ebdf3c85\nexport const useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n","import { useSyncExternalStore as _useSyncExternalStore } from \"use-sync-external-store/shim\";\n\nexport const useSyncExternalStore = <T>(\n subscibe: (onStoreChange: () => void) => () => void,\n getSnapShot: () => T\n): T => {\n return _useSyncExternalStore(subscibe, getSnapShot, getSnapShot);\n};\n","import {\n Children,\n memo,\n useRef,\n useMemo,\n CSSProperties,\n ReactElement,\n forwardRef,\n useImperativeHandle,\n ReactNode,\n useEffect,\n RefObject,\n} from \"react\";\nimport {\n HANDLE_SCROLL,\n UPDATE_CACHE_LENGTH,\n Store,\n UPDATE_ITEM_SIZES,\n UPDATE_VIEWPORT_SIZE,\n useVirtualStore,\n} from \"./state\";\nimport { useIsomorphicLayoutEffect } from \"./useIsomorphicLayoutEffect\";\nimport { useSyncExternalStore } from \"./useSyncExternalStore\";\nimport { abs, debounce, max, min } from \"./utils\";\n\nconst SCROLL_STOP = 0;\nconst SCROLL_DOWN = 1;\nconst SCROLL_UP = 2;\nconst SCROLL_MANUAL = 3;\ntype ScrollDirection =\n | typeof SCROLL_STOP\n | typeof SCROLL_DOWN\n | typeof SCROLL_UP\n | typeof SCROLL_MANUAL;\n\nconst INITIAL_END_REACHED_INDEX = -1;\n\ntype ObserverHandle = {\n _initRoot: (rootElement: HTMLElement) => () => void;\n _initItem: (itemElement: HTMLElement, index: number) => () => void;\n _getScrollDirection: () => ScrollDirection;\n _updateScrollPosition: (offset: number, diff?: boolean) => void;\n};\n\ntype ItemProps = {\n _children: ReactNode;\n _handle: ObserverHandle;\n _store: Store;\n _index: number;\n _element: \"div\";\n _isHorizontal: boolean | undefined;\n _isRtl: boolean | undefined;\n};\n\nconst Item = memo(\n ({\n _children: children,\n _handle: handle,\n _store: store,\n _index: index,\n _element: Element,\n _isHorizontal: isHorizontal,\n _isRtl: isRtl,\n }: ItemProps): ReactElement => {\n const ref = useRef<HTMLDivElement>(null);\n\n const offset = useSyncExternalStore(store._subscribe, () =>\n store._getItemOffset(index)\n );\n const hide = useSyncExternalStore(store._subscribe, () =>\n store._isUnmeasuredItem(index)\n );\n\n // The index may be changed if elements are inserted to or removed from the start of props.children\n useIsomorphicLayoutEffect(\n () => handle._initItem(ref.current!, index),\n [index]\n );\n\n return (\n <Element\n ref={ref}\n style={useMemo<CSSProperties>(() => {\n const style: CSSProperties = {\n margin: \"0\",\n padding: \"0\",\n position: \"absolute\",\n [isHorizontal ? \"height\" : \"width\"]: \"100%\",\n [isHorizontal ? \"top\" : isRtl ? \"right\" : \"left\"]: 0,\n [isHorizontal ? (isRtl ? \"right\" : \"left\") : \"top\"]: offset,\n // willChange: \"transform\",\n };\n if (isHorizontal) {\n style.display = \"flex\";\n }\n if (hide) {\n style.visibility = \"hidden\";\n }\n return style;\n }, [offset, isHorizontal, isRtl, hide])}\n >\n {children}\n </Element>\n );\n }\n);\n\nconst isInvalidElement = <T,>(e: T) => e == null || typeof e === \"boolean\";\n\nconst Window = ({\n _children: children,\n _ref: ref,\n _element: Element,\n _style: style,\n _isHorizontal: isHorizontal,\n}: {\n _children: ReactNode;\n _ref: RefObject<HTMLDivElement>;\n _element: \"div\";\n _style: CSSProperties | undefined;\n _isHorizontal: boolean | undefined;\n}) => {\n return (\n <Element\n ref={ref}\n style={useMemo<CSSProperties>(\n () => ({\n overflow: isHorizontal ? \"auto hidden\" : \"hidden auto\",\n position: \"relative\",\n contain: \"strict\",\n // transform: \"translate3d(0px, 0px, 0px)\",\n // willChange: \"scroll-position\",\n // backfaceVisibility: \"hidden\",\n width: \"100%\",\n height: \"100%\",\n padding: 0,\n margin: 0,\n ...style,\n }),\n [isHorizontal, style]\n )}\n >\n {children}\n </Element>\n );\n};\n\nconst Inner = ({\n _children: children,\n _store: store,\n _element: Element,\n _style: style,\n _isHorizontal: isHorizontal,\n _isRtl: isRtl,\n}: {\n _children: ReactNode;\n _store: Store;\n _element: \"div\";\n _style: CSSProperties | undefined;\n _isHorizontal: boolean | undefined;\n _isRtl: boolean | undefined;\n}) => {\n const scrollSize = useSyncExternalStore(\n store._subscribe,\n store._getScrollSize\n );\n const viewportSize = useSyncExternalStore(\n store._subscribe,\n store._getViewportSize\n );\n\n return (\n <Element\n style={useMemo<CSSProperties>(() => {\n const clampedScrollSize =\n scrollSize >= viewportSize ? scrollSize : viewportSize;\n const width = isHorizontal ? clampedScrollSize : \"100%\";\n const height = isHorizontal ? \"100%\" : clampedScrollSize;\n return {\n position: \"absolute\",\n top: 0,\n [isRtl ? \"right\" : \"left\"]: 0,\n width,\n height,\n minWidth: width,\n minHeight: height,\n ...style,\n };\n }, [scrollSize, viewportSize, style, isHorizontal, isRtl])}\n >\n {children}\n </Element>\n );\n};\n\nexport interface CustomComponentProps {\n style: CSSProperties;\n children: ReactNode;\n}\n\nexport type CustomComponent = React.ForwardRefExoticComponent<\n React.PropsWithoutRef<CustomComponentProps> & React.RefAttributes<any>\n>;\n\ntype CustomElementType = keyof JSX.IntrinsicElements | CustomComponent;\n\n/**\n * Methods of {@link List}.\n */\nexport interface ListHandle {\n /**\n * Scroll to the item specified by index.\n * @param index index of item\n */\n scrollToIndex(index: number): void;\n}\n\n/**\n * Props of {@link List}.\n */\nexport interface ListProps {\n /**\n * Elements rendered by this component.\n */\n children: ReactNode;\n /**\n * Item size hint for unmeasured items. It's recommended to specify this prop if item sizes are fixed and known, or much larger than the defaultValue. It will help to reduce scroll jump when items are measured.\n * @defaultValue 40\n */\n itemSize?: number;\n /**\n * Number of items to render above/below the visible bounds of the list. You can increase to avoid showing blank items in fast scrolling.\n * @defaultValue 6\n */\n overscan?: number;\n /**\n * If true, rendered as a horizontally scrollable list. Otherwise rendered as a vertically scrollable list.\n */\n horizontal?: boolean;\n /**\n * You have to set true if you use this component under `direction: rtl` style.\n */\n rtl?: boolean;\n /**\n * Number of items to be the margin from the end of the scroll. See also {@link onEndReached}.\n * @defaultValue 0\n */\n endThreshold?: number;\n /**\n * Inline style prop to override style of scrollable element.\n */\n style?: CSSProperties;\n /**\n * Inline style prop to override style of inner element.\n */\n innerStyle?: CSSProperties;\n /**\n * Customized element type for scrollable element.\n * @defaultValue \"div\"\n */\n element?: CustomElementType;\n /**\n * Customized element type for inner element.\n * @defaultValue \"div\"\n */\n innerElement?: CustomElementType;\n /**\n * Customized element type for item element.\n * @defaultValue \"div\"\n */\n itemElement?: CustomElementType;\n /**\n * Callback invoked when scrolling reached to the end. The margin from the end is specified by {@link endThreshold}.\n */\n onEndReached?: () => void;\n}\n\n/**\n * Virtualized list component. See {@link ListProps} and {@link ListHandle}.\n */\nexport const List = forwardRef<ListHandle, ListProps>(\n (\n {\n children,\n itemSize = 40,\n overscan = 6,\n horizontal: isHorizontal,\n rtl: isRtl,\n endThreshold = 0,\n style: styleProp,\n innerStyle: innerStyleProp,\n element = \"div\",\n innerElement = \"div\",\n itemElement = \"div\",\n onEndReached,\n },\n ref\n ): ReactElement => {\n // memoize element count\n const rawCount = useMemo(() => {\n let i = 0;\n Children.forEach(children, (e) => {\n if (isInvalidElement(e)) {\n return;\n }\n i++;\n });\n return i;\n }, [children]);\n\n const store = useVirtualStore(rawCount, itemSize, isHorizontal);\n const startIndex = useSyncExternalStore(\n store._subscribe,\n store._getStartIndex\n );\n const endIndex = useSyncExternalStore(store._subscribe, store._getEndIndex);\n const jump = useSyncExternalStore(store._subscribe, store._getJump);\n const scrollRef = useRef<HTMLDivElement>(null);\n const onEndReachedCalledIndex = useRef<number>(INITIAL_END_REACHED_INDEX);\n\n const handleRef = useRef<ObserverHandle>();\n const handle =\n handleRef.current ||\n (handleRef.current = ((): ObserverHandle => {\n // For SSR\n if (typeof ResizeObserver === \"undefined\") {\n return {} as any as ObserverHandle;\n }\n let prevOffset = -1;\n let scrollDirection: ScrollDirection = SCROLL_STOP;\n let resized = false;\n let isNegativeOffset: boolean | undefined;\n let rootElement: HTMLElement | undefined;\n const scrollToKey = isHorizontal ? \"scrollLeft\" : \"scrollTop\";\n const mountedIndexes = new WeakMap<Element, number>();\n const ro = new ResizeObserver((entries) => {\n const resizes: [index: number, size: number][] = [];\n for (const entry of entries) {\n if (entry.target === rootElement) {\n store._update({\n _type: UPDATE_VIEWPORT_SIZE,\n _width: entry.contentRect.width,\n _height: entry.contentRect.height,\n });\n } else {\n const index = mountedIndexes.get(entry.target);\n if (index != null) {\n resizes.push([\n index,\n entry.contentRect[isHorizontal ? \"width\" : \"height\"],\n ]);\n }\n }\n }\n\n if (resizes.length) {\n store._update({\n _type: UPDATE_ITEM_SIZES,\n _entries: resizes,\n });\n resized = true;\n }\n });\n\n return {\n _initRoot(root) {\n rootElement = root;\n\n const syncViewportToScrollPosition = () => {\n let offset = root[scrollToKey];\n if (isRtl) {\n // The scroll position may be negative value in rtl direction.\n // https://github.com/othree/jquery.rtl-scroll-type\n offset = abs(offset);\n }\n if (prevOffset === offset) {\n return;\n }\n // Skip scroll direction detection just after resizing because it may result in the opposite direction.\n // Scroll events are dispatched enough so it's ok to skip some of them.\n if (scrollDirection === SCROLL_STOP || !resized) {\n // Ignore until manual scrolling\n if (scrollDirection !== SCROLL_MANUAL) {\n scrollDirection =\n prevOffset > offset ? SCROLL_UP : SCROLL_DOWN;\n }\n } else {\n resized = false;\n }\n store._update({\n _type: HANDLE_SCROLL,\n _offset: (prevOffset = offset),\n });\n };\n\n const onScrollStopped = debounce(() => {\n // Check scroll position once just after scrolling stopped\n syncViewportToScrollPosition();\n scrollDirection = SCROLL_STOP;\n }, 300);\n\n const onScroll = () => {\n syncViewportToScrollPosition();\n onScrollStopped();\n };\n\n ro.observe(root);\n root.addEventListener(\"scroll\", onScroll);\n\n return () => {\n ro.disconnect();\n root.removeEventListener(\"scroll\", onScroll);\n onScrollStopped._cancel();\n };\n },\n _initItem(el, i) {\n mountedIndexes.set(el, i);\n ro.observe(el);\n return () => {\n mountedIndexes.delete(el);\n ro.unobserve(el);\n };\n },\n _getScrollDirection() {\n return scrollDirection;\n },\n _updateScrollPosition(offset, diff) {\n if (!rootElement) return;\n if (isRtl) {\n if (isNegativeOffset == null) {\n // Assume offset type in rtl direction.\n // The scroll position is negative in spec however its not in some browsers, for example Chrome earlier than v85.\n // https://github.com/othree/jquery.rtl-scroll-type\n const prev = rootElement[scrollToKey];\n rootElement[scrollToKey] = 1;\n isNegativeOffset = rootElement[scrollToKey] === 0;\n rootElement[scrollToKey] = prev;\n }\n if (isNegativeOffset) {\n offset *= -1;\n }\n }\n if (diff) {\n rootElement[scrollToKey] += offset;\n } else {\n rootElement[scrollToKey] = offset;\n scrollDirection = SCROLL_MANUAL;\n }\n },\n };\n })());\n\n // The elements length and cached items length are different just after element is added/removed.\n const count = min(rawCount, store._getItemCount());\n\n const startIndexWithMargin = max(startIndex - overscan, 0);\n const endIndexWithMargin = min(endIndex + overscan, count - 1);\n\n // So update cache length. Updating state in render will cause warn so use useEffect for now.\n useIsomorphicLayoutEffect(() => {\n store._update({\n _type: UPDATE_CACHE_LENGTH,\n _length: rawCount,\n });\n }, [rawCount]);\n\n useIsomorphicLayoutEffect(() => handle._initRoot(scrollRef.current!), []);\n\n useIsomorphicLayoutEffect(() => {\n if (!jump.length) return;\n\n // Compensate scroll jump\n const scrollDirection = handle._getScrollDirection();\n if (scrollDirection === SCROLL_UP) {\n const diff = jump.reduce((acc, [, j]) => acc + j, 0);\n if (diff) {\n handle._updateScrollPosition(diff, true);\n }\n } else if (scrollDirection === SCROLL_MANUAL) {\n const isStartInView = startIndex === 0;\n const isEndInView = endIndex - (count - 1) === 0;\n const diff = jump.reduce((acc, [index, j]) => {\n if (index < startIndex) {\n // Keep start if scroll position is not stuck to the start\n if (!isStartInView) {\n acc += j;\n }\n } else {\n // Keep end if scroll position is stuck to the end\n if (!isStartInView && isEndInView) {\n acc += j;\n }\n }\n return acc;\n }, 0);\n if (diff) {\n handle._updateScrollPosition(diff, true);\n }\n } else {\n // NOP\n }\n }, [jump]);\n\n useEffect(() => {\n if (!onEndReached) return;\n\n if (onEndReachedCalledIndex.current > count) {\n // Probably items have been refreshed, so reset index\n onEndReachedCalledIndex.current = INITIAL_END_REACHED_INDEX;\n }\n\n const endMargin = count - 1 - endIndex;\n if (\n endMargin <= endThreshold &&\n onEndReachedCalledIndex.current < count\n ) {\n onEndReachedCalledIndex.current = count;\n onEndReached();\n }\n }, [endIndex]);\n\n useImperativeHandle(\n ref,\n () => ({\n scrollToIndex: async (index) => {\n const el = scrollRef.current;\n if (!el) return;\n\n index = max(min(index, count - 1), 0);\n\n const getOffset = (): number => {\n let offset = store._getItemOffset(index);\n // Use element's scrollHeight/scrollWidth instead of stored scrollSize.\n // This is because stored size may differ from the actual size, for example when a new item is added and not yet measured.\n const scrollSize = isHorizontal ? el.scrollWidth : el.scrollHeight;\n const viewportSize = store._getViewportSize();\n if (scrollSize - (offset + viewportSize) <= 0) {\n // Adjust if the offset is over the end, to get correct startIndex.\n offset = scrollSize - viewportSize;\n }\n return offset;\n };\n\n if (store._hasUnmeasuredItemsInRange(index)) {\n do {\n // In order to scroll to the correct position, mount the items and measure their sizes before scrolling.\n store._update({\n _type: HANDLE_SCROLL,\n _offset: getOffset(),\n });\n try {\n // Wait for the scroll destination items to be measured.\n await store._waitForScrollDestinationItemsMeasured();\n } catch (e) {\n // canceled\n return;\n }\n } while (store._hasUnmeasuredItemsInRange(index));\n\n // Scroll with the updated value\n handle._updateScrollPosition(getOffset());\n } else {\n const offset = getOffset();\n handle._updateScrollPosition(offset);\n // Sync viewport to scroll destination\n store._update({ _type: HANDLE_SCROLL, _offset: offset });\n }\n },\n }),\n [count]\n );\n\n const items = useMemo(() => {\n let i = -1;\n return Children.map(children, (e) => {\n if (isInvalidElement(e)) {\n return;\n }\n i++;\n if (i < startIndexWithMargin || i > endIndexWithMargin) {\n return;\n }\n return e != null ? (\n <Item\n key={(e as { key?: ReactElement[\"key\"] })?.key || i}\n _handle={handle}\n _store={store}\n _index={i}\n _element={itemElement as \"div\"}\n _isHorizontal={isHorizontal}\n _isRtl={isRtl}\n _children={e}\n />\n ) : null;\n });\n }, [children, startIndexWithMargin, endIndexWithMargin]);\n\n return (\n <Window\n _ref={scrollRef}\n _isHorizontal={isHorizontal}\n _element={element as \"div\"}\n _style={styleProp}\n _children={\n <Inner\n _store={store}\n _element={innerElement as \"div\"}\n _style={innerStyleProp}\n _isHorizontal={isHorizontal}\n _isRtl={isRtl}\n _children={items}\n />\n }\n />\n );\n }\n);\n","import { useRef } from \"react\";\nimport {\n findStartIndexWithOffset,\n resetCache,\n getItemSize,\n computeTotalSize,\n findEndIndex,\n computeStartOffset,\n Cache,\n UNCACHED,\n setItemSize,\n hasUnmeasuredItemsInRange,\n} from \"./cache\";\nimport type { Writeable } from \"./types\";\n\nexport const UPDATE_CACHE_LENGTH = 0;\nexport const UPDATE_ITEM_SIZES = 1;\nexport const UPDATE_VIEWPORT_SIZE = 2;\nexport const HANDLE_SCROLL = 3;\n\nexport type ScrollJump = Readonly<[index: number, sizeDiff: number][]>;\n\ntype State = {\n _startIndex: number;\n _viewportWidth: number;\n _viewportHeight: number;\n _cache: Cache;\n _jump: ScrollJump;\n};\n\ntype Actions =\n | { _type: typeof UPDATE_CACHE_LENGTH; _length: number }\n | {\n _type: typeof UPDATE_ITEM_SIZES;\n _entries: [index: number, size: number][];\n }\n | { _type: typeof UPDATE_VIEWPORT_SIZE; _width: number; _height: number }\n | { _type: typeof HANDLE_SCROLL; _offset: number };\n\nconst mutate = (state: State, action: Actions, itemSize: number): boolean => {\n switch (action._type) {\n case UPDATE_CACHE_LENGTH: {\n if (state._cache._length === action._length) return false;\n state._cache = resetCache(action._length, itemSize, state._cache);\n return true;\n }\n case UPDATE_ITEM_SIZES: {\n const updated = action._entries.filter(\n ([index, size]) => state._cache._sizes[index] !== size\n );\n // Skip if all items are cached and not updated\n if (!updated.length) {\n return false;\n }\n\n const jump: [index: number, sizeDiff: number][] = [];\n updated.forEach(([index, size]) => {\n jump.push([index, size - getItemSize(state._cache, index)]);\n setItemSize(state._cache as Writeable<Cache>, index, size);\n });\n state._jump = jump;\n return true;\n }\n case UPDATE_VIEWPORT_SIZE: {\n if (\n state._viewportWidth === action._width &&\n state._viewportHeight === action._height\n ) {\n return false;\n }\n state._viewportWidth = action._width;\n state._viewportHeight = action._height;\n return true;\n }\n case HANDLE_SCROLL: {\n const prevStartIndex = state._startIndex;\n const prevOffset = computeStartOffset(\n state._cache as Writeable<Cache>,\n prevStartIndex\n );\n if (prevOffset === action._offset) {\n return false;\n }\n return (\n (state._startIndex = findStartIndexWithOffset(\n state._cache,\n action._offset,\n prevStartIndex,\n prevOffset\n )) !== prevStartIndex\n );\n }\n }\n};\n\nexport type Store = {\n _getStartIndex(): number;\n _getEndIndex(): number;\n _isUnmeasuredItem(index: number): boolean;\n _hasUnmeasuredItemsInRange(startIndex: number): boolean;\n _getItemOffset(index: number): number;\n _getViewportSize(): number;\n _getScrollSize(): number;\n _getItemCount(): number;\n _getJump(): ScrollJump;\n _waitForScrollDestinationItemsMeasured(): Promise<void>;\n _subscribe(cb: () => void): () => void;\n _update(action: Actions): void;\n};\n\n// https://github.com/facebook/react/issues/25191#issuecomment-1237456448\nexport const useVirtualStore = (\n itemCount: number,\n itemSize: number,\n isHorizontal: boolean | undefined\n): Store => {\n const ref = useRef<Store | undefined>();\n return (\n ref.current ||\n (ref.current = (() => {\n const subscribers = new Set<() => void>();\n const state: Readonly<State> = {\n _startIndex: 0,\n _viewportWidth: 0,\n _viewportHeight: 0,\n _cache: resetCache(itemCount, itemSize),\n _jump: [],\n };\n const getViewportSize = (): number =>\n isHorizontal ? state._viewportWidth : state._viewportHeight;\n\n let scrollToQueue: [() => void, () => void] | undefined;\n\n return {\n _getStartIndex() {\n return state._startIndex;\n },\n _getEndIndex() {\n return findEndIndex(\n state._cache,\n state._startIndex,\n getViewportSize()\n );\n },\n _isUnmeasuredItem(index) {\n return state._cache._sizes[index] === UNCACHED;\n },\n _hasUnmeasuredItemsInRange(startIndex) {\n return hasUnmeasuredItemsInRange(\n state._cache,\n startIndex,\n findEndIndex(state._cache, startIndex, getViewportSize())\n );\n },\n _getItemOffset(index) {\n return computeStartOffset(state._cache as Writeable<Cache>, index);\n },\n _getViewportSize() {\n return getViewportSize();\n },\n _getScrollSize() {\n return computeTotalSize(state._cache as Writeable<Cache>);\n },\n _getItemCount() {\n return state._cache._length;\n },\n _getJump() {\n return state._jump;\n },\n _waitForScrollDestinationItemsMeasured() {\n if (scrollToQueue) {\n // Cancel waiting scrollTo\n scrollToQueue[1]();\n }\n // The measurement will be done asynchronously and the timing is not predictable so we use promise.\n // For example, ResizeObserver may not fire when window is not visible.\n return new Promise((resolve, reject) => {\n scrollToQueue = [\n () => {\n // HACK: It should be resolved in the next microtask that is after React's render\n Promise.resolve().then(() => {\n resolve();\n scrollToQueue = undefined;\n });\n },\n reject,\n ];\n });\n },\n _subscribe(cb) {\n subscribers.add(cb);\n return () => {\n subscribers.delete(cb);\n };\n },\n _update(action) {\n const mutated = mutate(state, action, itemSize);\n if (mutated) {\n subscribers.forEach((cb) => {\n cb();\n });\n if (scrollToQueue && action._type === UPDATE_ITEM_SIZES) {\n scrollToQueue[0]();\n }\n }\n },\n };\n })())\n );\n};\n"],"names":["min","Math","max","abs","range","length","cb","Array","from","_","i","getItemSize","cache","index","size","_sizes","_defaultItemSize","findIndex","distance","sum","_length","h","findEndIndex","computeStartOffset","_measuredOffsetIndex","_offsets","top","resetCache","itemSize","_a","useIsomorphicLayoutEffect","window","useLayoutEffect","useEffect","useSyncExternalStore","subscibe","getSnapShot","_useSyncExternalStore","Item","memo","_children","children","_handle","handle","_store","store","_index","_element","Element","_isHorizontal","isHorizontal","_isRtl","isRtl","ref","useRef","offset","_subscribe","_getItemOffset","hide","_isUnmeasuredItem","_initItem","current","_jsx","style","useMemo","margin","padding","position","display","visibility","isInvalidElement","e","Window","_ref","_style","overflow","contain","width","height","Inner","scrollSize","_getScrollSize","viewportSize","_getViewportSize","clampedScrollSize","minWidth","minHeight","List","forwardRef","overscan","horizontal","rtl","endThreshold","styleProp","innerStyle","innerStyleProp","element","innerElement","itemElement","onEndReached","rawCount","Children","forEach","useVirtualStore","itemCount","subscribers","Set","state","_startIndex","_viewportWidth","_viewportHeight","_cache","_jump","getViewportSize","scrollToQueue","_getStartIndex","_getEndIndex","_hasUnmeasuredItemsInRange","startIndex","hasUnmeasuredItemsInRange","endIndex","lastIndex","computeTotalSize","_getItemCount","_getJump","_waitForScrollDestinationItemsMeasured","Promise","resolve","reject","then","undefined","add","delete","_update","action","mutate","_type","updated","_entries","filter","jump","push","setItemSize","_width","_height","prevStartIndex","prevOffset","_offset","findStartIndexWithOffset","scrollRef","onEndReachedCalledIndex","handleRef","ResizeObserver","isNegativeOffset","rootElement","scrollDirection","resized","scrollToKey","mountedIndexes","WeakMap","ro","entries","resizes","entry","target","contentRect","get","_initRoot","root","syncViewportToScrollPosition","onScrollStopped","debounce","id","cancel","clearTimeout","debouncedFn","setTimeout","_cancel","onScroll","observe","addEventListener","disconnect","removeEventListener","el","set","unobserve","_getScrollDirection","_updateScrollPosition","diff","prev","count","startIndexWithMargin","endIndexWithMargin","reduce","acc","j","isStartInView","isEndInView","useImperativeHandle","scrollToIndex","async","getOffset","scrollWidth","scrollHeight","items","map","key","jsx"],"mappings":"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"}
|
package/lib/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as e}from"react/jsx-runtime";import{useRef as t,useLayoutEffect as n,useEffect as r,memo as i,useMemo as o,forwardRef as l,Children as s,useImperativeHandle as _}from"react";import{useSyncExternalStore as
|
|
1
|
+
import{jsx as e}from"react/jsx-runtime";import{useRef as t,useLayoutEffect as n,useEffect as r,memo as i,useMemo as o,forwardRef as l,Children as s,useImperativeHandle as _}from"react";import{useSyncExternalStore as u}from"use-sync-external-store/shim/index.js";const c=Math.min,d=Math.max,a=Math.abs,f=(e,t)=>Array.from({length:e},((e,n)=>t(n))),h=(e,t)=>{const n=e.t[t];return-1===n?e.i:n},m=(e,t,n)=>{let r=0;if(n>=0)for(;t<e.o-1;){const i=h(e,t);if(r+=i,t++,r>=n){r-i/2>=n&&t--;break}}else for(;t>0;){t--;const i=h(e,t);if(r-=i,r<=n){r+i/2<n&&t++;break}}return c(d(t,0),e.o-1)},p=m,g=(e,t)=>{if(!e.o)return 0;if(e.l>=t)return e._[t];let n=e._[e.l];for(let r=e.l;r<=t&&(e._[r]=n,r!==t);r++)n+=h(e,r);return e.l=t,n},y=(e,t,n)=>{var r;return{i:t,o:e,l:null!==(r=n&&c(n.l,e-1))&&void 0!==r?r:0,t:f(e,(e=>{var t;return null!==(t=n&&n.t[e])&&void 0!==t?t:-1})),_:f(e,(e=>{var t;return 0===e?0:null!==(t=n&&n._[e])&&void 0!==t?t:-1}))}},v="undefined"!=typeof window?n:r,w=(e,t)=>u(e,t,t),z=/*#__PURE__*/i((({u:n,h:r,m:i,p:l,g:s,v:_,I:u})=>{const c=t(null),d=w(i.S,(()=>i.R(l))),a=w(i.S,(()=>i.H(l)));return v((()=>r.M(c.current,l)),[l]),e(s,{ref:c,style:o((()=>{const e={margin:"0",padding:"0",position:"absolute",[_?"height":"width"]:"100%",[_?"top":u?"right":"left"]:0,[_?u?"right":"left":"top"]:d};return _&&(e.display="flex"),a&&(e.visibility="hidden"),e}),[d,_,u,a]),children:n})})),x=e=>null==e||"boolean"==typeof e,I=({u:t,T:n,g:r,O:i,v:l})=>e(r,{ref:n,style:o((()=>({overflow:l?"auto hidden":"hidden auto",position:"relative",contain:"strict",width:"100%",height:"100%",padding:0,margin:0,...i})),[l,i]),children:t}),S=({u:t,m:n,g:r,O:i,v:l,I:s})=>{const _=w(n.S,n.j),u=w(n.S,n.k);return e(r,{style:o((()=>{const e=_>=u?_:u,t=l?e:"100%",n=l?"100%":e;return{position:"absolute",top:0,[s?"right":"left"]:0,width:t,height:n,minWidth:t,minHeight:n,...i}}),[_,u,i,l,s]),children:t})},b=/*#__PURE__*/l((({children:n,itemSize:i=40,overscan:l=6,horizontal:u,rtl:f,endThreshold:b=0,style:R,innerStyle:H,element:E="div",innerElement:M="div",itemElement:T="div",onEndReached:O},j)=>{const k=o((()=>{let e=0;return s.forEach(n,(t=>{x(t)||e++})),e}),[n]),P=((e,n,r)=>{const i=t();return i.current||(i.current=(()=>{const t=new Set,i={P:0,W:0,D:0,U:y(e,n),A:[]},o=()=>r?i.W:i.D;let l;return{C:()=>i.P,F:()=>p(i.U,i.P,o()),H:e=>-1===i.U.t[e],J:e=>((e,t,n)=>{for(let r=t;r<=n;r++)if(-1===e.t[r])return!0;return!1})(i.U,e,p(i.U,e,o())),R:e=>g(i.U,e),k:()=>o(),j:()=>(e=>{if(!e.o)return 0;const t=e.o-1;if(e.l>=t)return e._[t]+h(e,t);let n=e._[e.l];for(let r=e.l;r<=t;r++)e._[r]=n,n+=h(e,r);return e.l=t,n})(i.U),L:()=>i.U.o,V:()=>i.A,q:()=>(l&&l[1](),new Promise(((e,t)=>{l=[()=>{Promise.resolve().then((()=>{e(),l=void 0}))},t]}))),S:e=>(t.add(e),()=>{t.delete(e)}),B(e){((e,t,n)=>{switch(t.G){case 0:return e.U.o!==t.o&&(e.U=y(t.o,n,e.U),!0);case 1:{const n=t.K.filter((([t,n])=>e.U.t[t]!==n));if(!n.length)return!1;const r=[];return n.forEach((([t,n])=>{r.push([t,n-h(e.U,t)]),((e,t,n)=>{e.t[t]=n,e.l=c(t,e.l)})(e.U,t,n)})),e.A=r,!0}case 2:return(e.W!==t.N||e.D!==t.X)&&(e.W=t.N,e.D=t.X,!0);case 3:{const n=e.P,r=g(e.U,n);return r!==t.Y&&(e.P=((e,t,n,r)=>m(e,n,t-r))(e.U,t.Y,n,r))!==n}}})(i,e,n)&&(t.forEach((e=>{e()})),l&&1===e.G&&l[0]())}}})())})(k,i,u),W=w(P.S,P.C),D=w(P.S,P.F),U=w(P.S,P.V),A=t(null),C=t(-1),F=t(),J=F.current||(F.current=(()=>{if("undefined"==typeof ResizeObserver)return{};let e,t,n=-1,r=0,i=!1;const o=u?"scrollLeft":"scrollTop",l=new WeakMap,s=new ResizeObserver((e=>{const n=[];for(const r of e)if(r.target===t)P.B({G:2,N:r.contentRect.width,X:r.contentRect.height});else{const e=l.get(r.target);null!=e&&n.push([e,r.contentRect[u?"width":"height"]])}n.length&&(P.B({G:1,K:n}),i=!0)}));return{Z(e){t=e;const l=()=>{let t=e[o];f&&(t=a(t)),n!==t&&(0!==r&&i?i=!1:3!==r&&(r=n>t?2:1),P.B({G:3,Y:n=t}))},_=(()=>{let e=null;const t=()=>{null!=e&&clearTimeout(e)},n=()=>{t(),e=setTimeout((()=>{e=null,l(),r=0}),300)};return n.$=t,n})(),u=()=>{l(),_()};return s.observe(e),e.addEventListener("scroll",u),()=>{s.disconnect(),e.removeEventListener("scroll",u),_.$()}},M:(e,t)=>(l.set(e,t),s.observe(e),()=>{l.delete(e),s.unobserve(e)}),ee:()=>r,te(n,i){if(t){if(f){if(null==e){const n=t[o];t[o]=1,e=0===t[o],t[o]=n}e&&(n*=-1)}i?t[o]+=n:(t[o]=n,r=3)}}}})()),L=c(k,P.L()),V=d(W-l,0),q=c(D+l,L-1);v((()=>{P.B({G:0,o:k})}),[k]),v((()=>J.Z(A.current)),[]),v((()=>{if(!U.length)return;const e=J.ee();if(2===e){const e=U.reduce(((e,[,t])=>e+t),0);e&&J.te(e,!0)}else if(3===e){const e=0===W,t=D-(L-1)==0,n=U.reduce(((n,[r,i])=>(r<W?e||(n+=i):!e&&t&&(n+=i),n)),0);n&&J.te(n,!0)}}),[U]),r((()=>{O&&(C.current>L&&(C.current=-1),L-1-D<=b&&C.current<L&&(C.current=L,O()))}),[D]),_(j,(()=>({scrollToIndex:async e=>{const t=A.current;if(!t)return;e=d(c(e,L-1),0);const n=()=>{let n=P.R(e);const r=u?t.scrollWidth:t.scrollHeight,i=P.k();return r-(n+i)<=0&&(n=r-i),n};if(P.J(e)){do{P.B({G:3,Y:n()});try{await P.q()}catch(e){return}}while(P.J(e));J.te(n())}else{const e=n();J.te(e),P.B({G:3,Y:e})}}})),[L]);const B=o((()=>{let t=-1;return s.map(n,(n=>{if(!(x(n)||(t++,t<V||t>q)))return null!=n?e(z,{h:J,m:P,p:t,g:T,v:u,I:f,u:n},(null==n?void 0:n.key)||t):null}))}),[n,V,q]);return e(I,{T:A,v:u,g:E,O:R,u:e(S,{m:P,g:M,O:H,v:u,I:f,u:B})})}));export{b as List};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/lib/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/src/utils.ts","../src/src/cache.ts","../src/src/useIsomorphicLayoutEffect.ts","../src/src/useSyncExternalStore.ts","../src/src/List.tsx","../src/src/state.ts"],"sourcesContent":["export const min = Math.min;\nexport const max = Math.max;\nexport const abs = Math.abs;\n\nexport const range = <T>(length: number, cb: (i: number) => T): T[] =>\n Array.from({ length }, (_, i) => cb(i));\n\nexport const debounce = <T extends (...args: any[]) => void>(\n fn: T,\n ms: number\n) => {\n let id: NodeJS.Timeout | null = null;\n\n const cancel = () => {\n if (id != null) {\n clearTimeout(id);\n }\n };\n const debouncedFn = () => {\n cancel();\n id = setTimeout(() => {\n id = null;\n fn();\n }, ms);\n };\n debouncedFn._cancel = cancel;\n return debouncedFn;\n};\n","import type { DeepReadonly, Writeable } from \"./types\";\nimport { max, min, range } from \"./utils\";\n\nexport const UNCACHED = -1;\n\nexport type Cache = DeepReadonly<{\n _defaultItemSize: number;\n _length: number;\n _sizes: number[];\n _measuredOffsetIndex: number;\n _offsets: number[];\n}>;\n\nexport const getItemSize = (cache: Cache, index: number): number => {\n const size = cache._sizes[index]!;\n return size === UNCACHED ? cache._defaultItemSize : size;\n};\n\nexport const setItemSize = (\n cache: Writeable<Cache>,\n index: number,\n size: number\n) => {\n cache._sizes[index] = size;\n // mark as dirty\n cache._measuredOffsetIndex = min(index, cache._measuredOffsetIndex);\n};\n\nexport const computeTotalSize = (cache: Writeable<Cache>): number => {\n if (!cache._length) return 0;\n const lastIndex = cache._length - 1;\n if (cache._measuredOffsetIndex >= lastIndex) {\n return cache._offsets[lastIndex]! + getItemSize(cache, lastIndex);\n }\n\n let top = cache._offsets[cache._measuredOffsetIndex]!;\n for (let i = cache._measuredOffsetIndex; i <= lastIndex; i++) {\n cache._offsets[i] = top;\n top += getItemSize(cache, i);\n }\n\n cache._measuredOffsetIndex = lastIndex;\n return top;\n};\n\nconst findIndex = (cache: Cache, i: number, distance: number): number => {\n let sum = 0;\n if (distance >= 0) {\n // search forward\n while (i < cache._length - 1) {\n const h = getItemSize(cache, i);\n sum += h;\n i++;\n if (sum >= distance) {\n if (sum - h / 2 >= distance) {\n i--;\n }\n break;\n }\n }\n } else {\n // search backward\n while (i > 0) {\n i--;\n const h = getItemSize(cache, i);\n sum -= h;\n if (sum <= distance) {\n if (sum + h / 2 < distance) {\n i++;\n }\n break;\n }\n }\n }\n\n return min(max(i, 0), cache._length - 1);\n};\n\nexport const findStartIndexWithOffset = (\n cache: Cache,\n offset: number,\n prevStartIndex: number,\n prevOffset: number\n): number => {\n return findIndex(cache, prevStartIndex, offset - prevOffset);\n};\n\nexport const findEndIndex = findIndex;\n\nexport const hasUnmeasuredItemsInRange = (\n cache: Cache,\n startIndex: number,\n endIndex: number\n): boolean => {\n for (let i = startIndex; i <= endIndex; i++) {\n if (cache._sizes[i] === UNCACHED) {\n return true;\n }\n }\n return false;\n};\n\nexport const computeStartOffset = (\n cache: Writeable<Cache>,\n index: number\n): number => {\n if (!cache._length) return 0;\n if (cache._measuredOffsetIndex >= index) {\n return cache._offsets[index]!;\n }\n\n let top = cache._offsets[cache._measuredOffsetIndex]!;\n for (let i = cache._measuredOffsetIndex; i <= index; i++) {\n cache._offsets[i] = top;\n if (i === index) {\n break;\n }\n top += getItemSize(cache, i);\n }\n cache._measuredOffsetIndex = index;\n return top;\n};\n\nexport const resetCache = (\n length: number,\n itemSize: number,\n cache?: Cache\n): Cache => {\n return {\n _defaultItemSize: itemSize,\n _length: length,\n _measuredOffsetIndex:\n (cache && min(cache._measuredOffsetIndex, length - 1)) ?? 0,\n _sizes: range(length, (i) => (cache && cache._sizes[i]) ?? UNCACHED),\n _offsets: range(length, (i) =>\n i === 0\n ? 0 // first offset must be 0\n : (cache && cache._offsets[i]) ?? UNCACHED\n ),\n };\n};\n","import { useEffect, useLayoutEffect } from \"react\";\n\n// https://gist.github.com/gaearon/e7d97cdf38a2907924ea12e4ebdf3c85\nexport const useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n","import { useSyncExternalStore as _useSyncExternalStore } from \"use-sync-external-store/shim\";\n\nexport const useSyncExternalStore = <T>(\n subscibe: (onStoreChange: () => void) => () => void,\n getSnapShot: () => T\n): T => {\n return _useSyncExternalStore(subscibe, getSnapShot, getSnapShot);\n};\n","import {\n Children,\n memo,\n useRef,\n useMemo,\n CSSProperties,\n ReactElement,\n forwardRef,\n useImperativeHandle,\n ReactNode,\n useEffect,\n RefObject,\n} from \"react\";\nimport {\n HANDLE_SCROLL,\n UPDATE_CACHE_LENGTH,\n Store,\n UPDATE_ITEM_SIZES,\n UPDATE_VIEWPORT_SIZE,\n useVirtualStore,\n} from \"./state\";\nimport { useIsomorphicLayoutEffect } from \"./useIsomorphicLayoutEffect\";\nimport { useSyncExternalStore } from \"./useSyncExternalStore\";\nimport { debounce, max, min } from \"./utils\";\n\nconst SCROLL_STOP = 0;\nconst SCROLL_DOWN = 1;\nconst SCROLL_UP = 2;\nconst SCROLL_MANUAL = 3;\ntype ScrollDirection =\n | typeof SCROLL_STOP\n | typeof SCROLL_DOWN\n | typeof SCROLL_UP\n | typeof SCROLL_MANUAL;\n\nconst INITIAL_END_REACHED_INDEX = -1;\n\ntype ObserverHandle = {\n _init: (rootElement: HTMLElement) => () => void;\n _observe: (itemElement: HTMLElement, index: number) => () => void;\n _getScrollDirection: () => ScrollDirection;\n _startManuallScroll: () => void;\n};\n\ntype ItemProps = {\n _children: ReactNode;\n _handle: ObserverHandle;\n _store: Store;\n _index: number;\n _element: \"div\";\n _isHorizontal: boolean | undefined;\n};\n\nconst Item = memo(\n ({\n _children: children,\n _handle: handle,\n _store: store,\n _index: index,\n _element: Element,\n _isHorizontal: isHorizontal,\n }: ItemProps): ReactElement => {\n const ref = useRef<HTMLDivElement>(null);\n\n const offset = useSyncExternalStore(store._subscribe, () =>\n store._getItemOffset(index)\n );\n const hide = useSyncExternalStore(store._subscribe, () =>\n store._isUnmeasuredItem(index)\n );\n\n // The index may be changed if elements are inserted to or removed from the start of props.children\n useIsomorphicLayoutEffect(\n () => handle._observe(ref.current!, index),\n [index]\n );\n\n return (\n <Element\n ref={ref}\n style={useMemo<CSSProperties>(() => {\n const style: CSSProperties = {\n margin: \"0\",\n padding: \"0\",\n position: \"absolute\",\n [isHorizontal ? \"height\" : \"width\"]: \"100%\",\n [isHorizontal ? \"top\" : \"left\"]: 0,\n [isHorizontal ? \"left\" : \"top\"]: offset,\n // willChange: \"transform\",\n };\n if (isHorizontal) {\n style.display = \"flex\";\n }\n if (hide) {\n style.visibility = \"hidden\";\n }\n return style;\n }, [offset, isHorizontal, hide])}\n >\n {children}\n </Element>\n );\n }\n);\n\nconst isInvalidElement = <T,>(e: T) => e == null || typeof e === \"boolean\";\n\nconst Window = ({\n _children: children,\n _ref: ref,\n _element: Element,\n _style: style,\n _isHorizontal: isHorizontal,\n}: {\n _children: ReactNode;\n _ref: RefObject<HTMLDivElement>;\n _element: \"div\";\n _style: CSSProperties | undefined;\n _isHorizontal: boolean | undefined;\n}) => {\n return (\n <Element\n ref={ref}\n style={useMemo<CSSProperties>(\n () => ({\n overflow: isHorizontal ? \"auto hidden\" : \"hidden auto\",\n position: \"relative\",\n contain: \"strict\",\n // transform: \"translate3d(0px, 0px, 0px)\",\n // willChange: \"scroll-position\",\n // backfaceVisibility: \"hidden\",\n width: \"100%\",\n height: \"100%\",\n padding: 0,\n margin: 0,\n ...style,\n }),\n [isHorizontal, style]\n )}\n >\n {children}\n </Element>\n );\n};\n\nconst Inner = ({\n _children: children,\n _store: store,\n _element: Element,\n _style: style,\n _isHorizontal: isHorizontal,\n}: {\n _children: ReactNode;\n _store: Store;\n _element: \"div\";\n _style: CSSProperties | undefined;\n _isHorizontal: boolean | undefined;\n}) => {\n const scrollSize = useSyncExternalStore(\n store._subscribe,\n store._getScrollSize\n );\n const viewportSize = useSyncExternalStore(\n store._subscribe,\n store._getViewportSize\n );\n\n return (\n <Element\n style={useMemo<CSSProperties>(() => {\n const clampedScrollSize =\n scrollSize >= viewportSize ? scrollSize : viewportSize;\n const width = isHorizontal ? clampedScrollSize : \"100%\";\n const height = isHorizontal ? \"100%\" : clampedScrollSize;\n return {\n position: \"absolute\",\n top: 0,\n left: 0,\n width,\n height,\n minWidth: width,\n minHeight: height,\n ...style,\n };\n }, [scrollSize, viewportSize, style, isHorizontal])}\n >\n {children}\n </Element>\n );\n};\n\nexport interface CustomComponentProps {\n style: CSSProperties;\n children: ReactNode;\n}\n\nexport type CustomComponent = React.ForwardRefExoticComponent<\n React.PropsWithoutRef<CustomComponentProps> & React.RefAttributes<any>\n>;\n\ntype CustomElementType = keyof JSX.IntrinsicElements | CustomComponent;\n\n/**\n * Methods of {@link List}.\n */\nexport interface ListHandle {\n /**\n * Scroll to the item specified by index.\n * @param index index of item\n */\n scrollToIndex(index: number): void;\n}\n\n/**\n * Props of {@link List}.\n */\nexport interface ListProps {\n /**\n * Elements rendered by this component.\n */\n children: ReactNode;\n /**\n * Item size hint for unmeasured items. It's recommended to specify this prop if item sizes are fixed and known, or much larger than the defaultValue. It will help to reduce scroll jump when items are measured.\n * @defaultValue 40\n */\n itemSize?: number;\n /**\n * Number of items to render above/below the visible bounds of the list. You can increase to avoid showing blank items in fast scrolling.\n * @defaultValue 6\n */\n overscan?: number;\n /**\n * If true, rendered as a horizontally scrollable list. Otherwise rendered as a vertically scrollable list.\n */\n horizontal?: boolean;\n /**\n * Number of items to be the margin from the end of the scroll. See also {@link onEndReached}.\n * @defaultValue 0\n */\n endThreshold?: number;\n /**\n * Inline style prop to override style of scrollable element.\n */\n style?: CSSProperties;\n /**\n * Inline style prop to override style of inner element.\n */\n innerStyle?: CSSProperties;\n /**\n * Customized element type for scrollable element.\n * @defaultValue \"div\"\n */\n element?: CustomElementType;\n /**\n * Customized element type for inner element.\n * @defaultValue \"div\"\n */\n innerElement?: CustomElementType;\n /**\n * Customized element type for item element.\n * @defaultValue \"div\"\n */\n itemElement?: CustomElementType;\n /**\n * Callback invoked when scrolling reached to the end. The margin from the end is specified by {@link endThreshold}.\n */\n onEndReached?: () => void;\n}\n\n/**\n * Virtualized list component. See {@link ListProps} and {@link ListHandle}.\n */\nexport const List = forwardRef<ListHandle, ListProps>(\n (\n {\n children,\n itemSize = 40,\n overscan = 6,\n horizontal: isHorizontal,\n endThreshold = 0,\n style: styleProp,\n innerStyle: innerStyleProp,\n element = \"div\",\n innerElement = \"div\",\n itemElement = \"div\",\n onEndReached,\n },\n ref\n ): ReactElement => {\n const scrollToKey = isHorizontal ? \"scrollLeft\" : \"scrollTop\";\n // memoize element count\n const rawCount = useMemo(() => {\n let i = 0;\n Children.forEach(children, (e) => {\n if (isInvalidElement(e)) {\n return;\n }\n i++;\n });\n return i;\n }, [children]);\n\n const store = useVirtualStore(rawCount, itemSize, isHorizontal);\n const startIndex = useSyncExternalStore(\n store._subscribe,\n store._getStartIndex\n );\n const endIndex = useSyncExternalStore(store._subscribe, store._getEndIndex);\n const isViewportInitialized = useSyncExternalStore(\n store._subscribe,\n store._isViewportSizeInitialized\n );\n const jump = useSyncExternalStore(store._subscribe, store._getJump);\n const scrollRef = useRef<HTMLDivElement>(null);\n const onEndReachedCalledIndex = useRef<number>(INITIAL_END_REACHED_INDEX);\n\n const handleRef = useRef<ObserverHandle>();\n const handle =\n handleRef.current ||\n (handleRef.current = ((): ObserverHandle => {\n let ro: ResizeObserver;\n let prevOffset = -1;\n let scrollDirection: ScrollDirection = SCROLL_STOP;\n let resized = false;\n const mountedIndexes = new WeakMap<Element, number>();\n\n return {\n _init(root) {\n const syncViewportToScrollPosition = () => {\n const offset = root[scrollToKey];\n if (prevOffset === offset) {\n return;\n }\n // Skip scroll direction detection just after resizing because it may result in the opposite direction.\n // Scroll events are dispatched enough so it's ok to skip some of them.\n if (scrollDirection === SCROLL_STOP || !resized) {\n // Ignore until manual scrolling\n if (scrollDirection !== SCROLL_MANUAL) {\n scrollDirection =\n prevOffset > offset ? SCROLL_UP : SCROLL_DOWN;\n }\n } else {\n resized = false;\n }\n store._update({\n _type: HANDLE_SCROLL,\n _offset: (prevOffset = offset),\n });\n };\n\n const onScrollStopped = debounce(() => {\n // Check scroll position once just after scrolling stopped\n syncViewportToScrollPosition();\n scrollDirection = SCROLL_STOP;\n }, 300);\n\n const onScroll = () => {\n syncViewportToScrollPosition();\n onScrollStopped();\n };\n\n ro = new ResizeObserver((entries) => {\n const resizes: [index: number, size: number][] = [];\n for (const entry of entries) {\n if (entry.target === root) {\n store._update({\n _type: UPDATE_VIEWPORT_SIZE,\n _width: entry.contentRect.width,\n _height: entry.contentRect.height,\n });\n } else {\n const index = mountedIndexes.get(entry.target);\n if (index != null) {\n resizes.push([\n index,\n entry.contentRect[isHorizontal ? \"width\" : \"height\"],\n ]);\n }\n }\n }\n\n if (resizes.length) {\n store._update({\n _type: UPDATE_ITEM_SIZES,\n _entries: resizes,\n });\n resized = true;\n }\n });\n\n ro.observe(root);\n root.addEventListener(\"scroll\", onScroll);\n\n return () => {\n ro.disconnect();\n root.removeEventListener(\"scroll\", onScroll);\n onScrollStopped._cancel();\n };\n },\n _observe(el, i) {\n mountedIndexes.set(el, i);\n ro.observe(el);\n return () => {\n mountedIndexes.delete(el);\n ro.unobserve(el);\n };\n },\n _getScrollDirection() {\n return scrollDirection;\n },\n _startManuallScroll() {\n scrollDirection = SCROLL_MANUAL;\n },\n };\n })());\n\n // The elements length and cached items length are different just after element is added/removed.\n const count = min(rawCount, store._getItemCount());\n\n const startIndexWithMargin = max(startIndex - overscan, 0);\n const endIndexWithMargin = min(endIndex + overscan, count - 1);\n\n // So update cache length. Updating state in render will cause warn so use useEffect for now.\n useIsomorphicLayoutEffect(() => {\n store._update({\n _type: UPDATE_CACHE_LENGTH,\n _length: rawCount,\n });\n }, [rawCount]);\n\n useIsomorphicLayoutEffect(() => handle._init(scrollRef.current!), []);\n\n useIsomorphicLayoutEffect(() => {\n if (!scrollRef.current || !jump.length) return;\n\n // Compensate scroll jump\n const scrollDirection = handle._getScrollDirection();\n if (scrollDirection === SCROLL_UP) {\n const diff = jump.reduce((acc, [, j]) => acc + j, 0);\n if (diff) {\n scrollRef.current[scrollToKey] += diff;\n }\n } else if (scrollDirection === SCROLL_MANUAL) {\n const isStartInView = startIndex === 0;\n const isEndInView = endIndex - (count - 1) === 0;\n const diff = jump.reduce((acc, [index, j]) => {\n if (index < startIndex) {\n // Keep start if scroll position is not stuck to the start\n if (!isStartInView) {\n acc += j;\n }\n } else {\n // Keep end if scroll position is stuck to the end\n if (!isStartInView && isEndInView) {\n acc += j;\n }\n }\n return acc;\n }, 0);\n if (diff) {\n scrollRef.current[scrollToKey] += diff;\n }\n } else {\n // NOP\n }\n }, [jump]);\n\n useEffect(() => {\n if (!onEndReached) return;\n\n if (onEndReachedCalledIndex.current > count) {\n // Probably items have been refreshed, so reset index\n onEndReachedCalledIndex.current = INITIAL_END_REACHED_INDEX;\n }\n\n const endMargin = count - 1 - endIndex;\n if (\n endMargin <= endThreshold &&\n onEndReachedCalledIndex.current < count\n ) {\n onEndReachedCalledIndex.current = count;\n onEndReached();\n }\n }, [endIndex]);\n\n useImperativeHandle(\n ref,\n () => ({\n scrollToIndex: async (index) => {\n const el = scrollRef.current;\n if (!el) return;\n\n index = max(min(index, count - 1), 0);\n\n const getScrollDestination = (): number => {\n let offset = store._getItemOffset(index);\n // Use element's scrollHeight/scrollWidth instead of stored scrollSize.\n // This is because stored size may differ from the actual size, for example when a new item is added and not yet measured.\n const scrollSize = isHorizontal ? el.scrollWidth : el.scrollHeight;\n const viewportSize = store._getViewportSize();\n if (scrollSize - (offset + viewportSize) <= 0) {\n // Adjust if the offset is over the end, to get correct startIndex.\n offset = scrollSize - viewportSize;\n }\n return offset;\n };\n\n if (store._hasUnmeasuredItemsInRange(index)) {\n do {\n // In order to scroll to the correct position, mount the items and measure their sizes before scrolling.\n store._update({\n _type: HANDLE_SCROLL,\n _offset: getScrollDestination(),\n });\n try {\n // Wait for the scroll destination items to be measured.\n await store._waitForScrollDestinationItemsMeasured();\n } catch (e) {\n // canceled\n return;\n }\n } while (store._hasUnmeasuredItemsInRange(index));\n\n // Scroll with the updated value\n el[scrollToKey] = getScrollDestination();\n } else {\n const offset = getScrollDestination();\n el[scrollToKey] = offset;\n // Sync viewport to scroll destination\n store._update({ _type: HANDLE_SCROLL, _offset: offset });\n }\n\n handle._startManuallScroll();\n },\n }),\n [count]\n );\n\n const items = useMemo(() => {\n let i = -1;\n return Children.map(children, (e) => {\n if (isInvalidElement(e)) {\n return;\n }\n i++;\n if (i < startIndexWithMargin || i > endIndexWithMargin) {\n return;\n }\n return e != null ? (\n <Item\n key={(e as { key?: ReactElement[\"key\"] })?.key || i}\n _handle={handle}\n _store={store}\n _index={i}\n _element={itemElement as \"div\"}\n _isHorizontal={isHorizontal}\n _children={e}\n />\n ) : null;\n });\n }, [children, startIndexWithMargin, endIndexWithMargin]);\n\n return (\n <Window\n _ref={scrollRef}\n _isHorizontal={isHorizontal}\n _element={element as \"div\"}\n _style={styleProp}\n _children={\n <Inner\n _store={store}\n _element={innerElement as \"div\"}\n _style={innerStyleProp}\n _isHorizontal={isHorizontal}\n _children={isViewportInitialized && items}\n />\n }\n />\n );\n }\n);\n","import { useRef } from \"react\";\nimport {\n findStartIndexWithOffset,\n resetCache,\n getItemSize,\n computeTotalSize,\n findEndIndex,\n computeStartOffset,\n Cache,\n UNCACHED,\n setItemSize,\n hasUnmeasuredItemsInRange,\n} from \"./cache\";\nimport type { Writeable } from \"./types\";\n\nexport const UPDATE_CACHE_LENGTH = 0;\nexport const UPDATE_ITEM_SIZES = 1;\nexport const UPDATE_VIEWPORT_SIZE = 2;\nexport const HANDLE_SCROLL = 3;\n\nexport type ScrollJump = Readonly<[index: number, sizeDiff: number][]>;\n\ntype State = {\n _startIndex: number;\n _viewportWidth: number;\n _viewportHeight: number;\n _cache: Cache;\n _jump: ScrollJump;\n};\n\ntype Actions =\n | { _type: typeof UPDATE_CACHE_LENGTH; _length: number }\n | {\n _type: typeof UPDATE_ITEM_SIZES;\n _entries: [index: number, size: number][];\n }\n | { _type: typeof UPDATE_VIEWPORT_SIZE; _width: number; _height: number }\n | { _type: typeof HANDLE_SCROLL; _offset: number };\n\nconst mutate = (state: State, action: Actions, itemSize: number): boolean => {\n switch (action._type) {\n case UPDATE_CACHE_LENGTH: {\n if (state._cache._length === action._length) return false;\n state._cache = resetCache(action._length, itemSize, state._cache);\n return true;\n }\n case UPDATE_ITEM_SIZES: {\n const updated = action._entries.filter(\n ([index, size]) => state._cache._sizes[index] !== size\n );\n // Skip if all items are cached and not updated\n if (!updated.length) {\n return false;\n }\n\n const jump: [index: number, sizeDiff: number][] = [];\n updated.forEach(([index, size]) => {\n jump.push([index, size - getItemSize(state._cache, index)]);\n setItemSize(state._cache as Writeable<Cache>, index, size);\n });\n state._jump = jump;\n return true;\n }\n case UPDATE_VIEWPORT_SIZE: {\n if (\n state._viewportWidth === action._width &&\n state._viewportHeight === action._height\n ) {\n return false;\n }\n state._viewportWidth = action._width;\n state._viewportHeight = action._height;\n return true;\n }\n case HANDLE_SCROLL: {\n const prevStartIndex = state._startIndex;\n const prevOffset = computeStartOffset(\n state._cache as Writeable<Cache>,\n prevStartIndex\n );\n if (prevOffset === action._offset) {\n return false;\n }\n return (\n (state._startIndex = findStartIndexWithOffset(\n state._cache,\n action._offset,\n prevStartIndex,\n prevOffset\n )) !== prevStartIndex\n );\n }\n }\n};\n\nexport type Store = {\n _getStartIndex(): number;\n _getEndIndex(): number;\n _isUnmeasuredItem(index: number): boolean;\n _hasUnmeasuredItemsInRange(startIndex: number): boolean;\n _getItemOffset(index: number): number;\n _getViewportSize(): number;\n _isViewportSizeInitialized(): boolean;\n _getScrollSize(): number;\n _getItemCount(): number;\n _getJump(): ScrollJump;\n _waitForScrollDestinationItemsMeasured(): Promise<void>;\n _subscribe(cb: () => void): () => void;\n _update(action: Actions): void;\n};\n\n// https://github.com/facebook/react/issues/25191#issuecomment-1237456448\nexport const useVirtualStore = (\n itemCount: number,\n itemSize: number,\n isHorizontal: boolean | undefined\n): Store => {\n const ref = useRef<Store | undefined>();\n return (\n ref.current ||\n (ref.current = (() => {\n const subscribers = new Set<() => void>();\n const state: Readonly<State> = {\n _startIndex: 0,\n _viewportWidth: 0,\n _viewportHeight: 0,\n _cache: resetCache(itemCount, itemSize),\n _jump: [],\n };\n const getViewportSize = (): number =>\n isHorizontal ? state._viewportWidth : state._viewportHeight;\n\n let scrollToQueue: [() => void, () => void] | undefined;\n\n return {\n _getStartIndex() {\n return state._startIndex;\n },\n _getEndIndex() {\n return findEndIndex(\n state._cache,\n state._startIndex,\n getViewportSize()\n );\n },\n _isUnmeasuredItem(index) {\n return state._cache._sizes[index] === UNCACHED;\n },\n _hasUnmeasuredItemsInRange(startIndex) {\n return hasUnmeasuredItemsInRange(\n state._cache,\n startIndex,\n findEndIndex(state._cache, startIndex, getViewportSize())\n );\n },\n _getItemOffset(index) {\n return computeStartOffset(state._cache as Writeable<Cache>, index);\n },\n _getViewportSize() {\n return getViewportSize();\n },\n _isViewportSizeInitialized() {\n return getViewportSize() !== 0;\n },\n _getScrollSize() {\n return computeTotalSize(state._cache as Writeable<Cache>);\n },\n _getItemCount() {\n return state._cache._length;\n },\n _getJump() {\n return state._jump;\n },\n _waitForScrollDestinationItemsMeasured() {\n if (scrollToQueue) {\n // Cancel waiting scrollTo\n scrollToQueue[1]();\n }\n // The measurement will be done asynchronously and the timing is not predictable so we use promise.\n // For example, ResizeObserver may not fire when window is not visible.\n return new Promise((resolve, reject) => {\n scrollToQueue = [\n () => {\n // HACK: It should be resolved in the next microtask that is after React's render\n Promise.resolve().then(() => {\n resolve();\n scrollToQueue = undefined;\n });\n },\n reject,\n ];\n });\n },\n _subscribe(cb) {\n subscribers.add(cb);\n return () => {\n subscribers.delete(cb);\n };\n },\n _update(action) {\n const mutated = mutate(state, action, itemSize);\n if (mutated) {\n subscribers.forEach((cb) => {\n cb();\n });\n if (scrollToQueue && action._type === UPDATE_ITEM_SIZES) {\n scrollToQueue[0]();\n }\n }\n },\n };\n })())\n );\n};\n"],"names":["min","Math","max","range","length","cb","Array","from","_","i","getItemSize","cache","index","size","_sizes","_defaultItemSize","findIndex","distance","sum","_length","h","findEndIndex","computeStartOffset","_measuredOffsetIndex","_offsets","top","resetCache","itemSize","_a","useIsomorphicLayoutEffect","window","useLayoutEffect","useEffect","useSyncExternalStore","subscibe","getSnapShot","_useSyncExternalStore","Item","memo","_children","children","_handle","handle","_store","store","_index","_element","Element","_isHorizontal","isHorizontal","ref","useRef","offset","_subscribe","_getItemOffset","hide","_isUnmeasuredItem","_observe","current","_jsx","style","useMemo","margin","padding","position","display","visibility","isInvalidElement","e","Window","_ref","_style","overflow","contain","width","height","Inner","scrollSize","_getScrollSize","viewportSize","_getViewportSize","clampedScrollSize","left","minWidth","minHeight","List","forwardRef","overscan","horizontal","endThreshold","styleProp","innerStyle","innerStyleProp","element","innerElement","itemElement","onEndReached","scrollToKey","rawCount","Children","forEach","useVirtualStore","itemCount","subscribers","Set","state","_startIndex","_viewportWidth","_viewportHeight","_cache","_jump","getViewportSize","scrollToQueue","_getStartIndex","_getEndIndex","_hasUnmeasuredItemsInRange","startIndex","hasUnmeasuredItemsInRange","endIndex","_isViewportSizeInitialized","lastIndex","computeTotalSize","_getItemCount","_getJump","_waitForScrollDestinationItemsMeasured","Promise","resolve","reject","then","undefined","add","delete","_update","action","mutate","_type","updated","_entries","filter","jump","push","setItemSize","_width","_height","prevStartIndex","prevOffset","_offset","findStartIndexWithOffset","isViewportInitialized","scrollRef","onEndReachedCalledIndex","handleRef","ro","scrollDirection","resized","mountedIndexes","WeakMap","_init","root","syncViewportToScrollPosition","onScrollStopped","debounce","id","cancel","clearTimeout","debouncedFn","setTimeout","_cancel","onScroll","ResizeObserver","entries","resizes","entry","target","contentRect","get","observe","addEventListener","disconnect","removeEventListener","el","set","unobserve","_getScrollDirection","_startManuallScroll","count","startIndexWithMargin","endIndexWithMargin","diff","reduce","acc","j","isStartInView","isEndInView","useImperativeHandle","scrollToIndex","async","getScrollDestination","scrollWidth","scrollHeight","items","map","key"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/src/utils.ts","../src/src/cache.ts","../src/src/useIsomorphicLayoutEffect.ts","../src/src/useSyncExternalStore.ts","../src/src/List.tsx","../src/src/state.ts"],"sourcesContent":["export const min = Math.min;\nexport const max = Math.max;\nexport const abs = Math.abs;\n\nexport const range = <T>(length: number, cb: (i: number) => T): T[] =>\n Array.from({ length }, (_, i) => cb(i));\n\nexport const debounce = <T extends (...args: any[]) => void>(\n fn: T,\n ms: number\n) => {\n let id: NodeJS.Timeout | null = null;\n\n const cancel = () => {\n if (id != null) {\n clearTimeout(id);\n }\n };\n const debouncedFn = () => {\n cancel();\n id = setTimeout(() => {\n id = null;\n fn();\n }, ms);\n };\n debouncedFn._cancel = cancel;\n return debouncedFn;\n};\n","import type { DeepReadonly, Writeable } from \"./types\";\nimport { max, min, range } from \"./utils\";\n\nexport const UNCACHED = -1;\n\nexport type Cache = DeepReadonly<{\n _defaultItemSize: number;\n _length: number;\n _sizes: number[];\n _measuredOffsetIndex: number;\n _offsets: number[];\n}>;\n\nexport const getItemSize = (cache: Cache, index: number): number => {\n const size = cache._sizes[index]!;\n return size === UNCACHED ? cache._defaultItemSize : size;\n};\n\nexport const setItemSize = (\n cache: Writeable<Cache>,\n index: number,\n size: number\n) => {\n cache._sizes[index] = size;\n // mark as dirty\n cache._measuredOffsetIndex = min(index, cache._measuredOffsetIndex);\n};\n\nexport const computeTotalSize = (cache: Writeable<Cache>): number => {\n if (!cache._length) return 0;\n const lastIndex = cache._length - 1;\n if (cache._measuredOffsetIndex >= lastIndex) {\n return cache._offsets[lastIndex]! + getItemSize(cache, lastIndex);\n }\n\n let top = cache._offsets[cache._measuredOffsetIndex]!;\n for (let i = cache._measuredOffsetIndex; i <= lastIndex; i++) {\n cache._offsets[i] = top;\n top += getItemSize(cache, i);\n }\n\n cache._measuredOffsetIndex = lastIndex;\n return top;\n};\n\nconst findIndex = (cache: Cache, i: number, distance: number): number => {\n let sum = 0;\n if (distance >= 0) {\n // search forward\n while (i < cache._length - 1) {\n const h = getItemSize(cache, i);\n sum += h;\n i++;\n if (sum >= distance) {\n if (sum - h / 2 >= distance) {\n i--;\n }\n break;\n }\n }\n } else {\n // search backward\n while (i > 0) {\n i--;\n const h = getItemSize(cache, i);\n sum -= h;\n if (sum <= distance) {\n if (sum + h / 2 < distance) {\n i++;\n }\n break;\n }\n }\n }\n\n return min(max(i, 0), cache._length - 1);\n};\n\nexport const findStartIndexWithOffset = (\n cache: Cache,\n offset: number,\n prevStartIndex: number,\n prevOffset: number\n): number => {\n return findIndex(cache, prevStartIndex, offset - prevOffset);\n};\n\nexport const findEndIndex = findIndex;\n\nexport const hasUnmeasuredItemsInRange = (\n cache: Cache,\n startIndex: number,\n endIndex: number\n): boolean => {\n for (let i = startIndex; i <= endIndex; i++) {\n if (cache._sizes[i] === UNCACHED) {\n return true;\n }\n }\n return false;\n};\n\nexport const computeStartOffset = (\n cache: Writeable<Cache>,\n index: number\n): number => {\n if (!cache._length) return 0;\n if (cache._measuredOffsetIndex >= index) {\n return cache._offsets[index]!;\n }\n\n let top = cache._offsets[cache._measuredOffsetIndex]!;\n for (let i = cache._measuredOffsetIndex; i <= index; i++) {\n cache._offsets[i] = top;\n if (i === index) {\n break;\n }\n top += getItemSize(cache, i);\n }\n cache._measuredOffsetIndex = index;\n return top;\n};\n\nexport const resetCache = (\n length: number,\n itemSize: number,\n cache?: Cache\n): Cache => {\n return {\n _defaultItemSize: itemSize,\n _length: length,\n _measuredOffsetIndex:\n (cache && min(cache._measuredOffsetIndex, length - 1)) ?? 0,\n _sizes: range(length, (i) => (cache && cache._sizes[i]) ?? UNCACHED),\n _offsets: range(length, (i) =>\n i === 0\n ? 0 // first offset must be 0\n : (cache && cache._offsets[i]) ?? UNCACHED\n ),\n };\n};\n","import { useEffect, useLayoutEffect } from \"react\";\n\n// https://gist.github.com/gaearon/e7d97cdf38a2907924ea12e4ebdf3c85\nexport const useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n","import { useSyncExternalStore as _useSyncExternalStore } from \"use-sync-external-store/shim\";\n\nexport const useSyncExternalStore = <T>(\n subscibe: (onStoreChange: () => void) => () => void,\n getSnapShot: () => T\n): T => {\n return _useSyncExternalStore(subscibe, getSnapShot, getSnapShot);\n};\n","import {\n Children,\n memo,\n useRef,\n useMemo,\n CSSProperties,\n ReactElement,\n forwardRef,\n useImperativeHandle,\n ReactNode,\n useEffect,\n RefObject,\n} from \"react\";\nimport {\n HANDLE_SCROLL,\n UPDATE_CACHE_LENGTH,\n Store,\n UPDATE_ITEM_SIZES,\n UPDATE_VIEWPORT_SIZE,\n useVirtualStore,\n} from \"./state\";\nimport { useIsomorphicLayoutEffect } from \"./useIsomorphicLayoutEffect\";\nimport { useSyncExternalStore } from \"./useSyncExternalStore\";\nimport { abs, debounce, max, min } from \"./utils\";\n\nconst SCROLL_STOP = 0;\nconst SCROLL_DOWN = 1;\nconst SCROLL_UP = 2;\nconst SCROLL_MANUAL = 3;\ntype ScrollDirection =\n | typeof SCROLL_STOP\n | typeof SCROLL_DOWN\n | typeof SCROLL_UP\n | typeof SCROLL_MANUAL;\n\nconst INITIAL_END_REACHED_INDEX = -1;\n\ntype ObserverHandle = {\n _initRoot: (rootElement: HTMLElement) => () => void;\n _initItem: (itemElement: HTMLElement, index: number) => () => void;\n _getScrollDirection: () => ScrollDirection;\n _updateScrollPosition: (offset: number, diff?: boolean) => void;\n};\n\ntype ItemProps = {\n _children: ReactNode;\n _handle: ObserverHandle;\n _store: Store;\n _index: number;\n _element: \"div\";\n _isHorizontal: boolean | undefined;\n _isRtl: boolean | undefined;\n};\n\nconst Item = memo(\n ({\n _children: children,\n _handle: handle,\n _store: store,\n _index: index,\n _element: Element,\n _isHorizontal: isHorizontal,\n _isRtl: isRtl,\n }: ItemProps): ReactElement => {\n const ref = useRef<HTMLDivElement>(null);\n\n const offset = useSyncExternalStore(store._subscribe, () =>\n store._getItemOffset(index)\n );\n const hide = useSyncExternalStore(store._subscribe, () =>\n store._isUnmeasuredItem(index)\n );\n\n // The index may be changed if elements are inserted to or removed from the start of props.children\n useIsomorphicLayoutEffect(\n () => handle._initItem(ref.current!, index),\n [index]\n );\n\n return (\n <Element\n ref={ref}\n style={useMemo<CSSProperties>(() => {\n const style: CSSProperties = {\n margin: \"0\",\n padding: \"0\",\n position: \"absolute\",\n [isHorizontal ? \"height\" : \"width\"]: \"100%\",\n [isHorizontal ? \"top\" : isRtl ? \"right\" : \"left\"]: 0,\n [isHorizontal ? (isRtl ? \"right\" : \"left\") : \"top\"]: offset,\n // willChange: \"transform\",\n };\n if (isHorizontal) {\n style.display = \"flex\";\n }\n if (hide) {\n style.visibility = \"hidden\";\n }\n return style;\n }, [offset, isHorizontal, isRtl, hide])}\n >\n {children}\n </Element>\n );\n }\n);\n\nconst isInvalidElement = <T,>(e: T) => e == null || typeof e === \"boolean\";\n\nconst Window = ({\n _children: children,\n _ref: ref,\n _element: Element,\n _style: style,\n _isHorizontal: isHorizontal,\n}: {\n _children: ReactNode;\n _ref: RefObject<HTMLDivElement>;\n _element: \"div\";\n _style: CSSProperties | undefined;\n _isHorizontal: boolean | undefined;\n}) => {\n return (\n <Element\n ref={ref}\n style={useMemo<CSSProperties>(\n () => ({\n overflow: isHorizontal ? \"auto hidden\" : \"hidden auto\",\n position: \"relative\",\n contain: \"strict\",\n // transform: \"translate3d(0px, 0px, 0px)\",\n // willChange: \"scroll-position\",\n // backfaceVisibility: \"hidden\",\n width: \"100%\",\n height: \"100%\",\n padding: 0,\n margin: 0,\n ...style,\n }),\n [isHorizontal, style]\n )}\n >\n {children}\n </Element>\n );\n};\n\nconst Inner = ({\n _children: children,\n _store: store,\n _element: Element,\n _style: style,\n _isHorizontal: isHorizontal,\n _isRtl: isRtl,\n}: {\n _children: ReactNode;\n _store: Store;\n _element: \"div\";\n _style: CSSProperties | undefined;\n _isHorizontal: boolean | undefined;\n _isRtl: boolean | undefined;\n}) => {\n const scrollSize = useSyncExternalStore(\n store._subscribe,\n store._getScrollSize\n );\n const viewportSize = useSyncExternalStore(\n store._subscribe,\n store._getViewportSize\n );\n\n return (\n <Element\n style={useMemo<CSSProperties>(() => {\n const clampedScrollSize =\n scrollSize >= viewportSize ? scrollSize : viewportSize;\n const width = isHorizontal ? clampedScrollSize : \"100%\";\n const height = isHorizontal ? \"100%\" : clampedScrollSize;\n return {\n position: \"absolute\",\n top: 0,\n [isRtl ? \"right\" : \"left\"]: 0,\n width,\n height,\n minWidth: width,\n minHeight: height,\n ...style,\n };\n }, [scrollSize, viewportSize, style, isHorizontal, isRtl])}\n >\n {children}\n </Element>\n );\n};\n\nexport interface CustomComponentProps {\n style: CSSProperties;\n children: ReactNode;\n}\n\nexport type CustomComponent = React.ForwardRefExoticComponent<\n React.PropsWithoutRef<CustomComponentProps> & React.RefAttributes<any>\n>;\n\ntype CustomElementType = keyof JSX.IntrinsicElements | CustomComponent;\n\n/**\n * Methods of {@link List}.\n */\nexport interface ListHandle {\n /**\n * Scroll to the item specified by index.\n * @param index index of item\n */\n scrollToIndex(index: number): void;\n}\n\n/**\n * Props of {@link List}.\n */\nexport interface ListProps {\n /**\n * Elements rendered by this component.\n */\n children: ReactNode;\n /**\n * Item size hint for unmeasured items. It's recommended to specify this prop if item sizes are fixed and known, or much larger than the defaultValue. It will help to reduce scroll jump when items are measured.\n * @defaultValue 40\n */\n itemSize?: number;\n /**\n * Number of items to render above/below the visible bounds of the list. You can increase to avoid showing blank items in fast scrolling.\n * @defaultValue 6\n */\n overscan?: number;\n /**\n * If true, rendered as a horizontally scrollable list. Otherwise rendered as a vertically scrollable list.\n */\n horizontal?: boolean;\n /**\n * You have to set true if you use this component under `direction: rtl` style.\n */\n rtl?: boolean;\n /**\n * Number of items to be the margin from the end of the scroll. See also {@link onEndReached}.\n * @defaultValue 0\n */\n endThreshold?: number;\n /**\n * Inline style prop to override style of scrollable element.\n */\n style?: CSSProperties;\n /**\n * Inline style prop to override style of inner element.\n */\n innerStyle?: CSSProperties;\n /**\n * Customized element type for scrollable element.\n * @defaultValue \"div\"\n */\n element?: CustomElementType;\n /**\n * Customized element type for inner element.\n * @defaultValue \"div\"\n */\n innerElement?: CustomElementType;\n /**\n * Customized element type for item element.\n * @defaultValue \"div\"\n */\n itemElement?: CustomElementType;\n /**\n * Callback invoked when scrolling reached to the end. The margin from the end is specified by {@link endThreshold}.\n */\n onEndReached?: () => void;\n}\n\n/**\n * Virtualized list component. See {@link ListProps} and {@link ListHandle}.\n */\nexport const List = forwardRef<ListHandle, ListProps>(\n (\n {\n children,\n itemSize = 40,\n overscan = 6,\n horizontal: isHorizontal,\n rtl: isRtl,\n endThreshold = 0,\n style: styleProp,\n innerStyle: innerStyleProp,\n element = \"div\",\n innerElement = \"div\",\n itemElement = \"div\",\n onEndReached,\n },\n ref\n ): ReactElement => {\n // memoize element count\n const rawCount = useMemo(() => {\n let i = 0;\n Children.forEach(children, (e) => {\n if (isInvalidElement(e)) {\n return;\n }\n i++;\n });\n return i;\n }, [children]);\n\n const store = useVirtualStore(rawCount, itemSize, isHorizontal);\n const startIndex = useSyncExternalStore(\n store._subscribe,\n store._getStartIndex\n );\n const endIndex = useSyncExternalStore(store._subscribe, store._getEndIndex);\n const jump = useSyncExternalStore(store._subscribe, store._getJump);\n const scrollRef = useRef<HTMLDivElement>(null);\n const onEndReachedCalledIndex = useRef<number>(INITIAL_END_REACHED_INDEX);\n\n const handleRef = useRef<ObserverHandle>();\n const handle =\n handleRef.current ||\n (handleRef.current = ((): ObserverHandle => {\n // For SSR\n if (typeof ResizeObserver === \"undefined\") {\n return {} as any as ObserverHandle;\n }\n let prevOffset = -1;\n let scrollDirection: ScrollDirection = SCROLL_STOP;\n let resized = false;\n let isNegativeOffset: boolean | undefined;\n let rootElement: HTMLElement | undefined;\n const scrollToKey = isHorizontal ? \"scrollLeft\" : \"scrollTop\";\n const mountedIndexes = new WeakMap<Element, number>();\n const ro = new ResizeObserver((entries) => {\n const resizes: [index: number, size: number][] = [];\n for (const entry of entries) {\n if (entry.target === rootElement) {\n store._update({\n _type: UPDATE_VIEWPORT_SIZE,\n _width: entry.contentRect.width,\n _height: entry.contentRect.height,\n });\n } else {\n const index = mountedIndexes.get(entry.target);\n if (index != null) {\n resizes.push([\n index,\n entry.contentRect[isHorizontal ? \"width\" : \"height\"],\n ]);\n }\n }\n }\n\n if (resizes.length) {\n store._update({\n _type: UPDATE_ITEM_SIZES,\n _entries: resizes,\n });\n resized = true;\n }\n });\n\n return {\n _initRoot(root) {\n rootElement = root;\n\n const syncViewportToScrollPosition = () => {\n let offset = root[scrollToKey];\n if (isRtl) {\n // The scroll position may be negative value in rtl direction.\n // https://github.com/othree/jquery.rtl-scroll-type\n offset = abs(offset);\n }\n if (prevOffset === offset) {\n return;\n }\n // Skip scroll direction detection just after resizing because it may result in the opposite direction.\n // Scroll events are dispatched enough so it's ok to skip some of them.\n if (scrollDirection === SCROLL_STOP || !resized) {\n // Ignore until manual scrolling\n if (scrollDirection !== SCROLL_MANUAL) {\n scrollDirection =\n prevOffset > offset ? SCROLL_UP : SCROLL_DOWN;\n }\n } else {\n resized = false;\n }\n store._update({\n _type: HANDLE_SCROLL,\n _offset: (prevOffset = offset),\n });\n };\n\n const onScrollStopped = debounce(() => {\n // Check scroll position once just after scrolling stopped\n syncViewportToScrollPosition();\n scrollDirection = SCROLL_STOP;\n }, 300);\n\n const onScroll = () => {\n syncViewportToScrollPosition();\n onScrollStopped();\n };\n\n ro.observe(root);\n root.addEventListener(\"scroll\", onScroll);\n\n return () => {\n ro.disconnect();\n root.removeEventListener(\"scroll\", onScroll);\n onScrollStopped._cancel();\n };\n },\n _initItem(el, i) {\n mountedIndexes.set(el, i);\n ro.observe(el);\n return () => {\n mountedIndexes.delete(el);\n ro.unobserve(el);\n };\n },\n _getScrollDirection() {\n return scrollDirection;\n },\n _updateScrollPosition(offset, diff) {\n if (!rootElement) return;\n if (isRtl) {\n if (isNegativeOffset == null) {\n // Assume offset type in rtl direction.\n // The scroll position is negative in spec however its not in some browsers, for example Chrome earlier than v85.\n // https://github.com/othree/jquery.rtl-scroll-type\n const prev = rootElement[scrollToKey];\n rootElement[scrollToKey] = 1;\n isNegativeOffset = rootElement[scrollToKey] === 0;\n rootElement[scrollToKey] = prev;\n }\n if (isNegativeOffset) {\n offset *= -1;\n }\n }\n if (diff) {\n rootElement[scrollToKey] += offset;\n } else {\n rootElement[scrollToKey] = offset;\n scrollDirection = SCROLL_MANUAL;\n }\n },\n };\n })());\n\n // The elements length and cached items length are different just after element is added/removed.\n const count = min(rawCount, store._getItemCount());\n\n const startIndexWithMargin = max(startIndex - overscan, 0);\n const endIndexWithMargin = min(endIndex + overscan, count - 1);\n\n // So update cache length. Updating state in render will cause warn so use useEffect for now.\n useIsomorphicLayoutEffect(() => {\n store._update({\n _type: UPDATE_CACHE_LENGTH,\n _length: rawCount,\n });\n }, [rawCount]);\n\n useIsomorphicLayoutEffect(() => handle._initRoot(scrollRef.current!), []);\n\n useIsomorphicLayoutEffect(() => {\n if (!jump.length) return;\n\n // Compensate scroll jump\n const scrollDirection = handle._getScrollDirection();\n if (scrollDirection === SCROLL_UP) {\n const diff = jump.reduce((acc, [, j]) => acc + j, 0);\n if (diff) {\n handle._updateScrollPosition(diff, true);\n }\n } else if (scrollDirection === SCROLL_MANUAL) {\n const isStartInView = startIndex === 0;\n const isEndInView = endIndex - (count - 1) === 0;\n const diff = jump.reduce((acc, [index, j]) => {\n if (index < startIndex) {\n // Keep start if scroll position is not stuck to the start\n if (!isStartInView) {\n acc += j;\n }\n } else {\n // Keep end if scroll position is stuck to the end\n if (!isStartInView && isEndInView) {\n acc += j;\n }\n }\n return acc;\n }, 0);\n if (diff) {\n handle._updateScrollPosition(diff, true);\n }\n } else {\n // NOP\n }\n }, [jump]);\n\n useEffect(() => {\n if (!onEndReached) return;\n\n if (onEndReachedCalledIndex.current > count) {\n // Probably items have been refreshed, so reset index\n onEndReachedCalledIndex.current = INITIAL_END_REACHED_INDEX;\n }\n\n const endMargin = count - 1 - endIndex;\n if (\n endMargin <= endThreshold &&\n onEndReachedCalledIndex.current < count\n ) {\n onEndReachedCalledIndex.current = count;\n onEndReached();\n }\n }, [endIndex]);\n\n useImperativeHandle(\n ref,\n () => ({\n scrollToIndex: async (index) => {\n const el = scrollRef.current;\n if (!el) return;\n\n index = max(min(index, count - 1), 0);\n\n const getOffset = (): number => {\n let offset = store._getItemOffset(index);\n // Use element's scrollHeight/scrollWidth instead of stored scrollSize.\n // This is because stored size may differ from the actual size, for example when a new item is added and not yet measured.\n const scrollSize = isHorizontal ? el.scrollWidth : el.scrollHeight;\n const viewportSize = store._getViewportSize();\n if (scrollSize - (offset + viewportSize) <= 0) {\n // Adjust if the offset is over the end, to get correct startIndex.\n offset = scrollSize - viewportSize;\n }\n return offset;\n };\n\n if (store._hasUnmeasuredItemsInRange(index)) {\n do {\n // In order to scroll to the correct position, mount the items and measure their sizes before scrolling.\n store._update({\n _type: HANDLE_SCROLL,\n _offset: getOffset(),\n });\n try {\n // Wait for the scroll destination items to be measured.\n await store._waitForScrollDestinationItemsMeasured();\n } catch (e) {\n // canceled\n return;\n }\n } while (store._hasUnmeasuredItemsInRange(index));\n\n // Scroll with the updated value\n handle._updateScrollPosition(getOffset());\n } else {\n const offset = getOffset();\n handle._updateScrollPosition(offset);\n // Sync viewport to scroll destination\n store._update({ _type: HANDLE_SCROLL, _offset: offset });\n }\n },\n }),\n [count]\n );\n\n const items = useMemo(() => {\n let i = -1;\n return Children.map(children, (e) => {\n if (isInvalidElement(e)) {\n return;\n }\n i++;\n if (i < startIndexWithMargin || i > endIndexWithMargin) {\n return;\n }\n return e != null ? (\n <Item\n key={(e as { key?: ReactElement[\"key\"] })?.key || i}\n _handle={handle}\n _store={store}\n _index={i}\n _element={itemElement as \"div\"}\n _isHorizontal={isHorizontal}\n _isRtl={isRtl}\n _children={e}\n />\n ) : null;\n });\n }, [children, startIndexWithMargin, endIndexWithMargin]);\n\n return (\n <Window\n _ref={scrollRef}\n _isHorizontal={isHorizontal}\n _element={element as \"div\"}\n _style={styleProp}\n _children={\n <Inner\n _store={store}\n _element={innerElement as \"div\"}\n _style={innerStyleProp}\n _isHorizontal={isHorizontal}\n _isRtl={isRtl}\n _children={items}\n />\n }\n />\n );\n }\n);\n","import { useRef } from \"react\";\nimport {\n findStartIndexWithOffset,\n resetCache,\n getItemSize,\n computeTotalSize,\n findEndIndex,\n computeStartOffset,\n Cache,\n UNCACHED,\n setItemSize,\n hasUnmeasuredItemsInRange,\n} from \"./cache\";\nimport type { Writeable } from \"./types\";\n\nexport const UPDATE_CACHE_LENGTH = 0;\nexport const UPDATE_ITEM_SIZES = 1;\nexport const UPDATE_VIEWPORT_SIZE = 2;\nexport const HANDLE_SCROLL = 3;\n\nexport type ScrollJump = Readonly<[index: number, sizeDiff: number][]>;\n\ntype State = {\n _startIndex: number;\n _viewportWidth: number;\n _viewportHeight: number;\n _cache: Cache;\n _jump: ScrollJump;\n};\n\ntype Actions =\n | { _type: typeof UPDATE_CACHE_LENGTH; _length: number }\n | {\n _type: typeof UPDATE_ITEM_SIZES;\n _entries: [index: number, size: number][];\n }\n | { _type: typeof UPDATE_VIEWPORT_SIZE; _width: number; _height: number }\n | { _type: typeof HANDLE_SCROLL; _offset: number };\n\nconst mutate = (state: State, action: Actions, itemSize: number): boolean => {\n switch (action._type) {\n case UPDATE_CACHE_LENGTH: {\n if (state._cache._length === action._length) return false;\n state._cache = resetCache(action._length, itemSize, state._cache);\n return true;\n }\n case UPDATE_ITEM_SIZES: {\n const updated = action._entries.filter(\n ([index, size]) => state._cache._sizes[index] !== size\n );\n // Skip if all items are cached and not updated\n if (!updated.length) {\n return false;\n }\n\n const jump: [index: number, sizeDiff: number][] = [];\n updated.forEach(([index, size]) => {\n jump.push([index, size - getItemSize(state._cache, index)]);\n setItemSize(state._cache as Writeable<Cache>, index, size);\n });\n state._jump = jump;\n return true;\n }\n case UPDATE_VIEWPORT_SIZE: {\n if (\n state._viewportWidth === action._width &&\n state._viewportHeight === action._height\n ) {\n return false;\n }\n state._viewportWidth = action._width;\n state._viewportHeight = action._height;\n return true;\n }\n case HANDLE_SCROLL: {\n const prevStartIndex = state._startIndex;\n const prevOffset = computeStartOffset(\n state._cache as Writeable<Cache>,\n prevStartIndex\n );\n if (prevOffset === action._offset) {\n return false;\n }\n return (\n (state._startIndex = findStartIndexWithOffset(\n state._cache,\n action._offset,\n prevStartIndex,\n prevOffset\n )) !== prevStartIndex\n );\n }\n }\n};\n\nexport type Store = {\n _getStartIndex(): number;\n _getEndIndex(): number;\n _isUnmeasuredItem(index: number): boolean;\n _hasUnmeasuredItemsInRange(startIndex: number): boolean;\n _getItemOffset(index: number): number;\n _getViewportSize(): number;\n _getScrollSize(): number;\n _getItemCount(): number;\n _getJump(): ScrollJump;\n _waitForScrollDestinationItemsMeasured(): Promise<void>;\n _subscribe(cb: () => void): () => void;\n _update(action: Actions): void;\n};\n\n// https://github.com/facebook/react/issues/25191#issuecomment-1237456448\nexport const useVirtualStore = (\n itemCount: number,\n itemSize: number,\n isHorizontal: boolean | undefined\n): Store => {\n const ref = useRef<Store | undefined>();\n return (\n ref.current ||\n (ref.current = (() => {\n const subscribers = new Set<() => void>();\n const state: Readonly<State> = {\n _startIndex: 0,\n _viewportWidth: 0,\n _viewportHeight: 0,\n _cache: resetCache(itemCount, itemSize),\n _jump: [],\n };\n const getViewportSize = (): number =>\n isHorizontal ? state._viewportWidth : state._viewportHeight;\n\n let scrollToQueue: [() => void, () => void] | undefined;\n\n return {\n _getStartIndex() {\n return state._startIndex;\n },\n _getEndIndex() {\n return findEndIndex(\n state._cache,\n state._startIndex,\n getViewportSize()\n );\n },\n _isUnmeasuredItem(index) {\n return state._cache._sizes[index] === UNCACHED;\n },\n _hasUnmeasuredItemsInRange(startIndex) {\n return hasUnmeasuredItemsInRange(\n state._cache,\n startIndex,\n findEndIndex(state._cache, startIndex, getViewportSize())\n );\n },\n _getItemOffset(index) {\n return computeStartOffset(state._cache as Writeable<Cache>, index);\n },\n _getViewportSize() {\n return getViewportSize();\n },\n _getScrollSize() {\n return computeTotalSize(state._cache as Writeable<Cache>);\n },\n _getItemCount() {\n return state._cache._length;\n },\n _getJump() {\n return state._jump;\n },\n _waitForScrollDestinationItemsMeasured() {\n if (scrollToQueue) {\n // Cancel waiting scrollTo\n scrollToQueue[1]();\n }\n // The measurement will be done asynchronously and the timing is not predictable so we use promise.\n // For example, ResizeObserver may not fire when window is not visible.\n return new Promise((resolve, reject) => {\n scrollToQueue = [\n () => {\n // HACK: It should be resolved in the next microtask that is after React's render\n Promise.resolve().then(() => {\n resolve();\n scrollToQueue = undefined;\n });\n },\n reject,\n ];\n });\n },\n _subscribe(cb) {\n subscribers.add(cb);\n return () => {\n subscribers.delete(cb);\n };\n },\n _update(action) {\n const mutated = mutate(state, action, itemSize);\n if (mutated) {\n subscribers.forEach((cb) => {\n cb();\n });\n if (scrollToQueue && action._type === UPDATE_ITEM_SIZES) {\n scrollToQueue[0]();\n }\n }\n },\n };\n })())\n );\n};\n"],"names":["min","Math","max","abs","range","length","cb","Array","from","_","i","getItemSize","cache","index","size","_sizes","_defaultItemSize","findIndex","distance","sum","_length","h","findEndIndex","computeStartOffset","_measuredOffsetIndex","_offsets","top","resetCache","itemSize","_a","useIsomorphicLayoutEffect","window","useLayoutEffect","useEffect","useSyncExternalStore","subscibe","getSnapShot","_useSyncExternalStore","Item","memo","_children","children","_handle","handle","_store","store","_index","_element","Element","_isHorizontal","isHorizontal","_isRtl","isRtl","ref","useRef","offset","_subscribe","_getItemOffset","hide","_isUnmeasuredItem","_initItem","current","_jsx","style","useMemo","margin","padding","position","display","visibility","isInvalidElement","e","Window","_ref","_style","overflow","contain","width","height","Inner","scrollSize","_getScrollSize","viewportSize","_getViewportSize","clampedScrollSize","minWidth","minHeight","List","forwardRef","overscan","horizontal","rtl","endThreshold","styleProp","innerStyle","innerStyleProp","element","innerElement","itemElement","onEndReached","rawCount","Children","forEach","useVirtualStore","itemCount","subscribers","Set","state","_startIndex","_viewportWidth","_viewportHeight","_cache","_jump","getViewportSize","scrollToQueue","_getStartIndex","_getEndIndex","_hasUnmeasuredItemsInRange","startIndex","hasUnmeasuredItemsInRange","endIndex","lastIndex","computeTotalSize","_getItemCount","_getJump","_waitForScrollDestinationItemsMeasured","Promise","resolve","reject","then","undefined","add","delete","_update","action","mutate","_type","updated","_entries","filter","jump","push","setItemSize","_width","_height","prevStartIndex","prevOffset","_offset","findStartIndexWithOffset","scrollRef","onEndReachedCalledIndex","handleRef","ResizeObserver","isNegativeOffset","rootElement","scrollDirection","resized","scrollToKey","mountedIndexes","WeakMap","ro","entries","resizes","entry","target","contentRect","get","_initRoot","root","syncViewportToScrollPosition","onScrollStopped","debounce","id","cancel","clearTimeout","debouncedFn","setTimeout","_cancel","onScroll","observe","addEventListener","disconnect","removeEventListener","el","set","unobserve","_getScrollDirection","_updateScrollPosition","diff","prev","count","startIndexWithMargin","endIndexWithMargin","reduce","acc","j","isStartInView","isEndInView","useImperativeHandle","scrollToIndex","async","getOffset","scrollWidth","scrollHeight","items","map","key"],"mappings":"sQAAO,MAAMA,EAAMC,KAAKD,IACXE,EAAMD,KAAKC,IACXC,EAAMF,KAAKE,IAEXC,EAAQA,CAAIC,EAAgBC,IACvCC,MAAMC,KAAK,CAAEH,WAAU,CAACI,EAAGC,IAAMJ,EAAGI,KCQzBC,EAAcA,CAACC,EAAcC,KACxC,MAAMC,EAAOF,EAAMG,EAAOF,GAC1B,OAZsB,IAYfC,EAAoBF,EAAMI,EAAmBF,CAAI,EA8BpDG,EAAYA,CAACL,EAAcF,EAAWQ,KAC1C,IAAIC,EAAM,EACV,GAAID,GAAY,EAEd,KAAOR,EAAIE,EAAMQ,EAAU,GAAG,CAC5B,MAAMC,EAAIV,EAAYC,EAAOF,GAG7B,GAFAS,GAAOE,EACPX,IACIS,GAAOD,EAAU,CACfC,EAAME,EAAI,GAAKH,GACjBR,IAEF,KACD,CACF,MAGD,KAAOA,EAAI,GAAG,CACZA,IACA,MAAMW,EAAIV,EAAYC,EAAOF,GAE7B,GADAS,GAAOE,EACHF,GAAOD,EAAU,CACfC,EAAME,EAAI,EAAIH,GAChBR,IAEF,KACD,CACF,CAGH,OAAOV,EAAIE,EAAIQ,EAAG,GAAIE,EAAMQ,EAAU,EAAE,EAY7BE,EAAeL,EAefM,EAAqBA,CAChCX,EACAC,KAEA,IAAKD,EAAMQ,EAAS,OAAO,EAC3B,GAAIR,EAAMY,GAAwBX,EAChC,OAAOD,EAAMa,EAASZ,GAGxB,IAAIa,EAAMd,EAAMa,EAASb,EAAMY,GAC/B,IAAK,IAAId,EAAIE,EAAMY,EAAsBd,GAAKG,IAC5CD,EAAMa,EAASf,GAAKgB,EAChBhB,IAAMG,GAFyCH,IAKnDgB,GAAOf,EAAYC,EAAOF,GAG5B,OADAE,EAAMY,EAAuBX,EACtBa,CAAG,EAGCC,EAAaA,CACxBtB,EACAuB,EACAhB,WAEA,MAAO,CACLI,EAAkBY,EAClBR,EAASf,EACTmB,UACEK,EAACjB,GAASZ,EAAIY,EAAMY,EAAsBnB,EAAS,kBAAO,EAC5DU,EAAQX,EAAMC,GAASK,IAAM,IAAAmB,EAAA,OAA8B,QAA9BA,EAACjB,GAASA,EAAMG,EAAOL,UAAO,IAAAmB,EAAAA,GAlIvC,CAkI+C,IACnEJ,EAAUrB,EAAMC,GAASK,UACvB,OAAM,IAANA,EACI,EAC4B,QAA5BmB,EAACjB,GAASA,EAAMa,EAASf,UAAG,IAAAmB,EAAAA,GAtId,CAsI0B,IAE/C,ECxIUC,EACO,oBAAXC,OAAyBC,EAAkBC,ECFvCC,EAAuBA,CAClCC,EACAC,IAEOC,EAAsBF,EAAUC,EAAaA,GCgDhDE,eAAOC,GACX,EACEC,EAAWC,EACXC,EAASC,EACTC,EAAQC,EACRC,EAAQjC,EACRkC,EAAUC,EACVC,EAAeC,EACfC,EAAQC,MAER,MAAMC,EAAMC,EAAuB,MAE7BC,EAASrB,EAAqBW,EAAMW,GAAY,IACpDX,EAAMY,EAAe5C,KAEjB6C,EAAOxB,EAAqBW,EAAMW,GAAY,IAClDX,EAAMc,EAAkB9C,KAS1B,OALAiB,GACE,IAAMa,EAAOiB,EAAUP,EAAIQ,QAAUhD,IACrC,CAACA,IAIDiD,EAACd,EAAO,CACNK,IAAKA,EACLU,MAAOC,GAAuB,KAC5B,MAAMD,EAAuB,CAC3BE,OAAQ,IACRC,QAAS,IACTC,SAAU,WACV,CAACjB,EAAe,SAAW,SAAU,OACrC,CAACA,EAAe,MAAQE,EAAQ,QAAU,QAAS,EACnD,CAACF,EAAgBE,EAAQ,QAAU,OAAU,OAAQG,GASvD,OANIL,IACFa,EAAMK,QAAU,QAEdV,IACFK,EAAMM,WAAa,UAEdN,CAAK,GACX,CAACR,EAAQL,EAAcE,EAAOM,IAAMjB,SAEtCA,GACO,IAKV6B,EAAwBC,GAAc,MAALA,GAA0B,kBAANA,EAErDC,EAASA,EACbhC,EAAWC,EACXgC,EAAMpB,EACNN,EAAUC,EACV0B,EAAQX,EACRd,EAAeC,KASbY,EAACd,EAAO,CACNK,IAAKA,EACLU,MAAOC,GACL,KAAO,CACLW,SAAUzB,EAAe,cAAgB,cACzCiB,SAAU,WACVS,QAAS,SAITC,MAAO,OACPC,OAAQ,OACRZ,QAAS,EACTD,OAAQ,KACLF,KAEL,CAACb,EAAca,IAGhBtB,SAAAA,IAKDsC,EAAQA,EACZvC,EAAWC,EACXG,EAAQC,EACRE,EAAUC,EACV0B,EAAQX,EACRd,EAAeC,EACfC,EAAQC,MASR,MAAM4B,EAAa9C,EACjBW,EAAMW,EACNX,EAAMoC,GAEFC,EAAehD,EACnBW,EAAMW,EACNX,EAAMsC,GAGR,OACErB,EAACd,EAAO,CACNe,MAAOC,GAAuB,KAC5B,MAAMoB,EACJJ,GAAcE,EAAeF,EAAaE,EACtCL,EAAQ3B,EAAekC,EAAoB,OAC3CN,EAAS5B,EAAe,OAASkC,EACvC,MAAO,CACLjB,SAAU,WACVzC,IAAK,EACL,CAAC0B,EAAQ,QAAU,QAAS,EAC5ByB,QACAC,SACAO,SAAUR,EACVS,UAAWR,KACRf,EACJ,GACA,CAACiB,EAAYE,EAAcnB,EAAOb,EAAcE,aAElDX,GACO,EAyFD8C,eAAOC,GAClB,EAEI/C,WACAb,WAAW,GACX6D,WAAW,EACXC,WAAYxC,EACZyC,IAAKvC,EACLwC,eAAe,EACf7B,MAAO8B,EACPC,WAAYC,EACZC,UAAU,MACVC,eAAe,MACfC,cAAc,MACdC,gBAEF9C,KAGA,MAAM+C,EAAWpC,GAAQ,KACvB,IAAItD,EAAI,EAOR,OANA2F,EAASC,QAAQ7D,GAAW8B,IACtBD,EAAiBC,IAGrB7D,GAAG,IAEEA,CAAC,GACP,CAAC+B,IAEEI,ECvMqB0D,EAC7BC,EACA5E,EACAsB,KAEA,MAAMG,EAAMC,IACZ,OACED,EAAIQ,UACHR,EAAIQ,QAAU,MACb,MAAM4C,EAAc,IAAIC,IAClBC,EAAyB,CAC7BC,EAAa,EACbC,EAAgB,EAChBC,EAAiB,EACjBC,EAAQpF,EAAW6E,EAAW5E,GAC9BoF,EAAO,IAEHC,EAAkBA,IACtB/D,EAAeyD,EAAME,EAAiBF,EAAMG,EAE9C,IAAII,EAEJ,MAAO,CACLC,EAAcA,IACLR,EAAMC,EAEfQ,EAAYA,IACH9F,EACLqF,EAAMI,EACNJ,EAAMC,EACNK,KAGJtD,EAAkB9C,IJ7IF,II8IP8F,EAAMI,EAAOhG,EAAOF,GAE7BwG,EAA2BC,GJ1DMC,EACvC3G,EACA0G,EACAE,KAEA,IAAK,IAAI9G,EAAI4G,EAAY5G,GAAK8G,EAAU9G,IACtC,IA5FoB,IA4FhBE,EAAMG,EAAOL,GACf,OAAO,EAGX,OAAO,CAAK,EIiDG6G,CACLZ,EAAMI,EACNO,EACAhG,EAAaqF,EAAMI,EAAQO,EAAYL,MAG3CxD,EAAe5C,GACNU,EAAmBoF,EAAMI,EAA4BlG,GAE9DsE,EAAgBA,IACP8B,IAEThC,EAAcA,IJpIWrE,KAC/B,IAAKA,EAAMQ,EAAS,OAAO,EAC3B,MAAMqG,EAAY7G,EAAMQ,EAAU,EAClC,GAAIR,EAAMY,GAAwBiG,EAChC,OAAO7G,EAAMa,EAASgG,GAAc9G,EAAYC,EAAO6G,GAGzD,IAAI/F,EAAMd,EAAMa,EAASb,EAAMY,GAC/B,IAAK,IAAId,EAAIE,EAAMY,EAAsBd,GAAK+G,EAAW/G,IACvDE,EAAMa,EAASf,GAAKgB,EACpBA,GAAOf,EAAYC,EAAOF,GAI5B,OADAE,EAAMY,EAAuBiG,EACtB/F,CAAG,EIuHKgG,CAAiBf,EAAMI,GAEhCY,EAAaA,IACJhB,EAAMI,EAAO3F,EAEtBwG,EAAQA,IACCjB,EAAMK,EAEfa,EAAsCA,KAChCX,GAEFA,EAAc,KAIT,IAAIY,SAAQ,CAACC,EAASC,KAC3Bd,EAAgB,CACd,KAEEY,QAAQC,UAAUE,MAAK,KACrBF,IACAb,OAAgBgB,CAAS,GACzB,EAEJF,EACD,KAGLxE,EAAWlD,IACTmG,EAAY0B,IAAI7H,GACT,KACLmG,EAAY2B,OAAO9H,EAAG,GAG1B+H,EAAQC,GA5JDC,EAAC5B,EAAc2B,EAAiB1G,KAC7C,OAAQ0G,EAAOE,GACb,KA1B+B,EA2B7B,OAAI7B,EAAMI,EAAO3F,IAAYkH,EAAOlH,IACpCuF,EAAMI,EAASpF,EAAW2G,EAAOlH,EAASQ,EAAU+E,EAAMI,IACnD,GAET,KA9B6B,EA8BL,CACtB,MAAM0B,EAAUH,EAAOI,EAASC,QAC9B,EAAE9H,EAAOC,KAAU6F,EAAMI,EAAOhG,EAAOF,KAAWC,IAGpD,IAAK2H,EAAQpI,OACX,OAAO,EAGT,MAAMuI,EAA4C,GAMlD,OALAH,EAAQnC,SAAQ,EAAEzF,EAAOC,MACvB8H,EAAKC,KAAK,CAAChI,EAAOC,EAAOH,EAAYgG,EAAMI,EAAQlG,KJvChCiI,EACzBlI,EACAC,EACAC,KAEAF,EAAMG,EAAOF,GAASC,EAEtBF,EAAMY,EAAuBxB,EAAIa,EAAOD,EAAMY,EAAqB,EIiC7DsH,CAAYnC,EAAMI,EAA4BlG,EAAOC,EAAK,IAE5D6F,EAAMK,EAAQ4B,GACP,CACR,CACD,KA9CgC,EA+C9B,OACEjC,EAAME,IAAmByB,EAAOS,GAChCpC,EAAMG,IAAoBwB,EAAOU,KAInCrC,EAAME,EAAiByB,EAAOS,EAC9BpC,EAAMG,EAAkBwB,EAAOU,GACxB,GAET,KAxDyB,EAwDL,CAClB,MAAMC,EAAiBtC,EAAMC,EACvBsC,EAAa3H,EACjBoF,EAAMI,EACNkC,GAEF,OAAIC,IAAeZ,EAAOa,IAIvBxC,EAAMC,EJNyBwC,EACtCxI,EACA2C,EACA0F,EACAC,IAEOjI,EAAUL,EAAOqI,EAAgB1F,EAAS2F,GIAtBE,CACnBzC,EAAMI,EACNuB,EAAOa,EACPF,EACAC,MACKD,CAEV,EAAA,EAyGqBV,CAAO5B,EAAO2B,EAAQ1G,KAEpC6E,EAAYH,SAAShG,IACnBA,GAAI,IAEF4G,GAzLiB,IAyLAoB,EAAOE,GAC1BtB,EAAc,KAGnB,EAEJ,EAxFc,GAwFV,EDuGSX,CAAgBH,EAAUxE,EAAUsB,GAC5CoE,EAAapF,EACjBW,EAAMW,EACNX,EAAMsE,GAEFK,EAAWtF,EAAqBW,EAAMW,EAAYX,EAAMuE,GACxDwB,EAAO1G,EAAqBW,EAAMW,EAAYX,EAAM+E,GACpDyB,EAAY/F,EAAuB,MACnCgG,EAA0BhG,GA3RF,GA6RxBiG,EAAYjG,IACZX,EACJ4G,EAAU1F,UACT0F,EAAU1F,QAAU,MAEnB,GAA8B,oBAAnB2F,eACT,MAAO,GAET,IAGIC,EACAC,EAJAR,GAAc,EACdS,EAhTQ,EAiTRC,GAAU,EAGd,MAAMC,EAAc3G,EAAe,aAAe,YAC5C4G,EAAiB,IAAIC,QACrBC,EAAK,IAAIR,gBAAgBS,IAC7B,MAAMC,EAA2C,GACjD,IAAK,MAAMC,KAASF,EAClB,GAAIE,EAAMC,SAAWV,EACnB7G,EAAMwF,EAAQ,CACZG,ECnUoB,EDoUpBO,EAAQoB,EAAME,YAAYxF,MAC1BmE,EAASmB,EAAME,YAAYvF,aAExB,CACL,MAAMjE,EAAQiJ,EAAeQ,IAAIH,EAAMC,QAC1B,MAATvJ,GACFqJ,EAAQrB,KAAK,CACXhI,EACAsJ,EAAME,YAAYnH,EAAe,QAAU,WAGhD,CAGCgH,EAAQ7J,SACVwC,EAAMwF,EAAQ,CACZG,ECrVmB,EDsVnBE,EAAUwB,IAEZN,GAAU,EACX,IAGH,MAAO,CACLW,EAAUC,GACRd,EAAcc,EAEd,MAAMC,EAA+BA,KACnC,IAAIlH,EAASiH,EAAKX,GACdzG,IAGFG,EAASpD,EAAIoD,IAEX2F,IAAe3F,IA9Vb,IAmWFoG,GAAoCC,EAOtCA,GAAU,EAvWJ,IAkWFD,IACFA,EACET,EAAa3F,EArWf,EADE,GA2WNV,EAAMwF,EAAQ,CACZG,ECpXa,EDqXbW,EAAUD,EAAa3F,IACvB,EAGEmH,EJpYMC,MAItB,IAAIC,EAA4B,KAEhC,MAAMC,EAASA,KACH,MAAND,GACFE,aAAaF,EACd,EAEGG,EAAcA,KAClBF,IACAD,EAAKI,YAAW,KACdJ,EAAK,KIwXGH,IACAd,EArXM,CJHV,GIyXK,IJxXL,EAGR,OADAoB,EAAYE,EAAUJ,EACfE,CAAW,EIiXgBJ,GAMlBO,EAAWA,KACfT,IACAC,GAAiB,EAMnB,OAHAV,EAAGmB,QAAQX,GACXA,EAAKY,iBAAiB,SAAUF,GAEzB,KACLlB,EAAGqB,aACHb,EAAKc,oBAAoB,SAAUJ,GACnCR,EAAgBO,GAAS,CAE5B,EACDrH,EAASA,CAAC2H,EAAI7K,KACZoJ,EAAe0B,IAAID,EAAI7K,GACvBsJ,EAAGmB,QAAQI,GACJ,KACLzB,EAAe1B,OAAOmD,GACtBvB,EAAGyB,UAAUF,EAAG,GAGpBG,GAAmBA,IACV/B,EAETgC,GAAsBpI,EAAQqI,GAC5B,GAAKlC,EAAL,CACA,GAAItG,EAAO,CACT,GAAwB,MAApBqG,EAA0B,CAI5B,MAAMoC,EAAOnC,EAAYG,GACzBH,EAAYG,GAAe,EAC3BJ,EAAgD,IAA7BC,EAAYG,GAC/BH,EAAYG,GAAegC,CAC5B,CACGpC,IACFlG,IAAW,EAEd,CACGqI,EACFlC,EAAYG,IAAgBtG,GAE5BmG,EAAYG,GAAetG,EAC3BoG,EAlaQ,EA+YQ,CAqBnB,EAEJ,EA/HoB,IAkIjBmC,EAAQ9L,EAAIoG,EAAUvD,EAAM8E,KAE5BoE,EAAuB7L,EAAIoH,EAAa7B,EAAU,GAClDuG,EAAqBhM,EAAIwH,EAAW/B,EAAUqG,EAAQ,GAG5DhK,GAA0B,KACxBe,EAAMwF,EAAQ,CACZG,EC9b2B,ED+b3BpH,EAASgF,GACT,GACD,CAACA,IAEJtE,GAA0B,IAAMa,EAAO4H,EAAUlB,EAAUxF,UAAW,IAEtE/B,GAA0B,KACxB,IAAK8G,EAAKvI,OAAQ,OAGlB,MAAMsJ,EAAkBhH,EAAO+I,KAC/B,GA9bY,IA8bR/B,EAA+B,CACjC,MAAMiC,EAAOhD,EAAKqD,QAAO,CAACC,GAAQC,CAAAA,KAAOD,EAAMC,GAAG,GAC9CP,GACFjJ,EAAOgJ,GAAsBC,GAAM,EAEtC,MAAM,GAlcS,IAkcLjC,EAAmC,CAC5C,MAAMyC,EAA+B,IAAf9E,EAChB+E,EAAc7E,GAAYsE,EAAQ,IAAO,EACzCF,EAAOhD,EAAKqD,QAAO,CAACC,GAAMrL,EAAOsL,MACjCtL,EAAQyG,EAEL8E,IACHF,GAAOC,IAIJC,GAAiBC,IACpBH,GAAOC,GAGJD,IACN,GACCN,GACFjJ,EAAOgJ,GAAsBC,GAAM,EAEtC,CAAM,GAGN,CAAChD,IAEJ3G,GAAU,KACHkE,IAEDmD,EAAwBzF,QAAUiI,IAEpCxC,EAAwBzF,SAzdE,GA4dViI,EAAQ,EAAItE,GAEf5B,GACb0D,EAAwBzF,QAAUiI,IAElCxC,EAAwBzF,QAAUiI,EAClC3F,KACD,GACA,CAACqB,IAEJ8E,EACEjJ,GACA,KAAO,CACLkJ,cAAeC,UACb,MAAMjB,EAAKlC,EAAUxF,QACrB,IAAK0H,EAAI,OAET1K,EAAQX,EAAIF,EAAIa,EAAOiL,EAAQ,GAAI,GAEnC,MAAMW,EAAYA,KAChB,IAAIlJ,EAASV,EAAMY,EAAe5C,GAGlC,MAAMmE,EAAa9B,EAAeqI,EAAGmB,YAAcnB,EAAGoB,aAChDzH,EAAerC,EAAMsC,IAK3B,OAJIH,GAAczB,EAAS2B,IAAiB,IAE1C3B,EAASyB,EAAaE,GAEjB3B,CAAM,EAGf,GAAIV,EAAMwE,EAA2BxG,GAAQ,CAC3C,EAAG,CAEDgC,EAAMwF,EAAQ,CACZG,ECjhBa,EDkhBbW,EAASsD,MAEX,UAEQ5J,EAAMgF,GACb,CAAC,MAAOtD,GAEP,MACD,CACF,OAAQ1B,EAAMwE,EAA2BxG,IAG1C8B,EAAOgJ,GAAsBc,IAC9B,KAAM,CACL,MAAMlJ,EAASkJ,IACf9J,EAAOgJ,GAAsBpI,GAE7BV,EAAMwF,EAAQ,CAAEG,ECniBC,EDmiBqBW,EAAS5F,GAChD,MAGL,CAACuI,IAGH,MAAMc,EAAQ5I,GAAQ,KACpB,IAAItD,GAAK,EACT,OAAO2F,EAASwG,IAAIpK,GAAW8B,IAC7B,KAAID,EAAiBC,KAGrB7D,IACIA,EAAIqL,GAAwBrL,EAAIsL,IAGpC,OAAY,MAALzH,EACLT,EAACxB,EAAI,CAEHI,EAASC,EACTC,EAAQC,EACRC,EAAQpC,EACRqC,EAAUmD,EACVjD,EAAeC,EACfC,EAAQC,EACRZ,EAAW+B,IAPLA,aAAA,EAAAA,EAAqCuI,MAAOpM,GASlD,IAAI,GACR,GACD,CAAC+B,EAAUsJ,EAAsBC,IAEpC,OACElI,EAACU,EAAM,CACLC,EAAM4E,EACNpG,EAAeC,EACfH,EAAUiD,EACVtB,EAAQmB,EACRrD,EACEsB,EAACiB,EAAK,CACJnC,EAAQC,EACRE,EAAUkD,EACVvB,EAAQqB,EACR9C,EAAeC,EACfC,EAAQC,EACRZ,EAAWoK,KAGf"}
|
package/lib/state.d.ts
CHANGED
|
@@ -24,7 +24,6 @@ export type Store = {
|
|
|
24
24
|
_hasUnmeasuredItemsInRange(startIndex: number): boolean;
|
|
25
25
|
_getItemOffset(index: number): number;
|
|
26
26
|
_getViewportSize(): number;
|
|
27
|
-
_isViewportSizeInitialized(): boolean;
|
|
28
27
|
_getScrollSize(): number;
|
|
29
28
|
_getItemCount(): number;
|
|
30
29
|
_getJump(): ScrollJump;
|