react-virtuoso 3.1.4 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +19 -37
- package/dist/index.js +1 -2
- package/dist/index.m.js +3819 -2
- package/dist/react-urx/index.d.ts +112 -0
- package/dist/urx/index.d.ts +7 -0
- package/package.json +29 -40
- package/dist/index.js.map +0 -1
- package/dist/index.m.js.map +0 -1
package/dist/index.m.js
CHANGED
|
@@ -1,2 +1,3819 @@
|
|
|
1
|
-
import{systemToComponent as t}from"@virtuoso.dev/react-urx";import*as e from"@virtuoso.dev/urx";import*as n from"react";import{useLayoutEffect as o,useEffect as r,useRef as i,useCallback as a,createElement as l,useContext as s}from"react";import{flushSync as u}from"react-dom";function c(){return c=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(t[o]=n[o])}return t},c.apply(this,arguments)}function m(t,e){if(null==t)return{};var n,o,r={},i=Object.keys(t);for(o=0;o<i.length;o++)e.indexOf(n=i[o])>=0||(r[n]=t[n]);return r}function d(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,o=new Array(e);n<e;n++)o[n]=t[n];return o}function f(t,e){var n="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(n)return(n=n.call(t)).next.bind(n);if(Array.isArray(t)||(n=function(t,e){if(t){if("string"==typeof t)return d(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?d(t,e):void 0}}(t))||e&&t&&"number"==typeof t.length){n&&(t=n);var o=0;return function(){return o>=t.length?{done:!0}:{done:!1,value:t[o++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var p,h,g="undefined"!=typeof document?o:r;!function(t){t[t.DEBUG=0]="DEBUG",t[t.INFO=1]="INFO",t[t.WARN=2]="WARN",t[t.ERROR=3]="ERROR"}(h||(h={}));var v=((p={})[h.DEBUG]="debug",p[h.INFO]="log",p[h.WARN]="warn",p[h.ERROR]="error",p),S=e.system(function(){var t=e.statefulStream(h.ERROR);return{log:e.statefulStream(function(n,o,r){var i;void 0===r&&(r=h.INFO),r>=(null!=(i=("undefined"==typeof globalThis?window:globalThis).VIRTUOSO_LOG_LEVEL)?i:e.getValue(t))&&console[v[r]]("%creact-virtuoso: %c%s %o","color: #0253b3; font-weight: bold","color: initial",n,o)}),logLevel:t}},[],{singleton:!0});function C(t,e){void 0===e&&(e=!0);var n=i(null),o=function(t){};if("undefined"!=typeof ResizeObserver){var r=new ResizeObserver(function(e){var n=e[0].target;null!==n.offsetParent&&t(n)});o=function(t){t&&e?(r.observe(t),n.current=t):(n.current&&r.unobserve(n.current),n.current=null)}}return{ref:n,callbackRef:o}}function I(t,e){return void 0===e&&(e=!0),C(t,e).callbackRef}function T(t,e,n,o,r,i,a){return C(function(n){for(var l=function(t,e,n,o){var r=t.length;if(0===r)return null;for(var i=[],a=0;a<r;a++){var l=t.item(a);if(l&&void 0!==l.dataset.index){var s=parseInt(l.dataset.index),u=parseFloat(l.dataset.knownSize),c=e(l,"offsetHeight");if(0===c&&o("Zero-sized element, this should not happen",{child:l},h.ERROR),c!==u){var m=i[i.length-1];0===i.length||m.size!==c||m.endIndex!==s-1?i.push({startIndex:s,endIndex:s,size:c}):i[i.length-1].endIndex++}}}return i}(n.children,e,0,r),s=n.parentElement;!s.dataset.virtuosoScroller;)s=s.parentElement;var u="window"===s.firstElementChild.dataset.viewportType,c=a?a.scrollTop:u?window.pageYOffset||document.documentElement.scrollTop:s.scrollTop,m=a?a.scrollHeight:u?document.documentElement.scrollHeight:s.scrollHeight,d=a?a.offsetHeight:u?window.innerHeight:s.offsetHeight;o({scrollTop:Math.max(c,0),scrollHeight:m,viewportHeight:d}),null==i||i(function(t,e,n){return"normal"===e||null!=e&&e.endsWith("px")||n("row-gap was not resolved to pixel value correctly",e,h.WARN),"normal"===e?0:parseInt(null!=e?e:"0",10)}(0,getComputedStyle(n).rowGap,r)),null!==l&&t(l)},n)}function w(t,e){return Math.round(t.getBoundingClientRect()[e])}function x(t,e){return Math.abs(t-e)<1.01}function b(t,n,o,l,s){void 0===l&&(l=e.noop);var c=i(null),m=i(null),d=i(null),f=i(!1),p=a(function(e){var o=e.target,r=o===window||o===document,i=r?window.pageYOffset||document.documentElement.scrollTop:o.scrollTop,a=r?document.documentElement.scrollHeight:o.scrollHeight,l=r?window.innerHeight:o.offsetHeight,s=function(){t({scrollTop:Math.max(i,0),scrollHeight:a,viewportHeight:l})};f.current?u(s):s(),f.current=!1,null!==m.current&&(i===m.current||i<=0||i===a-l)&&(m.current=null,n(!0),d.current&&(clearTimeout(d.current),d.current=null))},[t,n]);return r(function(){var t=s||c.current;return l(s||c.current),p({target:t}),t.addEventListener("scroll",p,{passive:!0}),function(){l(null),t.removeEventListener("scroll",p)}},[c,p,o,l,s]),{scrollerRef:c,scrollByCallback:function(t){f.current=!0,c.current.scrollBy(t)},scrollToCallback:function(e){var o=c.current;if(o&&(!("offsetHeight"in o)||0!==o.offsetHeight)){var r,i,a,l="smooth"===e.behavior;if(o===window?(i=Math.max(w(document.documentElement,"height"),document.documentElement.scrollHeight),r=window.innerHeight,a=document.documentElement.scrollTop):(i=o.scrollHeight,r=w(o,"height"),a=o.scrollTop),e.top=Math.ceil(Math.max(Math.min(i-r,e.top),0)),x(r,i)||e.top===a)return t({scrollTop:a,scrollHeight:i,viewportHeight:r}),void(l&&n(!0));l?(m.current=e.top,d.current&&clearTimeout(d.current),d.current=setTimeout(function(){d.current=null,m.current=null,n(!0)},1e3)):m.current=null,o.scrollTo(e)}}}}var y=e.system(function(){var t=e.stream(),n=e.stream(),o=e.statefulStream(0),r=e.stream(),i=e.statefulStream(0),a=e.stream(),l=e.stream(),s=e.statefulStream(0),u=e.statefulStream(0),c=e.statefulStream(0),m=e.statefulStream(0),d=e.stream(),f=e.stream(),p=e.statefulStream(!1),h=e.statefulStream(!1);return e.connect(e.pipe(t,e.map(function(t){return t.scrollTop})),n),e.connect(e.pipe(t,e.map(function(t){return t.scrollHeight})),l),e.connect(n,i),{scrollContainerState:t,scrollTop:n,viewportHeight:a,headerHeight:s,fixedHeaderHeight:u,fixedFooterHeight:c,footerHeight:m,scrollHeight:l,smoothScrollTargetReached:r,react18ConcurrentRendering:h,scrollTo:d,scrollBy:f,statefulScrollTop:i,deviation:o,scrollingInProgress:p}},[],{singleton:!0}),H={lvl:0};function E(t,e,n,o,r){return void 0===o&&(o=H),void 0===r&&(r=H),{k:t,v:e,lvl:n,l:o,r:r}}function R(t){return t===H}function L(){return H}function F(t,e){if(R(t))return H;var n=t.k,o=t.l,r=t.r;if(e===n){if(R(o))return r;if(R(r))return o;var i=O(o);return U(W(t,{k:i[0],v:i[1],l:M(o)}))}return U(W(t,e<n?{l:F(o,e)}:{r:F(r,e)}))}function k(t,e,n){if(void 0===n&&(n="k"),R(t))return[-Infinity,void 0];if(t[n]===e)return[t.k,t.v];if(t[n]<e){var o=k(t.r,e,n);return-Infinity===o[0]?[t.k,t.v]:o}return k(t.l,e,n)}function z(t,e,n){return R(t)?E(e,n,1):e===t.k?W(t,{k:e,v:n}):function(t){return D(G(t))}(W(t,e<t.k?{l:z(t.l,e,n)}:{r:z(t.r,e,n)}))}function B(t,e,n){if(R(t))return[];var o=t.k,r=t.v,i=t.r,a=[];return o>e&&(a=a.concat(B(t.l,e,n))),o>=e&&o<=n&&a.push({k:o,v:r}),o<=n&&(a=a.concat(B(i,e,n))),a}function P(t){return R(t)?[]:[].concat(P(t.l),[{k:t.k,v:t.v}],P(t.r))}function O(t){return R(t.r)?[t.k,t.v]:O(t.r)}function M(t){return R(t.r)?t.l:U(W(t,{r:M(t.r)}))}function W(t,e){return E(void 0!==e.k?e.k:t.k,void 0!==e.v?e.v:t.v,void 0!==e.lvl?e.lvl:t.lvl,void 0!==e.l?e.l:t.l,void 0!==e.r?e.r:t.r)}function V(t){return R(t)||t.lvl>t.r.lvl}function U(t){var e=t.l,n=t.r,o=t.lvl;if(n.lvl>=o-1&&e.lvl>=o-1)return t;if(o>n.lvl+1){if(V(e))return G(W(t,{lvl:o-1}));if(R(e)||R(e.r))throw new Error("Unexpected empty nodes");return W(e.r,{l:W(e,{r:e.r.l}),r:W(t,{l:e.r.r,lvl:o-1}),lvl:o})}if(V(t))return D(W(t,{lvl:o-1}));if(R(n)||R(n.l))throw new Error("Unexpected empty nodes");var r=n.l,i=V(r)?n.lvl-1:n.lvl;return W(r,{l:W(t,{r:r.l,lvl:o-1}),r:D(W(n,{l:r.r,lvl:i})),lvl:r.lvl+1})}function A(t,e,n){return R(t)?[]:N(B(t,k(t,e)[0],n),function(t){return{index:t.k,value:t.v}})}function N(t,e){var n=t.length;if(0===n)return[];for(var o=e(t[0]),r=o.index,i=o.value,a=[],l=1;l<n;l++){var s=e(t[l]),u=s.index,c=s.value;a.push({start:r,end:u-1,value:i}),r=u,i=c}return a.push({start:r,end:Infinity,value:i}),a}function D(t){var e=t.r,n=t.lvl;return R(e)||R(e.r)||e.lvl!==n||e.r.lvl!==n?t:W(e,{l:W(t,{r:e.l}),lvl:n+1})}function G(t){var e=t.l;return R(e)||e.lvl!==t.lvl?t:W(e,{r:W(t,{l:e.r})})}function _(t,e,n,o){void 0===o&&(o=0);for(var r=t.length-1;o<=r;){var i=Math.floor((o+r)/2),a=n(t[i],e);if(0===a)return i;if(-1===a){if(r-o<2)return i-1;r=i-1}else{if(r===o)return i;o=i+1}}throw new Error("Failed binary finding record in array - "+t.join(",")+", searched for "+e)}function j(t,e,n){return t[_(t,e,n)]}var K=e.system(function(){return{recalcInProgress:e.statefulStream(!1)}},[],{singleton:!0});function Y(t){var e=t.size,n=t.startIndex,o=t.endIndex;return function(t){return t.start===n&&(t.end===o||Infinity===t.end)&&t.value===e}}function q(t,e){var n=t.index;return e===n?0:e<n?-1:1}function Z(t,e){var n=t.offset;return e===n?0:e<n?-1:1}function J(t){return{index:t.index,value:t}}function $(t,e,n,o){var r=t,i=0,a=0,l=0,s=0;if(0!==e){l=r[s=_(r,e-1,q)].offset;var u=k(n,e-1);i=u[0],a=u[1],r.length&&r[s].size===k(n,e)[1]&&(s-=1),r=r.slice(0,s+1)}else r=[];for(var c,m=f(A(n,e,Infinity));!(c=m()).done;){var d=c.value,p=d.start,h=d.value,g=p-i,v=g*a+l+g*o;r.push({offset:v,size:h,index:p}),i=p,l=v,a=h}return{offsetTree:r,lastIndex:i,lastOffset:l,lastSize:a}}function Q(t,e){var n=e[0],o=e[1],r=e[3];n.length>0&&(0,e[2])("received item sizes",n,h.DEBUG);var i=t.sizeTree,a=i,l=0;if(o.length>0&&R(i)&&2===n.length){var s=n[0].size,u=n[1].size;a=o.reduce(function(t,e){return z(z(t,e,s),e+1,u)},a)}else{var c=function(t,e){for(var n,o=R(t)?0:Infinity,r=f(e);!(n=r()).done;){var i=n.value,a=i.size,l=i.startIndex,s=i.endIndex;if(o=Math.min(o,l),R(t))t=z(t,0,a);else{var u=A(t,l-1,s+1);if(!u.some(Y(i))){for(var c,m=!1,d=!1,p=f(u);!(c=p()).done;){var h=c.value,g=h.start,v=h.end,S=h.value;m?(s>=g||a===S)&&(t=F(t,g)):(d=S!==a,m=!0),v>s&&s>=g&&S!==a&&(t=z(t,s+1,S))}d&&(t=z(t,l,a))}}}return[t,o]}(a,n);a=c[0],l=c[1]}if(a===i)return t;var m=$(t.offsetTree,l,a,r),d=m.offsetTree;return{sizeTree:a,offsetTree:d,lastIndex:m.lastIndex,lastOffset:m.lastOffset,lastSize:m.lastSize,groupOffsetTree:o.reduce(function(t,e){return z(t,e,X(e,d,r))},L()),groupIndices:o}}function X(t,e,n){if(0===e.length)return 0;var o=j(e,t,q),r=t-o.index,i=o.size*r+(r-1)*n+o.offset;return i>0?i+n:i}function tt(t,e,n){if(function(t){return void 0!==t.groupIndex}(t))return e.groupIndices[t.groupIndex]+1;var o=et("LAST"===t.index?n:t.index,e);return Math.max(0,o,Math.min(n,o))}function et(t,e){if(!nt(e))return t;for(var n=0;e.groupIndices[n]<=t+n;)n++;return t+n}function nt(t){return!R(t.groupOffsetTree)}var ot={offsetHeight:"height",offsetWidth:"width"},rt=e.system(function(t){var n=t[0].log,o=t[1].recalcInProgress,r=e.stream(),i=e.stream(),a=e.statefulStreamFromEmitter(i,0),l=e.stream(),s=e.stream(),u=e.statefulStream(0),m=e.statefulStream([]),d=e.statefulStream(void 0),f=e.statefulStream(void 0),p=e.statefulStream(function(t,e){return w(t,ot[e])}),g=e.statefulStream(void 0),v=e.statefulStream(0),S={offsetTree:[],sizeTree:L(),groupOffsetTree:L(),lastIndex:0,lastOffset:0,lastSize:0,groupIndices:[]},C=e.statefulStreamFromEmitter(e.pipe(r,e.withLatestFrom(m,n,v),e.scan(Q,S),e.distinctUntilChanged()),S);e.connect(e.pipe(m,e.filter(function(t){return t.length>0}),e.withLatestFrom(C,v),e.map(function(t){var e=t[0],n=t[1],o=t[2],r=e.reduce(function(t,e,r){return z(t,e,X(e,n.offsetTree,o)||r)},L());return c({},n,{groupIndices:e,groupOffsetTree:r})})),C),e.connect(e.pipe(i,e.withLatestFrom(C),e.filter(function(t){return t[0]<t[1].lastIndex}),e.map(function(t){var e=t[1];return[{startIndex:t[0],endIndex:e.lastIndex,size:e.lastSize}]})),r),e.connect(d,f);var I=e.statefulStreamFromEmitter(e.pipe(d,e.map(function(t){return void 0===t})),!0);e.connect(e.pipe(f,e.filter(function(t){return void 0!==t&&R(e.getValue(C).sizeTree)}),e.map(function(t){return[{startIndex:0,endIndex:0,size:t}]})),r);var T=e.streamFromEmitter(e.pipe(r,e.withLatestFrom(C),e.scan(function(t,e){var n=e[1];return{changed:n!==t.sizes,sizes:n}},{changed:!1,sizes:S}),e.map(function(t){return t.changed})));e.subscribe(e.pipe(u,e.scan(function(t,e){return{diff:t.prev-e,prev:e}},{diff:0,prev:0}),e.map(function(t){return t.diff})),function(t){t>0?(e.publish(o,!0),e.publish(l,t)):t<0&&e.publish(s,t)}),e.subscribe(e.pipe(u,e.withLatestFrom(n)),function(t){t[0]<0&&(0,t[1])("`firstItemIndex` prop should not be set to less than zero. If you don't know the total count, just use a very high value",{firstItemIndex:u},h.ERROR)});var x=e.streamFromEmitter(l);e.connect(e.pipe(l,e.withLatestFrom(C),e.map(function(t){var e=t[0],n=t[1];if(n.groupIndices.length>0)throw new Error("Virtuoso: prepending items does not work with groups");return P(n.sizeTree).reduce(function(t,n){var o=n.k,r=n.v;return{ranges:[].concat(t.ranges,[{startIndex:t.prevIndex,endIndex:o+e-1,size:t.prevSize}]),prevIndex:o+e,prevSize:r}},{ranges:[],prevIndex:0,prevSize:n.lastSize}).ranges})),r);var b=e.streamFromEmitter(e.pipe(s,e.withLatestFrom(C,v),e.map(function(t){return X(-t[0],t[1].offsetTree,t[2])})));return e.connect(e.pipe(s,e.withLatestFrom(C,v),e.map(function(t){var e=t[0],n=t[1],o=t[2];if(n.groupIndices.length>0)throw new Error("Virtuoso: shifting items does not work with groups");var r=P(n.sizeTree).reduce(function(t,n){var o=n.v;return z(t,Math.max(0,n.k+e),o)},L());return c({},n,{sizeTree:r},$(n.offsetTree,0,r,o))})),C),{data:g,totalCount:i,sizeRanges:r,groupIndices:m,defaultItemSize:f,fixedItemSize:d,unshiftWith:l,shiftWith:s,shiftWithOffset:b,beforeUnshiftWith:x,firstItemIndex:u,gap:v,sizes:C,listRefresh:T,statefulTotalCount:a,trackItemSizes:I,itemSize:p}},e.tup(S,K),{singleton:!0}),it="undefined"!=typeof document&&"scrollBehavior"in document.documentElement.style;function at(t){var e="number"==typeof t?{index:t}:t;return e.align||(e.align="start"),e.behavior&&it||(e.behavior="auto"),e.offset||(e.offset=0),e}var lt=e.system(function(t){var n=t[0],o=n.sizes,r=n.totalCount,i=n.listRefresh,a=n.gap,l=t[1],s=l.scrollingInProgress,u=l.viewportHeight,c=l.scrollTo,m=l.smoothScrollTargetReached,d=l.headerHeight,f=l.footerHeight,p=l.fixedHeaderHeight,g=l.fixedFooterHeight,v=t[2].log,S=e.stream(),C=e.statefulStream(0),I=null,T=null,w=null;function x(){I&&(I(),I=null),w&&(w(),w=null),T&&(clearTimeout(T),T=null),e.publish(s,!1)}return e.connect(e.pipe(S,e.withLatestFrom(o,u,r,C,d,f,v),e.withLatestFrom(a,p,g),e.map(function(t){var n=t[0],o=n[0],r=n[1],a=n[2],l=n[3],u=n[4],c=n[5],d=n[6],f=n[7],p=t[1],g=t[2],v=t[3],C=at(o),b=C.align,y=C.behavior,H=C.offset,E=l-1,R=tt(C,r,E),L=X(R,r.offsetTree,p)+c;"end"===b?(L+=g+k(r.sizeTree,R)[1]-a+v,R===E&&(L+=d)):"center"===b?L+=(g+k(r.sizeTree,R)[1]-a+v)/2:L-=u,H&&(L+=H);var F=function(t){x(),t?(f("retrying to scroll to",{location:o},h.DEBUG),e.publish(S,o)):f("list did not change, scroll successful",{},h.DEBUG)};if(x(),"smooth"===y){var z=!1;w=e.subscribe(i,function(t){z=z||t}),I=e.handleNext(m,function(){F(z)})}else I=e.handleNext(e.pipe(i,function(t){var e=setTimeout(function(){t(!1)},150);return function(n){n&&(t(!0),clearTimeout(e))}}),F);return T=setTimeout(function(){x()},1200),e.publish(s,!0),f("scrolling from index to",{index:R,top:L,behavior:y},h.DEBUG),{top:L,behavior:y}})),c),{scrollToIndex:S,topListHeight:C}},e.tup(rt,y,S),{singleton:!0}),st="up",ut={atBottom:!1,notAtBottomBecause:"NOT_SHOWING_LAST_ITEM",state:{offsetBottom:0,scrollTop:0,viewportHeight:0,scrollHeight:0}},ct=e.system(function(t){var n=t[0],o=n.scrollContainerState,r=n.scrollTop,i=n.viewportHeight,a=n.headerHeight,l=n.footerHeight,s=n.scrollBy,u=e.statefulStream(!1),c=e.statefulStream(!0),m=e.stream(),d=e.stream(),f=e.statefulStream(4),p=e.statefulStream(0),h=e.statefulStreamFromEmitter(e.pipe(e.merge(e.pipe(e.duc(r),e.skip(1),e.mapTo(!0)),e.pipe(e.duc(r),e.skip(1),e.mapTo(!1),e.debounceTime(100))),e.distinctUntilChanged()),!1),g=e.statefulStreamFromEmitter(e.pipe(e.merge(e.pipe(s,e.mapTo(!0)),e.pipe(s,e.mapTo(!1),e.debounceTime(200))),e.distinctUntilChanged()),!1);e.connect(e.pipe(e.combineLatest(e.duc(r),e.duc(p)),e.map(function(t){return t[0]<=t[1]}),e.distinctUntilChanged()),c),e.connect(e.pipe(c,e.throttleTime(50)),d);var v=e.streamFromEmitter(e.pipe(e.combineLatest(o,e.duc(i),e.duc(a),e.duc(l),e.duc(f)),e.scan(function(t,e){var n,o,r=e[0],i=r.scrollTop,a=r.scrollHeight,l=e[1],s={viewportHeight:l,scrollTop:i,scrollHeight:a};return i+l-a>-e[4]?(i>t.state.scrollTop?(n="SCROLLED_DOWN",o=t.state.scrollTop-i):(n="SIZE_DECREASED",o=t.state.scrollTop-i||t.scrollTopDelta),{atBottom:!0,state:s,atBottomBecause:n,scrollTopDelta:o}):{atBottom:!1,notAtBottomBecause:s.scrollHeight>t.state.scrollHeight?"SIZE_INCREASED":l<t.state.viewportHeight?"VIEWPORT_HEIGHT_DECREASING":i<t.state.scrollTop?"SCROLLING_UPWARDS":"NOT_FULLY_SCROLLED_TO_LAST_ITEM_BOTTOM",state:s}},ut),e.distinctUntilChanged(function(t,e){return t&&t.atBottom===e.atBottom}))),S=e.statefulStreamFromEmitter(e.pipe(o,e.scan(function(t,e){var n=e.scrollTop,o=e.scrollHeight,r=e.viewportHeight;return x(t.scrollHeight,o)?{scrollTop:n,scrollHeight:o,jump:0,changed:!1}:t.scrollTop!==n&&o-(n+r)<1?{scrollHeight:o,scrollTop:n,jump:t.scrollTop-n,changed:!0}:{scrollHeight:o,scrollTop:n,jump:0,changed:!0}},{scrollHeight:0,jump:0,scrollTop:0,changed:!1}),e.filter(function(t){return t.changed}),e.map(function(t){return t.jump})),0);e.connect(e.pipe(v,e.map(function(t){return t.atBottom})),u),e.connect(e.pipe(u,e.throttleTime(50)),m);var C=e.statefulStream("down");e.connect(e.pipe(o,e.map(function(t){return t.scrollTop}),e.distinctUntilChanged(),e.scan(function(t,n){return e.getValue(g)?{direction:t.direction,prevScrollTop:n}:{direction:n<t.prevScrollTop?st:"down",prevScrollTop:n}},{direction:"down",prevScrollTop:0}),e.map(function(t){return t.direction})),C),e.connect(e.pipe(o,e.throttleTime(50),e.mapTo("none")),C);var I=e.statefulStream(0);return e.connect(e.pipe(h,e.filter(function(t){return!t}),e.mapTo(0)),I),e.connect(e.pipe(r,e.throttleTime(100),e.withLatestFrom(h),e.filter(function(t){return!!t[1]}),e.scan(function(t,e){return[t[1],e[0]]},[0,0]),e.map(function(t){return t[1]-t[0]})),I),{isScrolling:h,isAtTop:c,isAtBottom:u,atBottomState:v,atTopStateChange:d,atBottomStateChange:m,scrollDirection:C,atBottomThreshold:f,atTopThreshold:p,scrollVelocity:I,lastJumpDueToItemResize:S}},e.tup(y)),mt=e.system(function(t){var n=t[0].log,o=e.statefulStream(!1),r=e.streamFromEmitter(e.pipe(o,e.filter(function(t){return t}),e.distinctUntilChanged()));return e.subscribe(o,function(t){t&&e.getValue(n)("props updated",{},h.DEBUG)}),{propsReady:o,didMount:r}},e.tup(S),{singleton:!0}),dt=e.system(function(t){var n=t[0],o=n.sizes,r=n.listRefresh,i=n.defaultItemSize,a=t[1].scrollTop,l=t[2].scrollToIndex,s=t[3].didMount,u=e.statefulStream(!0),c=e.statefulStream(0);return e.connect(e.pipe(s,e.withLatestFrom(c),e.filter(function(t){return!!t[1]}),e.mapTo(!1)),u),e.subscribe(e.pipe(e.combineLatest(r,s),e.withLatestFrom(u,o,i),e.filter(function(t){var e=t[1],n=t[3];return t[0][1]&&(!R(t[2].sizeTree)||void 0!==n)&&!e}),e.withLatestFrom(c)),function(t){var n=t[1];setTimeout(function(){e.handleNext(a,function(){e.publish(u,!0)}),e.publish(l,n)})}),{scrolledToInitialItem:u,initialTopMostItemIndex:c}},e.tup(rt,y,lt,mt),{singleton:!0});function ft(t){return!!t&&("smooth"===t?"smooth":"auto")}var pt=e.system(function(t){var n=t[0],o=n.totalCount,r=n.listRefresh,i=t[1],a=i.isAtBottom,l=i.atBottomState,s=t[2].scrollToIndex,u=t[3].scrolledToInitialItem,c=t[4],m=c.propsReady,d=c.didMount,f=t[5].log,p=t[6].scrollingInProgress,g=e.statefulStream(!1),v=e.stream(),S=null;function C(t){e.publish(s,{index:"LAST",align:"end",behavior:t})}function I(t){var n=e.handleNext(l,function(n){!t||n.atBottom||"SIZE_INCREASED"!==n.notAtBottomBecause||S||(e.getValue(f)("scrolling to bottom due to increased size",{},h.DEBUG),C("auto"))});setTimeout(n,100)}return e.subscribe(e.pipe(e.combineLatest(e.pipe(e.duc(o),e.skip(1)),d),e.withLatestFrom(e.duc(g),a,u,p),e.map(function(t){var e=t[0],n=e[0],o=e[1]&&t[3],r="auto";return o&&(r=function(t,e){return"function"==typeof t?ft(t(e)):e&&ft(t)}(t[1],t[2]||t[4]),o=o&&!!r),{totalCount:n,shouldFollow:o,followOutputBehavior:r}}),e.filter(function(t){return t.shouldFollow})),function(t){var n=t.totalCount,o=t.followOutputBehavior;S&&(S(),S=null),S=e.handleNext(r,function(){e.getValue(f)("following output to ",{totalCount:n},h.DEBUG),C(o),S=null})}),e.subscribe(e.pipe(e.combineLatest(e.duc(g),o,m),e.filter(function(t){return t[0]&&t[2]}),e.scan(function(t,e){var n=e[1];return{refreshed:t.value===n,value:n}},{refreshed:!1,value:0}),e.filter(function(t){return t.refreshed}),e.withLatestFrom(g,o)),function(t){I(!1!==t[1])}),e.subscribe(v,function(){I(!1!==e.getValue(g))}),e.subscribe(e.combineLatest(e.duc(g),l),function(t){var e=t[1];t[0]&&!e.atBottom&&"VIEWPORT_HEIGHT_DECREASING"===e.notAtBottomBecause&&C("auto")}),{followOutput:g,autoscrollToBottom:v}},e.tup(rt,ct,lt,dt,mt,S,y));function ht(t){return t.reduce(function(t,e){return t.groupIndices.push(t.totalCount),t.totalCount+=e+1,t},{totalCount:0,groupIndices:[]})}var gt=e.system(function(t){var n=t[0],o=n.totalCount,r=n.groupIndices,i=n.sizes,a=t[1],l=a.scrollTop,s=a.headerHeight,u=e.stream(),c=e.stream(),m=e.streamFromEmitter(e.pipe(u,e.map(ht)));return e.connect(e.pipe(m,e.map(function(t){return t.totalCount})),o),e.connect(e.pipe(m,e.map(function(t){return t.groupIndices})),r),e.connect(e.pipe(e.combineLatest(l,i,s),e.filter(function(t){return nt(t[1])}),e.map(function(t){return k(t[1].groupOffsetTree,Math.max(t[0]-t[2],0),"v")[0]}),e.distinctUntilChanged(),e.map(function(t){return[t]})),c),{groupCounts:u,topItemsIndexes:c}},e.tup(rt,y));function vt(t,e){return!(!t||t[0]!==e[0]||t[1]!==e[1])}function St(t,e){return!(!t||t.startIndex!==e.startIndex||t.endIndex!==e.endIndex)}function Ct(t,e,n){return"number"==typeof t?n===st&&"top"===e||"down"===n&&"bottom"===e?t:0:n===st?"top"===e?t.main:t.reverse:"bottom"===e?t.main:t.reverse}function It(t,e){return"number"==typeof t?t:t[e]||0}var Tt=e.system(function(t){var n=t[0],o=n.scrollTop,r=n.viewportHeight,i=n.deviation,a=n.headerHeight,l=n.fixedHeaderHeight,s=e.stream(),u=e.statefulStream(0),c=e.statefulStream(0),m=e.statefulStream(0),d=e.statefulStreamFromEmitter(e.pipe(e.combineLatest(e.duc(o),e.duc(r),e.duc(a),e.duc(s,vt),e.duc(m),e.duc(u),e.duc(l),e.duc(i),e.duc(c)),e.map(function(t){var e=t[0],n=t[1],o=t[2],r=t[3],i=r[0],a=r[1],l=t[4],s=t[6],u=t[7],c=t[8],m=e-u,d=t[5]+s,f=Math.max(o-m,0),p="none",h=It(c,"top"),g=It(c,"bottom");return i-=u,a+=o+s,(i+=o+s)>e+d-h&&(p=st),(a-=u)<e-f+n+g&&(p="down"),"none"!==p?[Math.max(m-o-Ct(l,"top",p)-h,0),m-f-s+n+Ct(l,"bottom",p)+g]:null}),e.filter(function(t){return null!=t}),e.distinctUntilChanged(vt)),[0,0]);return{listBoundary:s,overscan:m,topListHeight:u,increaseViewportBy:c,visibleRange:d}},e.tup(y),{singleton:!0}),wt={items:[],topItems:[],offsetTop:0,offsetBottom:0,top:0,bottom:0,topListHeight:0,totalCount:0,firstItemIndex:0};function xt(t,e,n){if(0===t.length)return[];if(!nt(e))return t.map(function(t){return c({},t,{index:t.index+n,originalIndex:t.index})});for(var o,r=[],i=A(e.groupOffsetTree,t[0].index,t[t.length-1].index),a=void 0,l=0,s=f(t);!(o=s()).done;){var u=o.value;(!a||a.end<u.index)&&(a=i.shift(),l=e.groupIndices.indexOf(a.start)),r.push(c({},u.index===a.start?{type:"group",index:l}:{index:u.index-(l+1)+n,groupIndex:l},{size:u.size,offset:u.offset,originalIndex:u.index,data:u.data}))}return r}function bt(t,e,n,o,r,i){var a=0,l=0;if(t.length>0){a=t[0].offset;var s=t[t.length-1];l=s.offset+s.size}var u=n-r.lastIndex,c=a,m=r.lastOffset+u*r.lastSize+(u-1)*o-l;return{items:xt(t,r,i),topItems:xt(e,r,i),topListHeight:e.reduce(function(t,e){return e.size+t},0),offsetTop:a,offsetBottom:m,top:c,bottom:l,totalCount:n,firstItemIndex:i}}var yt=e.system(function(t){var n=t[0],o=n.sizes,r=n.totalCount,i=n.data,a=n.firstItemIndex,l=n.gap,s=t[1],u=t[2],m=u.visibleRange,d=u.listBoundary,p=u.topListHeight,h=t[3],g=h.scrolledToInitialItem,v=h.initialTopMostItemIndex,S=t[4].topListHeight,C=t[5],I=t[6].didMount,T=t[7].recalcInProgress,w=e.statefulStream([]),x=e.stream();e.connect(s.topItemsIndexes,w);var b=e.statefulStreamFromEmitter(e.pipe(e.combineLatest(I,T,e.duc(m,vt),e.duc(r),e.duc(o),e.duc(v),g,e.duc(w),e.duc(a),e.duc(l),i),e.filter(function(t){return t[0]&&!t[1]}),e.map(function(t){var n=t[2],o=n[0],r=n[1],i=t[3],a=t[5],l=t[6],s=t[7],u=t[8],m=t[9],d=t[10],p=t[4],h=p.sizeTree,g=p.offsetTree;if(0===i||0===o&&0===r)return c({},wt,{totalCount:i});if(R(h))return bt(function(t,e,n){if(nt(e)){var o=et(t,e);return[{index:k(e.groupOffsetTree,o)[0],size:0,offset:0},{index:o,size:0,offset:0,data:n&&n[0]}]}return[{index:t,size:0,offset:0,data:n&&n[0]}]}(function(t,e){return"number"==typeof t?t:"LAST"===t.index?e-1:t.index}(a,i),p,d),[],i,m,p,u);var v=[];if(s.length>0)for(var S,C=s[0],I=s[s.length-1],T=0,w=f(A(h,C,I));!(S=w()).done;)for(var x=S.value,b=x.value,y=Math.max(x.start,C),H=Math.min(x.end,I),E=y;E<=H;E++)v.push({index:E,size:b,offset:T,data:d&&d[E]}),T+=b;if(!l)return bt([],v,i,m,p,u);var L=s.length>0?s[s.length-1]+1:0,F=function(t,e,n,o){return void 0===o&&(o=0),o>0&&(e=Math.max(e,j(t,o,q).offset)),N((i=n,l=_(r=t,e,a=Z),s=_(r,i,a,l),r.slice(l,s+1)),J);var r,i,a,l,s}(g,o,r,L);if(0===F.length)return null;var z=i-1;return bt(e.tap([],function(t){for(var e,n=f(F);!(e=n()).done;){var i=e.value,a=i.value,l=a.offset,s=i.start,u=a.size;if(a.offset<o){var c=(s+=Math.floor((o-a.offset+m)/(u+m)))-i.start;l+=c*u+c*m}s<L&&(l+=(L-s)*u,s=L);for(var p=Math.min(i.end,z),h=s;h<=p&&!(l>=r);h++)t.push({index:h,size:u,offset:l,data:d&&d[h]}),l+=u+m}}),v,i,m,p,u)}),e.filter(function(t){return null!==t}),e.distinctUntilChanged()),wt);return e.connect(e.pipe(i,e.filter(function(t){return void 0!==t}),e.map(function(t){return t.length})),r),e.connect(e.pipe(b,e.map(function(t){return t.topListHeight})),S),e.connect(S,p),e.connect(e.pipe(b,e.map(function(t){return[t.top,t.bottom]})),d),e.connect(e.pipe(b,e.map(function(t){return t.items})),x),c({listState:b,topItemsIndexes:w,endReached:e.streamFromEmitter(e.pipe(b,e.filter(function(t){return t.items.length>0}),e.withLatestFrom(r,i),e.filter(function(t){var e=t[0].items;return e[e.length-1].originalIndex===t[1]-1}),e.map(function(t){return[t[1]-1,t[2]]}),e.distinctUntilChanged(vt),e.map(function(t){return t[0]}))),startReached:e.streamFromEmitter(e.pipe(b,e.throttleTime(200),e.filter(function(t){var e=t.items;return e.length>0&&e[0].originalIndex===t.topItems.length}),e.map(function(t){return t.items[0].index}),e.distinctUntilChanged())),rangeChanged:e.streamFromEmitter(e.pipe(b,e.filter(function(t){return t.items.length>0}),e.map(function(t){for(var e=t.items,n=0,o=e.length-1;"group"===e[n].type&&n<o;)n++;for(;"group"===e[o].type&&o>n;)o--;return{startIndex:e[n].index,endIndex:e[o].index}}),e.distinctUntilChanged(St))),itemsRendered:x},C)},e.tup(rt,gt,Tt,dt,lt,ct,mt,K),{singleton:!0}),Ht=e.system(function(t){var n=t[0],o=n.sizes,r=n.firstItemIndex,i=n.data,a=n.gap,l=t[1].listState,s=t[2].didMount,u=e.statefulStream(0);return e.connect(e.pipe(s,e.withLatestFrom(u),e.filter(function(t){return 0!==t[1]}),e.withLatestFrom(o,r,a,i),e.map(function(t){var e=t[0][1],n=t[1],o=t[2],r=t[3],i=t[4],a=void 0===i?[]:i,l=0;if(n.groupIndices.length>0)for(var s,u=f(n.groupIndices);!((s=u()).done||s.value-l>=e);)l++;var c=e+l;return bt(Array.from({length:c}).map(function(t,e){return{index:e,size:0,offset:0,data:a[e]}}),[],c,r,n,o)})),l),{initialItemCount:u}},e.tup(rt,yt,mt),{singleton:!0}),Et=e.system(function(t){var n=t[0].scrollVelocity,o=e.statefulStream(!1),r=e.stream(),i=e.statefulStream(!1);return e.connect(e.pipe(n,e.withLatestFrom(i,o,r),e.filter(function(t){return!!t[1]}),e.map(function(t){var e=t[0],n=t[1],o=t[2],r=t[3],i=n.enter;if(o){if((0,n.exit)(e,r))return!1}else if(i(e,r))return!0;return o}),e.distinctUntilChanged()),o),e.subscribe(e.pipe(e.combineLatest(o,n,r),e.withLatestFrom(i)),function(t){var e=t[0],n=t[1];return e[0]&&n&&n.change&&n.change(e[1],e[2])}),{isSeeking:o,scrollSeekConfiguration:i,scrollVelocity:n,scrollSeekRangeChanged:r}},e.tup(ct),{singleton:!0}),Rt=e.system(function(t){var n=t[0].topItemsIndexes,o=e.statefulStream(0);return e.connect(e.pipe(o,e.filter(function(t){return t>0}),e.map(function(t){return Array.from({length:t}).map(function(t,e){return e})})),n),{topItemCount:o}},e.tup(yt)),Lt=e.system(function(t){var n=t[0],o=n.footerHeight,r=n.headerHeight,i=n.fixedHeaderHeight,a=n.fixedFooterHeight,l=t[1].listState,s=e.stream(),u=e.statefulStreamFromEmitter(e.pipe(e.combineLatest(o,a,r,i,l),e.map(function(t){var e=t[4];return t[0]+t[1]+t[2]+t[3]+e.offsetBottom+e.bottom})),0);return e.connect(e.duc(u),s),{totalListHeight:u,totalListHeightChanged:s}},e.tup(y,yt),{singleton:!0});function Ft(t){var e,n=!1;return function(){return n||(n=!0,e=t()),e}}var kt=Ft(function(){return/iP(ad|od|hone)/i.test(navigator.userAgent)&&/WebKit/i.test(navigator.userAgent)}),zt=e.system(function(t){var n=t[0],o=n.scrollBy,r=n.scrollTop,i=n.deviation,a=n.scrollingInProgress,l=t[1],s=l.isScrolling,u=l.isAtBottom,c=l.scrollDirection,m=t[3],d=m.beforeUnshiftWith,f=m.shiftWithOffset,p=m.sizes,g=m.gap,v=t[4].log,S=t[5].recalcInProgress,C=e.streamFromEmitter(e.pipe(t[2].listState,e.withLatestFrom(l.lastJumpDueToItemResize),e.scan(function(t,e){var n=t[1],o=e[0],r=o.items,i=o.totalCount,a=o.bottom+o.offsetBottom,l=0;return t[2]===i&&n.length>0&&r.length>0&&(0===r[0].originalIndex&&0===n[0].originalIndex||0!=(l=a-t[3])&&(l+=e[1])),[l,r,i,a]},[0,[],0,0]),e.filter(function(t){return 0!==t[0]}),e.withLatestFrom(r,c,a,u,v),e.filter(function(t){return!t[3]&&0!==t[1]&&t[2]===st}),e.map(function(t){var e=t[0][0];return(0,t[5])("Upward scrolling compensation",{amount:e},h.DEBUG),e})));function I(t){t>0?(e.publish(o,{top:-t,behavior:"auto"}),e.publish(i,0)):(e.publish(i,0),e.publish(o,{top:-t,behavior:"auto"}))}return e.subscribe(e.pipe(C,e.withLatestFrom(i,s)),function(t){var n=t[0],o=t[1];t[2]&&kt()?e.publish(i,o-n):I(-n)}),e.subscribe(e.pipe(e.combineLatest(e.statefulStreamFromEmitter(s,!1),i,S),e.filter(function(t){return!t[0]&&!t[2]&&0!==t[1]}),e.map(function(t){return t[1]}),e.throttleTime(1)),I),e.connect(e.pipe(f,e.map(function(t){return{top:-t}})),o),e.subscribe(e.pipe(d,e.withLatestFrom(p,g),e.map(function(t){var e=t[0];return e*t[1].lastSize+e*t[2]})),function(t){e.publish(i,t),requestAnimationFrame(function(){e.publish(o,{top:t}),requestAnimationFrame(function(){e.publish(i,0),e.publish(S,!1)})})}),{deviation:i}},e.tup(y,ct,yt,rt,S,K)),Bt=e.system(function(t){var n=t[0].totalListHeight,o=t[1].didMount,r=t[2].scrollTo,i=e.statefulStream(0);return e.subscribe(e.pipe(o,e.withLatestFrom(i),e.filter(function(t){return 0!==t[1]}),e.map(function(t){return{top:t[1]}})),function(t){e.handleNext(e.pipe(n,e.filter(function(t){return 0!==t})),function(){setTimeout(function(){e.publish(r,t)})})}),{initialScrollTop:i}},e.tup(Lt,mt,y),{singleton:!0}),Pt=e.system(function(t){var n=t[0].viewportHeight,o=t[1].totalListHeight,r=e.statefulStream(!1);return{alignToBottom:r,paddingTopAddition:e.statefulStreamFromEmitter(e.pipe(e.combineLatest(r,n,o),e.filter(function(t){return t[0]}),e.map(function(t){return Math.max(0,t[1]-t[2])}),e.distinctUntilChanged()),0)}},e.tup(y,Lt),{singleton:!0}),Ot=e.system(function(t){var n=t[0],o=n.scrollTo,r=n.scrollContainerState,i=e.stream(),a=e.stream(),l=e.stream(),s=e.statefulStream(!1),u=e.statefulStream(void 0);return e.connect(e.pipe(e.combineLatest(i,a),e.map(function(t){var e=t[0],n=e.viewportHeight,o=e.scrollHeight;return{scrollTop:Math.max(0,e.scrollTop-t[1].offsetTop),scrollHeight:o,viewportHeight:n}})),r),e.connect(e.pipe(o,e.withLatestFrom(a),e.map(function(t){var e=t[0];return c({},e,{top:e.top+t[1].offsetTop})})),l),{useWindowScroll:s,customScrollParent:u,windowScrollContainerState:i,windowViewportRect:a,windowScrollTo:l}},e.tup(y)),Mt=["done","behavior","align"],Wt=e.system(function(t){var n=t[0],o=n.sizes,r=n.totalCount,i=n.gap,a=t[1],l=a.scrollTop,s=a.viewportHeight,u=a.headerHeight,d=a.fixedHeaderHeight,f=a.fixedFooterHeight,p=a.scrollingInProgress,h=t[2].scrollToIndex,g=e.stream();return e.connect(e.pipe(g,e.withLatestFrom(o,s,r,u,d,f,l),e.withLatestFrom(i),e.map(function(t){var n=t[0],o=n[0],r=n[1],i=n[2],a=n[3],l=n[4],s=n[5],u=n[6],d=n[7],f=t[1],h=o.done,g=o.behavior,v=o.align,S=m(o,Mt),C=null,I=tt(o,r,a-1),T=X(I,r.offsetTree,f)+l+s;return T<d+s?C=c({},S,{behavior:g,align:null!=v?v:"start"}):T+k(r.sizeTree,I)[1]>d+i-u&&(C=c({},S,{behavior:g,align:null!=v?v:"end"})),C?h&&e.handleNext(e.pipe(p,e.skip(1),e.filter(function(t){return!1===t})),h):h&&h(),C}),e.filter(function(t){return null!==t})),h),{scrollIntoView:g}},e.tup(rt,y,lt,yt,S),{singleton:!0}),Vt=["listState","topItemsIndexes"],Ut=e.system(function(t){return c({},t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},e.tup(Tt,Ht,mt,Et,Lt,Bt,Pt,Ot,Wt)),At=e.system(function(t){var n=t[0],o=n.totalCount,r=n.sizeRanges,i=n.fixedItemSize,a=n.defaultItemSize,l=n.trackItemSizes,s=n.itemSize,u=n.data,d=n.firstItemIndex,f=n.groupIndices,p=n.statefulTotalCount,h=n.gap,g=t[1],v=g.initialTopMostItemIndex,S=g.scrolledToInitialItem,C=t[2],I=t[3],T=t[4],w=T.listState,x=T.topItemsIndexes,b=m(T,Vt),y=t[5].scrollToIndex,H=t[7].topItemCount,E=t[8].groupCounts,R=t[9],L=t[10];return e.connect(b.rangeChanged,R.scrollSeekRangeChanged),e.connect(e.pipe(R.windowViewportRect,e.map(function(t){return t.visibleHeight})),C.viewportHeight),c({totalCount:o,data:u,firstItemIndex:d,sizeRanges:r,initialTopMostItemIndex:v,scrolledToInitialItem:S,topItemsIndexes:x,topItemCount:H,groupCounts:E,fixedItemHeight:i,defaultItemHeight:a,gap:h},I,{statefulTotalCount:p,listState:w,scrollToIndex:y,trackItemSizes:l,itemSize:s,groupIndices:f},b,R,C,L)},e.tup(rt,dt,y,pt,yt,lt,zt,Rt,gt,Ut,S)),Nt=Ft(function(){if("undefined"==typeof document)return"sticky";var t=document.createElement("div");return t.style.position="-webkit-sticky","-webkit-sticky"===t.style.position?"-webkit-sticky":"sticky"});function Dt(t,e){var n=i(null),o=a(function(o){if(null!==o&&o.offsetParent){var r,i,a=o.getBoundingClientRect(),l=a.width;if(e){var s=e.getBoundingClientRect(),u=a.top-s.top;r=s.height-Math.max(0,u),i=u+e.scrollTop}else r=window.innerHeight-Math.max(0,a.top),i=a.top+window.pageYOffset;n.current={offsetTop:i,visibleHeight:r,visibleWidth:l},t(n.current)}},[t,e]),l=C(o),s=l.callbackRef,u=l.ref,c=a(function(){o(u.current)},[o,u]);return r(function(){if(e){e.addEventListener("scroll",c);var t=new ResizeObserver(c);return t.observe(e),function(){e.removeEventListener("scroll",c),t.unobserve(e)}}return window.addEventListener("scroll",c),window.addEventListener("resize",c),function(){window.removeEventListener("scroll",c),window.removeEventListener("resize",c)}},[c,e]),s}var Gt=n.createContext(void 0),_t=n.createContext(void 0),jt=["placeholder"],Kt=["style","children"],Yt=["style","children"];function qt(t){return t}var Zt=e.system(function(){var t=e.statefulStream(function(t){return"Item "+t}),n=e.statefulStream(null),o=e.statefulStream(function(t){return"Group "+t}),r=e.statefulStream({}),i=e.statefulStream(qt),a=e.statefulStream("div"),l=e.statefulStream(e.noop),s=function(t,n){return void 0===n&&(n=null),e.statefulStreamFromEmitter(e.pipe(r,e.map(function(e){return e[t]}),e.distinctUntilChanged()),n)};return{context:n,itemContent:t,groupContent:o,components:r,computeItemKey:i,headerFooterTag:a,scrollerRef:l,FooterComponent:s("Footer"),HeaderComponent:s("Header"),TopItemListComponent:s("TopItemList"),ListComponent:s("List","div"),ItemComponent:s("Item","div"),GroupComponent:s("Group","div"),ScrollerComponent:s("Scroller","div"),EmptyPlaceholder:s("EmptyPlaceholder"),ScrollSeekPlaceholder:s("ScrollSeekPlaceholder")}});function Jt(t,n){var o=e.stream();return e.subscribe(o,function(){return console.warn("react-virtuoso: You are using a deprecated property. "+n,"color: red;","color: inherit;","color: blue;")}),e.connect(o,t),o}var $t=e.system(function(t){var n=t[0],o=t[1],r={item:Jt(o.itemContent,"Rename the %citem%c prop to %citemContent."),group:Jt(o.groupContent,"Rename the %cgroup%c prop to %cgroupContent."),topItems:Jt(n.topItemCount,"Rename the %ctopItems%c prop to %ctopItemCount."),itemHeight:Jt(n.fixedItemHeight,"Rename the %citemHeight%c prop to %cfixedItemHeight."),scrollingStateChange:Jt(n.isScrolling,"Rename the %cscrollingStateChange%c prop to %cisScrolling."),adjustForPrependedItems:e.stream(),maxHeightCacheSize:e.stream(),footer:e.stream(),header:e.stream(),HeaderContainer:e.stream(),FooterContainer:e.stream(),ItemContainer:e.stream(),ScrollContainer:e.stream(),GroupContainer:e.stream(),ListContainer:e.stream(),emptyComponent:e.stream(),scrollSeek:e.stream()};function i(t,n,r){e.connect(e.pipe(t,e.withLatestFrom(o.components),e.map(function(t){var e,o=t[0],i=t[1];return console.warn("react-virtuoso: "+r+" property is deprecated. Pass components."+n+" instead."),c({},i,((e={})[n]=o,e))})),o.components)}return e.subscribe(r.adjustForPrependedItems,function(){console.warn("react-virtuoso: adjustForPrependedItems is no longer supported. Use the firstItemIndex property instead - https://virtuoso.dev/prepend-items.","color: red;","color: inherit;","color: blue;")}),e.subscribe(r.maxHeightCacheSize,function(){console.warn("react-virtuoso: maxHeightCacheSize is no longer necessary. Setting it has no effect - remove it from your code.")}),e.subscribe(r.HeaderContainer,function(){console.warn("react-virtuoso: HeaderContainer is deprecated. Use headerFooterTag if you want to change the wrapper of the header component and pass components.Header to change its contents.")}),e.subscribe(r.FooterContainer,function(){console.warn("react-virtuoso: FooterContainer is deprecated. Use headerFooterTag if you want to change the wrapper of the footer component and pass components.Footer to change its contents.")}),e.subscribe(r.scrollSeek,function(t){var r=t.placeholder,i=m(t,jt);console.warn("react-virtuoso: scrollSeek property is deprecated. Pass scrollSeekConfiguration and specify the placeholder in components.ScrollSeekPlaceholder instead."),e.publish(o.components,c({},e.getValue(o.components),{ScrollSeekPlaceholder:r})),e.publish(n.scrollSeekConfiguration,i)}),i(r.footer,"Footer","footer"),i(r.header,"Header","header"),i(r.ItemContainer,"Item","ItemContainer"),i(r.ListContainer,"List","ListContainer"),i(r.ScrollContainer,"Scroller","ScrollContainer"),i(r.emptyComponent,"EmptyPlaceholder","emptyComponent"),i(r.GroupContainer,"Group","GroupContainer"),c({},n,o,r)},e.tup(At,Zt)),Qt=function(t){return n.createElement("div",{style:{height:t.height}})},Xt={position:Nt(),zIndex:1,overflowAnchor:"none"},te={overflowAnchor:"none"},ee=n.memo(function(t){var o=t.showTopList,r=void 0!==o&&o,i=ge("listState"),a=he("sizeRanges"),s=ge("useWindowScroll"),u=ge("customScrollParent"),m=he("windowScrollContainerState"),d=he("scrollContainerState"),f=u||s?m:d,p=ge("itemContent"),h=ge("context"),g=ge("groupContent"),v=ge("trackItemSizes"),S=ge("itemSize"),C=ge("log"),I=he("gap"),w=T(a,S,v,r?e.noop:f,C,I,u).callbackRef,x=n.useState(0),b=x[0],y=x[1];ve("deviation",function(t){b!==t&&y(t)});var H=ge("EmptyPlaceholder"),E=ge("ScrollSeekPlaceholder")||Qt,R=ge("ListComponent"),L=ge("ItemComponent"),F=ge("GroupComponent"),k=ge("computeItemKey"),z=ge("isSeeking"),B=ge("groupIndices").length>0,P=ge("paddingTopAddition"),O=r?{}:{boxSizing:"border-box",paddingTop:i.offsetTop+P,paddingBottom:i.offsetBottom,marginTop:b};return!r&&0===i.totalCount&&H?l(H,ie(H,h)):l(R,c({},ie(R,h),{ref:w,style:O,"data-test-id":r?"virtuoso-top-item-list":"virtuoso-item-list"}),(r?i.topItems:i.items).map(function(t){var e=t.originalIndex,n=k(e+i.firstItemIndex,t.data,h);return z?l(E,c({},ie(E,h),{key:n,index:t.index,height:t.size,type:t.type||"item"},"group"===t.type?{}:{groupIndex:t.groupIndex})):"group"===t.type?l(F,c({},ie(F,h),{key:n,"data-index":e,"data-known-size":t.size,"data-item-index":t.index,style:Xt}),g(t.index)):l(L,c({},ie(L,h),{key:n,"data-index":e,"data-known-size":t.size,"data-item-index":t.index,"data-item-group-index":t.groupIndex,style:te}),B?p(t.index,t.groupIndex,t.data,h):p(t.index,t.data,h))}))}),ne={height:"100%",outline:"none",overflowY:"auto",position:"relative",WebkitOverflowScrolling:"touch"},oe={width:"100%",height:"100%",position:"absolute",top:0},re={width:"100%",position:Nt(),top:0};function ie(t,e){if("string"!=typeof t)return{context:e}}var ae=n.memo(function(){var t=ge("HeaderComponent"),e=he("headerHeight"),n=ge("headerFooterTag"),o=I(function(t){return e(w(t,"height"))}),r=ge("context");return t?l(n,{ref:o},l(t,ie(t,r))):null}),le=n.memo(function(){var t=ge("FooterComponent"),e=he("footerHeight"),n=ge("headerFooterTag"),o=I(function(t){return e(w(t,"height"))}),r=ge("context");return t?l(n,{ref:o},l(t,ie(t,r))):null});function se(t){var e=t.usePublisher,o=t.useEmitter,r=t.useEmitterValue;return n.memo(function(t){var n=t.style,i=t.children,a=m(t,Kt),s=e("scrollContainerState"),u=r("ScrollerComponent"),d=e("smoothScrollTargetReached"),f=r("scrollerRef"),p=r("context"),h=b(s,d,u,f),g=h.scrollerRef,v=h.scrollByCallback;return o("scrollTo",h.scrollToCallback),o("scrollBy",v),l(u,c({ref:g,style:c({},ne,n),"data-test-id":"virtuoso-scroller","data-virtuoso-scroller":!0,tabIndex:0},a,ie(u,p)),i)})}function ue(t){var o=t.usePublisher,r=t.useEmitter,i=t.useEmitterValue;return n.memo(function(t){var n=t.style,a=t.children,s=m(t,Yt),u=o("windowScrollContainerState"),d=i("ScrollerComponent"),f=o("smoothScrollTargetReached"),p=i("totalListHeight"),h=i("deviation"),v=i("customScrollParent"),S=i("context"),C=b(u,f,d,e.noop,v),I=C.scrollerRef,T=C.scrollByCallback,w=C.scrollToCallback;return g(function(){return I.current=v||window,function(){I.current=null}},[I,v]),r("windowScrollTo",w),r("scrollBy",T),l(d,c({style:c({position:"relative"},n,0!==p?{height:p+h}:{}),"data-virtuoso-scroller":!0},s,ie(d,S)),a)})}var ce=function(t){var o=t.children,r=s(Gt),i=he("viewportHeight"),a=he("fixedItemHeight"),l=I(e.compose(i,function(t){return w(t,"height")}));return n.useEffect(function(){r&&(i(r.viewportHeight),a(r.itemHeight))},[r,i,a]),n.createElement("div",{style:oe,ref:l,"data-viewport-type":"element"},o)},me=function(t){var e=t.children,o=s(Gt),r=he("windowViewportRect"),i=he("fixedItemHeight"),a=ge("customScrollParent"),l=Dt(r,a);return n.useEffect(function(){o&&(i(o.itemHeight),r({offsetTop:0,visibleHeight:o.viewportHeight,visibleWidth:100}))},[o,r,i]),n.createElement("div",{ref:l,style:oe,"data-viewport-type":"window"},e)},de=function(t){var e=t.children,n=ge("TopItemListComponent"),o=ge("headerHeight"),r=c({},re,{marginTop:o+"px"}),i=ge("context");return l(n||"div",{style:r,context:i},e)},fe=t($t,{required:{},optional:{context:"context",followOutput:"followOutput",firstItemIndex:"firstItemIndex",itemContent:"itemContent",groupContent:"groupContent",overscan:"overscan",increaseViewportBy:"increaseViewportBy",totalCount:"totalCount",topItemCount:"topItemCount",initialTopMostItemIndex:"initialTopMostItemIndex",components:"components",groupCounts:"groupCounts",atBottomThreshold:"atBottomThreshold",atTopThreshold:"atTopThreshold",computeItemKey:"computeItemKey",defaultItemHeight:"defaultItemHeight",fixedItemHeight:"fixedItemHeight",itemSize:"itemSize",scrollSeekConfiguration:"scrollSeekConfiguration",headerFooterTag:"headerFooterTag",data:"data",initialItemCount:"initialItemCount",initialScrollTop:"initialScrollTop",alignToBottom:"alignToBottom",useWindowScroll:"useWindowScroll",customScrollParent:"customScrollParent",scrollerRef:"scrollerRef",logLevel:"logLevel",react18ConcurrentRendering:"react18ConcurrentRendering",item:"item",group:"group",topItems:"topItems",itemHeight:"itemHeight",scrollingStateChange:"scrollingStateChange",maxHeightCacheSize:"maxHeightCacheSize",footer:"footer",header:"header",ItemContainer:"ItemContainer",ScrollContainer:"ScrollContainer",ListContainer:"ListContainer",GroupContainer:"GroupContainer",emptyComponent:"emptyComponent",HeaderContainer:"HeaderContainer",FooterContainer:"FooterContainer",scrollSeek:"scrollSeek"},methods:{scrollToIndex:"scrollToIndex",scrollIntoView:"scrollIntoView",scrollTo:"scrollTo",scrollBy:"scrollBy",adjustForPrependedItems:"adjustForPrependedItems",autoscrollToBottom:"autoscrollToBottom"},events:{isScrolling:"isScrolling",endReached:"endReached",startReached:"startReached",rangeChanged:"rangeChanged",atBottomStateChange:"atBottomStateChange",atTopStateChange:"atTopStateChange",totalListHeightChanged:"totalListHeightChanged",itemsRendered:"itemsRendered",groupIndices:"groupIndices"}},n.memo(function(t){var e=ge("useWindowScroll"),o=ge("topItemsIndexes").length>0,r=ge("customScrollParent"),i=r||e?me:ce;return n.createElement(r||e?Ce:Se,c({},t),n.createElement(i,null,n.createElement(ae,null),n.createElement(ee,null),n.createElement(le,null)),o&&n.createElement(de,null,n.createElement(ee,{showTopList:!0})))})),pe=fe.Component,he=fe.usePublisher,ge=fe.useEmitterValue,ve=fe.useEmitter,Se=se({usePublisher:he,useEmitterValue:ge,useEmitter:ve}),Ce=ue({usePublisher:he,useEmitterValue:ge,useEmitter:ve}),Ie={items:[],offsetBottom:0,offsetTop:0,top:0,bottom:0,itemHeight:0,itemWidth:0},Te={items:[{index:0}],offsetBottom:0,offsetTop:0,top:0,bottom:0,itemHeight:0,itemWidth:0},we=Math.round,xe=Math.ceil,be=Math.floor,ye=Math.min,He=Math.max;function Ee(t,e,n){return Array.from({length:e-t+1}).map(function(e,o){return{index:o+t,data:null==n?void 0:n[o+t]}})}function Re(t,e){return t&&t.column===e.column&&t.row===e.row}var Le=e.system(function(t){var n=t[0],o=n.overscan,r=n.visibleRange,i=n.listBoundary,a=t[1],l=a.scrollTop,s=a.viewportHeight,u=a.scrollBy,m=a.scrollTo,d=a.smoothScrollTargetReached,f=a.scrollContainerState,p=a.footerHeight,h=a.headerHeight,g=t[2],v=t[3],S=t[4],C=S.propsReady,I=S.didMount,T=t[5],w=T.windowViewportRect,x=T.windowScrollTo,b=T.useWindowScroll,y=T.customScrollParent,H=T.windowScrollContainerState,E=t[6],R=e.statefulStream(0),L=e.statefulStream(0),F=e.statefulStream(Ie),k=e.statefulStream({height:0,width:0}),z=e.statefulStream({height:0,width:0}),B=e.stream(),P=e.stream(),O=e.statefulStream(0),M=e.statefulStream(void 0),W=e.statefulStream({row:0,column:0});e.connect(e.pipe(e.combineLatest(I,L,M),e.filter(function(t){return 0!==t[1]}),e.map(function(t){return{items:Ee(0,t[1]-1,t[2]),top:0,bottom:0,offsetBottom:0,offsetTop:0,itemHeight:0,itemWidth:0}})),F),e.connect(e.pipe(e.combineLatest(e.duc(R),r,e.duc(W,Re),e.duc(z,function(t,e){return t&&t.width===e.width&&t.height===e.height}),M),e.withLatestFrom(k),e.map(function(t){var e=t[0],n=e[0],o=e[1],r=o[0],i=o[1],a=e[2],l=e[3],s=e[4],u=t[1],m=a.row,d=a.column,f=l.height,p=l.width,h=u.width;if(0===n||0===h)return Ie;if(0===p)return function(t){return c({},Te,{items:t})}(Ee(0,0,s));var g=ze(h,p,d),v=g*be((r+m)/(f+m)),S=g*xe((i+m)/(f+m))-1;S=ye(n-1,He(S,g-1));var C=Ee(v=ye(S,He(0,v)),S,s),I=Fe(u,a,l,C),T=I.top,w=I.bottom,x=xe(n/g);return{items:C,offsetTop:T,offsetBottom:x*f+(x-1)*m-w,top:T,bottom:w,itemHeight:f,itemWidth:p}})),F),e.connect(e.pipe(M,e.filter(function(t){return void 0!==t}),e.map(function(t){return t.length})),R),e.connect(e.pipe(k,e.map(function(t){return t.height})),s),e.connect(e.pipe(e.combineLatest(k,z,F,W),e.map(function(t){var e=Fe(t[0],t[3],t[1],t[2].items);return[e.top,e.bottom]}),e.distinctUntilChanged(vt)),i);var V=e.streamFromEmitter(e.pipe(e.duc(F),e.filter(function(t){return t.items.length>0}),e.withLatestFrom(R),e.filter(function(t){var e=t[0].items;return e[e.length-1].index===t[1]-1}),e.map(function(t){return t[1]-1}),e.distinctUntilChanged())),U=e.streamFromEmitter(e.pipe(e.duc(F),e.filter(function(t){var e=t.items;return e.length>0&&0===e[0].index}),e.mapTo(0),e.distinctUntilChanged())),A=e.streamFromEmitter(e.pipe(e.duc(F),e.filter(function(t){return t.items.length>0}),e.map(function(t){var e=t.items;return{startIndex:e[0].index,endIndex:e[e.length-1].index}}),e.distinctUntilChanged(St)));e.connect(A,v.scrollSeekRangeChanged),e.connect(e.pipe(B,e.withLatestFrom(k,z,R,W),e.map(function(t){var e=t[1],n=t[2],o=t[3],r=t[4],i=at(t[0]),a=i.align,l=i.behavior,s=i.offset,u=i.index;"LAST"===u&&(u=o-1);var c=ke(e,r,n,u=He(0,u,ye(o-1,u)));return"end"===a?c=we(c-e.height+n.height):"center"===a&&(c=we(c-e.height/2+n.height/2)),s&&(c+=s),{top:c,behavior:l}})),m);var N=e.statefulStreamFromEmitter(e.pipe(F,e.map(function(t){return t.offsetBottom+t.bottom})),0);return e.connect(e.pipe(w,e.map(function(t){return{width:t.visibleWidth,height:t.visibleHeight}})),k),c({data:M,totalCount:R,viewportDimensions:k,itemDimensions:z,scrollTop:l,scrollHeight:P,overscan:o,scrollBy:u,scrollTo:m,scrollToIndex:B,smoothScrollTargetReached:d,windowViewportRect:w,windowScrollTo:x,useWindowScroll:b,customScrollParent:y,windowScrollContainerState:H,deviation:O,scrollContainerState:f,footerHeight:p,headerHeight:h,initialItemCount:L,gap:W},v,{gridState:F,totalListHeight:N},g,{startReached:U,endReached:V,rangeChanged:A,propsReady:C},E)},e.tup(Tt,y,ct,Et,mt,Ot,S));function Fe(t,e,n,o){var r=n.height;return void 0===r||0===o.length?{top:0,bottom:0}:{top:ke(t,e,n,o[0].index),bottom:ke(t,e,n,o[o.length-1].index)+r}}function ke(t,e,n,o){var r=ze(t.width,n.width,e.column),i=be(o/r),a=i*n.height+He(0,i-1)*e.row;return a>0?a+e.row:a}function ze(t,e,n){return He(1,be((t+n)/(e+n)))}var Be=["placeholder"],Pe=e.system(function(){var t=e.statefulStream(function(t){return"Item "+t}),n=e.statefulStream({}),o=e.statefulStream(null),r=e.statefulStream("virtuoso-grid-item"),i=e.statefulStream("virtuoso-grid-list"),a=e.statefulStream(qt),l=e.statefulStream("div"),s=e.statefulStream(e.noop),u=function(t,o){return void 0===o&&(o=null),e.statefulStreamFromEmitter(e.pipe(n,e.map(function(e){return e[t]}),e.distinctUntilChanged()),o)};return{context:o,itemContent:t,components:n,computeItemKey:a,itemClassName:r,listClassName:i,headerFooterTag:l,scrollerRef:s,FooterComponent:u("Footer"),HeaderComponent:u("Header"),ListComponent:u("List","div"),ItemComponent:u("Item","div"),ScrollerComponent:u("Scroller","div"),ScrollSeekPlaceholder:u("ScrollSeekPlaceholder","div")}}),Oe=e.system(function(t){var n=t[0],o=t[1],r={item:Jt(o.itemContent,"Rename the %citem%c prop to %citemContent."),ItemContainer:e.stream(),ScrollContainer:e.stream(),ListContainer:e.stream(),emptyComponent:e.stream(),scrollSeek:e.stream()};function i(t,n,r){e.connect(e.pipe(t,e.withLatestFrom(o.components),e.map(function(t){var e,o=t[0],i=t[1];return console.warn("react-virtuoso: "+r+" property is deprecated. Pass components."+n+" instead."),c({},i,((e={})[n]=o,e))})),o.components)}return e.subscribe(r.scrollSeek,function(t){var r=t.placeholder,i=m(t,Be);console.warn("react-virtuoso: scrollSeek property is deprecated. Pass scrollSeekConfiguration and specify the placeholder in components.ScrollSeekPlaceholder instead."),e.publish(o.components,c({},e.getValue(o.components),{ScrollSeekPlaceholder:r})),e.publish(n.scrollSeekConfiguration,i)}),i(r.ItemContainer,"Item","ItemContainer"),i(r.ListContainer,"List","ListContainer"),i(r.ScrollContainer,"Scroller","ScrollContainer"),c({},n,o,r)},e.tup(Le,Pe)),Me=n.memo(function(){var t=_e("gridState"),e=_e("listClassName"),n=_e("itemClassName"),o=_e("itemContent"),r=_e("computeItemKey"),i=_e("isSeeking"),a=Ge("scrollHeight"),s=_e("ItemComponent"),u=_e("ListComponent"),m=_e("ScrollSeekPlaceholder"),d=_e("context"),f=Ge("itemDimensions"),p=Ge("gap"),h=_e("log"),g=I(function(t){a(t.parentElement.parentElement.scrollHeight);var e=t.firstChild;e&&f(e.getBoundingClientRect()),p({row:qe("row-gap",getComputedStyle(t).rowGap,h),column:qe("column-gap",getComputedStyle(t).columnGap,h)})});return l(u,c({ref:g,className:e},ie(u,d),{style:{paddingTop:t.offsetTop,paddingBottom:t.offsetBottom}}),t.items.map(function(e){var a=r(e.index,e.data,d);return i?l(m,c({key:a},ie(m,d),{index:e.index,height:t.itemHeight,width:t.itemWidth})):l(s,c({},ie(s,d),{className:n,"data-index":e.index,key:a}),o(e.index,e.data,d))}))}),We=n.memo(function(){var t=_e("HeaderComponent"),e=Ge("headerHeight"),n=_e("headerFooterTag"),o=I(function(t){return e(w(t,"height"))}),r=_e("context");return t?l(n,{ref:o},l(t,ie(t,r))):null}),Ve=n.memo(function(){var t=_e("FooterComponent"),e=Ge("footerHeight"),n=_e("headerFooterTag"),o=I(function(t){return e(w(t,"height"))}),r=_e("context");return t?l(n,{ref:o},l(t,ie(t,r))):null}),Ue=function(t){var e=t.children,o=s(_t),r=Ge("itemDimensions"),i=Ge("viewportDimensions"),a=I(function(t){i(t.getBoundingClientRect())});return n.useEffect(function(){o&&(i({height:o.viewportHeight,width:o.viewportWidth}),r({height:o.itemHeight,width:o.itemWidth}))},[o,i,r]),n.createElement("div",{style:oe,ref:a},e)},Ae=function(t){var e=t.children,o=s(_t),r=Ge("windowViewportRect"),i=Ge("itemDimensions"),a=_e("customScrollParent"),l=Dt(r,a);return n.useEffect(function(){o&&(i({height:o.itemHeight,width:o.itemWidth}),r({offsetTop:0,visibleHeight:o.viewportHeight,visibleWidth:o.viewportWidth}))},[o,r,i]),n.createElement("div",{ref:l,style:oe},e)},Ne=t(Oe,{optional:{context:"context",totalCount:"totalCount",overscan:"overscan",itemContent:"itemContent",components:"components",computeItemKey:"computeItemKey",data:"data",initialItemCount:"initialItemCount",scrollSeekConfiguration:"scrollSeekConfiguration",headerFooterTag:"headerFooterTag",listClassName:"listClassName",itemClassName:"itemClassName",useWindowScroll:"useWindowScroll",customScrollParent:"customScrollParent",scrollerRef:"scrollerRef",item:"item",ItemContainer:"ItemContainer",ScrollContainer:"ScrollContainer",ListContainer:"ListContainer",scrollSeek:"scrollSeek"},methods:{scrollTo:"scrollTo",scrollBy:"scrollBy",scrollToIndex:"scrollToIndex"},events:{isScrolling:"isScrolling",endReached:"endReached",startReached:"startReached",rangeChanged:"rangeChanged",atBottomStateChange:"atBottomStateChange",atTopStateChange:"atTopStateChange"}},n.memo(function(t){var e=c({},t),o=_e("useWindowScroll"),r=_e("customScrollParent"),i=r||o?Ae:Ue;return n.createElement(r||o?Ye:Ke,c({},e),n.createElement(i,null,n.createElement(We,null),n.createElement(Me,null),n.createElement(Ve,null)))})),De=Ne.Component,Ge=Ne.usePublisher,_e=Ne.useEmitterValue,je=Ne.useEmitter,Ke=se({usePublisher:Ge,useEmitterValue:_e,useEmitter:je}),Ye=ue({usePublisher:Ge,useEmitterValue:_e,useEmitter:je});function qe(t,e,n){return"normal"===e||null!=e&&e.endsWith("px")||n(t+" was not resolved to pixel value correctly",e,h.WARN),"normal"===e?0:parseInt(null!=e?e:"0",10)}var Ze=e.system(function(){var t=e.statefulStream(function(t){return n.createElement("td",null,"Item $",t)}),o=e.statefulStream(null),r=e.statefulStream(null),i=e.statefulStream(null),a=e.statefulStream({}),l=e.statefulStream(qt),s=e.statefulStream(e.noop),u=function(t,n){return void 0===n&&(n=null),e.statefulStreamFromEmitter(e.pipe(a,e.map(function(e){return e[t]}),e.distinctUntilChanged()),n)};return{context:o,itemContent:t,fixedHeaderContent:r,fixedFooterContent:i,components:a,computeItemKey:l,scrollerRef:s,TableComponent:u("Table","table"),TableHeadComponent:u("TableHead","thead"),TableFooterComponent:u("TableFoot","tfoot"),TableBodyComponent:u("TableBody","tbody"),TableRowComponent:u("TableRow","tr"),ScrollerComponent:u("Scroller","div"),EmptyPlaceholder:u("EmptyPlaceholder"),ScrollSeekPlaceholder:u("ScrollSeekPlaceholder"),FillerRow:u("FillerRow")}}),Je=e.system(function(t){return c({},t[0],t[1])},e.tup(At,Ze)),$e=function(t){return n.createElement("tr",null,n.createElement("td",{style:{height:t.height}}))},Qe=function(t){return n.createElement("tr",null,n.createElement("td",{style:{height:t.height,padding:0,border:0}}))},Xe=n.memo(function(){var t=an("listState"),e=rn("sizeRanges"),o=an("useWindowScroll"),r=an("customScrollParent"),i=rn("windowScrollContainerState"),a=rn("scrollContainerState"),s=r||o?i:a,u=an("itemContent"),m=an("trackItemSizes"),d=T(e,an("itemSize"),m,s,an("log"),void 0,r),f=d.callbackRef,p=d.ref,h=n.useState(0),g=h[0],v=h[1];ln("deviation",function(t){g!==t&&(p.current.style.marginTop=t+"px",v(t))});var S=an("EmptyPlaceholder"),C=an("ScrollSeekPlaceholder")||$e,I=an("FillerRow")||Qe,w=an("TableBodyComponent"),x=an("TableRowComponent"),b=an("computeItemKey"),y=an("isSeeking"),H=an("paddingTopAddition"),E=an("firstItemIndex"),R=an("statefulTotalCount"),L=an("context");if(0===R&&S)return l(S,ie(S,L));var F=t.offsetTop+H+g,k=t.offsetBottom,z=F>0?n.createElement(I,{height:F,key:"padding-top"}):null,B=k>0?n.createElement(I,{height:k,key:"padding-bottom"}):null,P=t.items.map(function(t){var e=t.originalIndex,n=b(e+E,t.data,L);return y?l(C,c({},ie(C,L),{key:n,index:t.index,height:t.size,type:t.type||"item"})):l(x,c({},ie(x,L),{key:n,"data-index":e,"data-known-size":t.size,"data-item-index":t.index,style:{overflowAnchor:"none"}}),u(t.index,t.data,L))});return l(w,c({ref:f,"data-test-id":"virtuoso-item-list"},ie(w,L)),[z].concat(P,[B]))}),tn=function(t){var o=t.children,r=s(Gt),i=rn("viewportHeight"),a=rn("fixedItemHeight"),l=I(e.compose(i,function(t){return w(t,"height")}));return n.useEffect(function(){r&&(i(r.viewportHeight),a(r.itemHeight))},[r,i,a]),n.createElement("div",{style:oe,ref:l,"data-viewport-type":"element"},o)},en=function(t){var e=t.children,o=s(Gt),r=rn("windowViewportRect"),i=rn("fixedItemHeight"),a=an("customScrollParent"),l=Dt(r,a);return n.useEffect(function(){o&&(i(o.itemHeight),r({offsetTop:0,visibleHeight:o.viewportHeight,visibleWidth:100}))},[o,r,i]),n.createElement("div",{ref:l,style:oe,"data-viewport-type":"window"},e)},nn=t(Je,{required:{},optional:{context:"context",followOutput:"followOutput",firstItemIndex:"firstItemIndex",itemContent:"itemContent",fixedHeaderContent:"fixedHeaderContent",fixedFooterContent:"fixedFooterContent",overscan:"overscan",increaseViewportBy:"increaseViewportBy",totalCount:"totalCount",topItemCount:"topItemCount",initialTopMostItemIndex:"initialTopMostItemIndex",components:"components",groupCounts:"groupCounts",atBottomThreshold:"atBottomThreshold",atTopThreshold:"atTopThreshold",computeItemKey:"computeItemKey",defaultItemHeight:"defaultItemHeight",fixedItemHeight:"fixedItemHeight",itemSize:"itemSize",scrollSeekConfiguration:"scrollSeekConfiguration",data:"data",initialItemCount:"initialItemCount",initialScrollTop:"initialScrollTop",alignToBottom:"alignToBottom",useWindowScroll:"useWindowScroll",customScrollParent:"customScrollParent",scrollerRef:"scrollerRef",logLevel:"logLevel",react18ConcurrentRendering:"react18ConcurrentRendering"},methods:{scrollToIndex:"scrollToIndex",scrollIntoView:"scrollIntoView",scrollTo:"scrollTo",scrollBy:"scrollBy"},events:{isScrolling:"isScrolling",endReached:"endReached",startReached:"startReached",rangeChanged:"rangeChanged",atBottomStateChange:"atBottomStateChange",atTopStateChange:"atTopStateChange",totalListHeightChanged:"totalListHeightChanged",itemsRendered:"itemsRendered",groupIndices:"groupIndices"}},n.memo(function(t){var o=an("useWindowScroll"),r=an("customScrollParent"),i=rn("fixedHeaderHeight"),a=rn("fixedFooterHeight"),l=an("fixedHeaderContent"),s=an("fixedFooterContent"),u=an("context"),m=I(e.compose(i,function(t){return w(t,"height")})),d=I(e.compose(a,function(t){return w(t,"height")})),f=r||o?un:sn,p=r||o?en:tn,h=an("TableComponent"),g=an("TableHeadComponent"),v=an("TableFooterComponent"),S=l?n.createElement(g,c({key:"TableHead",style:{zIndex:1,position:"sticky",top:0},ref:m},ie(g,u)),l()):null,C=s?n.createElement(v,c({key:"TableFoot",style:{zIndex:1,position:"sticky",bottom:0},ref:d},ie(v,u)),s()):null;return n.createElement(f,c({},t),n.createElement(p,null,n.createElement(h,c({style:{borderSpacing:0}},ie(h,u)),[S,n.createElement(Xe,{key:"TableBody"}),C])))})),on=nn.Component,rn=nn.usePublisher,an=nn.useEmitterValue,ln=nn.useEmitter,sn=se({usePublisher:rn,useEmitterValue:an,useEmitter:ln}),un=ue({usePublisher:rn,useEmitterValue:an,useEmitter:ln}),cn=pe,mn=pe,dn=on,fn=De;export{mn as GroupedVirtuoso,h as LogLevel,dn as TableVirtuoso,cn as Virtuoso,fn as VirtuosoGrid,_t as VirtuosoGridMockContext,Gt as VirtuosoMockContext};
|
|
2
|
-
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { createContext, forwardRef, useState, useImperativeHandle, createElement, useCallback, useContext, useLayoutEffect, useEffect, useRef } from "react";
|
|
4
|
+
import { flushSync } from "react-dom";
|
|
5
|
+
const PUBLISH = 0;
|
|
6
|
+
const SUBSCRIBE = 1;
|
|
7
|
+
const RESET = 2;
|
|
8
|
+
const VALUE = 4;
|
|
9
|
+
function compose(a, b) {
|
|
10
|
+
return (arg) => a(b(arg));
|
|
11
|
+
}
|
|
12
|
+
function thrush(arg, proc) {
|
|
13
|
+
return proc(arg);
|
|
14
|
+
}
|
|
15
|
+
function curry2to1(proc, arg1) {
|
|
16
|
+
return (arg2) => proc(arg1, arg2);
|
|
17
|
+
}
|
|
18
|
+
function curry1to0(proc, arg) {
|
|
19
|
+
return () => proc(arg);
|
|
20
|
+
}
|
|
21
|
+
function tap(arg, proc) {
|
|
22
|
+
proc(arg);
|
|
23
|
+
return arg;
|
|
24
|
+
}
|
|
25
|
+
function tup(...args) {
|
|
26
|
+
return args;
|
|
27
|
+
}
|
|
28
|
+
function call(proc) {
|
|
29
|
+
proc();
|
|
30
|
+
}
|
|
31
|
+
function always(value) {
|
|
32
|
+
return () => value;
|
|
33
|
+
}
|
|
34
|
+
function joinProc(...procs) {
|
|
35
|
+
return () => {
|
|
36
|
+
procs.map(call);
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function noop() {
|
|
40
|
+
}
|
|
41
|
+
function subscribe(emitter, subscription) {
|
|
42
|
+
return emitter(SUBSCRIBE, subscription);
|
|
43
|
+
}
|
|
44
|
+
function publish(publisher, value) {
|
|
45
|
+
publisher(PUBLISH, value);
|
|
46
|
+
}
|
|
47
|
+
function reset(emitter) {
|
|
48
|
+
emitter(RESET);
|
|
49
|
+
}
|
|
50
|
+
function getValue(depot) {
|
|
51
|
+
return depot(VALUE);
|
|
52
|
+
}
|
|
53
|
+
function connect(emitter, publisher) {
|
|
54
|
+
return subscribe(emitter, curry2to1(publisher, PUBLISH));
|
|
55
|
+
}
|
|
56
|
+
function handleNext(emitter, subscription) {
|
|
57
|
+
const unsub = emitter(SUBSCRIBE, (value) => {
|
|
58
|
+
unsub();
|
|
59
|
+
subscription(value);
|
|
60
|
+
});
|
|
61
|
+
return unsub;
|
|
62
|
+
}
|
|
63
|
+
function stream() {
|
|
64
|
+
const subscriptions = [];
|
|
65
|
+
return (action, arg) => {
|
|
66
|
+
switch (action) {
|
|
67
|
+
case RESET:
|
|
68
|
+
subscriptions.splice(0, subscriptions.length);
|
|
69
|
+
return;
|
|
70
|
+
case SUBSCRIBE:
|
|
71
|
+
subscriptions.push(arg);
|
|
72
|
+
return () => {
|
|
73
|
+
const indexOf = subscriptions.indexOf(arg);
|
|
74
|
+
if (indexOf > -1) {
|
|
75
|
+
subscriptions.splice(indexOf, 1);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
case PUBLISH:
|
|
79
|
+
subscriptions.slice().forEach((subscription) => {
|
|
80
|
+
subscription(arg);
|
|
81
|
+
});
|
|
82
|
+
return;
|
|
83
|
+
default:
|
|
84
|
+
throw new Error(`unrecognized action ${action}`);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function statefulStream(initial) {
|
|
89
|
+
let value = initial;
|
|
90
|
+
const innerSubject = stream();
|
|
91
|
+
return (action, arg) => {
|
|
92
|
+
switch (action) {
|
|
93
|
+
case SUBSCRIBE:
|
|
94
|
+
const subscription = arg;
|
|
95
|
+
subscription(value);
|
|
96
|
+
break;
|
|
97
|
+
case PUBLISH:
|
|
98
|
+
value = arg;
|
|
99
|
+
break;
|
|
100
|
+
case VALUE:
|
|
101
|
+
return value;
|
|
102
|
+
}
|
|
103
|
+
return innerSubject(action, arg);
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function eventHandler(emitter) {
|
|
107
|
+
let unsub;
|
|
108
|
+
let currentSubscription;
|
|
109
|
+
const cleanup = () => unsub && unsub();
|
|
110
|
+
return function(action, subscription) {
|
|
111
|
+
switch (action) {
|
|
112
|
+
case SUBSCRIBE:
|
|
113
|
+
if (subscription) {
|
|
114
|
+
if (currentSubscription === subscription) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
cleanup();
|
|
118
|
+
currentSubscription = subscription;
|
|
119
|
+
unsub = subscribe(emitter, subscription);
|
|
120
|
+
return unsub;
|
|
121
|
+
} else {
|
|
122
|
+
cleanup();
|
|
123
|
+
return noop;
|
|
124
|
+
}
|
|
125
|
+
case RESET:
|
|
126
|
+
cleanup();
|
|
127
|
+
currentSubscription = null;
|
|
128
|
+
return;
|
|
129
|
+
default:
|
|
130
|
+
throw new Error(`unrecognized action ${action}`);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function streamFromEmitter(emitter) {
|
|
135
|
+
return tap(stream(), (stream2) => connect(emitter, stream2));
|
|
136
|
+
}
|
|
137
|
+
function statefulStreamFromEmitter(emitter, initial) {
|
|
138
|
+
return tap(statefulStream(initial), (stream2) => connect(emitter, stream2));
|
|
139
|
+
}
|
|
140
|
+
function combineOperators(...operators) {
|
|
141
|
+
return (subscriber) => {
|
|
142
|
+
return operators.reduceRight(thrush, subscriber);
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function pipe(source, ...operators) {
|
|
146
|
+
const project = combineOperators(...operators);
|
|
147
|
+
return (action, subscription) => {
|
|
148
|
+
switch (action) {
|
|
149
|
+
case SUBSCRIBE:
|
|
150
|
+
return subscribe(source, project(subscription));
|
|
151
|
+
case RESET:
|
|
152
|
+
reset(source);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function defaultComparator(previous, next) {
|
|
158
|
+
return previous === next;
|
|
159
|
+
}
|
|
160
|
+
function distinctUntilChanged(comparator = defaultComparator) {
|
|
161
|
+
let current;
|
|
162
|
+
return (done) => (next) => {
|
|
163
|
+
if (!comparator(current, next)) {
|
|
164
|
+
current = next;
|
|
165
|
+
done(next);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function filter(predicate) {
|
|
170
|
+
return (done) => (value) => {
|
|
171
|
+
predicate(value) && done(value);
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function map(project) {
|
|
175
|
+
return (done) => compose(done, project);
|
|
176
|
+
}
|
|
177
|
+
function mapTo(value) {
|
|
178
|
+
return (done) => () => done(value);
|
|
179
|
+
}
|
|
180
|
+
function scan(scanner, initial) {
|
|
181
|
+
return (done) => (value) => done(initial = scanner(initial, value));
|
|
182
|
+
}
|
|
183
|
+
function skip(times) {
|
|
184
|
+
return (done) => (value) => {
|
|
185
|
+
times > 0 ? times-- : done(value);
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function throttleTime(interval) {
|
|
189
|
+
let currentValue;
|
|
190
|
+
let timeout;
|
|
191
|
+
return (done) => (value) => {
|
|
192
|
+
currentValue = value;
|
|
193
|
+
if (timeout) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
timeout = setTimeout(() => {
|
|
197
|
+
timeout = void 0;
|
|
198
|
+
done(currentValue);
|
|
199
|
+
}, interval);
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function debounceTime(interval) {
|
|
203
|
+
let currentValue;
|
|
204
|
+
let timeout;
|
|
205
|
+
return (done) => (value) => {
|
|
206
|
+
currentValue = value;
|
|
207
|
+
if (timeout) {
|
|
208
|
+
clearTimeout(timeout);
|
|
209
|
+
}
|
|
210
|
+
timeout = setTimeout(() => {
|
|
211
|
+
done(currentValue);
|
|
212
|
+
}, interval);
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
function withLatestFrom(...sources) {
|
|
216
|
+
const values = new Array(sources.length);
|
|
217
|
+
let called = 0;
|
|
218
|
+
let pendingCall = null;
|
|
219
|
+
const allCalled = Math.pow(2, sources.length) - 1;
|
|
220
|
+
sources.forEach((source, index) => {
|
|
221
|
+
const bit = Math.pow(2, index);
|
|
222
|
+
subscribe(source, (value) => {
|
|
223
|
+
const prevCalled = called;
|
|
224
|
+
called = called | bit;
|
|
225
|
+
values[index] = value;
|
|
226
|
+
if (prevCalled !== allCalled && called === allCalled && pendingCall) {
|
|
227
|
+
pendingCall();
|
|
228
|
+
pendingCall = null;
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
return (done) => (value) => {
|
|
233
|
+
const call2 = () => done([value].concat(values));
|
|
234
|
+
if (called === allCalled) {
|
|
235
|
+
call2();
|
|
236
|
+
} else {
|
|
237
|
+
pendingCall = call2;
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
function merge(...sources) {
|
|
242
|
+
return function(action, subscription) {
|
|
243
|
+
switch (action) {
|
|
244
|
+
case SUBSCRIBE:
|
|
245
|
+
return joinProc(...sources.map((source) => subscribe(source, subscription)));
|
|
246
|
+
case RESET:
|
|
247
|
+
return;
|
|
248
|
+
default:
|
|
249
|
+
throw new Error(`unrecognized action ${action}`);
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
function duc(source, comparator = defaultComparator) {
|
|
254
|
+
return pipe(source, distinctUntilChanged(comparator));
|
|
255
|
+
}
|
|
256
|
+
function combineLatest(...emitters) {
|
|
257
|
+
const innerSubject = stream();
|
|
258
|
+
const values = new Array(emitters.length);
|
|
259
|
+
let called = 0;
|
|
260
|
+
const allCalled = Math.pow(2, emitters.length) - 1;
|
|
261
|
+
emitters.forEach((source, index) => {
|
|
262
|
+
const bit = Math.pow(2, index);
|
|
263
|
+
subscribe(source, (value) => {
|
|
264
|
+
values[index] = value;
|
|
265
|
+
called = called | bit;
|
|
266
|
+
if (called === allCalled) {
|
|
267
|
+
publish(innerSubject, values);
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
return function(action, subscription) {
|
|
272
|
+
switch (action) {
|
|
273
|
+
case SUBSCRIBE:
|
|
274
|
+
if (called === allCalled) {
|
|
275
|
+
subscription(values);
|
|
276
|
+
}
|
|
277
|
+
return subscribe(innerSubject, subscription);
|
|
278
|
+
case RESET:
|
|
279
|
+
return reset(innerSubject);
|
|
280
|
+
default:
|
|
281
|
+
throw new Error(`unrecognized action ${action}`);
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
function system(constructor, dependencies = [], { singleton } = { singleton: true }) {
|
|
286
|
+
return {
|
|
287
|
+
id: id(),
|
|
288
|
+
constructor,
|
|
289
|
+
dependencies,
|
|
290
|
+
singleton
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
const id = () => Symbol();
|
|
294
|
+
function init(systemSpec) {
|
|
295
|
+
const singletons = /* @__PURE__ */ new Map();
|
|
296
|
+
const _init = ({ id: id2, constructor, dependencies, singleton }) => {
|
|
297
|
+
if (singleton && singletons.has(id2)) {
|
|
298
|
+
return singletons.get(id2);
|
|
299
|
+
}
|
|
300
|
+
const system2 = constructor(dependencies.map((e) => _init(e)));
|
|
301
|
+
if (singleton) {
|
|
302
|
+
singletons.set(id2, system2);
|
|
303
|
+
}
|
|
304
|
+
return system2;
|
|
305
|
+
};
|
|
306
|
+
return _init(systemSpec);
|
|
307
|
+
}
|
|
308
|
+
function omit(keys, obj) {
|
|
309
|
+
const result = {};
|
|
310
|
+
const index = {};
|
|
311
|
+
let idx = 0;
|
|
312
|
+
const len = keys.length;
|
|
313
|
+
while (idx < len) {
|
|
314
|
+
index[keys[idx]] = 1;
|
|
315
|
+
idx += 1;
|
|
316
|
+
}
|
|
317
|
+
for (const prop in obj) {
|
|
318
|
+
if (!index.hasOwnProperty(prop)) {
|
|
319
|
+
result[prop] = obj[prop];
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return result;
|
|
323
|
+
}
|
|
324
|
+
const useIsomorphicLayoutEffect$2 = typeof document !== "undefined" ? React.useLayoutEffect : React.useEffect;
|
|
325
|
+
function systemToComponent(systemSpec, map2, Root) {
|
|
326
|
+
const requiredPropNames = Object.keys(map2.required || {});
|
|
327
|
+
const optionalPropNames = Object.keys(map2.optional || {});
|
|
328
|
+
const methodNames = Object.keys(map2.methods || {});
|
|
329
|
+
const eventNames = Object.keys(map2.events || {});
|
|
330
|
+
const Context = createContext({});
|
|
331
|
+
function applyPropsToSystem(system2, props) {
|
|
332
|
+
if (system2["propsReady"]) {
|
|
333
|
+
publish(system2["propsReady"], false);
|
|
334
|
+
}
|
|
335
|
+
for (const requiredPropName of requiredPropNames) {
|
|
336
|
+
const stream2 = system2[map2.required[requiredPropName]];
|
|
337
|
+
publish(stream2, props[requiredPropName]);
|
|
338
|
+
}
|
|
339
|
+
for (const optionalPropName of optionalPropNames) {
|
|
340
|
+
if (optionalPropName in props) {
|
|
341
|
+
const stream2 = system2[map2.optional[optionalPropName]];
|
|
342
|
+
publish(stream2, props[optionalPropName]);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
if (system2["propsReady"]) {
|
|
346
|
+
publish(system2["propsReady"], true);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
function buildMethods(system2) {
|
|
350
|
+
return methodNames.reduce((acc, methodName) => {
|
|
351
|
+
acc[methodName] = (value) => {
|
|
352
|
+
const stream2 = system2[map2.methods[methodName]];
|
|
353
|
+
publish(stream2, value);
|
|
354
|
+
};
|
|
355
|
+
return acc;
|
|
356
|
+
}, {});
|
|
357
|
+
}
|
|
358
|
+
function buildEventHandlers(system2) {
|
|
359
|
+
return eventNames.reduce((handlers, eventName) => {
|
|
360
|
+
handlers[eventName] = eventHandler(system2[map2.events[eventName]]);
|
|
361
|
+
return handlers;
|
|
362
|
+
}, {});
|
|
363
|
+
}
|
|
364
|
+
const Component = forwardRef((propsWithChildren, ref) => {
|
|
365
|
+
const { children, ...props } = propsWithChildren;
|
|
366
|
+
const [system2] = useState(() => {
|
|
367
|
+
return tap(init(systemSpec), (system22) => applyPropsToSystem(system22, props));
|
|
368
|
+
});
|
|
369
|
+
const [handlers] = useState(curry1to0(buildEventHandlers, system2));
|
|
370
|
+
useIsomorphicLayoutEffect$2(() => {
|
|
371
|
+
for (const eventName of eventNames) {
|
|
372
|
+
if (eventName in props) {
|
|
373
|
+
subscribe(handlers[eventName], props[eventName]);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return () => {
|
|
377
|
+
Object.values(handlers).map(reset);
|
|
378
|
+
};
|
|
379
|
+
}, [props, handlers, system2]);
|
|
380
|
+
useIsomorphicLayoutEffect$2(() => {
|
|
381
|
+
applyPropsToSystem(system2, props);
|
|
382
|
+
});
|
|
383
|
+
useImperativeHandle(ref, always(buildMethods(system2)));
|
|
384
|
+
return createElement(
|
|
385
|
+
Context.Provider,
|
|
386
|
+
{ value: system2 },
|
|
387
|
+
Root ? createElement(
|
|
388
|
+
Root,
|
|
389
|
+
omit([...requiredPropNames, ...optionalPropNames, ...eventNames], props),
|
|
390
|
+
children
|
|
391
|
+
) : children
|
|
392
|
+
);
|
|
393
|
+
});
|
|
394
|
+
const usePublisher2 = (key) => {
|
|
395
|
+
return useCallback(curry2to1(publish, React.useContext(Context)[key]), [key]);
|
|
396
|
+
};
|
|
397
|
+
const useEmitterValue2 = (key) => {
|
|
398
|
+
const system2 = useContext(Context);
|
|
399
|
+
const source = system2[key];
|
|
400
|
+
const [value, setValue] = useState(curry1to0(getValue, source));
|
|
401
|
+
useIsomorphicLayoutEffect$2(
|
|
402
|
+
() => subscribe(source, (next) => {
|
|
403
|
+
if (next !== value) {
|
|
404
|
+
setValue(always(next));
|
|
405
|
+
}
|
|
406
|
+
}),
|
|
407
|
+
[source, value]
|
|
408
|
+
);
|
|
409
|
+
return value;
|
|
410
|
+
};
|
|
411
|
+
const useEmitter2 = (key, callback) => {
|
|
412
|
+
const context = useContext(Context);
|
|
413
|
+
const source = context[key];
|
|
414
|
+
useIsomorphicLayoutEffect$2(() => subscribe(source, callback), [callback, source]);
|
|
415
|
+
};
|
|
416
|
+
return {
|
|
417
|
+
Component,
|
|
418
|
+
usePublisher: usePublisher2,
|
|
419
|
+
useEmitterValue: useEmitterValue2,
|
|
420
|
+
useEmitter: useEmitter2
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
const useIsomorphicLayoutEffect = typeof document !== "undefined" ? useLayoutEffect : useEffect;
|
|
424
|
+
const useIsomorphicLayoutEffect$1 = useIsomorphicLayoutEffect;
|
|
425
|
+
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
426
|
+
LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
|
|
427
|
+
LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
|
|
428
|
+
LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
|
|
429
|
+
LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
|
|
430
|
+
return LogLevel2;
|
|
431
|
+
})(LogLevel || {});
|
|
432
|
+
const CONSOLE_METHOD_MAP = {
|
|
433
|
+
[0]: "debug",
|
|
434
|
+
[1]: "log",
|
|
435
|
+
[2]: "warn",
|
|
436
|
+
[3]: "error"
|
|
437
|
+
};
|
|
438
|
+
const getGlobalThis = () => typeof globalThis === "undefined" ? window : globalThis;
|
|
439
|
+
const loggerSystem = system(
|
|
440
|
+
() => {
|
|
441
|
+
const logLevel = statefulStream(3);
|
|
442
|
+
const log = statefulStream((label, message, level = 1) => {
|
|
443
|
+
const currentLevel = getGlobalThis()["VIRTUOSO_LOG_LEVEL"] ?? getValue(logLevel);
|
|
444
|
+
if (level >= currentLevel) {
|
|
445
|
+
console[CONSOLE_METHOD_MAP[level]](
|
|
446
|
+
"%creact-virtuoso: %c%s %o",
|
|
447
|
+
"color: #0253b3; font-weight: bold",
|
|
448
|
+
"color: initial",
|
|
449
|
+
label,
|
|
450
|
+
message
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
return {
|
|
455
|
+
log,
|
|
456
|
+
logLevel
|
|
457
|
+
};
|
|
458
|
+
},
|
|
459
|
+
[],
|
|
460
|
+
{ singleton: true }
|
|
461
|
+
);
|
|
462
|
+
function useSizeWithElRef(callback, enabled = true) {
|
|
463
|
+
const ref = useRef(null);
|
|
464
|
+
let callbackRef = (_el) => {
|
|
465
|
+
};
|
|
466
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
467
|
+
const observer = new ResizeObserver((entries) => {
|
|
468
|
+
const element = entries[0].target;
|
|
469
|
+
if (element.offsetParent !== null) {
|
|
470
|
+
callback(element);
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
callbackRef = (elRef) => {
|
|
474
|
+
if (elRef && enabled) {
|
|
475
|
+
observer.observe(elRef);
|
|
476
|
+
ref.current = elRef;
|
|
477
|
+
} else {
|
|
478
|
+
if (ref.current) {
|
|
479
|
+
observer.unobserve(ref.current);
|
|
480
|
+
}
|
|
481
|
+
ref.current = null;
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
return { ref, callbackRef };
|
|
486
|
+
}
|
|
487
|
+
function useSize(callback, enabled = true) {
|
|
488
|
+
return useSizeWithElRef(callback, enabled).callbackRef;
|
|
489
|
+
}
|
|
490
|
+
function useChangedListContentsSizes(callback, itemSize, enabled, scrollContainerStateCallback, log, gap, customScrollParent) {
|
|
491
|
+
return useSizeWithElRef((el) => {
|
|
492
|
+
const ranges = getChangedChildSizes(el.children, itemSize, "offsetHeight", log);
|
|
493
|
+
let scrollableElement = el.parentElement;
|
|
494
|
+
while (!scrollableElement.dataset["virtuosoScroller"]) {
|
|
495
|
+
scrollableElement = scrollableElement.parentElement;
|
|
496
|
+
}
|
|
497
|
+
const windowScrolling = scrollableElement.firstElementChild.dataset["viewportType"] === "window";
|
|
498
|
+
const scrollTop = customScrollParent ? customScrollParent.scrollTop : windowScrolling ? window.pageYOffset || document.documentElement.scrollTop : scrollableElement.scrollTop;
|
|
499
|
+
const scrollHeight = customScrollParent ? customScrollParent.scrollHeight : windowScrolling ? document.documentElement.scrollHeight : scrollableElement.scrollHeight;
|
|
500
|
+
const viewportHeight = customScrollParent ? customScrollParent.offsetHeight : windowScrolling ? window.innerHeight : scrollableElement.offsetHeight;
|
|
501
|
+
scrollContainerStateCallback({
|
|
502
|
+
scrollTop: Math.max(scrollTop, 0),
|
|
503
|
+
scrollHeight,
|
|
504
|
+
viewportHeight
|
|
505
|
+
});
|
|
506
|
+
gap == null ? void 0 : gap(resolveGapValue$1("row-gap", getComputedStyle(el).rowGap, log));
|
|
507
|
+
if (ranges !== null) {
|
|
508
|
+
callback(ranges);
|
|
509
|
+
}
|
|
510
|
+
}, enabled);
|
|
511
|
+
}
|
|
512
|
+
function getChangedChildSizes(children, itemSize, field, log) {
|
|
513
|
+
const length = children.length;
|
|
514
|
+
if (length === 0) {
|
|
515
|
+
return null;
|
|
516
|
+
}
|
|
517
|
+
const results = [];
|
|
518
|
+
for (let i = 0; i < length; i++) {
|
|
519
|
+
const child = children.item(i);
|
|
520
|
+
if (!child || child.dataset.index === void 0) {
|
|
521
|
+
continue;
|
|
522
|
+
}
|
|
523
|
+
const index = parseInt(child.dataset.index);
|
|
524
|
+
const knownSize = parseFloat(child.dataset.knownSize);
|
|
525
|
+
const size = itemSize(child, field);
|
|
526
|
+
if (size === 0) {
|
|
527
|
+
log("Zero-sized element, this should not happen", { child }, LogLevel.ERROR);
|
|
528
|
+
}
|
|
529
|
+
if (size === knownSize) {
|
|
530
|
+
continue;
|
|
531
|
+
}
|
|
532
|
+
const lastResult = results[results.length - 1];
|
|
533
|
+
if (results.length === 0 || lastResult.size !== size || lastResult.endIndex !== index - 1) {
|
|
534
|
+
results.push({ startIndex: index, endIndex: index, size });
|
|
535
|
+
} else {
|
|
536
|
+
results[results.length - 1].endIndex++;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return results;
|
|
540
|
+
}
|
|
541
|
+
function resolveGapValue$1(property, value, log) {
|
|
542
|
+
if (value !== "normal" && !(value == null ? void 0 : value.endsWith("px"))) {
|
|
543
|
+
log(`${property} was not resolved to pixel value correctly`, value, LogLevel.WARN);
|
|
544
|
+
}
|
|
545
|
+
if (value === "normal") {
|
|
546
|
+
return 0;
|
|
547
|
+
}
|
|
548
|
+
return parseInt(value ?? "0", 10);
|
|
549
|
+
}
|
|
550
|
+
function correctItemSize(el, dimension) {
|
|
551
|
+
return Math.round(el.getBoundingClientRect()[dimension]);
|
|
552
|
+
}
|
|
553
|
+
function approximatelyEqual(num1, num2) {
|
|
554
|
+
return Math.abs(num1 - num2) < 1.01;
|
|
555
|
+
}
|
|
556
|
+
function useScrollTop(scrollContainerStateCallback, smoothScrollTargetReached, scrollerElement, scrollerRefCallback = noop, customScrollParent) {
|
|
557
|
+
const scrollerRef = useRef(null);
|
|
558
|
+
const scrollTopTarget = useRef(null);
|
|
559
|
+
const timeoutRef = useRef(null);
|
|
560
|
+
const handler = useCallback(
|
|
561
|
+
(ev) => {
|
|
562
|
+
const el = ev.target;
|
|
563
|
+
const windowScroll = el === window || el === document;
|
|
564
|
+
const scrollTop = windowScroll ? window.pageYOffset || document.documentElement.scrollTop : el.scrollTop;
|
|
565
|
+
const scrollHeight = windowScroll ? document.documentElement.scrollHeight : el.scrollHeight;
|
|
566
|
+
const viewportHeight = windowScroll ? window.innerHeight : el.offsetHeight;
|
|
567
|
+
const call2 = () => {
|
|
568
|
+
scrollContainerStateCallback({
|
|
569
|
+
scrollTop: Math.max(scrollTop, 0),
|
|
570
|
+
scrollHeight,
|
|
571
|
+
viewportHeight
|
|
572
|
+
});
|
|
573
|
+
};
|
|
574
|
+
if (ev.suppressFlushSync) {
|
|
575
|
+
call2();
|
|
576
|
+
} else {
|
|
577
|
+
flushSync(call2);
|
|
578
|
+
}
|
|
579
|
+
if (scrollTopTarget.current !== null) {
|
|
580
|
+
if (scrollTop === scrollTopTarget.current || scrollTop <= 0 || scrollTop === scrollHeight - viewportHeight) {
|
|
581
|
+
scrollTopTarget.current = null;
|
|
582
|
+
smoothScrollTargetReached(true);
|
|
583
|
+
if (timeoutRef.current) {
|
|
584
|
+
clearTimeout(timeoutRef.current);
|
|
585
|
+
timeoutRef.current = null;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
},
|
|
590
|
+
[scrollContainerStateCallback, smoothScrollTargetReached]
|
|
591
|
+
);
|
|
592
|
+
useEffect(() => {
|
|
593
|
+
const localRef = customScrollParent ? customScrollParent : scrollerRef.current;
|
|
594
|
+
scrollerRefCallback(customScrollParent ? customScrollParent : scrollerRef.current);
|
|
595
|
+
handler({ target: localRef, suppressFlushSync: true });
|
|
596
|
+
localRef.addEventListener("scroll", handler, { passive: true });
|
|
597
|
+
return () => {
|
|
598
|
+
scrollerRefCallback(null);
|
|
599
|
+
localRef.removeEventListener("scroll", handler);
|
|
600
|
+
};
|
|
601
|
+
}, [scrollerRef, handler, scrollerElement, scrollerRefCallback, customScrollParent]);
|
|
602
|
+
function scrollToCallback(location) {
|
|
603
|
+
const scrollerElement2 = scrollerRef.current;
|
|
604
|
+
if (!scrollerElement2 || "offsetHeight" in scrollerElement2 && scrollerElement2.offsetHeight === 0) {
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
const isSmooth = location.behavior === "smooth";
|
|
608
|
+
let offsetHeight;
|
|
609
|
+
let scrollHeight;
|
|
610
|
+
let scrollTop;
|
|
611
|
+
if (scrollerElement2 === window) {
|
|
612
|
+
scrollHeight = Math.max(correctItemSize(document.documentElement, "height"), document.documentElement.scrollHeight);
|
|
613
|
+
offsetHeight = window.innerHeight;
|
|
614
|
+
scrollTop = document.documentElement.scrollTop;
|
|
615
|
+
} else {
|
|
616
|
+
scrollHeight = scrollerElement2.scrollHeight;
|
|
617
|
+
offsetHeight = correctItemSize(scrollerElement2, "height");
|
|
618
|
+
scrollTop = scrollerElement2.scrollTop;
|
|
619
|
+
}
|
|
620
|
+
const maxScrollTop = scrollHeight - offsetHeight;
|
|
621
|
+
location.top = Math.ceil(Math.max(Math.min(maxScrollTop, location.top), 0));
|
|
622
|
+
if (approximatelyEqual(offsetHeight, scrollHeight) || location.top === scrollTop) {
|
|
623
|
+
scrollContainerStateCallback({ scrollTop, scrollHeight, viewportHeight: offsetHeight });
|
|
624
|
+
if (isSmooth) {
|
|
625
|
+
smoothScrollTargetReached(true);
|
|
626
|
+
}
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
if (isSmooth) {
|
|
630
|
+
scrollTopTarget.current = location.top;
|
|
631
|
+
if (timeoutRef.current) {
|
|
632
|
+
clearTimeout(timeoutRef.current);
|
|
633
|
+
}
|
|
634
|
+
timeoutRef.current = setTimeout(() => {
|
|
635
|
+
timeoutRef.current = null;
|
|
636
|
+
scrollTopTarget.current = null;
|
|
637
|
+
smoothScrollTargetReached(true);
|
|
638
|
+
}, 1e3);
|
|
639
|
+
} else {
|
|
640
|
+
scrollTopTarget.current = null;
|
|
641
|
+
}
|
|
642
|
+
scrollerElement2.scrollTo(location);
|
|
643
|
+
}
|
|
644
|
+
function scrollByCallback(location) {
|
|
645
|
+
scrollerRef.current.scrollBy(location);
|
|
646
|
+
}
|
|
647
|
+
return { scrollerRef, scrollByCallback, scrollToCallback };
|
|
648
|
+
}
|
|
649
|
+
const domIOSystem = system(
|
|
650
|
+
() => {
|
|
651
|
+
const scrollContainerState = stream();
|
|
652
|
+
const scrollTop = stream();
|
|
653
|
+
const deviation = statefulStream(0);
|
|
654
|
+
const smoothScrollTargetReached = stream();
|
|
655
|
+
const statefulScrollTop = statefulStream(0);
|
|
656
|
+
const viewportHeight = stream();
|
|
657
|
+
const scrollHeight = stream();
|
|
658
|
+
const headerHeight = statefulStream(0);
|
|
659
|
+
const fixedHeaderHeight = statefulStream(0);
|
|
660
|
+
const fixedFooterHeight = statefulStream(0);
|
|
661
|
+
const footerHeight = statefulStream(0);
|
|
662
|
+
const scrollTo = stream();
|
|
663
|
+
const scrollBy = stream();
|
|
664
|
+
const scrollingInProgress = statefulStream(false);
|
|
665
|
+
connect(
|
|
666
|
+
pipe(
|
|
667
|
+
scrollContainerState,
|
|
668
|
+
map(({ scrollTop: scrollTop2 }) => scrollTop2)
|
|
669
|
+
),
|
|
670
|
+
scrollTop
|
|
671
|
+
);
|
|
672
|
+
connect(
|
|
673
|
+
pipe(
|
|
674
|
+
scrollContainerState,
|
|
675
|
+
map(({ scrollHeight: scrollHeight2 }) => scrollHeight2)
|
|
676
|
+
),
|
|
677
|
+
scrollHeight
|
|
678
|
+
);
|
|
679
|
+
connect(scrollTop, statefulScrollTop);
|
|
680
|
+
return {
|
|
681
|
+
scrollContainerState,
|
|
682
|
+
scrollTop,
|
|
683
|
+
viewportHeight,
|
|
684
|
+
headerHeight,
|
|
685
|
+
fixedHeaderHeight,
|
|
686
|
+
fixedFooterHeight,
|
|
687
|
+
footerHeight,
|
|
688
|
+
scrollHeight,
|
|
689
|
+
smoothScrollTargetReached,
|
|
690
|
+
scrollTo,
|
|
691
|
+
scrollBy,
|
|
692
|
+
statefulScrollTop,
|
|
693
|
+
deviation,
|
|
694
|
+
scrollingInProgress
|
|
695
|
+
};
|
|
696
|
+
},
|
|
697
|
+
[],
|
|
698
|
+
{ singleton: true }
|
|
699
|
+
);
|
|
700
|
+
const NIL_NODE = { lvl: 0 };
|
|
701
|
+
function newAANode(k, v, lvl, l = NIL_NODE, r = NIL_NODE) {
|
|
702
|
+
return { k, v, lvl, l, r };
|
|
703
|
+
}
|
|
704
|
+
function empty(node) {
|
|
705
|
+
return node === NIL_NODE;
|
|
706
|
+
}
|
|
707
|
+
function newTree() {
|
|
708
|
+
return NIL_NODE;
|
|
709
|
+
}
|
|
710
|
+
function remove(node, key) {
|
|
711
|
+
if (empty(node))
|
|
712
|
+
return NIL_NODE;
|
|
713
|
+
const { k, l, r } = node;
|
|
714
|
+
if (key === k) {
|
|
715
|
+
if (empty(l)) {
|
|
716
|
+
return r;
|
|
717
|
+
} else if (empty(r)) {
|
|
718
|
+
return l;
|
|
719
|
+
} else {
|
|
720
|
+
const [lastKey, lastValue] = last(l);
|
|
721
|
+
return adjust(clone(node, { k: lastKey, v: lastValue, l: deleteLast(l) }));
|
|
722
|
+
}
|
|
723
|
+
} else if (key < k) {
|
|
724
|
+
return adjust(clone(node, { l: remove(l, key) }));
|
|
725
|
+
} else {
|
|
726
|
+
return adjust(clone(node, { r: remove(r, key) }));
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
function findMaxKeyValue(node, value, field = "k") {
|
|
730
|
+
if (empty(node)) {
|
|
731
|
+
return [-Infinity, void 0];
|
|
732
|
+
}
|
|
733
|
+
if (node[field] === value) {
|
|
734
|
+
return [node.k, node.v];
|
|
735
|
+
}
|
|
736
|
+
if (node[field] < value) {
|
|
737
|
+
const r = findMaxKeyValue(node.r, value, field);
|
|
738
|
+
if (r[0] === -Infinity) {
|
|
739
|
+
return [node.k, node.v];
|
|
740
|
+
} else {
|
|
741
|
+
return r;
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
return findMaxKeyValue(node.l, value, field);
|
|
745
|
+
}
|
|
746
|
+
function insert(node, k, v) {
|
|
747
|
+
if (empty(node)) {
|
|
748
|
+
return newAANode(k, v, 1);
|
|
749
|
+
}
|
|
750
|
+
if (k === node.k) {
|
|
751
|
+
return clone(node, { k, v });
|
|
752
|
+
} else if (k < node.k) {
|
|
753
|
+
return rebalance(clone(node, { l: insert(node.l, k, v) }));
|
|
754
|
+
} else {
|
|
755
|
+
return rebalance(clone(node, { r: insert(node.r, k, v) }));
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
function walkWithin(node, start, end) {
|
|
759
|
+
if (empty(node)) {
|
|
760
|
+
return [];
|
|
761
|
+
}
|
|
762
|
+
const { k, v, l, r } = node;
|
|
763
|
+
let result = [];
|
|
764
|
+
if (k > start) {
|
|
765
|
+
result = result.concat(walkWithin(l, start, end));
|
|
766
|
+
}
|
|
767
|
+
if (k >= start && k <= end) {
|
|
768
|
+
result.push({ k, v });
|
|
769
|
+
}
|
|
770
|
+
if (k <= end) {
|
|
771
|
+
result = result.concat(walkWithin(r, start, end));
|
|
772
|
+
}
|
|
773
|
+
return result;
|
|
774
|
+
}
|
|
775
|
+
function walk(node) {
|
|
776
|
+
if (empty(node)) {
|
|
777
|
+
return [];
|
|
778
|
+
}
|
|
779
|
+
return [...walk(node.l), { k: node.k, v: node.v }, ...walk(node.r)];
|
|
780
|
+
}
|
|
781
|
+
function last(node) {
|
|
782
|
+
return empty(node.r) ? [node.k, node.v] : last(node.r);
|
|
783
|
+
}
|
|
784
|
+
function deleteLast(node) {
|
|
785
|
+
return empty(node.r) ? node.l : adjust(clone(node, { r: deleteLast(node.r) }));
|
|
786
|
+
}
|
|
787
|
+
function clone(node, args) {
|
|
788
|
+
return newAANode(
|
|
789
|
+
args.k !== void 0 ? args.k : node.k,
|
|
790
|
+
args.v !== void 0 ? args.v : node.v,
|
|
791
|
+
args.lvl !== void 0 ? args.lvl : node.lvl,
|
|
792
|
+
args.l !== void 0 ? args.l : node.l,
|
|
793
|
+
args.r !== void 0 ? args.r : node.r
|
|
794
|
+
);
|
|
795
|
+
}
|
|
796
|
+
function isSingle(node) {
|
|
797
|
+
return empty(node) || node.lvl > node.r.lvl;
|
|
798
|
+
}
|
|
799
|
+
function rebalance(node) {
|
|
800
|
+
return split(skew(node));
|
|
801
|
+
}
|
|
802
|
+
function adjust(node) {
|
|
803
|
+
const { l, r, lvl } = node;
|
|
804
|
+
if (r.lvl >= lvl - 1 && l.lvl >= lvl - 1) {
|
|
805
|
+
return node;
|
|
806
|
+
} else if (lvl > r.lvl + 1) {
|
|
807
|
+
if (isSingle(l)) {
|
|
808
|
+
return skew(clone(node, { lvl: lvl - 1 }));
|
|
809
|
+
} else {
|
|
810
|
+
if (!empty(l) && !empty(l.r)) {
|
|
811
|
+
return clone(l.r, {
|
|
812
|
+
l: clone(l, { r: l.r.l }),
|
|
813
|
+
r: clone(node, {
|
|
814
|
+
l: l.r.r,
|
|
815
|
+
lvl: lvl - 1
|
|
816
|
+
}),
|
|
817
|
+
lvl
|
|
818
|
+
});
|
|
819
|
+
} else {
|
|
820
|
+
throw new Error("Unexpected empty nodes");
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
} else {
|
|
824
|
+
if (isSingle(node)) {
|
|
825
|
+
return split(clone(node, { lvl: lvl - 1 }));
|
|
826
|
+
} else {
|
|
827
|
+
if (!empty(r) && !empty(r.l)) {
|
|
828
|
+
const rl = r.l;
|
|
829
|
+
const rlvl = isSingle(rl) ? r.lvl - 1 : r.lvl;
|
|
830
|
+
return clone(rl, {
|
|
831
|
+
l: clone(node, {
|
|
832
|
+
r: rl.l,
|
|
833
|
+
lvl: lvl - 1
|
|
834
|
+
}),
|
|
835
|
+
r: split(clone(r, { l: rl.r, lvl: rlvl })),
|
|
836
|
+
lvl: rl.lvl + 1
|
|
837
|
+
});
|
|
838
|
+
} else {
|
|
839
|
+
throw new Error("Unexpected empty nodes");
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
function rangesWithin(node, startIndex, endIndex) {
|
|
845
|
+
if (empty(node)) {
|
|
846
|
+
return [];
|
|
847
|
+
}
|
|
848
|
+
const adjustedStart = findMaxKeyValue(node, startIndex)[0];
|
|
849
|
+
return toRanges(walkWithin(node, adjustedStart, endIndex));
|
|
850
|
+
}
|
|
851
|
+
function arrayToRanges(items, parser) {
|
|
852
|
+
const length = items.length;
|
|
853
|
+
if (length === 0) {
|
|
854
|
+
return [];
|
|
855
|
+
}
|
|
856
|
+
let { index: start, value } = parser(items[0]);
|
|
857
|
+
const result = [];
|
|
858
|
+
for (let i = 1; i < length; i++) {
|
|
859
|
+
const { index: nextIndex, value: nextValue } = parser(items[i]);
|
|
860
|
+
result.push({ start, end: nextIndex - 1, value });
|
|
861
|
+
start = nextIndex;
|
|
862
|
+
value = nextValue;
|
|
863
|
+
}
|
|
864
|
+
result.push({ start, end: Infinity, value });
|
|
865
|
+
return result;
|
|
866
|
+
}
|
|
867
|
+
function toRanges(nodes) {
|
|
868
|
+
return arrayToRanges(nodes, ({ k: index, v: value }) => ({ index, value }));
|
|
869
|
+
}
|
|
870
|
+
function split(node) {
|
|
871
|
+
const { r, lvl } = node;
|
|
872
|
+
return !empty(r) && !empty(r.r) && r.lvl === lvl && r.r.lvl === lvl ? clone(r, { l: clone(node, { r: r.l }), lvl: lvl + 1 }) : node;
|
|
873
|
+
}
|
|
874
|
+
function skew(node) {
|
|
875
|
+
const { l } = node;
|
|
876
|
+
return !empty(l) && l.lvl === node.lvl ? clone(l, { r: clone(node, { l: l.r }) }) : node;
|
|
877
|
+
}
|
|
878
|
+
function findIndexOfClosestSmallerOrEqual(items, value, comparator, start = 0) {
|
|
879
|
+
let end = items.length - 1;
|
|
880
|
+
while (start <= end) {
|
|
881
|
+
const index = Math.floor((start + end) / 2);
|
|
882
|
+
const item = items[index];
|
|
883
|
+
const match = comparator(item, value);
|
|
884
|
+
if (match === 0) {
|
|
885
|
+
return index;
|
|
886
|
+
}
|
|
887
|
+
if (match === -1) {
|
|
888
|
+
if (end - start < 2) {
|
|
889
|
+
return index - 1;
|
|
890
|
+
}
|
|
891
|
+
end = index - 1;
|
|
892
|
+
} else {
|
|
893
|
+
if (end === start) {
|
|
894
|
+
return index;
|
|
895
|
+
}
|
|
896
|
+
start = index + 1;
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
throw new Error(`Failed binary finding record in array - ${items.join(",")}, searched for ${value}`);
|
|
900
|
+
}
|
|
901
|
+
function findClosestSmallerOrEqual(items, value, comparator) {
|
|
902
|
+
return items[findIndexOfClosestSmallerOrEqual(items, value, comparator)];
|
|
903
|
+
}
|
|
904
|
+
function findRange(items, startValue, endValue, comparator) {
|
|
905
|
+
const startIndex = findIndexOfClosestSmallerOrEqual(items, startValue, comparator);
|
|
906
|
+
const endIndex = findIndexOfClosestSmallerOrEqual(items, endValue, comparator, startIndex);
|
|
907
|
+
return items.slice(startIndex, endIndex + 1);
|
|
908
|
+
}
|
|
909
|
+
const recalcSystem = system(
|
|
910
|
+
() => {
|
|
911
|
+
const recalcInProgress = statefulStream(false);
|
|
912
|
+
return { recalcInProgress };
|
|
913
|
+
},
|
|
914
|
+
[],
|
|
915
|
+
{ singleton: true }
|
|
916
|
+
);
|
|
917
|
+
function rangeIncludes(refRange) {
|
|
918
|
+
const { size, startIndex, endIndex } = refRange;
|
|
919
|
+
return (range) => {
|
|
920
|
+
return range.start === startIndex && (range.end === endIndex || range.end === Infinity) && range.value === size;
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
function insertRanges(sizeTree, ranges) {
|
|
924
|
+
let syncStart = empty(sizeTree) ? 0 : Infinity;
|
|
925
|
+
for (const range of ranges) {
|
|
926
|
+
const { size, startIndex, endIndex } = range;
|
|
927
|
+
syncStart = Math.min(syncStart, startIndex);
|
|
928
|
+
if (empty(sizeTree)) {
|
|
929
|
+
sizeTree = insert(sizeTree, 0, size);
|
|
930
|
+
continue;
|
|
931
|
+
}
|
|
932
|
+
const overlappingRanges = rangesWithin(sizeTree, startIndex - 1, endIndex + 1);
|
|
933
|
+
if (overlappingRanges.some(rangeIncludes(range))) {
|
|
934
|
+
continue;
|
|
935
|
+
}
|
|
936
|
+
let firstPassDone = false;
|
|
937
|
+
let shouldInsert = false;
|
|
938
|
+
for (const { start: rangeStart, end: rangeEnd, value: rangeValue } of overlappingRanges) {
|
|
939
|
+
if (!firstPassDone) {
|
|
940
|
+
shouldInsert = rangeValue !== size;
|
|
941
|
+
firstPassDone = true;
|
|
942
|
+
} else {
|
|
943
|
+
if (endIndex >= rangeStart || size === rangeValue) {
|
|
944
|
+
sizeTree = remove(sizeTree, rangeStart);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
if (rangeEnd > endIndex && endIndex >= rangeStart) {
|
|
948
|
+
if (rangeValue !== size) {
|
|
949
|
+
sizeTree = insert(sizeTree, endIndex + 1, rangeValue);
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
if (shouldInsert) {
|
|
954
|
+
sizeTree = insert(sizeTree, startIndex, size);
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
return [sizeTree, syncStart];
|
|
958
|
+
}
|
|
959
|
+
function initialSizeState() {
|
|
960
|
+
return {
|
|
961
|
+
offsetTree: [],
|
|
962
|
+
sizeTree: newTree(),
|
|
963
|
+
groupOffsetTree: newTree(),
|
|
964
|
+
lastIndex: 0,
|
|
965
|
+
lastOffset: 0,
|
|
966
|
+
lastSize: 0,
|
|
967
|
+
groupIndices: []
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
function indexComparator({ index: itemIndex }, index) {
|
|
971
|
+
return index === itemIndex ? 0 : index < itemIndex ? -1 : 1;
|
|
972
|
+
}
|
|
973
|
+
function offsetComparator({ offset: itemOffset }, offset) {
|
|
974
|
+
return offset === itemOffset ? 0 : offset < itemOffset ? -1 : 1;
|
|
975
|
+
}
|
|
976
|
+
function offsetPointParser(point) {
|
|
977
|
+
return { index: point.index, value: point };
|
|
978
|
+
}
|
|
979
|
+
function rangesWithinOffsets(tree, startOffset, endOffset, minStartIndex = 0) {
|
|
980
|
+
if (minStartIndex > 0) {
|
|
981
|
+
startOffset = Math.max(startOffset, findClosestSmallerOrEqual(tree, minStartIndex, indexComparator).offset);
|
|
982
|
+
}
|
|
983
|
+
return arrayToRanges(findRange(tree, startOffset, endOffset, offsetComparator), offsetPointParser);
|
|
984
|
+
}
|
|
985
|
+
function createOffsetTree(prevOffsetTree, syncStart, sizeTree, gap) {
|
|
986
|
+
let offsetTree = prevOffsetTree;
|
|
987
|
+
let prevIndex = 0;
|
|
988
|
+
let prevSize = 0;
|
|
989
|
+
let prevOffset = 0;
|
|
990
|
+
let startIndex = 0;
|
|
991
|
+
if (syncStart !== 0) {
|
|
992
|
+
startIndex = findIndexOfClosestSmallerOrEqual(offsetTree, syncStart - 1, indexComparator);
|
|
993
|
+
const offsetInfo = offsetTree[startIndex];
|
|
994
|
+
prevOffset = offsetInfo.offset;
|
|
995
|
+
const kv = findMaxKeyValue(sizeTree, syncStart - 1);
|
|
996
|
+
prevIndex = kv[0];
|
|
997
|
+
prevSize = kv[1];
|
|
998
|
+
if (offsetTree.length && offsetTree[startIndex].size === findMaxKeyValue(sizeTree, syncStart)[1]) {
|
|
999
|
+
startIndex -= 1;
|
|
1000
|
+
}
|
|
1001
|
+
offsetTree = offsetTree.slice(0, startIndex + 1);
|
|
1002
|
+
} else {
|
|
1003
|
+
offsetTree = [];
|
|
1004
|
+
}
|
|
1005
|
+
for (const { start: startIndex2, value } of rangesWithin(sizeTree, syncStart, Infinity)) {
|
|
1006
|
+
const indexOffset = startIndex2 - prevIndex;
|
|
1007
|
+
const aOffset = indexOffset * prevSize + prevOffset + indexOffset * gap;
|
|
1008
|
+
offsetTree.push({
|
|
1009
|
+
offset: aOffset,
|
|
1010
|
+
size: value,
|
|
1011
|
+
index: startIndex2
|
|
1012
|
+
});
|
|
1013
|
+
prevIndex = startIndex2;
|
|
1014
|
+
prevOffset = aOffset;
|
|
1015
|
+
prevSize = value;
|
|
1016
|
+
}
|
|
1017
|
+
return {
|
|
1018
|
+
offsetTree,
|
|
1019
|
+
lastIndex: prevIndex,
|
|
1020
|
+
lastOffset: prevOffset,
|
|
1021
|
+
lastSize: prevSize
|
|
1022
|
+
};
|
|
1023
|
+
}
|
|
1024
|
+
function sizeStateReducer(state, [ranges, groupIndices, log, gap]) {
|
|
1025
|
+
if (ranges.length > 0) {
|
|
1026
|
+
log("received item sizes", ranges, LogLevel.DEBUG);
|
|
1027
|
+
}
|
|
1028
|
+
const sizeTree = state.sizeTree;
|
|
1029
|
+
let newSizeTree = sizeTree;
|
|
1030
|
+
let syncStart = 0;
|
|
1031
|
+
if (groupIndices.length > 0 && empty(sizeTree) && ranges.length === 2) {
|
|
1032
|
+
const groupSize = ranges[0].size;
|
|
1033
|
+
const itemSize = ranges[1].size;
|
|
1034
|
+
newSizeTree = groupIndices.reduce((tree, groupIndex) => {
|
|
1035
|
+
return insert(insert(tree, groupIndex, groupSize), groupIndex + 1, itemSize);
|
|
1036
|
+
}, newSizeTree);
|
|
1037
|
+
} else {
|
|
1038
|
+
[newSizeTree, syncStart] = insertRanges(newSizeTree, ranges);
|
|
1039
|
+
}
|
|
1040
|
+
if (newSizeTree === sizeTree) {
|
|
1041
|
+
return state;
|
|
1042
|
+
}
|
|
1043
|
+
const { offsetTree: newOffsetTree, lastIndex, lastSize, lastOffset } = createOffsetTree(state.offsetTree, syncStart, newSizeTree, gap);
|
|
1044
|
+
return {
|
|
1045
|
+
sizeTree: newSizeTree,
|
|
1046
|
+
offsetTree: newOffsetTree,
|
|
1047
|
+
lastIndex,
|
|
1048
|
+
lastOffset,
|
|
1049
|
+
lastSize,
|
|
1050
|
+
groupOffsetTree: groupIndices.reduce((tree, index) => {
|
|
1051
|
+
return insert(tree, index, offsetOf(index, newOffsetTree, gap));
|
|
1052
|
+
}, newTree()),
|
|
1053
|
+
groupIndices
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
function offsetOf(index, tree, gap) {
|
|
1057
|
+
if (tree.length === 0) {
|
|
1058
|
+
return 0;
|
|
1059
|
+
}
|
|
1060
|
+
const { offset, index: startIndex, size } = findClosestSmallerOrEqual(tree, index, indexComparator);
|
|
1061
|
+
const itemCount = index - startIndex;
|
|
1062
|
+
const top = size * itemCount + (itemCount - 1) * gap + offset;
|
|
1063
|
+
return top > 0 ? top + gap : top;
|
|
1064
|
+
}
|
|
1065
|
+
function isGroupLocation(location) {
|
|
1066
|
+
return typeof location.groupIndex !== "undefined";
|
|
1067
|
+
}
|
|
1068
|
+
function originalIndexFromLocation(location, sizes, lastIndex) {
|
|
1069
|
+
if (isGroupLocation(location)) {
|
|
1070
|
+
return sizes.groupIndices[location.groupIndex] + 1;
|
|
1071
|
+
} else {
|
|
1072
|
+
const numericIndex = location.index === "LAST" ? lastIndex : location.index;
|
|
1073
|
+
let result = originalIndexFromItemIndex(numericIndex, sizes);
|
|
1074
|
+
result = Math.max(0, result, Math.min(lastIndex, result));
|
|
1075
|
+
return result;
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
function originalIndexFromItemIndex(itemIndex, sizes) {
|
|
1079
|
+
if (!hasGroups(sizes)) {
|
|
1080
|
+
return itemIndex;
|
|
1081
|
+
}
|
|
1082
|
+
let groupOffset = 0;
|
|
1083
|
+
while (sizes.groupIndices[groupOffset] <= itemIndex + groupOffset) {
|
|
1084
|
+
groupOffset++;
|
|
1085
|
+
}
|
|
1086
|
+
return itemIndex + groupOffset;
|
|
1087
|
+
}
|
|
1088
|
+
function hasGroups(sizes) {
|
|
1089
|
+
return !empty(sizes.groupOffsetTree);
|
|
1090
|
+
}
|
|
1091
|
+
const SIZE_MAP = {
|
|
1092
|
+
offsetHeight: "height",
|
|
1093
|
+
offsetWidth: "width"
|
|
1094
|
+
};
|
|
1095
|
+
const sizeSystem = system(
|
|
1096
|
+
([{ log }, { recalcInProgress }]) => {
|
|
1097
|
+
const sizeRanges = stream();
|
|
1098
|
+
const totalCount = stream();
|
|
1099
|
+
const statefulTotalCount = statefulStreamFromEmitter(totalCount, 0);
|
|
1100
|
+
const unshiftWith = stream();
|
|
1101
|
+
const shiftWith = stream();
|
|
1102
|
+
const firstItemIndex = statefulStream(0);
|
|
1103
|
+
const groupIndices = statefulStream([]);
|
|
1104
|
+
const fixedItemSize = statefulStream(void 0);
|
|
1105
|
+
const defaultItemSize = statefulStream(void 0);
|
|
1106
|
+
const itemSize = statefulStream((el, field) => correctItemSize(el, SIZE_MAP[field]));
|
|
1107
|
+
const data = statefulStream(void 0);
|
|
1108
|
+
const gap = statefulStream(0);
|
|
1109
|
+
const initial = initialSizeState();
|
|
1110
|
+
const sizes = statefulStreamFromEmitter(
|
|
1111
|
+
pipe(sizeRanges, withLatestFrom(groupIndices, log, gap), scan(sizeStateReducer, initial), distinctUntilChanged()),
|
|
1112
|
+
initial
|
|
1113
|
+
);
|
|
1114
|
+
connect(
|
|
1115
|
+
pipe(
|
|
1116
|
+
groupIndices,
|
|
1117
|
+
filter((indexes) => indexes.length > 0),
|
|
1118
|
+
withLatestFrom(sizes, gap),
|
|
1119
|
+
map(([groupIndices2, sizes2, gap2]) => {
|
|
1120
|
+
const groupOffsetTree = groupIndices2.reduce((tree, index, idx) => {
|
|
1121
|
+
return insert(tree, index, offsetOf(index, sizes2.offsetTree, gap2) || idx);
|
|
1122
|
+
}, newTree());
|
|
1123
|
+
return {
|
|
1124
|
+
...sizes2,
|
|
1125
|
+
groupIndices: groupIndices2,
|
|
1126
|
+
groupOffsetTree
|
|
1127
|
+
};
|
|
1128
|
+
})
|
|
1129
|
+
),
|
|
1130
|
+
sizes
|
|
1131
|
+
);
|
|
1132
|
+
connect(
|
|
1133
|
+
pipe(
|
|
1134
|
+
totalCount,
|
|
1135
|
+
withLatestFrom(sizes),
|
|
1136
|
+
filter(([totalCount2, { lastIndex }]) => {
|
|
1137
|
+
return totalCount2 < lastIndex;
|
|
1138
|
+
}),
|
|
1139
|
+
map(([totalCount2, { lastIndex, lastSize }]) => {
|
|
1140
|
+
return [
|
|
1141
|
+
{
|
|
1142
|
+
startIndex: totalCount2,
|
|
1143
|
+
endIndex: lastIndex,
|
|
1144
|
+
size: lastSize
|
|
1145
|
+
}
|
|
1146
|
+
];
|
|
1147
|
+
})
|
|
1148
|
+
),
|
|
1149
|
+
sizeRanges
|
|
1150
|
+
);
|
|
1151
|
+
connect(fixedItemSize, defaultItemSize);
|
|
1152
|
+
const trackItemSizes = statefulStreamFromEmitter(
|
|
1153
|
+
pipe(
|
|
1154
|
+
fixedItemSize,
|
|
1155
|
+
map((size) => size === void 0)
|
|
1156
|
+
),
|
|
1157
|
+
true
|
|
1158
|
+
);
|
|
1159
|
+
connect(
|
|
1160
|
+
pipe(
|
|
1161
|
+
defaultItemSize,
|
|
1162
|
+
filter((value) => {
|
|
1163
|
+
return value !== void 0 && empty(getValue(sizes).sizeTree);
|
|
1164
|
+
}),
|
|
1165
|
+
map((size) => [{ startIndex: 0, endIndex: 0, size }])
|
|
1166
|
+
),
|
|
1167
|
+
sizeRanges
|
|
1168
|
+
);
|
|
1169
|
+
const listRefresh = streamFromEmitter(
|
|
1170
|
+
pipe(
|
|
1171
|
+
sizeRanges,
|
|
1172
|
+
withLatestFrom(sizes),
|
|
1173
|
+
scan(
|
|
1174
|
+
({ sizes: oldSizes }, [_, newSizes]) => {
|
|
1175
|
+
return {
|
|
1176
|
+
changed: newSizes !== oldSizes,
|
|
1177
|
+
sizes: newSizes
|
|
1178
|
+
};
|
|
1179
|
+
},
|
|
1180
|
+
{ changed: false, sizes: initial }
|
|
1181
|
+
),
|
|
1182
|
+
map((value) => value.changed)
|
|
1183
|
+
)
|
|
1184
|
+
);
|
|
1185
|
+
subscribe(
|
|
1186
|
+
pipe(
|
|
1187
|
+
firstItemIndex,
|
|
1188
|
+
scan(
|
|
1189
|
+
(prev, next) => {
|
|
1190
|
+
return { diff: prev.prev - next, prev: next };
|
|
1191
|
+
},
|
|
1192
|
+
{ diff: 0, prev: 0 }
|
|
1193
|
+
),
|
|
1194
|
+
map((val) => val.diff)
|
|
1195
|
+
),
|
|
1196
|
+
(offset) => {
|
|
1197
|
+
if (offset > 0) {
|
|
1198
|
+
publish(recalcInProgress, true);
|
|
1199
|
+
publish(unshiftWith, offset);
|
|
1200
|
+
} else if (offset < 0) {
|
|
1201
|
+
publish(shiftWith, offset);
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
);
|
|
1205
|
+
subscribe(pipe(firstItemIndex, withLatestFrom(log)), ([index, log2]) => {
|
|
1206
|
+
if (index < 0) {
|
|
1207
|
+
log2(
|
|
1208
|
+
"`firstItemIndex` prop should not be set to less than zero. If you don't know the total count, just use a very high value",
|
|
1209
|
+
{ firstItemIndex },
|
|
1210
|
+
LogLevel.ERROR
|
|
1211
|
+
);
|
|
1212
|
+
}
|
|
1213
|
+
});
|
|
1214
|
+
const beforeUnshiftWith = streamFromEmitter(unshiftWith);
|
|
1215
|
+
connect(
|
|
1216
|
+
pipe(
|
|
1217
|
+
unshiftWith,
|
|
1218
|
+
withLatestFrom(sizes),
|
|
1219
|
+
map(([unshiftWith2, sizes2]) => {
|
|
1220
|
+
if (sizes2.groupIndices.length > 0) {
|
|
1221
|
+
throw new Error("Virtuoso: prepending items does not work with groups");
|
|
1222
|
+
}
|
|
1223
|
+
return walk(sizes2.sizeTree).reduce(
|
|
1224
|
+
(acc, { k: index, v: size }) => {
|
|
1225
|
+
return {
|
|
1226
|
+
ranges: [...acc.ranges, { startIndex: acc.prevIndex, endIndex: index + unshiftWith2 - 1, size: acc.prevSize }],
|
|
1227
|
+
prevIndex: index + unshiftWith2,
|
|
1228
|
+
prevSize: size
|
|
1229
|
+
};
|
|
1230
|
+
},
|
|
1231
|
+
{
|
|
1232
|
+
ranges: [],
|
|
1233
|
+
prevIndex: 0,
|
|
1234
|
+
prevSize: sizes2.lastSize
|
|
1235
|
+
}
|
|
1236
|
+
).ranges;
|
|
1237
|
+
})
|
|
1238
|
+
),
|
|
1239
|
+
sizeRanges
|
|
1240
|
+
);
|
|
1241
|
+
const shiftWithOffset = streamFromEmitter(
|
|
1242
|
+
pipe(
|
|
1243
|
+
shiftWith,
|
|
1244
|
+
withLatestFrom(sizes, gap),
|
|
1245
|
+
map(([shiftWith2, { offsetTree }, gap2]) => {
|
|
1246
|
+
const newFirstItemIndex = -shiftWith2;
|
|
1247
|
+
return offsetOf(newFirstItemIndex, offsetTree, gap2);
|
|
1248
|
+
})
|
|
1249
|
+
)
|
|
1250
|
+
);
|
|
1251
|
+
connect(
|
|
1252
|
+
pipe(
|
|
1253
|
+
shiftWith,
|
|
1254
|
+
withLatestFrom(sizes, gap),
|
|
1255
|
+
map(([shiftWith2, sizes2, gap2]) => {
|
|
1256
|
+
if (sizes2.groupIndices.length > 0) {
|
|
1257
|
+
throw new Error("Virtuoso: shifting items does not work with groups");
|
|
1258
|
+
}
|
|
1259
|
+
const newSizeTree = walk(sizes2.sizeTree).reduce((acc, { k, v }) => {
|
|
1260
|
+
return insert(acc, Math.max(0, k + shiftWith2), v);
|
|
1261
|
+
}, newTree());
|
|
1262
|
+
return {
|
|
1263
|
+
...sizes2,
|
|
1264
|
+
sizeTree: newSizeTree,
|
|
1265
|
+
...createOffsetTree(sizes2.offsetTree, 0, newSizeTree, gap2)
|
|
1266
|
+
};
|
|
1267
|
+
})
|
|
1268
|
+
),
|
|
1269
|
+
sizes
|
|
1270
|
+
);
|
|
1271
|
+
return {
|
|
1272
|
+
data,
|
|
1273
|
+
totalCount,
|
|
1274
|
+
sizeRanges,
|
|
1275
|
+
groupIndices,
|
|
1276
|
+
defaultItemSize,
|
|
1277
|
+
fixedItemSize,
|
|
1278
|
+
unshiftWith,
|
|
1279
|
+
shiftWith,
|
|
1280
|
+
shiftWithOffset,
|
|
1281
|
+
beforeUnshiftWith,
|
|
1282
|
+
firstItemIndex,
|
|
1283
|
+
gap,
|
|
1284
|
+
sizes,
|
|
1285
|
+
listRefresh,
|
|
1286
|
+
statefulTotalCount,
|
|
1287
|
+
trackItemSizes,
|
|
1288
|
+
itemSize
|
|
1289
|
+
};
|
|
1290
|
+
},
|
|
1291
|
+
tup(loggerSystem, recalcSystem),
|
|
1292
|
+
{ singleton: true }
|
|
1293
|
+
);
|
|
1294
|
+
const SUPPORTS_SCROLL_TO_OPTIONS = typeof document !== "undefined" && "scrollBehavior" in document.documentElement.style;
|
|
1295
|
+
function normalizeIndexLocation(location) {
|
|
1296
|
+
const result = typeof location === "number" ? { index: location } : location;
|
|
1297
|
+
if (!result.align) {
|
|
1298
|
+
result.align = "start";
|
|
1299
|
+
}
|
|
1300
|
+
if (!result.behavior || !SUPPORTS_SCROLL_TO_OPTIONS) {
|
|
1301
|
+
result.behavior = "auto";
|
|
1302
|
+
}
|
|
1303
|
+
if (!result.offset) {
|
|
1304
|
+
result.offset = 0;
|
|
1305
|
+
}
|
|
1306
|
+
return result;
|
|
1307
|
+
}
|
|
1308
|
+
const scrollToIndexSystem = system(
|
|
1309
|
+
([
|
|
1310
|
+
{ sizes, totalCount, listRefresh, gap },
|
|
1311
|
+
{
|
|
1312
|
+
scrollingInProgress,
|
|
1313
|
+
viewportHeight,
|
|
1314
|
+
scrollTo,
|
|
1315
|
+
smoothScrollTargetReached,
|
|
1316
|
+
headerHeight,
|
|
1317
|
+
footerHeight,
|
|
1318
|
+
fixedHeaderHeight,
|
|
1319
|
+
fixedFooterHeight
|
|
1320
|
+
},
|
|
1321
|
+
{ log }
|
|
1322
|
+
]) => {
|
|
1323
|
+
const scrollToIndex = stream();
|
|
1324
|
+
const topListHeight = statefulStream(0);
|
|
1325
|
+
let unsubscribeNextListRefresh = null;
|
|
1326
|
+
let cleartTimeoutRef = null;
|
|
1327
|
+
let unsubscribeListRefresh = null;
|
|
1328
|
+
function cleanup() {
|
|
1329
|
+
if (unsubscribeNextListRefresh) {
|
|
1330
|
+
unsubscribeNextListRefresh();
|
|
1331
|
+
unsubscribeNextListRefresh = null;
|
|
1332
|
+
}
|
|
1333
|
+
if (unsubscribeListRefresh) {
|
|
1334
|
+
unsubscribeListRefresh();
|
|
1335
|
+
unsubscribeListRefresh = null;
|
|
1336
|
+
}
|
|
1337
|
+
if (cleartTimeoutRef) {
|
|
1338
|
+
clearTimeout(cleartTimeoutRef);
|
|
1339
|
+
cleartTimeoutRef = null;
|
|
1340
|
+
}
|
|
1341
|
+
publish(scrollingInProgress, false);
|
|
1342
|
+
}
|
|
1343
|
+
connect(
|
|
1344
|
+
pipe(
|
|
1345
|
+
scrollToIndex,
|
|
1346
|
+
withLatestFrom(sizes, viewportHeight, totalCount, topListHeight, headerHeight, footerHeight, log),
|
|
1347
|
+
withLatestFrom(gap, fixedHeaderHeight, fixedFooterHeight),
|
|
1348
|
+
map(
|
|
1349
|
+
([
|
|
1350
|
+
[location, sizes2, viewportHeight2, totalCount2, topListHeight2, headerHeight2, footerHeight2, log2],
|
|
1351
|
+
gap2,
|
|
1352
|
+
fixedHeaderHeight2,
|
|
1353
|
+
fixedFooterHeight2
|
|
1354
|
+
]) => {
|
|
1355
|
+
const normalLocation = normalizeIndexLocation(location);
|
|
1356
|
+
const { align, behavior, offset } = normalLocation;
|
|
1357
|
+
const lastIndex = totalCount2 - 1;
|
|
1358
|
+
const index = originalIndexFromLocation(normalLocation, sizes2, lastIndex);
|
|
1359
|
+
let top = offsetOf(index, sizes2.offsetTree, gap2) + headerHeight2;
|
|
1360
|
+
if (align === "end") {
|
|
1361
|
+
top += fixedHeaderHeight2 + findMaxKeyValue(sizes2.sizeTree, index)[1] - viewportHeight2 + fixedFooterHeight2;
|
|
1362
|
+
if (index === lastIndex) {
|
|
1363
|
+
top += footerHeight2;
|
|
1364
|
+
}
|
|
1365
|
+
} else if (align === "center") {
|
|
1366
|
+
top += (fixedHeaderHeight2 + findMaxKeyValue(sizes2.sizeTree, index)[1] - viewportHeight2 + fixedFooterHeight2) / 2;
|
|
1367
|
+
} else {
|
|
1368
|
+
top -= topListHeight2;
|
|
1369
|
+
}
|
|
1370
|
+
if (offset) {
|
|
1371
|
+
top += offset;
|
|
1372
|
+
}
|
|
1373
|
+
const retry = (listChanged) => {
|
|
1374
|
+
cleanup();
|
|
1375
|
+
if (listChanged) {
|
|
1376
|
+
log2("retrying to scroll to", { location }, LogLevel.DEBUG);
|
|
1377
|
+
publish(scrollToIndex, location);
|
|
1378
|
+
} else {
|
|
1379
|
+
log2("list did not change, scroll successful", {}, LogLevel.DEBUG);
|
|
1380
|
+
}
|
|
1381
|
+
};
|
|
1382
|
+
cleanup();
|
|
1383
|
+
if (behavior === "smooth") {
|
|
1384
|
+
let listChanged = false;
|
|
1385
|
+
unsubscribeListRefresh = subscribe(listRefresh, (changed) => {
|
|
1386
|
+
listChanged = listChanged || changed;
|
|
1387
|
+
});
|
|
1388
|
+
unsubscribeNextListRefresh = handleNext(smoothScrollTargetReached, () => {
|
|
1389
|
+
retry(listChanged);
|
|
1390
|
+
});
|
|
1391
|
+
} else {
|
|
1392
|
+
unsubscribeNextListRefresh = handleNext(pipe(listRefresh, watchChangesFor(150)), retry);
|
|
1393
|
+
}
|
|
1394
|
+
cleartTimeoutRef = setTimeout(() => {
|
|
1395
|
+
cleanup();
|
|
1396
|
+
}, 1200);
|
|
1397
|
+
publish(scrollingInProgress, true);
|
|
1398
|
+
log2("scrolling from index to", { index, top, behavior }, LogLevel.DEBUG);
|
|
1399
|
+
return { top, behavior };
|
|
1400
|
+
}
|
|
1401
|
+
)
|
|
1402
|
+
),
|
|
1403
|
+
scrollTo
|
|
1404
|
+
);
|
|
1405
|
+
return {
|
|
1406
|
+
scrollToIndex,
|
|
1407
|
+
topListHeight
|
|
1408
|
+
};
|
|
1409
|
+
},
|
|
1410
|
+
tup(sizeSystem, domIOSystem, loggerSystem),
|
|
1411
|
+
{ singleton: true }
|
|
1412
|
+
);
|
|
1413
|
+
function watchChangesFor(limit) {
|
|
1414
|
+
return (done) => {
|
|
1415
|
+
const timeoutRef = setTimeout(() => {
|
|
1416
|
+
done(false);
|
|
1417
|
+
}, limit);
|
|
1418
|
+
return (value) => {
|
|
1419
|
+
if (value) {
|
|
1420
|
+
done(true);
|
|
1421
|
+
clearTimeout(timeoutRef);
|
|
1422
|
+
}
|
|
1423
|
+
};
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
const UP = "up";
|
|
1427
|
+
const DOWN = "down";
|
|
1428
|
+
const NONE$1 = "none";
|
|
1429
|
+
const INITIAL_BOTTOM_STATE = {
|
|
1430
|
+
atBottom: false,
|
|
1431
|
+
notAtBottomBecause: "NOT_SHOWING_LAST_ITEM",
|
|
1432
|
+
state: {
|
|
1433
|
+
offsetBottom: 0,
|
|
1434
|
+
scrollTop: 0,
|
|
1435
|
+
viewportHeight: 0,
|
|
1436
|
+
scrollHeight: 0
|
|
1437
|
+
}
|
|
1438
|
+
};
|
|
1439
|
+
const DEFAULT_AT_TOP_THRESHOLD = 0;
|
|
1440
|
+
const stateFlagsSystem = system(([{ scrollContainerState, scrollTop, viewportHeight, headerHeight, footerHeight, scrollBy }]) => {
|
|
1441
|
+
const isAtBottom = statefulStream(false);
|
|
1442
|
+
const isAtTop = statefulStream(true);
|
|
1443
|
+
const atBottomStateChange = stream();
|
|
1444
|
+
const atTopStateChange = stream();
|
|
1445
|
+
const atBottomThreshold = statefulStream(4);
|
|
1446
|
+
const atTopThreshold = statefulStream(DEFAULT_AT_TOP_THRESHOLD);
|
|
1447
|
+
const isScrolling = statefulStreamFromEmitter(
|
|
1448
|
+
pipe(
|
|
1449
|
+
merge(pipe(duc(scrollTop), skip(1), mapTo(true)), pipe(duc(scrollTop), skip(1), mapTo(false), debounceTime(100))),
|
|
1450
|
+
distinctUntilChanged()
|
|
1451
|
+
),
|
|
1452
|
+
false
|
|
1453
|
+
);
|
|
1454
|
+
const isScrollingBy = statefulStreamFromEmitter(
|
|
1455
|
+
pipe(merge(pipe(scrollBy, mapTo(true)), pipe(scrollBy, mapTo(false), debounceTime(200))), distinctUntilChanged()),
|
|
1456
|
+
false
|
|
1457
|
+
);
|
|
1458
|
+
connect(
|
|
1459
|
+
pipe(
|
|
1460
|
+
combineLatest(duc(scrollTop), duc(atTopThreshold)),
|
|
1461
|
+
map(([top, atTopThreshold2]) => top <= atTopThreshold2),
|
|
1462
|
+
distinctUntilChanged()
|
|
1463
|
+
),
|
|
1464
|
+
isAtTop
|
|
1465
|
+
);
|
|
1466
|
+
connect(pipe(isAtTop, throttleTime(50)), atTopStateChange);
|
|
1467
|
+
const atBottomState = streamFromEmitter(
|
|
1468
|
+
pipe(
|
|
1469
|
+
combineLatest(scrollContainerState, duc(viewportHeight), duc(headerHeight), duc(footerHeight), duc(atBottomThreshold)),
|
|
1470
|
+
scan((current, [{ scrollTop: scrollTop2, scrollHeight }, viewportHeight2, _headerHeight, _footerHeight, atBottomThreshold2]) => {
|
|
1471
|
+
const isAtBottom2 = scrollTop2 + viewportHeight2 - scrollHeight > -atBottomThreshold2;
|
|
1472
|
+
const state = {
|
|
1473
|
+
viewportHeight: viewportHeight2,
|
|
1474
|
+
scrollTop: scrollTop2,
|
|
1475
|
+
scrollHeight
|
|
1476
|
+
};
|
|
1477
|
+
if (isAtBottom2) {
|
|
1478
|
+
let atBottomBecause;
|
|
1479
|
+
let scrollTopDelta;
|
|
1480
|
+
if (scrollTop2 > current.state.scrollTop) {
|
|
1481
|
+
atBottomBecause = "SCROLLED_DOWN";
|
|
1482
|
+
scrollTopDelta = current.state.scrollTop - scrollTop2;
|
|
1483
|
+
} else {
|
|
1484
|
+
atBottomBecause = "SIZE_DECREASED";
|
|
1485
|
+
scrollTopDelta = current.state.scrollTop - scrollTop2 || current.scrollTopDelta;
|
|
1486
|
+
}
|
|
1487
|
+
return {
|
|
1488
|
+
atBottom: true,
|
|
1489
|
+
state,
|
|
1490
|
+
atBottomBecause,
|
|
1491
|
+
scrollTopDelta
|
|
1492
|
+
};
|
|
1493
|
+
}
|
|
1494
|
+
let notAtBottomBecause;
|
|
1495
|
+
if (state.scrollHeight > current.state.scrollHeight) {
|
|
1496
|
+
notAtBottomBecause = "SIZE_INCREASED";
|
|
1497
|
+
} else if (viewportHeight2 < current.state.viewportHeight) {
|
|
1498
|
+
notAtBottomBecause = "VIEWPORT_HEIGHT_DECREASING";
|
|
1499
|
+
} else if (scrollTop2 < current.state.scrollTop) {
|
|
1500
|
+
notAtBottomBecause = "SCROLLING_UPWARDS";
|
|
1501
|
+
} else {
|
|
1502
|
+
notAtBottomBecause = "NOT_FULLY_SCROLLED_TO_LAST_ITEM_BOTTOM";
|
|
1503
|
+
}
|
|
1504
|
+
return {
|
|
1505
|
+
atBottom: false,
|
|
1506
|
+
notAtBottomBecause,
|
|
1507
|
+
state
|
|
1508
|
+
};
|
|
1509
|
+
}, INITIAL_BOTTOM_STATE),
|
|
1510
|
+
distinctUntilChanged((prev, next) => {
|
|
1511
|
+
return prev && prev.atBottom === next.atBottom;
|
|
1512
|
+
})
|
|
1513
|
+
)
|
|
1514
|
+
);
|
|
1515
|
+
const lastJumpDueToItemResize = statefulStreamFromEmitter(
|
|
1516
|
+
pipe(
|
|
1517
|
+
scrollContainerState,
|
|
1518
|
+
scan(
|
|
1519
|
+
(current, { scrollTop: scrollTop2, scrollHeight, viewportHeight: viewportHeight2 }) => {
|
|
1520
|
+
if (!approximatelyEqual(current.scrollHeight, scrollHeight)) {
|
|
1521
|
+
const atBottom = scrollHeight - (scrollTop2 + viewportHeight2) < 1;
|
|
1522
|
+
if (current.scrollTop !== scrollTop2 && atBottom) {
|
|
1523
|
+
return {
|
|
1524
|
+
scrollHeight,
|
|
1525
|
+
scrollTop: scrollTop2,
|
|
1526
|
+
jump: current.scrollTop - scrollTop2,
|
|
1527
|
+
changed: true
|
|
1528
|
+
};
|
|
1529
|
+
} else {
|
|
1530
|
+
return {
|
|
1531
|
+
scrollHeight,
|
|
1532
|
+
scrollTop: scrollTop2,
|
|
1533
|
+
jump: 0,
|
|
1534
|
+
changed: true
|
|
1535
|
+
};
|
|
1536
|
+
}
|
|
1537
|
+
} else {
|
|
1538
|
+
return {
|
|
1539
|
+
scrollTop: scrollTop2,
|
|
1540
|
+
scrollHeight,
|
|
1541
|
+
jump: 0,
|
|
1542
|
+
changed: false
|
|
1543
|
+
};
|
|
1544
|
+
}
|
|
1545
|
+
},
|
|
1546
|
+
{ scrollHeight: 0, jump: 0, scrollTop: 0, changed: false }
|
|
1547
|
+
),
|
|
1548
|
+
filter((value) => value.changed),
|
|
1549
|
+
map((value) => value.jump)
|
|
1550
|
+
),
|
|
1551
|
+
0
|
|
1552
|
+
);
|
|
1553
|
+
connect(
|
|
1554
|
+
pipe(
|
|
1555
|
+
atBottomState,
|
|
1556
|
+
map((state) => state.atBottom)
|
|
1557
|
+
),
|
|
1558
|
+
isAtBottom
|
|
1559
|
+
);
|
|
1560
|
+
connect(pipe(isAtBottom, throttleTime(50)), atBottomStateChange);
|
|
1561
|
+
const scrollDirection = statefulStream(DOWN);
|
|
1562
|
+
connect(
|
|
1563
|
+
pipe(
|
|
1564
|
+
scrollContainerState,
|
|
1565
|
+
map(({ scrollTop: scrollTop2 }) => scrollTop2),
|
|
1566
|
+
distinctUntilChanged(),
|
|
1567
|
+
scan(
|
|
1568
|
+
(acc, scrollTop2) => {
|
|
1569
|
+
if (getValue(isScrollingBy)) {
|
|
1570
|
+
return { direction: acc.direction, prevScrollTop: scrollTop2 };
|
|
1571
|
+
}
|
|
1572
|
+
return { direction: scrollTop2 < acc.prevScrollTop ? UP : DOWN, prevScrollTop: scrollTop2 };
|
|
1573
|
+
},
|
|
1574
|
+
{ direction: DOWN, prevScrollTop: 0 }
|
|
1575
|
+
),
|
|
1576
|
+
map((value) => value.direction)
|
|
1577
|
+
),
|
|
1578
|
+
scrollDirection
|
|
1579
|
+
);
|
|
1580
|
+
connect(pipe(scrollContainerState, throttleTime(50), mapTo(NONE$1)), scrollDirection);
|
|
1581
|
+
const scrollVelocity = statefulStream(0);
|
|
1582
|
+
connect(
|
|
1583
|
+
pipe(
|
|
1584
|
+
isScrolling,
|
|
1585
|
+
filter((value) => !value),
|
|
1586
|
+
mapTo(0)
|
|
1587
|
+
),
|
|
1588
|
+
scrollVelocity
|
|
1589
|
+
);
|
|
1590
|
+
connect(
|
|
1591
|
+
pipe(
|
|
1592
|
+
scrollTop,
|
|
1593
|
+
throttleTime(100),
|
|
1594
|
+
withLatestFrom(isScrolling),
|
|
1595
|
+
filter(([_, isScrolling2]) => !!isScrolling2),
|
|
1596
|
+
scan(([_, prev], [next]) => [prev, next], [0, 0]),
|
|
1597
|
+
map(([prev, next]) => next - prev)
|
|
1598
|
+
),
|
|
1599
|
+
scrollVelocity
|
|
1600
|
+
);
|
|
1601
|
+
return {
|
|
1602
|
+
isScrolling,
|
|
1603
|
+
isAtTop,
|
|
1604
|
+
isAtBottom,
|
|
1605
|
+
atBottomState,
|
|
1606
|
+
atTopStateChange,
|
|
1607
|
+
atBottomStateChange,
|
|
1608
|
+
scrollDirection,
|
|
1609
|
+
atBottomThreshold,
|
|
1610
|
+
atTopThreshold,
|
|
1611
|
+
scrollVelocity,
|
|
1612
|
+
lastJumpDueToItemResize
|
|
1613
|
+
};
|
|
1614
|
+
}, tup(domIOSystem));
|
|
1615
|
+
const propsReadySystem = system(
|
|
1616
|
+
([{ log }]) => {
|
|
1617
|
+
const propsReady = statefulStream(false);
|
|
1618
|
+
const didMount = streamFromEmitter(
|
|
1619
|
+
pipe(
|
|
1620
|
+
propsReady,
|
|
1621
|
+
filter((ready) => ready),
|
|
1622
|
+
distinctUntilChanged()
|
|
1623
|
+
)
|
|
1624
|
+
);
|
|
1625
|
+
subscribe(propsReady, (value) => {
|
|
1626
|
+
value && getValue(log)("props updated", {}, LogLevel.DEBUG);
|
|
1627
|
+
});
|
|
1628
|
+
return { propsReady, didMount };
|
|
1629
|
+
},
|
|
1630
|
+
tup(loggerSystem),
|
|
1631
|
+
{ singleton: true }
|
|
1632
|
+
);
|
|
1633
|
+
function getInitialTopMostItemIndexNumber(location, totalCount) {
|
|
1634
|
+
const lastIndex = totalCount - 1;
|
|
1635
|
+
const index = typeof location === "number" ? location : location.index === "LAST" ? lastIndex : location.index;
|
|
1636
|
+
return index;
|
|
1637
|
+
}
|
|
1638
|
+
const initialTopMostItemIndexSystem = system(
|
|
1639
|
+
([{ sizes, listRefresh, defaultItemSize }, { scrollTop }, { scrollToIndex }, { didMount }]) => {
|
|
1640
|
+
const scrolledToInitialItem = statefulStream(true);
|
|
1641
|
+
const initialTopMostItemIndex = statefulStream(0);
|
|
1642
|
+
connect(
|
|
1643
|
+
pipe(
|
|
1644
|
+
didMount,
|
|
1645
|
+
withLatestFrom(initialTopMostItemIndex),
|
|
1646
|
+
filter(([_, location]) => !!location),
|
|
1647
|
+
mapTo(false)
|
|
1648
|
+
),
|
|
1649
|
+
scrolledToInitialItem
|
|
1650
|
+
);
|
|
1651
|
+
subscribe(
|
|
1652
|
+
pipe(
|
|
1653
|
+
combineLatest(listRefresh, didMount),
|
|
1654
|
+
withLatestFrom(scrolledToInitialItem, sizes, defaultItemSize),
|
|
1655
|
+
filter(([[, didMount2], scrolledToInitialItem2, { sizeTree }, defaultItemSize2]) => {
|
|
1656
|
+
return didMount2 && (!empty(sizeTree) || defaultItemSize2 !== void 0) && !scrolledToInitialItem2;
|
|
1657
|
+
}),
|
|
1658
|
+
withLatestFrom(initialTopMostItemIndex)
|
|
1659
|
+
),
|
|
1660
|
+
([, initialTopMostItemIndex2]) => {
|
|
1661
|
+
setTimeout(() => {
|
|
1662
|
+
handleNext(scrollTop, () => {
|
|
1663
|
+
publish(scrolledToInitialItem, true);
|
|
1664
|
+
});
|
|
1665
|
+
publish(scrollToIndex, initialTopMostItemIndex2);
|
|
1666
|
+
});
|
|
1667
|
+
}
|
|
1668
|
+
);
|
|
1669
|
+
return {
|
|
1670
|
+
scrolledToInitialItem,
|
|
1671
|
+
initialTopMostItemIndex
|
|
1672
|
+
};
|
|
1673
|
+
},
|
|
1674
|
+
tup(sizeSystem, domIOSystem, scrollToIndexSystem, propsReadySystem),
|
|
1675
|
+
{ singleton: true }
|
|
1676
|
+
);
|
|
1677
|
+
function normalizeFollowOutput(follow) {
|
|
1678
|
+
if (!follow) {
|
|
1679
|
+
return false;
|
|
1680
|
+
}
|
|
1681
|
+
return follow === "smooth" ? "smooth" : "auto";
|
|
1682
|
+
}
|
|
1683
|
+
const behaviorFromFollowOutput = (follow, isAtBottom) => {
|
|
1684
|
+
if (typeof follow === "function") {
|
|
1685
|
+
return normalizeFollowOutput(follow(isAtBottom));
|
|
1686
|
+
}
|
|
1687
|
+
return isAtBottom && normalizeFollowOutput(follow);
|
|
1688
|
+
};
|
|
1689
|
+
const followOutputSystem = system(
|
|
1690
|
+
([
|
|
1691
|
+
{ totalCount, listRefresh },
|
|
1692
|
+
{ isAtBottom, atBottomState },
|
|
1693
|
+
{ scrollToIndex },
|
|
1694
|
+
{ scrolledToInitialItem },
|
|
1695
|
+
{ propsReady, didMount },
|
|
1696
|
+
{ log },
|
|
1697
|
+
{ scrollingInProgress }
|
|
1698
|
+
]) => {
|
|
1699
|
+
const followOutput = statefulStream(false);
|
|
1700
|
+
const autoscrollToBottom = stream();
|
|
1701
|
+
let pendingScrollHandle = null;
|
|
1702
|
+
function scrollToBottom(followOutputBehavior) {
|
|
1703
|
+
publish(scrollToIndex, {
|
|
1704
|
+
index: "LAST",
|
|
1705
|
+
align: "end",
|
|
1706
|
+
behavior: followOutputBehavior
|
|
1707
|
+
});
|
|
1708
|
+
}
|
|
1709
|
+
subscribe(
|
|
1710
|
+
pipe(
|
|
1711
|
+
combineLatest(pipe(duc(totalCount), skip(1)), didMount),
|
|
1712
|
+
withLatestFrom(duc(followOutput), isAtBottom, scrolledToInitialItem, scrollingInProgress),
|
|
1713
|
+
map(([[totalCount2, didMount2], followOutput2, isAtBottom2, scrolledToInitialItem2, scrollingInProgress2]) => {
|
|
1714
|
+
let shouldFollow = didMount2 && scrolledToInitialItem2;
|
|
1715
|
+
let followOutputBehavior = "auto";
|
|
1716
|
+
if (shouldFollow) {
|
|
1717
|
+
followOutputBehavior = behaviorFromFollowOutput(followOutput2, isAtBottom2 || scrollingInProgress2);
|
|
1718
|
+
shouldFollow = shouldFollow && !!followOutputBehavior;
|
|
1719
|
+
}
|
|
1720
|
+
return { totalCount: totalCount2, shouldFollow, followOutputBehavior };
|
|
1721
|
+
}),
|
|
1722
|
+
filter(({ shouldFollow }) => shouldFollow)
|
|
1723
|
+
),
|
|
1724
|
+
({ totalCount: totalCount2, followOutputBehavior }) => {
|
|
1725
|
+
if (pendingScrollHandle) {
|
|
1726
|
+
pendingScrollHandle();
|
|
1727
|
+
pendingScrollHandle = null;
|
|
1728
|
+
}
|
|
1729
|
+
pendingScrollHandle = handleNext(listRefresh, () => {
|
|
1730
|
+
getValue(log)("following output to ", { totalCount: totalCount2 }, LogLevel.DEBUG);
|
|
1731
|
+
scrollToBottom(followOutputBehavior);
|
|
1732
|
+
pendingScrollHandle = null;
|
|
1733
|
+
});
|
|
1734
|
+
}
|
|
1735
|
+
);
|
|
1736
|
+
function trapNextSizeIncrease(followOutput2) {
|
|
1737
|
+
const cancel = handleNext(atBottomState, (state) => {
|
|
1738
|
+
if (followOutput2 && !state.atBottom && state.notAtBottomBecause === "SIZE_INCREASED" && !pendingScrollHandle) {
|
|
1739
|
+
getValue(log)("scrolling to bottom due to increased size", {}, LogLevel.DEBUG);
|
|
1740
|
+
scrollToBottom("auto");
|
|
1741
|
+
}
|
|
1742
|
+
});
|
|
1743
|
+
setTimeout(cancel, 100);
|
|
1744
|
+
}
|
|
1745
|
+
subscribe(
|
|
1746
|
+
pipe(
|
|
1747
|
+
combineLatest(duc(followOutput), totalCount, propsReady),
|
|
1748
|
+
filter(([follow, , ready]) => follow && ready),
|
|
1749
|
+
scan(
|
|
1750
|
+
({ value }, [, next]) => {
|
|
1751
|
+
return { refreshed: value === next, value: next };
|
|
1752
|
+
},
|
|
1753
|
+
{ refreshed: false, value: 0 }
|
|
1754
|
+
),
|
|
1755
|
+
filter(({ refreshed }) => refreshed),
|
|
1756
|
+
withLatestFrom(followOutput, totalCount)
|
|
1757
|
+
),
|
|
1758
|
+
([, followOutput2]) => {
|
|
1759
|
+
trapNextSizeIncrease(followOutput2 !== false);
|
|
1760
|
+
}
|
|
1761
|
+
);
|
|
1762
|
+
subscribe(autoscrollToBottom, () => {
|
|
1763
|
+
trapNextSizeIncrease(getValue(followOutput) !== false);
|
|
1764
|
+
});
|
|
1765
|
+
subscribe(combineLatest(duc(followOutput), atBottomState), ([followOutput2, state]) => {
|
|
1766
|
+
if (followOutput2 && !state.atBottom && state.notAtBottomBecause === "VIEWPORT_HEIGHT_DECREASING") {
|
|
1767
|
+
scrollToBottom("auto");
|
|
1768
|
+
}
|
|
1769
|
+
});
|
|
1770
|
+
return { followOutput, autoscrollToBottom };
|
|
1771
|
+
},
|
|
1772
|
+
tup(sizeSystem, stateFlagsSystem, scrollToIndexSystem, initialTopMostItemIndexSystem, propsReadySystem, loggerSystem, domIOSystem)
|
|
1773
|
+
);
|
|
1774
|
+
function groupCountsToIndicesAndCount(counts) {
|
|
1775
|
+
return counts.reduce(
|
|
1776
|
+
(acc, groupCount) => {
|
|
1777
|
+
acc.groupIndices.push(acc.totalCount);
|
|
1778
|
+
acc.totalCount += groupCount + 1;
|
|
1779
|
+
return acc;
|
|
1780
|
+
},
|
|
1781
|
+
{
|
|
1782
|
+
totalCount: 0,
|
|
1783
|
+
groupIndices: []
|
|
1784
|
+
}
|
|
1785
|
+
);
|
|
1786
|
+
}
|
|
1787
|
+
const groupedListSystem = system(([{ totalCount, groupIndices, sizes }, { scrollTop, headerHeight }]) => {
|
|
1788
|
+
const groupCounts = stream();
|
|
1789
|
+
const topItemsIndexes = stream();
|
|
1790
|
+
const groupIndicesAndCount = streamFromEmitter(pipe(groupCounts, map(groupCountsToIndicesAndCount)));
|
|
1791
|
+
connect(
|
|
1792
|
+
pipe(
|
|
1793
|
+
groupIndicesAndCount,
|
|
1794
|
+
map((value) => value.totalCount)
|
|
1795
|
+
),
|
|
1796
|
+
totalCount
|
|
1797
|
+
);
|
|
1798
|
+
connect(
|
|
1799
|
+
pipe(
|
|
1800
|
+
groupIndicesAndCount,
|
|
1801
|
+
map((value) => value.groupIndices)
|
|
1802
|
+
),
|
|
1803
|
+
groupIndices
|
|
1804
|
+
);
|
|
1805
|
+
connect(
|
|
1806
|
+
pipe(
|
|
1807
|
+
combineLatest(scrollTop, sizes, headerHeight),
|
|
1808
|
+
filter(([_, sizes2]) => hasGroups(sizes2)),
|
|
1809
|
+
map(([scrollTop2, state, headerHeight2]) => findMaxKeyValue(state.groupOffsetTree, Math.max(scrollTop2 - headerHeight2, 0), "v")[0]),
|
|
1810
|
+
distinctUntilChanged(),
|
|
1811
|
+
map((index) => [index])
|
|
1812
|
+
),
|
|
1813
|
+
topItemsIndexes
|
|
1814
|
+
);
|
|
1815
|
+
return { groupCounts, topItemsIndexes };
|
|
1816
|
+
}, tup(sizeSystem, domIOSystem));
|
|
1817
|
+
function tupleComparator(prev, current) {
|
|
1818
|
+
return !!(prev && prev[0] === current[0] && prev[1] === current[1]);
|
|
1819
|
+
}
|
|
1820
|
+
function rangeComparator(prev, next) {
|
|
1821
|
+
return !!(prev && prev.startIndex === next.startIndex && prev.endIndex === next.endIndex);
|
|
1822
|
+
}
|
|
1823
|
+
const TOP = "top";
|
|
1824
|
+
const BOTTOM = "bottom";
|
|
1825
|
+
const NONE = "none";
|
|
1826
|
+
function getOverscan(overscan, end, direction) {
|
|
1827
|
+
if (typeof overscan === "number") {
|
|
1828
|
+
return direction === UP && end === TOP || direction === DOWN && end === BOTTOM ? overscan : 0;
|
|
1829
|
+
} else {
|
|
1830
|
+
if (direction === UP) {
|
|
1831
|
+
return end === TOP ? overscan.main : overscan.reverse;
|
|
1832
|
+
} else {
|
|
1833
|
+
return end === BOTTOM ? overscan.main : overscan.reverse;
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
function getViewportIncrease(value, end) {
|
|
1838
|
+
return typeof value === "number" ? value : value[end] || 0;
|
|
1839
|
+
}
|
|
1840
|
+
const sizeRangeSystem = system(
|
|
1841
|
+
([{ scrollTop, viewportHeight, deviation, headerHeight, fixedHeaderHeight }]) => {
|
|
1842
|
+
const listBoundary = stream();
|
|
1843
|
+
const topListHeight = statefulStream(0);
|
|
1844
|
+
const increaseViewportBy = statefulStream(0);
|
|
1845
|
+
const overscan = statefulStream(0);
|
|
1846
|
+
const visibleRange = statefulStreamFromEmitter(
|
|
1847
|
+
pipe(
|
|
1848
|
+
combineLatest(
|
|
1849
|
+
duc(scrollTop),
|
|
1850
|
+
duc(viewportHeight),
|
|
1851
|
+
duc(headerHeight),
|
|
1852
|
+
duc(listBoundary, tupleComparator),
|
|
1853
|
+
duc(overscan),
|
|
1854
|
+
duc(topListHeight),
|
|
1855
|
+
duc(fixedHeaderHeight),
|
|
1856
|
+
duc(deviation),
|
|
1857
|
+
duc(increaseViewportBy)
|
|
1858
|
+
),
|
|
1859
|
+
map(
|
|
1860
|
+
([
|
|
1861
|
+
scrollTop2,
|
|
1862
|
+
viewportHeight2,
|
|
1863
|
+
headerHeight2,
|
|
1864
|
+
[listTop, listBottom],
|
|
1865
|
+
overscan2,
|
|
1866
|
+
topListHeight2,
|
|
1867
|
+
fixedHeaderHeight2,
|
|
1868
|
+
deviation2,
|
|
1869
|
+
increaseViewportBy2
|
|
1870
|
+
]) => {
|
|
1871
|
+
const top = scrollTop2 - deviation2;
|
|
1872
|
+
const stickyHeaderHeight = topListHeight2 + fixedHeaderHeight2;
|
|
1873
|
+
const headerVisible = Math.max(headerHeight2 - top, 0);
|
|
1874
|
+
let direction = NONE;
|
|
1875
|
+
const topViewportAddition = getViewportIncrease(increaseViewportBy2, TOP);
|
|
1876
|
+
const bottomViewportAddition = getViewportIncrease(increaseViewportBy2, BOTTOM);
|
|
1877
|
+
listTop -= deviation2;
|
|
1878
|
+
listTop += headerHeight2 + fixedHeaderHeight2;
|
|
1879
|
+
listBottom += headerHeight2 + fixedHeaderHeight2;
|
|
1880
|
+
listBottom -= deviation2;
|
|
1881
|
+
if (listTop > scrollTop2 + stickyHeaderHeight - topViewportAddition) {
|
|
1882
|
+
direction = UP;
|
|
1883
|
+
}
|
|
1884
|
+
if (listBottom < scrollTop2 - headerVisible + viewportHeight2 + bottomViewportAddition) {
|
|
1885
|
+
direction = DOWN;
|
|
1886
|
+
}
|
|
1887
|
+
if (direction !== NONE) {
|
|
1888
|
+
return [
|
|
1889
|
+
Math.max(top - headerHeight2 - getOverscan(overscan2, TOP, direction) - topViewportAddition, 0),
|
|
1890
|
+
top - headerVisible - fixedHeaderHeight2 + viewportHeight2 + getOverscan(overscan2, BOTTOM, direction) + bottomViewportAddition
|
|
1891
|
+
];
|
|
1892
|
+
}
|
|
1893
|
+
return null;
|
|
1894
|
+
}
|
|
1895
|
+
),
|
|
1896
|
+
filter((value) => value != null),
|
|
1897
|
+
distinctUntilChanged(tupleComparator)
|
|
1898
|
+
),
|
|
1899
|
+
[0, 0]
|
|
1900
|
+
);
|
|
1901
|
+
return {
|
|
1902
|
+
listBoundary,
|
|
1903
|
+
overscan,
|
|
1904
|
+
topListHeight,
|
|
1905
|
+
increaseViewportBy,
|
|
1906
|
+
visibleRange
|
|
1907
|
+
};
|
|
1908
|
+
},
|
|
1909
|
+
tup(domIOSystem),
|
|
1910
|
+
{ singleton: true }
|
|
1911
|
+
);
|
|
1912
|
+
function probeItemSet(index, sizes, data) {
|
|
1913
|
+
if (hasGroups(sizes)) {
|
|
1914
|
+
const itemIndex = originalIndexFromItemIndex(index, sizes);
|
|
1915
|
+
const groupIndex = findMaxKeyValue(sizes.groupOffsetTree, itemIndex)[0];
|
|
1916
|
+
return [
|
|
1917
|
+
{ index: groupIndex, size: 0, offset: 0 },
|
|
1918
|
+
{ index: itemIndex, size: 0, offset: 0, data: data && data[0] }
|
|
1919
|
+
];
|
|
1920
|
+
}
|
|
1921
|
+
return [{ index, size: 0, offset: 0, data: data && data[0] }];
|
|
1922
|
+
}
|
|
1923
|
+
const EMPTY_LIST_STATE = {
|
|
1924
|
+
items: [],
|
|
1925
|
+
topItems: [],
|
|
1926
|
+
offsetTop: 0,
|
|
1927
|
+
offsetBottom: 0,
|
|
1928
|
+
top: 0,
|
|
1929
|
+
bottom: 0,
|
|
1930
|
+
topListHeight: 0,
|
|
1931
|
+
totalCount: 0,
|
|
1932
|
+
firstItemIndex: 0
|
|
1933
|
+
};
|
|
1934
|
+
function transposeItems(items, sizes, firstItemIndex) {
|
|
1935
|
+
if (items.length === 0) {
|
|
1936
|
+
return [];
|
|
1937
|
+
}
|
|
1938
|
+
if (!hasGroups(sizes)) {
|
|
1939
|
+
return items.map((item) => ({ ...item, index: item.index + firstItemIndex, originalIndex: item.index }));
|
|
1940
|
+
}
|
|
1941
|
+
const startIndex = items[0].index;
|
|
1942
|
+
const endIndex = items[items.length - 1].index;
|
|
1943
|
+
const transposedItems = [];
|
|
1944
|
+
const groupRanges = rangesWithin(sizes.groupOffsetTree, startIndex, endIndex);
|
|
1945
|
+
let currentRange = void 0;
|
|
1946
|
+
let currentGroupIndex = 0;
|
|
1947
|
+
for (const item of items) {
|
|
1948
|
+
if (!currentRange || currentRange.end < item.index) {
|
|
1949
|
+
currentRange = groupRanges.shift();
|
|
1950
|
+
currentGroupIndex = sizes.groupIndices.indexOf(currentRange.start);
|
|
1951
|
+
}
|
|
1952
|
+
let transposedItem;
|
|
1953
|
+
if (item.index === currentRange.start) {
|
|
1954
|
+
transposedItem = {
|
|
1955
|
+
type: "group",
|
|
1956
|
+
index: currentGroupIndex
|
|
1957
|
+
};
|
|
1958
|
+
} else {
|
|
1959
|
+
transposedItem = {
|
|
1960
|
+
index: item.index - (currentGroupIndex + 1) + firstItemIndex,
|
|
1961
|
+
groupIndex: currentGroupIndex
|
|
1962
|
+
};
|
|
1963
|
+
}
|
|
1964
|
+
transposedItems.push({
|
|
1965
|
+
...transposedItem,
|
|
1966
|
+
size: item.size,
|
|
1967
|
+
offset: item.offset,
|
|
1968
|
+
originalIndex: item.index,
|
|
1969
|
+
data: item.data
|
|
1970
|
+
});
|
|
1971
|
+
}
|
|
1972
|
+
return transposedItems;
|
|
1973
|
+
}
|
|
1974
|
+
function buildListState(items, topItems, totalCount, gap, sizes, firstItemIndex) {
|
|
1975
|
+
const { lastSize, lastOffset, lastIndex } = sizes;
|
|
1976
|
+
let offsetTop = 0;
|
|
1977
|
+
let bottom = 0;
|
|
1978
|
+
if (items.length > 0) {
|
|
1979
|
+
offsetTop = items[0].offset;
|
|
1980
|
+
const lastItem = items[items.length - 1];
|
|
1981
|
+
bottom = lastItem.offset + lastItem.size;
|
|
1982
|
+
}
|
|
1983
|
+
const itemCount = totalCount - lastIndex;
|
|
1984
|
+
const total = lastOffset + itemCount * lastSize + (itemCount - 1) * gap;
|
|
1985
|
+
const top = offsetTop;
|
|
1986
|
+
const offsetBottom = total - bottom;
|
|
1987
|
+
return {
|
|
1988
|
+
items: transposeItems(items, sizes, firstItemIndex),
|
|
1989
|
+
topItems: transposeItems(topItems, sizes, firstItemIndex),
|
|
1990
|
+
topListHeight: topItems.reduce((height, item) => item.size + height, 0),
|
|
1991
|
+
offsetTop,
|
|
1992
|
+
offsetBottom,
|
|
1993
|
+
top,
|
|
1994
|
+
bottom,
|
|
1995
|
+
totalCount,
|
|
1996
|
+
firstItemIndex
|
|
1997
|
+
};
|
|
1998
|
+
}
|
|
1999
|
+
const listStateSystem = system(
|
|
2000
|
+
([
|
|
2001
|
+
{ sizes, totalCount, data, firstItemIndex, gap },
|
|
2002
|
+
groupedListSystem2,
|
|
2003
|
+
{ visibleRange, listBoundary, topListHeight: rangeTopListHeight },
|
|
2004
|
+
{ scrolledToInitialItem, initialTopMostItemIndex },
|
|
2005
|
+
{ topListHeight },
|
|
2006
|
+
stateFlags,
|
|
2007
|
+
{ didMount },
|
|
2008
|
+
{ recalcInProgress }
|
|
2009
|
+
]) => {
|
|
2010
|
+
const topItemsIndexes = statefulStream([]);
|
|
2011
|
+
const itemsRendered = stream();
|
|
2012
|
+
connect(groupedListSystem2.topItemsIndexes, topItemsIndexes);
|
|
2013
|
+
const listState = statefulStreamFromEmitter(
|
|
2014
|
+
pipe(
|
|
2015
|
+
combineLatest(
|
|
2016
|
+
didMount,
|
|
2017
|
+
recalcInProgress,
|
|
2018
|
+
duc(visibleRange, tupleComparator),
|
|
2019
|
+
duc(totalCount),
|
|
2020
|
+
duc(sizes),
|
|
2021
|
+
duc(initialTopMostItemIndex),
|
|
2022
|
+
scrolledToInitialItem,
|
|
2023
|
+
duc(topItemsIndexes),
|
|
2024
|
+
duc(firstItemIndex),
|
|
2025
|
+
duc(gap),
|
|
2026
|
+
data
|
|
2027
|
+
),
|
|
2028
|
+
filter(([mount, recalcInProgress2]) => {
|
|
2029
|
+
return mount && !recalcInProgress2;
|
|
2030
|
+
}),
|
|
2031
|
+
map(
|
|
2032
|
+
([
|
|
2033
|
+
,
|
|
2034
|
+
,
|
|
2035
|
+
[startOffset, endOffset],
|
|
2036
|
+
totalCount2,
|
|
2037
|
+
sizes2,
|
|
2038
|
+
initialTopMostItemIndex2,
|
|
2039
|
+
scrolledToInitialItem2,
|
|
2040
|
+
topItemsIndexes2,
|
|
2041
|
+
firstItemIndex2,
|
|
2042
|
+
gap2,
|
|
2043
|
+
data2
|
|
2044
|
+
]) => {
|
|
2045
|
+
const sizesValue = sizes2;
|
|
2046
|
+
const { sizeTree, offsetTree } = sizesValue;
|
|
2047
|
+
if (totalCount2 === 0 || startOffset === 0 && endOffset === 0) {
|
|
2048
|
+
return { ...EMPTY_LIST_STATE, totalCount: totalCount2 };
|
|
2049
|
+
}
|
|
2050
|
+
if (empty(sizeTree)) {
|
|
2051
|
+
return buildListState(
|
|
2052
|
+
probeItemSet(getInitialTopMostItemIndexNumber(initialTopMostItemIndex2, totalCount2), sizesValue, data2),
|
|
2053
|
+
[],
|
|
2054
|
+
totalCount2,
|
|
2055
|
+
gap2,
|
|
2056
|
+
sizesValue,
|
|
2057
|
+
firstItemIndex2
|
|
2058
|
+
);
|
|
2059
|
+
}
|
|
2060
|
+
const topItems = [];
|
|
2061
|
+
if (topItemsIndexes2.length > 0) {
|
|
2062
|
+
const startIndex = topItemsIndexes2[0];
|
|
2063
|
+
const endIndex = topItemsIndexes2[topItemsIndexes2.length - 1];
|
|
2064
|
+
let offset = 0;
|
|
2065
|
+
for (const range of rangesWithin(sizeTree, startIndex, endIndex)) {
|
|
2066
|
+
const size = range.value;
|
|
2067
|
+
const rangeStartIndex = Math.max(range.start, startIndex);
|
|
2068
|
+
const rangeEndIndex = Math.min(range.end, endIndex);
|
|
2069
|
+
for (let i = rangeStartIndex; i <= rangeEndIndex; i++) {
|
|
2070
|
+
topItems.push({ index: i, size, offset, data: data2 && data2[i] });
|
|
2071
|
+
offset += size;
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
if (!scrolledToInitialItem2) {
|
|
2076
|
+
return buildListState([], topItems, totalCount2, gap2, sizesValue, firstItemIndex2);
|
|
2077
|
+
}
|
|
2078
|
+
const minStartIndex = topItemsIndexes2.length > 0 ? topItemsIndexes2[topItemsIndexes2.length - 1] + 1 : 0;
|
|
2079
|
+
const offsetPointRanges = rangesWithinOffsets(offsetTree, startOffset, endOffset, minStartIndex);
|
|
2080
|
+
if (offsetPointRanges.length === 0) {
|
|
2081
|
+
return null;
|
|
2082
|
+
}
|
|
2083
|
+
const maxIndex = totalCount2 - 1;
|
|
2084
|
+
const items = tap([], (result) => {
|
|
2085
|
+
for (const range of offsetPointRanges) {
|
|
2086
|
+
const point = range.value;
|
|
2087
|
+
let offset = point.offset;
|
|
2088
|
+
let rangeStartIndex = range.start;
|
|
2089
|
+
const size = point.size;
|
|
2090
|
+
if (point.offset < startOffset) {
|
|
2091
|
+
rangeStartIndex += Math.floor((startOffset - point.offset + gap2) / (size + gap2));
|
|
2092
|
+
const itemCount = rangeStartIndex - range.start;
|
|
2093
|
+
offset += itemCount * size + itemCount * gap2;
|
|
2094
|
+
}
|
|
2095
|
+
if (rangeStartIndex < minStartIndex) {
|
|
2096
|
+
offset += (minStartIndex - rangeStartIndex) * size;
|
|
2097
|
+
rangeStartIndex = minStartIndex;
|
|
2098
|
+
}
|
|
2099
|
+
const endIndex = Math.min(range.end, maxIndex);
|
|
2100
|
+
for (let i = rangeStartIndex; i <= endIndex; i++) {
|
|
2101
|
+
if (offset >= endOffset) {
|
|
2102
|
+
break;
|
|
2103
|
+
}
|
|
2104
|
+
result.push({ index: i, size, offset, data: data2 && data2[i] });
|
|
2105
|
+
offset += size + gap2;
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
});
|
|
2109
|
+
return buildListState(items, topItems, totalCount2, gap2, sizesValue, firstItemIndex2);
|
|
2110
|
+
}
|
|
2111
|
+
),
|
|
2112
|
+
filter((value) => value !== null),
|
|
2113
|
+
distinctUntilChanged()
|
|
2114
|
+
),
|
|
2115
|
+
EMPTY_LIST_STATE
|
|
2116
|
+
);
|
|
2117
|
+
connect(
|
|
2118
|
+
pipe(
|
|
2119
|
+
data,
|
|
2120
|
+
filter((data2) => data2 !== void 0),
|
|
2121
|
+
map((data2) => data2 == null ? void 0 : data2.length)
|
|
2122
|
+
),
|
|
2123
|
+
totalCount
|
|
2124
|
+
);
|
|
2125
|
+
connect(
|
|
2126
|
+
pipe(
|
|
2127
|
+
listState,
|
|
2128
|
+
map((value) => value.topListHeight)
|
|
2129
|
+
),
|
|
2130
|
+
topListHeight
|
|
2131
|
+
);
|
|
2132
|
+
connect(topListHeight, rangeTopListHeight);
|
|
2133
|
+
connect(
|
|
2134
|
+
pipe(
|
|
2135
|
+
listState,
|
|
2136
|
+
map((state) => [state.top, state.bottom])
|
|
2137
|
+
),
|
|
2138
|
+
listBoundary
|
|
2139
|
+
);
|
|
2140
|
+
connect(
|
|
2141
|
+
pipe(
|
|
2142
|
+
listState,
|
|
2143
|
+
map((state) => state.items)
|
|
2144
|
+
),
|
|
2145
|
+
itemsRendered
|
|
2146
|
+
);
|
|
2147
|
+
const endReached = streamFromEmitter(
|
|
2148
|
+
pipe(
|
|
2149
|
+
listState,
|
|
2150
|
+
filter(({ items }) => items.length > 0),
|
|
2151
|
+
withLatestFrom(totalCount, data),
|
|
2152
|
+
filter(([{ items }, totalCount2]) => items[items.length - 1].originalIndex === totalCount2 - 1),
|
|
2153
|
+
map(([, totalCount2, data2]) => [totalCount2 - 1, data2]),
|
|
2154
|
+
distinctUntilChanged(tupleComparator),
|
|
2155
|
+
map(([count]) => count)
|
|
2156
|
+
)
|
|
2157
|
+
);
|
|
2158
|
+
const startReached = streamFromEmitter(
|
|
2159
|
+
pipe(
|
|
2160
|
+
listState,
|
|
2161
|
+
throttleTime(200),
|
|
2162
|
+
filter(({ items, topItems }) => {
|
|
2163
|
+
return items.length > 0 && items[0].originalIndex === topItems.length;
|
|
2164
|
+
}),
|
|
2165
|
+
map(({ items }) => items[0].index),
|
|
2166
|
+
distinctUntilChanged()
|
|
2167
|
+
)
|
|
2168
|
+
);
|
|
2169
|
+
const rangeChanged = streamFromEmitter(
|
|
2170
|
+
pipe(
|
|
2171
|
+
listState,
|
|
2172
|
+
filter(({ items }) => items.length > 0),
|
|
2173
|
+
map(({ items }) => {
|
|
2174
|
+
let startIndex = 0;
|
|
2175
|
+
let endIndex = items.length - 1;
|
|
2176
|
+
while (items[startIndex].type === "group" && startIndex < endIndex) {
|
|
2177
|
+
startIndex++;
|
|
2178
|
+
}
|
|
2179
|
+
while (items[endIndex].type === "group" && endIndex > startIndex) {
|
|
2180
|
+
endIndex--;
|
|
2181
|
+
}
|
|
2182
|
+
return {
|
|
2183
|
+
startIndex: items[startIndex].index,
|
|
2184
|
+
endIndex: items[endIndex].index
|
|
2185
|
+
};
|
|
2186
|
+
}),
|
|
2187
|
+
distinctUntilChanged(rangeComparator)
|
|
2188
|
+
)
|
|
2189
|
+
);
|
|
2190
|
+
return { listState, topItemsIndexes, endReached, startReached, rangeChanged, itemsRendered, ...stateFlags };
|
|
2191
|
+
},
|
|
2192
|
+
tup(
|
|
2193
|
+
sizeSystem,
|
|
2194
|
+
groupedListSystem,
|
|
2195
|
+
sizeRangeSystem,
|
|
2196
|
+
initialTopMostItemIndexSystem,
|
|
2197
|
+
scrollToIndexSystem,
|
|
2198
|
+
stateFlagsSystem,
|
|
2199
|
+
propsReadySystem,
|
|
2200
|
+
recalcSystem
|
|
2201
|
+
),
|
|
2202
|
+
{ singleton: true }
|
|
2203
|
+
);
|
|
2204
|
+
const initialItemCountSystem = system(
|
|
2205
|
+
([{ sizes, firstItemIndex, data, gap }, { listState }, { didMount }]) => {
|
|
2206
|
+
const initialItemCount = statefulStream(0);
|
|
2207
|
+
connect(
|
|
2208
|
+
pipe(
|
|
2209
|
+
didMount,
|
|
2210
|
+
withLatestFrom(initialItemCount),
|
|
2211
|
+
filter(([, count]) => count !== 0),
|
|
2212
|
+
withLatestFrom(sizes, firstItemIndex, gap, data),
|
|
2213
|
+
map(([[, count], sizes2, firstItemIndex2, gap2, data2 = []]) => {
|
|
2214
|
+
let includedGroupsCount = 0;
|
|
2215
|
+
if (sizes2.groupIndices.length > 0) {
|
|
2216
|
+
for (const index of sizes2.groupIndices) {
|
|
2217
|
+
if (index - includedGroupsCount >= count) {
|
|
2218
|
+
break;
|
|
2219
|
+
}
|
|
2220
|
+
includedGroupsCount++;
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
const adjustedCount = count + includedGroupsCount;
|
|
2224
|
+
const items = Array.from({ length: adjustedCount }).map((_, index) => ({ index, size: 0, offset: 0, data: data2[index] }));
|
|
2225
|
+
return buildListState(items, [], adjustedCount, gap2, sizes2, firstItemIndex2);
|
|
2226
|
+
})
|
|
2227
|
+
),
|
|
2228
|
+
listState
|
|
2229
|
+
);
|
|
2230
|
+
return { initialItemCount };
|
|
2231
|
+
},
|
|
2232
|
+
tup(sizeSystem, listStateSystem, propsReadySystem),
|
|
2233
|
+
{ singleton: true }
|
|
2234
|
+
);
|
|
2235
|
+
const scrollSeekSystem = system(
|
|
2236
|
+
([{ scrollVelocity }]) => {
|
|
2237
|
+
const isSeeking = statefulStream(false);
|
|
2238
|
+
const rangeChanged = stream();
|
|
2239
|
+
const scrollSeekConfiguration = statefulStream(false);
|
|
2240
|
+
connect(
|
|
2241
|
+
pipe(
|
|
2242
|
+
scrollVelocity,
|
|
2243
|
+
withLatestFrom(scrollSeekConfiguration, isSeeking, rangeChanged),
|
|
2244
|
+
filter(([_, config]) => !!config),
|
|
2245
|
+
map(([speed, config, isSeeking2, range]) => {
|
|
2246
|
+
const { exit, enter } = config;
|
|
2247
|
+
if (isSeeking2) {
|
|
2248
|
+
if (exit(speed, range)) {
|
|
2249
|
+
return false;
|
|
2250
|
+
}
|
|
2251
|
+
} else {
|
|
2252
|
+
if (enter(speed, range)) {
|
|
2253
|
+
return true;
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
return isSeeking2;
|
|
2257
|
+
}),
|
|
2258
|
+
distinctUntilChanged()
|
|
2259
|
+
),
|
|
2260
|
+
isSeeking
|
|
2261
|
+
);
|
|
2262
|
+
subscribe(
|
|
2263
|
+
pipe(combineLatest(isSeeking, scrollVelocity, rangeChanged), withLatestFrom(scrollSeekConfiguration)),
|
|
2264
|
+
([[isSeeking2, velocity, range], config]) => isSeeking2 && config && config.change && config.change(velocity, range)
|
|
2265
|
+
);
|
|
2266
|
+
return { isSeeking, scrollSeekConfiguration, scrollVelocity, scrollSeekRangeChanged: rangeChanged };
|
|
2267
|
+
},
|
|
2268
|
+
tup(stateFlagsSystem),
|
|
2269
|
+
{ singleton: true }
|
|
2270
|
+
);
|
|
2271
|
+
const topItemCountSystem = system(([{ topItemsIndexes }]) => {
|
|
2272
|
+
const topItemCount = statefulStream(0);
|
|
2273
|
+
connect(
|
|
2274
|
+
pipe(
|
|
2275
|
+
topItemCount,
|
|
2276
|
+
filter((length) => length > 0),
|
|
2277
|
+
map((length) => Array.from({ length }).map((_, index) => index))
|
|
2278
|
+
),
|
|
2279
|
+
topItemsIndexes
|
|
2280
|
+
);
|
|
2281
|
+
return { topItemCount };
|
|
2282
|
+
}, tup(listStateSystem));
|
|
2283
|
+
const totalListHeightSystem = system(
|
|
2284
|
+
([{ footerHeight, headerHeight, fixedHeaderHeight, fixedFooterHeight }, { listState }]) => {
|
|
2285
|
+
const totalListHeightChanged = stream();
|
|
2286
|
+
const totalListHeight = statefulStreamFromEmitter(
|
|
2287
|
+
pipe(
|
|
2288
|
+
combineLatest(footerHeight, fixedFooterHeight, headerHeight, fixedHeaderHeight, listState),
|
|
2289
|
+
map(([footerHeight2, fixedFooterHeight2, headerHeight2, fixedHeaderHeight2, listState2]) => {
|
|
2290
|
+
return footerHeight2 + fixedFooterHeight2 + headerHeight2 + fixedHeaderHeight2 + listState2.offsetBottom + listState2.bottom;
|
|
2291
|
+
})
|
|
2292
|
+
),
|
|
2293
|
+
0
|
|
2294
|
+
);
|
|
2295
|
+
connect(duc(totalListHeight), totalListHeightChanged);
|
|
2296
|
+
return { totalListHeight, totalListHeightChanged };
|
|
2297
|
+
},
|
|
2298
|
+
tup(domIOSystem, listStateSystem),
|
|
2299
|
+
{ singleton: true }
|
|
2300
|
+
);
|
|
2301
|
+
function simpleMemoize(func) {
|
|
2302
|
+
let called = false;
|
|
2303
|
+
let result;
|
|
2304
|
+
return () => {
|
|
2305
|
+
if (!called) {
|
|
2306
|
+
called = true;
|
|
2307
|
+
result = func();
|
|
2308
|
+
}
|
|
2309
|
+
return result;
|
|
2310
|
+
};
|
|
2311
|
+
}
|
|
2312
|
+
const isMobileSafari = simpleMemoize(() => {
|
|
2313
|
+
return /iP(ad|od|hone)/i.test(navigator.userAgent) && /WebKit/i.test(navigator.userAgent);
|
|
2314
|
+
});
|
|
2315
|
+
const upwardScrollFixSystem = system(
|
|
2316
|
+
([
|
|
2317
|
+
{ scrollBy, scrollTop, deviation, scrollingInProgress },
|
|
2318
|
+
{ isScrolling, isAtBottom, scrollDirection, lastJumpDueToItemResize },
|
|
2319
|
+
{ listState },
|
|
2320
|
+
{ beforeUnshiftWith, shiftWithOffset, sizes, gap },
|
|
2321
|
+
{ log },
|
|
2322
|
+
{ recalcInProgress }
|
|
2323
|
+
]) => {
|
|
2324
|
+
const deviationOffset = streamFromEmitter(
|
|
2325
|
+
pipe(
|
|
2326
|
+
listState,
|
|
2327
|
+
withLatestFrom(lastJumpDueToItemResize),
|
|
2328
|
+
scan(
|
|
2329
|
+
([, prevItems, prevTotalCount, prevTotalHeight], [{ items, totalCount, bottom, offsetBottom }, lastJumpDueToItemResize2]) => {
|
|
2330
|
+
const totalHeight = bottom + offsetBottom;
|
|
2331
|
+
let newDev = 0;
|
|
2332
|
+
if (prevTotalCount === totalCount) {
|
|
2333
|
+
if (prevItems.length > 0 && items.length > 0) {
|
|
2334
|
+
const atStart = items[0].originalIndex === 0 && prevItems[0].originalIndex === 0;
|
|
2335
|
+
if (!atStart) {
|
|
2336
|
+
newDev = totalHeight - prevTotalHeight;
|
|
2337
|
+
if (newDev !== 0) {
|
|
2338
|
+
newDev += lastJumpDueToItemResize2;
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
return [newDev, items, totalCount, totalHeight];
|
|
2344
|
+
},
|
|
2345
|
+
[0, [], 0, 0]
|
|
2346
|
+
),
|
|
2347
|
+
filter(([amount]) => amount !== 0),
|
|
2348
|
+
withLatestFrom(scrollTop, scrollDirection, scrollingInProgress, isAtBottom, log),
|
|
2349
|
+
filter(([, scrollTop2, scrollDirection2, scrollingInProgress2]) => {
|
|
2350
|
+
return !scrollingInProgress2 && scrollTop2 !== 0 && scrollDirection2 === UP;
|
|
2351
|
+
}),
|
|
2352
|
+
map(([[amount], , , , , log2]) => {
|
|
2353
|
+
log2("Upward scrolling compensation", { amount }, LogLevel.DEBUG);
|
|
2354
|
+
return amount;
|
|
2355
|
+
})
|
|
2356
|
+
)
|
|
2357
|
+
);
|
|
2358
|
+
function scrollByWith(offset) {
|
|
2359
|
+
if (offset > 0) {
|
|
2360
|
+
publish(scrollBy, { top: -offset, behavior: "auto" });
|
|
2361
|
+
publish(deviation, 0);
|
|
2362
|
+
} else {
|
|
2363
|
+
publish(deviation, 0);
|
|
2364
|
+
publish(scrollBy, { top: -offset, behavior: "auto" });
|
|
2365
|
+
}
|
|
2366
|
+
}
|
|
2367
|
+
subscribe(pipe(deviationOffset, withLatestFrom(deviation, isScrolling)), ([offset, deviationAmount, isScrolling2]) => {
|
|
2368
|
+
if (isScrolling2 && isMobileSafari()) {
|
|
2369
|
+
publish(deviation, deviationAmount - offset);
|
|
2370
|
+
} else {
|
|
2371
|
+
scrollByWith(-offset);
|
|
2372
|
+
}
|
|
2373
|
+
});
|
|
2374
|
+
subscribe(
|
|
2375
|
+
pipe(
|
|
2376
|
+
combineLatest(statefulStreamFromEmitter(isScrolling, false), deviation, recalcInProgress),
|
|
2377
|
+
filter(([is, deviation2, recalc]) => !is && !recalc && deviation2 !== 0),
|
|
2378
|
+
map(([_, deviation2]) => deviation2),
|
|
2379
|
+
throttleTime(1)
|
|
2380
|
+
),
|
|
2381
|
+
scrollByWith
|
|
2382
|
+
);
|
|
2383
|
+
connect(
|
|
2384
|
+
pipe(
|
|
2385
|
+
shiftWithOffset,
|
|
2386
|
+
map((offset) => {
|
|
2387
|
+
return { top: -offset };
|
|
2388
|
+
})
|
|
2389
|
+
),
|
|
2390
|
+
scrollBy
|
|
2391
|
+
);
|
|
2392
|
+
subscribe(
|
|
2393
|
+
pipe(
|
|
2394
|
+
beforeUnshiftWith,
|
|
2395
|
+
withLatestFrom(sizes, gap),
|
|
2396
|
+
map(([offset, { lastSize }, gap2]) => offset * lastSize + offset * gap2)
|
|
2397
|
+
),
|
|
2398
|
+
(offset) => {
|
|
2399
|
+
publish(deviation, offset);
|
|
2400
|
+
requestAnimationFrame(() => {
|
|
2401
|
+
publish(scrollBy, { top: offset });
|
|
2402
|
+
requestAnimationFrame(() => {
|
|
2403
|
+
publish(deviation, 0);
|
|
2404
|
+
publish(recalcInProgress, false);
|
|
2405
|
+
});
|
|
2406
|
+
});
|
|
2407
|
+
}
|
|
2408
|
+
);
|
|
2409
|
+
return { deviation };
|
|
2410
|
+
},
|
|
2411
|
+
tup(domIOSystem, stateFlagsSystem, listStateSystem, sizeSystem, loggerSystem, recalcSystem)
|
|
2412
|
+
);
|
|
2413
|
+
const initialScrollTopSystem = system(
|
|
2414
|
+
([{ totalListHeight }, { didMount }, { scrollTo }]) => {
|
|
2415
|
+
const initialScrollTop = statefulStream(0);
|
|
2416
|
+
subscribe(
|
|
2417
|
+
pipe(
|
|
2418
|
+
didMount,
|
|
2419
|
+
withLatestFrom(initialScrollTop),
|
|
2420
|
+
filter(([, offset]) => offset !== 0),
|
|
2421
|
+
map(([, offset]) => ({ top: offset }))
|
|
2422
|
+
),
|
|
2423
|
+
(location) => {
|
|
2424
|
+
handleNext(
|
|
2425
|
+
pipe(
|
|
2426
|
+
totalListHeight,
|
|
2427
|
+
filter((val) => val !== 0)
|
|
2428
|
+
),
|
|
2429
|
+
() => {
|
|
2430
|
+
setTimeout(() => {
|
|
2431
|
+
publish(scrollTo, location);
|
|
2432
|
+
});
|
|
2433
|
+
}
|
|
2434
|
+
);
|
|
2435
|
+
}
|
|
2436
|
+
);
|
|
2437
|
+
return {
|
|
2438
|
+
initialScrollTop
|
|
2439
|
+
};
|
|
2440
|
+
},
|
|
2441
|
+
tup(totalListHeightSystem, propsReadySystem, domIOSystem),
|
|
2442
|
+
{ singleton: true }
|
|
2443
|
+
);
|
|
2444
|
+
const alignToBottomSystem = system(
|
|
2445
|
+
([{ viewportHeight }, { totalListHeight }]) => {
|
|
2446
|
+
const alignToBottom = statefulStream(false);
|
|
2447
|
+
const paddingTopAddition = statefulStreamFromEmitter(
|
|
2448
|
+
pipe(
|
|
2449
|
+
combineLatest(alignToBottom, viewportHeight, totalListHeight),
|
|
2450
|
+
filter(([enabled]) => enabled),
|
|
2451
|
+
map(([, viewportHeight2, totalListHeight2]) => {
|
|
2452
|
+
return Math.max(0, viewportHeight2 - totalListHeight2);
|
|
2453
|
+
}),
|
|
2454
|
+
distinctUntilChanged()
|
|
2455
|
+
),
|
|
2456
|
+
0
|
|
2457
|
+
);
|
|
2458
|
+
return { alignToBottom, paddingTopAddition };
|
|
2459
|
+
},
|
|
2460
|
+
tup(domIOSystem, totalListHeightSystem),
|
|
2461
|
+
{ singleton: true }
|
|
2462
|
+
);
|
|
2463
|
+
const windowScrollerSystem = system(([{ scrollTo, scrollContainerState }]) => {
|
|
2464
|
+
const windowScrollContainerState = stream();
|
|
2465
|
+
const windowViewportRect = stream();
|
|
2466
|
+
const windowScrollTo = stream();
|
|
2467
|
+
const useWindowScroll = statefulStream(false);
|
|
2468
|
+
const customScrollParent = statefulStream(void 0);
|
|
2469
|
+
connect(
|
|
2470
|
+
pipe(
|
|
2471
|
+
combineLatest(windowScrollContainerState, windowViewportRect),
|
|
2472
|
+
map(([{ viewportHeight, scrollTop: windowScrollTop, scrollHeight }, { offsetTop }]) => {
|
|
2473
|
+
return {
|
|
2474
|
+
scrollTop: Math.max(0, windowScrollTop - offsetTop),
|
|
2475
|
+
scrollHeight,
|
|
2476
|
+
viewportHeight
|
|
2477
|
+
};
|
|
2478
|
+
})
|
|
2479
|
+
),
|
|
2480
|
+
scrollContainerState
|
|
2481
|
+
);
|
|
2482
|
+
connect(
|
|
2483
|
+
pipe(
|
|
2484
|
+
scrollTo,
|
|
2485
|
+
withLatestFrom(windowViewportRect),
|
|
2486
|
+
map(([scrollTo2, { offsetTop }]) => {
|
|
2487
|
+
return {
|
|
2488
|
+
...scrollTo2,
|
|
2489
|
+
top: scrollTo2.top + offsetTop
|
|
2490
|
+
};
|
|
2491
|
+
})
|
|
2492
|
+
),
|
|
2493
|
+
windowScrollTo
|
|
2494
|
+
);
|
|
2495
|
+
return {
|
|
2496
|
+
useWindowScroll,
|
|
2497
|
+
customScrollParent,
|
|
2498
|
+
windowScrollContainerState,
|
|
2499
|
+
windowViewportRect,
|
|
2500
|
+
windowScrollTo
|
|
2501
|
+
};
|
|
2502
|
+
}, tup(domIOSystem));
|
|
2503
|
+
const scrollIntoViewSystem = system(
|
|
2504
|
+
([
|
|
2505
|
+
{ sizes, totalCount, gap },
|
|
2506
|
+
{ scrollTop, viewportHeight, headerHeight, fixedHeaderHeight, fixedFooterHeight, scrollingInProgress },
|
|
2507
|
+
{ scrollToIndex }
|
|
2508
|
+
]) => {
|
|
2509
|
+
const scrollIntoView = stream();
|
|
2510
|
+
connect(
|
|
2511
|
+
pipe(
|
|
2512
|
+
scrollIntoView,
|
|
2513
|
+
withLatestFrom(sizes, viewportHeight, totalCount, headerHeight, fixedHeaderHeight, fixedFooterHeight, scrollTop),
|
|
2514
|
+
withLatestFrom(gap),
|
|
2515
|
+
map(([[viewLocation, sizes2, viewportHeight2, totalCount2, headerHeight2, fixedHeaderHeight2, fixedFooterHeight2, scrollTop2], gap2]) => {
|
|
2516
|
+
const { done, behavior, align, ...rest } = viewLocation;
|
|
2517
|
+
let location = null;
|
|
2518
|
+
const actualIndex = originalIndexFromLocation(viewLocation, sizes2, totalCount2 - 1);
|
|
2519
|
+
const itemTop2 = offsetOf(actualIndex, sizes2.offsetTree, gap2) + headerHeight2 + fixedHeaderHeight2;
|
|
2520
|
+
if (itemTop2 < scrollTop2 + fixedHeaderHeight2) {
|
|
2521
|
+
location = { ...rest, behavior, align: align ?? "start" };
|
|
2522
|
+
} else {
|
|
2523
|
+
const itemBottom = itemTop2 + findMaxKeyValue(sizes2.sizeTree, actualIndex)[1];
|
|
2524
|
+
if (itemBottom > scrollTop2 + viewportHeight2 - fixedFooterHeight2) {
|
|
2525
|
+
location = { ...rest, behavior, align: align ?? "end" };
|
|
2526
|
+
}
|
|
2527
|
+
}
|
|
2528
|
+
if (location) {
|
|
2529
|
+
done && handleNext(
|
|
2530
|
+
pipe(
|
|
2531
|
+
scrollingInProgress,
|
|
2532
|
+
skip(1),
|
|
2533
|
+
filter((value) => value === false)
|
|
2534
|
+
),
|
|
2535
|
+
done
|
|
2536
|
+
);
|
|
2537
|
+
} else {
|
|
2538
|
+
done && done();
|
|
2539
|
+
}
|
|
2540
|
+
return location;
|
|
2541
|
+
}),
|
|
2542
|
+
filter((value) => value !== null)
|
|
2543
|
+
),
|
|
2544
|
+
scrollToIndex
|
|
2545
|
+
);
|
|
2546
|
+
return {
|
|
2547
|
+
scrollIntoView
|
|
2548
|
+
};
|
|
2549
|
+
},
|
|
2550
|
+
tup(sizeSystem, domIOSystem, scrollToIndexSystem, listStateSystem, loggerSystem),
|
|
2551
|
+
{ singleton: true }
|
|
2552
|
+
);
|
|
2553
|
+
const featureGroup1System = system(
|
|
2554
|
+
([
|
|
2555
|
+
sizeRange,
|
|
2556
|
+
initialItemCount,
|
|
2557
|
+
propsReady,
|
|
2558
|
+
scrollSeek,
|
|
2559
|
+
totalListHeight,
|
|
2560
|
+
initialScrollTopSystem2,
|
|
2561
|
+
alignToBottom,
|
|
2562
|
+
windowScroller,
|
|
2563
|
+
scrollIntoView
|
|
2564
|
+
]) => {
|
|
2565
|
+
return {
|
|
2566
|
+
...sizeRange,
|
|
2567
|
+
...initialItemCount,
|
|
2568
|
+
...propsReady,
|
|
2569
|
+
...scrollSeek,
|
|
2570
|
+
...totalListHeight,
|
|
2571
|
+
...initialScrollTopSystem2,
|
|
2572
|
+
...alignToBottom,
|
|
2573
|
+
...windowScroller,
|
|
2574
|
+
...scrollIntoView
|
|
2575
|
+
};
|
|
2576
|
+
},
|
|
2577
|
+
tup(
|
|
2578
|
+
sizeRangeSystem,
|
|
2579
|
+
initialItemCountSystem,
|
|
2580
|
+
propsReadySystem,
|
|
2581
|
+
scrollSeekSystem,
|
|
2582
|
+
totalListHeightSystem,
|
|
2583
|
+
initialScrollTopSystem,
|
|
2584
|
+
alignToBottomSystem,
|
|
2585
|
+
windowScrollerSystem,
|
|
2586
|
+
scrollIntoViewSystem
|
|
2587
|
+
)
|
|
2588
|
+
);
|
|
2589
|
+
const listSystem = system(
|
|
2590
|
+
([
|
|
2591
|
+
{
|
|
2592
|
+
totalCount,
|
|
2593
|
+
sizeRanges,
|
|
2594
|
+
fixedItemSize,
|
|
2595
|
+
defaultItemSize,
|
|
2596
|
+
trackItemSizes,
|
|
2597
|
+
itemSize,
|
|
2598
|
+
data,
|
|
2599
|
+
firstItemIndex,
|
|
2600
|
+
groupIndices,
|
|
2601
|
+
statefulTotalCount,
|
|
2602
|
+
gap
|
|
2603
|
+
},
|
|
2604
|
+
{ initialTopMostItemIndex, scrolledToInitialItem },
|
|
2605
|
+
domIO,
|
|
2606
|
+
followOutput,
|
|
2607
|
+
{ listState, topItemsIndexes, ...flags },
|
|
2608
|
+
{ scrollToIndex },
|
|
2609
|
+
_,
|
|
2610
|
+
{ topItemCount },
|
|
2611
|
+
{ groupCounts },
|
|
2612
|
+
featureGroup1,
|
|
2613
|
+
log
|
|
2614
|
+
]) => {
|
|
2615
|
+
connect(flags.rangeChanged, featureGroup1.scrollSeekRangeChanged);
|
|
2616
|
+
connect(
|
|
2617
|
+
pipe(
|
|
2618
|
+
featureGroup1.windowViewportRect,
|
|
2619
|
+
map((value) => value.visibleHeight)
|
|
2620
|
+
),
|
|
2621
|
+
domIO.viewportHeight
|
|
2622
|
+
);
|
|
2623
|
+
return {
|
|
2624
|
+
totalCount,
|
|
2625
|
+
data,
|
|
2626
|
+
firstItemIndex,
|
|
2627
|
+
sizeRanges,
|
|
2628
|
+
initialTopMostItemIndex,
|
|
2629
|
+
scrolledToInitialItem,
|
|
2630
|
+
topItemsIndexes,
|
|
2631
|
+
topItemCount,
|
|
2632
|
+
groupCounts,
|
|
2633
|
+
fixedItemHeight: fixedItemSize,
|
|
2634
|
+
defaultItemHeight: defaultItemSize,
|
|
2635
|
+
gap,
|
|
2636
|
+
...followOutput,
|
|
2637
|
+
statefulTotalCount,
|
|
2638
|
+
listState,
|
|
2639
|
+
scrollToIndex,
|
|
2640
|
+
trackItemSizes,
|
|
2641
|
+
itemSize,
|
|
2642
|
+
groupIndices,
|
|
2643
|
+
...flags,
|
|
2644
|
+
...featureGroup1,
|
|
2645
|
+
...domIO,
|
|
2646
|
+
...log
|
|
2647
|
+
};
|
|
2648
|
+
},
|
|
2649
|
+
tup(
|
|
2650
|
+
sizeSystem,
|
|
2651
|
+
initialTopMostItemIndexSystem,
|
|
2652
|
+
domIOSystem,
|
|
2653
|
+
followOutputSystem,
|
|
2654
|
+
listStateSystem,
|
|
2655
|
+
scrollToIndexSystem,
|
|
2656
|
+
upwardScrollFixSystem,
|
|
2657
|
+
topItemCountSystem,
|
|
2658
|
+
groupedListSystem,
|
|
2659
|
+
featureGroup1System,
|
|
2660
|
+
loggerSystem
|
|
2661
|
+
)
|
|
2662
|
+
);
|
|
2663
|
+
const WEBKIT_STICKY = "-webkit-sticky";
|
|
2664
|
+
const STICKY = "sticky";
|
|
2665
|
+
const positionStickyCssValue = simpleMemoize(() => {
|
|
2666
|
+
if (typeof document === "undefined") {
|
|
2667
|
+
return STICKY;
|
|
2668
|
+
}
|
|
2669
|
+
const node = document.createElement("div");
|
|
2670
|
+
node.style.position = WEBKIT_STICKY;
|
|
2671
|
+
return node.style.position === WEBKIT_STICKY ? WEBKIT_STICKY : STICKY;
|
|
2672
|
+
});
|
|
2673
|
+
function useWindowViewportRectRef(callback, customScrollParent) {
|
|
2674
|
+
const viewportInfo = useRef(null);
|
|
2675
|
+
const calculateInfo = useCallback(
|
|
2676
|
+
(element) => {
|
|
2677
|
+
if (element === null || !element.offsetParent) {
|
|
2678
|
+
return;
|
|
2679
|
+
}
|
|
2680
|
+
const rect = element.getBoundingClientRect();
|
|
2681
|
+
const visibleWidth = rect.width;
|
|
2682
|
+
let visibleHeight, offsetTop;
|
|
2683
|
+
if (customScrollParent) {
|
|
2684
|
+
const customScrollParentRect = customScrollParent.getBoundingClientRect();
|
|
2685
|
+
const deltaTop = rect.top - customScrollParentRect.top;
|
|
2686
|
+
visibleHeight = customScrollParentRect.height - Math.max(0, deltaTop);
|
|
2687
|
+
offsetTop = deltaTop + customScrollParent.scrollTop;
|
|
2688
|
+
} else {
|
|
2689
|
+
visibleHeight = window.innerHeight - Math.max(0, rect.top);
|
|
2690
|
+
offsetTop = rect.top + window.pageYOffset;
|
|
2691
|
+
}
|
|
2692
|
+
viewportInfo.current = {
|
|
2693
|
+
offsetTop,
|
|
2694
|
+
visibleHeight,
|
|
2695
|
+
visibleWidth
|
|
2696
|
+
};
|
|
2697
|
+
callback(viewportInfo.current);
|
|
2698
|
+
},
|
|
2699
|
+
[callback, customScrollParent]
|
|
2700
|
+
);
|
|
2701
|
+
const { callbackRef, ref } = useSizeWithElRef(calculateInfo);
|
|
2702
|
+
const scrollAndResizeEventHandler = useCallback(() => {
|
|
2703
|
+
calculateInfo(ref.current);
|
|
2704
|
+
}, [calculateInfo, ref]);
|
|
2705
|
+
useEffect(() => {
|
|
2706
|
+
if (customScrollParent) {
|
|
2707
|
+
customScrollParent.addEventListener("scroll", scrollAndResizeEventHandler);
|
|
2708
|
+
const observer = new ResizeObserver(scrollAndResizeEventHandler);
|
|
2709
|
+
observer.observe(customScrollParent);
|
|
2710
|
+
return () => {
|
|
2711
|
+
customScrollParent.removeEventListener("scroll", scrollAndResizeEventHandler);
|
|
2712
|
+
observer.unobserve(customScrollParent);
|
|
2713
|
+
};
|
|
2714
|
+
} else {
|
|
2715
|
+
window.addEventListener("scroll", scrollAndResizeEventHandler);
|
|
2716
|
+
window.addEventListener("resize", scrollAndResizeEventHandler);
|
|
2717
|
+
return () => {
|
|
2718
|
+
window.removeEventListener("scroll", scrollAndResizeEventHandler);
|
|
2719
|
+
window.removeEventListener("resize", scrollAndResizeEventHandler);
|
|
2720
|
+
};
|
|
2721
|
+
}
|
|
2722
|
+
}, [scrollAndResizeEventHandler, customScrollParent]);
|
|
2723
|
+
return callbackRef;
|
|
2724
|
+
}
|
|
2725
|
+
const VirtuosoMockContext = React.createContext(void 0);
|
|
2726
|
+
const VirtuosoGridMockContext = React.createContext(void 0);
|
|
2727
|
+
function identity(value) {
|
|
2728
|
+
return value;
|
|
2729
|
+
}
|
|
2730
|
+
const listComponentPropsSystem = /* @__PURE__ */ system(() => {
|
|
2731
|
+
const itemContent = statefulStream((index) => `Item ${index}`);
|
|
2732
|
+
const context = statefulStream(null);
|
|
2733
|
+
const groupContent = statefulStream((index) => `Group ${index}`);
|
|
2734
|
+
const components = statefulStream({});
|
|
2735
|
+
const computeItemKey = statefulStream(identity);
|
|
2736
|
+
const headerFooterTag = statefulStream("div");
|
|
2737
|
+
const scrollerRef = statefulStream(noop);
|
|
2738
|
+
const distinctProp = (propName, defaultValue = null) => {
|
|
2739
|
+
return statefulStreamFromEmitter(
|
|
2740
|
+
pipe(
|
|
2741
|
+
components,
|
|
2742
|
+
map((components2) => components2[propName]),
|
|
2743
|
+
distinctUntilChanged()
|
|
2744
|
+
),
|
|
2745
|
+
defaultValue
|
|
2746
|
+
);
|
|
2747
|
+
};
|
|
2748
|
+
return {
|
|
2749
|
+
context,
|
|
2750
|
+
itemContent,
|
|
2751
|
+
groupContent,
|
|
2752
|
+
components,
|
|
2753
|
+
computeItemKey,
|
|
2754
|
+
headerFooterTag,
|
|
2755
|
+
scrollerRef,
|
|
2756
|
+
FooterComponent: distinctProp("Footer"),
|
|
2757
|
+
HeaderComponent: distinctProp("Header"),
|
|
2758
|
+
TopItemListComponent: distinctProp("TopItemList"),
|
|
2759
|
+
ListComponent: distinctProp("List", "div"),
|
|
2760
|
+
ItemComponent: distinctProp("Item", "div"),
|
|
2761
|
+
GroupComponent: distinctProp("Group", "div"),
|
|
2762
|
+
ScrollerComponent: distinctProp("Scroller", "div"),
|
|
2763
|
+
EmptyPlaceholder: distinctProp("EmptyPlaceholder"),
|
|
2764
|
+
ScrollSeekPlaceholder: distinctProp("ScrollSeekPlaceholder")
|
|
2765
|
+
};
|
|
2766
|
+
});
|
|
2767
|
+
const combinedSystem$2 = /* @__PURE__ */ system(([listSystem2, propsSystem]) => {
|
|
2768
|
+
return { ...listSystem2, ...propsSystem };
|
|
2769
|
+
}, tup(listSystem, listComponentPropsSystem));
|
|
2770
|
+
const DefaultScrollSeekPlaceholder$1 = ({ height }) => /* @__PURE__ */ jsx("div", { style: { height } });
|
|
2771
|
+
const GROUP_STYLE = { position: positionStickyCssValue(), zIndex: 1, overflowAnchor: "none" };
|
|
2772
|
+
const ITEM_STYLE = { overflowAnchor: "none" };
|
|
2773
|
+
const Items$1 = /* @__PURE__ */ React.memo(function VirtuosoItems({ showTopList = false }) {
|
|
2774
|
+
const listState = useEmitterValue$2("listState");
|
|
2775
|
+
const sizeRanges = usePublisher$2("sizeRanges");
|
|
2776
|
+
const useWindowScroll = useEmitterValue$2("useWindowScroll");
|
|
2777
|
+
const customScrollParent = useEmitterValue$2("customScrollParent");
|
|
2778
|
+
const windowScrollContainerStateCallback = usePublisher$2("windowScrollContainerState");
|
|
2779
|
+
const _scrollContainerStateCallback = usePublisher$2("scrollContainerState");
|
|
2780
|
+
const scrollContainerStateCallback = customScrollParent || useWindowScroll ? windowScrollContainerStateCallback : _scrollContainerStateCallback;
|
|
2781
|
+
const itemContent = useEmitterValue$2("itemContent");
|
|
2782
|
+
const context = useEmitterValue$2("context");
|
|
2783
|
+
const groupContent = useEmitterValue$2("groupContent");
|
|
2784
|
+
const trackItemSizes = useEmitterValue$2("trackItemSizes");
|
|
2785
|
+
const itemSize = useEmitterValue$2("itemSize");
|
|
2786
|
+
const log = useEmitterValue$2("log");
|
|
2787
|
+
const listGap = usePublisher$2("gap");
|
|
2788
|
+
const { callbackRef } = useChangedListContentsSizes(
|
|
2789
|
+
sizeRanges,
|
|
2790
|
+
itemSize,
|
|
2791
|
+
trackItemSizes,
|
|
2792
|
+
showTopList ? noop : scrollContainerStateCallback,
|
|
2793
|
+
log,
|
|
2794
|
+
listGap,
|
|
2795
|
+
customScrollParent
|
|
2796
|
+
);
|
|
2797
|
+
const [deviation, setDeviation] = React.useState(0);
|
|
2798
|
+
useEmitter$2("deviation", (value) => {
|
|
2799
|
+
if (deviation !== value) {
|
|
2800
|
+
setDeviation(value);
|
|
2801
|
+
}
|
|
2802
|
+
});
|
|
2803
|
+
const EmptyPlaceholder = useEmitterValue$2("EmptyPlaceholder");
|
|
2804
|
+
const ScrollSeekPlaceholder = useEmitterValue$2("ScrollSeekPlaceholder") || DefaultScrollSeekPlaceholder$1;
|
|
2805
|
+
const ListComponent = useEmitterValue$2("ListComponent");
|
|
2806
|
+
const ItemComponent = useEmitterValue$2("ItemComponent");
|
|
2807
|
+
const GroupComponent = useEmitterValue$2("GroupComponent");
|
|
2808
|
+
const computeItemKey = useEmitterValue$2("computeItemKey");
|
|
2809
|
+
const isSeeking = useEmitterValue$2("isSeeking");
|
|
2810
|
+
const hasGroups2 = useEmitterValue$2("groupIndices").length > 0;
|
|
2811
|
+
const paddingTopAddition = useEmitterValue$2("paddingTopAddition");
|
|
2812
|
+
const containerStyle = showTopList ? {} : {
|
|
2813
|
+
boxSizing: "border-box",
|
|
2814
|
+
paddingTop: listState.offsetTop + paddingTopAddition,
|
|
2815
|
+
paddingBottom: listState.offsetBottom,
|
|
2816
|
+
marginTop: deviation
|
|
2817
|
+
};
|
|
2818
|
+
if (!showTopList && listState.totalCount === 0 && EmptyPlaceholder) {
|
|
2819
|
+
return createElement(EmptyPlaceholder, contextPropIfNotDomElement(EmptyPlaceholder, context));
|
|
2820
|
+
}
|
|
2821
|
+
return createElement(
|
|
2822
|
+
ListComponent,
|
|
2823
|
+
{
|
|
2824
|
+
...contextPropIfNotDomElement(ListComponent, context),
|
|
2825
|
+
ref: callbackRef,
|
|
2826
|
+
style: containerStyle,
|
|
2827
|
+
"data-test-id": showTopList ? "virtuoso-top-item-list" : "virtuoso-item-list"
|
|
2828
|
+
},
|
|
2829
|
+
(showTopList ? listState.topItems : listState.items).map((item) => {
|
|
2830
|
+
const index = item.originalIndex;
|
|
2831
|
+
const key = computeItemKey(index + listState.firstItemIndex, item.data, context);
|
|
2832
|
+
if (isSeeking) {
|
|
2833
|
+
return createElement(ScrollSeekPlaceholder, {
|
|
2834
|
+
...contextPropIfNotDomElement(ScrollSeekPlaceholder, context),
|
|
2835
|
+
key,
|
|
2836
|
+
index: item.index,
|
|
2837
|
+
height: item.size,
|
|
2838
|
+
type: item.type || "item",
|
|
2839
|
+
...item.type === "group" ? {} : { groupIndex: item.groupIndex }
|
|
2840
|
+
});
|
|
2841
|
+
}
|
|
2842
|
+
if (item.type === "group") {
|
|
2843
|
+
return createElement(
|
|
2844
|
+
GroupComponent,
|
|
2845
|
+
{
|
|
2846
|
+
...contextPropIfNotDomElement(GroupComponent, context),
|
|
2847
|
+
key,
|
|
2848
|
+
"data-index": index,
|
|
2849
|
+
"data-known-size": item.size,
|
|
2850
|
+
"data-item-index": item.index,
|
|
2851
|
+
style: GROUP_STYLE
|
|
2852
|
+
},
|
|
2853
|
+
groupContent(item.index)
|
|
2854
|
+
);
|
|
2855
|
+
} else {
|
|
2856
|
+
return createElement(
|
|
2857
|
+
ItemComponent,
|
|
2858
|
+
{
|
|
2859
|
+
...contextPropIfNotDomElement(ItemComponent, context),
|
|
2860
|
+
key,
|
|
2861
|
+
"data-index": index,
|
|
2862
|
+
"data-known-size": item.size,
|
|
2863
|
+
"data-item-index": item.index,
|
|
2864
|
+
"data-item-group-index": item.groupIndex,
|
|
2865
|
+
item: item.data,
|
|
2866
|
+
style: ITEM_STYLE
|
|
2867
|
+
},
|
|
2868
|
+
hasGroups2 ? itemContent(item.index, item.groupIndex, item.data, context) : itemContent(item.index, item.data, context)
|
|
2869
|
+
);
|
|
2870
|
+
}
|
|
2871
|
+
})
|
|
2872
|
+
);
|
|
2873
|
+
});
|
|
2874
|
+
const scrollerStyle = {
|
|
2875
|
+
height: "100%",
|
|
2876
|
+
outline: "none",
|
|
2877
|
+
overflowY: "auto",
|
|
2878
|
+
position: "relative",
|
|
2879
|
+
WebkitOverflowScrolling: "touch"
|
|
2880
|
+
};
|
|
2881
|
+
const viewportStyle = {
|
|
2882
|
+
width: "100%",
|
|
2883
|
+
height: "100%",
|
|
2884
|
+
position: "absolute",
|
|
2885
|
+
top: 0
|
|
2886
|
+
};
|
|
2887
|
+
const topItemListStyle = {
|
|
2888
|
+
width: "100%",
|
|
2889
|
+
position: positionStickyCssValue(),
|
|
2890
|
+
top: 0,
|
|
2891
|
+
zIndex: 1
|
|
2892
|
+
};
|
|
2893
|
+
function contextPropIfNotDomElement(element, context) {
|
|
2894
|
+
if (typeof element === "string") {
|
|
2895
|
+
return void 0;
|
|
2896
|
+
}
|
|
2897
|
+
return { context };
|
|
2898
|
+
}
|
|
2899
|
+
const Header$1 = /* @__PURE__ */ React.memo(function VirtuosoHeader() {
|
|
2900
|
+
const Header2 = useEmitterValue$2("HeaderComponent");
|
|
2901
|
+
const headerHeight = usePublisher$2("headerHeight");
|
|
2902
|
+
const headerFooterTag = useEmitterValue$2("headerFooterTag");
|
|
2903
|
+
const ref = useSize((el) => headerHeight(correctItemSize(el, "height")));
|
|
2904
|
+
const context = useEmitterValue$2("context");
|
|
2905
|
+
return Header2 ? createElement(headerFooterTag, { ref }, createElement(Header2, contextPropIfNotDomElement(Header2, context))) : null;
|
|
2906
|
+
});
|
|
2907
|
+
const Footer$1 = /* @__PURE__ */ React.memo(function VirtuosoFooter() {
|
|
2908
|
+
const Footer2 = useEmitterValue$2("FooterComponent");
|
|
2909
|
+
const footerHeight = usePublisher$2("footerHeight");
|
|
2910
|
+
const headerFooterTag = useEmitterValue$2("headerFooterTag");
|
|
2911
|
+
const ref = useSize((el) => footerHeight(correctItemSize(el, "height")));
|
|
2912
|
+
const context = useEmitterValue$2("context");
|
|
2913
|
+
return Footer2 ? createElement(headerFooterTag, { ref }, createElement(Footer2, contextPropIfNotDomElement(Footer2, context))) : null;
|
|
2914
|
+
});
|
|
2915
|
+
function buildScroller({ usePublisher: usePublisher2, useEmitter: useEmitter2, useEmitterValue: useEmitterValue2 }) {
|
|
2916
|
+
const Scroller2 = React.memo(function VirtuosoScroller({ style, children, ...props }) {
|
|
2917
|
+
const scrollContainerStateCallback = usePublisher2("scrollContainerState");
|
|
2918
|
+
const ScrollerComponent = useEmitterValue2("ScrollerComponent");
|
|
2919
|
+
const smoothScrollTargetReached = usePublisher2("smoothScrollTargetReached");
|
|
2920
|
+
const scrollerRefCallback = useEmitterValue2("scrollerRef");
|
|
2921
|
+
const context = useEmitterValue2("context");
|
|
2922
|
+
const { scrollerRef, scrollByCallback, scrollToCallback } = useScrollTop(
|
|
2923
|
+
scrollContainerStateCallback,
|
|
2924
|
+
smoothScrollTargetReached,
|
|
2925
|
+
ScrollerComponent,
|
|
2926
|
+
scrollerRefCallback
|
|
2927
|
+
);
|
|
2928
|
+
useEmitter2("scrollTo", scrollToCallback);
|
|
2929
|
+
useEmitter2("scrollBy", scrollByCallback);
|
|
2930
|
+
return createElement(
|
|
2931
|
+
ScrollerComponent,
|
|
2932
|
+
{
|
|
2933
|
+
ref: scrollerRef,
|
|
2934
|
+
style: { ...scrollerStyle, ...style },
|
|
2935
|
+
"data-test-id": "virtuoso-scroller",
|
|
2936
|
+
"data-virtuoso-scroller": true,
|
|
2937
|
+
tabIndex: 0,
|
|
2938
|
+
...props,
|
|
2939
|
+
...contextPropIfNotDomElement(ScrollerComponent, context)
|
|
2940
|
+
},
|
|
2941
|
+
children
|
|
2942
|
+
);
|
|
2943
|
+
});
|
|
2944
|
+
return Scroller2;
|
|
2945
|
+
}
|
|
2946
|
+
function buildWindowScroller({ usePublisher: usePublisher2, useEmitter: useEmitter2, useEmitterValue: useEmitterValue2 }) {
|
|
2947
|
+
const Scroller2 = React.memo(function VirtuosoWindowScroller({ style, children, ...props }) {
|
|
2948
|
+
const scrollContainerStateCallback = usePublisher2("windowScrollContainerState");
|
|
2949
|
+
const ScrollerComponent = useEmitterValue2("ScrollerComponent");
|
|
2950
|
+
const smoothScrollTargetReached = usePublisher2("smoothScrollTargetReached");
|
|
2951
|
+
const totalListHeight = useEmitterValue2("totalListHeight");
|
|
2952
|
+
const deviation = useEmitterValue2("deviation");
|
|
2953
|
+
const customScrollParent = useEmitterValue2("customScrollParent");
|
|
2954
|
+
const context = useEmitterValue2("context");
|
|
2955
|
+
const { scrollerRef, scrollByCallback, scrollToCallback } = useScrollTop(
|
|
2956
|
+
scrollContainerStateCallback,
|
|
2957
|
+
smoothScrollTargetReached,
|
|
2958
|
+
ScrollerComponent,
|
|
2959
|
+
noop,
|
|
2960
|
+
customScrollParent
|
|
2961
|
+
);
|
|
2962
|
+
useIsomorphicLayoutEffect$1(() => {
|
|
2963
|
+
scrollerRef.current = customScrollParent ? customScrollParent : window;
|
|
2964
|
+
return () => {
|
|
2965
|
+
scrollerRef.current = null;
|
|
2966
|
+
};
|
|
2967
|
+
}, [scrollerRef, customScrollParent]);
|
|
2968
|
+
useEmitter2("windowScrollTo", scrollToCallback);
|
|
2969
|
+
useEmitter2("scrollBy", scrollByCallback);
|
|
2970
|
+
return createElement(
|
|
2971
|
+
ScrollerComponent,
|
|
2972
|
+
{
|
|
2973
|
+
style: { position: "relative", ...style, ...totalListHeight !== 0 ? { height: totalListHeight + deviation } : {} },
|
|
2974
|
+
"data-virtuoso-scroller": true,
|
|
2975
|
+
...props,
|
|
2976
|
+
...contextPropIfNotDomElement(ScrollerComponent, context)
|
|
2977
|
+
},
|
|
2978
|
+
children
|
|
2979
|
+
);
|
|
2980
|
+
});
|
|
2981
|
+
return Scroller2;
|
|
2982
|
+
}
|
|
2983
|
+
const Viewport$2 = ({ children }) => {
|
|
2984
|
+
const ctx = useContext(VirtuosoMockContext);
|
|
2985
|
+
const viewportHeight = usePublisher$2("viewportHeight");
|
|
2986
|
+
const fixedItemHeight = usePublisher$2("fixedItemHeight");
|
|
2987
|
+
const viewportRef = useSize(compose(viewportHeight, (el) => correctItemSize(el, "height")));
|
|
2988
|
+
React.useEffect(() => {
|
|
2989
|
+
if (ctx) {
|
|
2990
|
+
viewportHeight(ctx.viewportHeight);
|
|
2991
|
+
fixedItemHeight(ctx.itemHeight);
|
|
2992
|
+
}
|
|
2993
|
+
}, [ctx, viewportHeight, fixedItemHeight]);
|
|
2994
|
+
return /* @__PURE__ */ jsx("div", { style: viewportStyle, ref: viewportRef, "data-viewport-type": "element", children });
|
|
2995
|
+
};
|
|
2996
|
+
const WindowViewport$2 = ({ children }) => {
|
|
2997
|
+
const ctx = useContext(VirtuosoMockContext);
|
|
2998
|
+
const windowViewportRect = usePublisher$2("windowViewportRect");
|
|
2999
|
+
const fixedItemHeight = usePublisher$2("fixedItemHeight");
|
|
3000
|
+
const customScrollParent = useEmitterValue$2("customScrollParent");
|
|
3001
|
+
const viewportRef = useWindowViewportRectRef(windowViewportRect, customScrollParent);
|
|
3002
|
+
React.useEffect(() => {
|
|
3003
|
+
if (ctx) {
|
|
3004
|
+
fixedItemHeight(ctx.itemHeight);
|
|
3005
|
+
windowViewportRect({ offsetTop: 0, visibleHeight: ctx.viewportHeight, visibleWidth: 100 });
|
|
3006
|
+
}
|
|
3007
|
+
}, [ctx, windowViewportRect, fixedItemHeight]);
|
|
3008
|
+
return /* @__PURE__ */ jsx("div", { ref: viewportRef, style: viewportStyle, "data-viewport-type": "window", children });
|
|
3009
|
+
};
|
|
3010
|
+
const TopItemListContainer = ({ children }) => {
|
|
3011
|
+
const TopItemList = useEmitterValue$2("TopItemListComponent");
|
|
3012
|
+
const headerHeight = useEmitterValue$2("headerHeight");
|
|
3013
|
+
const style = { ...topItemListStyle, marginTop: `${headerHeight}px` };
|
|
3014
|
+
const context = useEmitterValue$2("context");
|
|
3015
|
+
return createElement(TopItemList || "div", { style, context }, children);
|
|
3016
|
+
};
|
|
3017
|
+
const ListRoot = /* @__PURE__ */ React.memo(function VirtuosoRoot(props) {
|
|
3018
|
+
const useWindowScroll = useEmitterValue$2("useWindowScroll");
|
|
3019
|
+
const showTopList = useEmitterValue$2("topItemsIndexes").length > 0;
|
|
3020
|
+
const customScrollParent = useEmitterValue$2("customScrollParent");
|
|
3021
|
+
const TheScroller = customScrollParent || useWindowScroll ? WindowScroller$2 : Scroller$2;
|
|
3022
|
+
const TheViewport = customScrollParent || useWindowScroll ? WindowViewport$2 : Viewport$2;
|
|
3023
|
+
return /* @__PURE__ */ jsxs(TheScroller, { ...props, children: [
|
|
3024
|
+
showTopList && /* @__PURE__ */ jsx(TopItemListContainer, { children: /* @__PURE__ */ jsx(Items$1, { showTopList: true }) }),
|
|
3025
|
+
/* @__PURE__ */ jsxs(TheViewport, { children: [
|
|
3026
|
+
/* @__PURE__ */ jsx(Header$1, {}),
|
|
3027
|
+
/* @__PURE__ */ jsx(Items$1, {}),
|
|
3028
|
+
/* @__PURE__ */ jsx(Footer$1, {})
|
|
3029
|
+
] })
|
|
3030
|
+
] });
|
|
3031
|
+
});
|
|
3032
|
+
const {
|
|
3033
|
+
Component: List,
|
|
3034
|
+
usePublisher: usePublisher$2,
|
|
3035
|
+
useEmitterValue: useEmitterValue$2,
|
|
3036
|
+
useEmitter: useEmitter$2
|
|
3037
|
+
} = /* @__PURE__ */ systemToComponent(
|
|
3038
|
+
combinedSystem$2,
|
|
3039
|
+
{
|
|
3040
|
+
required: {},
|
|
3041
|
+
optional: {
|
|
3042
|
+
context: "context",
|
|
3043
|
+
followOutput: "followOutput",
|
|
3044
|
+
firstItemIndex: "firstItemIndex",
|
|
3045
|
+
itemContent: "itemContent",
|
|
3046
|
+
groupContent: "groupContent",
|
|
3047
|
+
overscan: "overscan",
|
|
3048
|
+
increaseViewportBy: "increaseViewportBy",
|
|
3049
|
+
totalCount: "totalCount",
|
|
3050
|
+
topItemCount: "topItemCount",
|
|
3051
|
+
initialTopMostItemIndex: "initialTopMostItemIndex",
|
|
3052
|
+
components: "components",
|
|
3053
|
+
groupCounts: "groupCounts",
|
|
3054
|
+
atBottomThreshold: "atBottomThreshold",
|
|
3055
|
+
atTopThreshold: "atTopThreshold",
|
|
3056
|
+
computeItemKey: "computeItemKey",
|
|
3057
|
+
defaultItemHeight: "defaultItemHeight",
|
|
3058
|
+
fixedItemHeight: "fixedItemHeight",
|
|
3059
|
+
itemSize: "itemSize",
|
|
3060
|
+
scrollSeekConfiguration: "scrollSeekConfiguration",
|
|
3061
|
+
headerFooterTag: "headerFooterTag",
|
|
3062
|
+
data: "data",
|
|
3063
|
+
initialItemCount: "initialItemCount",
|
|
3064
|
+
initialScrollTop: "initialScrollTop",
|
|
3065
|
+
alignToBottom: "alignToBottom",
|
|
3066
|
+
useWindowScroll: "useWindowScroll",
|
|
3067
|
+
customScrollParent: "customScrollParent",
|
|
3068
|
+
scrollerRef: "scrollerRef",
|
|
3069
|
+
logLevel: "logLevel"
|
|
3070
|
+
},
|
|
3071
|
+
methods: {
|
|
3072
|
+
scrollToIndex: "scrollToIndex",
|
|
3073
|
+
scrollIntoView: "scrollIntoView",
|
|
3074
|
+
scrollTo: "scrollTo",
|
|
3075
|
+
scrollBy: "scrollBy",
|
|
3076
|
+
autoscrollToBottom: "autoscrollToBottom"
|
|
3077
|
+
},
|
|
3078
|
+
events: {
|
|
3079
|
+
isScrolling: "isScrolling",
|
|
3080
|
+
endReached: "endReached",
|
|
3081
|
+
startReached: "startReached",
|
|
3082
|
+
rangeChanged: "rangeChanged",
|
|
3083
|
+
atBottomStateChange: "atBottomStateChange",
|
|
3084
|
+
atTopStateChange: "atTopStateChange",
|
|
3085
|
+
totalListHeightChanged: "totalListHeightChanged",
|
|
3086
|
+
itemsRendered: "itemsRendered",
|
|
3087
|
+
groupIndices: "groupIndices"
|
|
3088
|
+
}
|
|
3089
|
+
},
|
|
3090
|
+
ListRoot
|
|
3091
|
+
);
|
|
3092
|
+
const Scroller$2 = /* @__PURE__ */ buildScroller({ usePublisher: usePublisher$2, useEmitterValue: useEmitterValue$2, useEmitter: useEmitter$2 });
|
|
3093
|
+
const WindowScroller$2 = /* @__PURE__ */ buildWindowScroller({ usePublisher: usePublisher$2, useEmitterValue: useEmitterValue$2, useEmitter: useEmitter$2 });
|
|
3094
|
+
const Virtuoso = List;
|
|
3095
|
+
const GroupedVirtuoso = List;
|
|
3096
|
+
const INITIAL_GRID_STATE = {
|
|
3097
|
+
items: [],
|
|
3098
|
+
offsetBottom: 0,
|
|
3099
|
+
offsetTop: 0,
|
|
3100
|
+
top: 0,
|
|
3101
|
+
bottom: 0,
|
|
3102
|
+
itemHeight: 0,
|
|
3103
|
+
itemWidth: 0
|
|
3104
|
+
};
|
|
3105
|
+
const PROBE_GRID_STATE = {
|
|
3106
|
+
items: [{ index: 0 }],
|
|
3107
|
+
offsetBottom: 0,
|
|
3108
|
+
offsetTop: 0,
|
|
3109
|
+
top: 0,
|
|
3110
|
+
bottom: 0,
|
|
3111
|
+
itemHeight: 0,
|
|
3112
|
+
itemWidth: 0
|
|
3113
|
+
};
|
|
3114
|
+
const { round, ceil, floor, min, max } = Math;
|
|
3115
|
+
function buildProbeGridState(items) {
|
|
3116
|
+
return {
|
|
3117
|
+
...PROBE_GRID_STATE,
|
|
3118
|
+
items
|
|
3119
|
+
};
|
|
3120
|
+
}
|
|
3121
|
+
function buildItems(startIndex, endIndex, data) {
|
|
3122
|
+
return Array.from({ length: endIndex - startIndex + 1 }).map(
|
|
3123
|
+
(_, i) => ({ index: i + startIndex, data: data == null ? void 0 : data[i + startIndex] })
|
|
3124
|
+
);
|
|
3125
|
+
}
|
|
3126
|
+
function gapComparator(prev, next) {
|
|
3127
|
+
return prev && prev.column === next.column && prev.row === next.row;
|
|
3128
|
+
}
|
|
3129
|
+
const gridSystem = /* @__PURE__ */ system(
|
|
3130
|
+
([
|
|
3131
|
+
{ overscan, visibleRange, listBoundary },
|
|
3132
|
+
{ scrollTop, viewportHeight, scrollBy, scrollTo, smoothScrollTargetReached, scrollContainerState, footerHeight, headerHeight },
|
|
3133
|
+
stateFlags,
|
|
3134
|
+
scrollSeek,
|
|
3135
|
+
{ propsReady, didMount },
|
|
3136
|
+
{ windowViewportRect, windowScrollTo, useWindowScroll, customScrollParent, windowScrollContainerState },
|
|
3137
|
+
log
|
|
3138
|
+
]) => {
|
|
3139
|
+
const totalCount = statefulStream(0);
|
|
3140
|
+
const initialItemCount = statefulStream(0);
|
|
3141
|
+
const gridState = statefulStream(INITIAL_GRID_STATE);
|
|
3142
|
+
const viewportDimensions = statefulStream({ height: 0, width: 0 });
|
|
3143
|
+
const itemDimensions = statefulStream({ height: 0, width: 0 });
|
|
3144
|
+
const scrollToIndex = stream();
|
|
3145
|
+
const scrollHeight = stream();
|
|
3146
|
+
const deviation = statefulStream(0);
|
|
3147
|
+
const data = statefulStream(void 0);
|
|
3148
|
+
const gap = statefulStream({ row: 0, column: 0 });
|
|
3149
|
+
connect(
|
|
3150
|
+
pipe(
|
|
3151
|
+
combineLatest(didMount, initialItemCount, data),
|
|
3152
|
+
filter(([, count]) => count !== 0),
|
|
3153
|
+
map(([, count, data2]) => {
|
|
3154
|
+
return {
|
|
3155
|
+
items: buildItems(0, count - 1, data2),
|
|
3156
|
+
top: 0,
|
|
3157
|
+
bottom: 0,
|
|
3158
|
+
offsetBottom: 0,
|
|
3159
|
+
offsetTop: 0,
|
|
3160
|
+
itemHeight: 0,
|
|
3161
|
+
itemWidth: 0
|
|
3162
|
+
};
|
|
3163
|
+
})
|
|
3164
|
+
),
|
|
3165
|
+
gridState
|
|
3166
|
+
);
|
|
3167
|
+
connect(
|
|
3168
|
+
pipe(
|
|
3169
|
+
combineLatest(
|
|
3170
|
+
duc(totalCount),
|
|
3171
|
+
visibleRange,
|
|
3172
|
+
duc(gap, gapComparator),
|
|
3173
|
+
duc(itemDimensions, (prev, next) => prev && prev.width === next.width && prev.height === next.height),
|
|
3174
|
+
data
|
|
3175
|
+
),
|
|
3176
|
+
withLatestFrom(viewportDimensions),
|
|
3177
|
+
map(([[totalCount2, [startOffset, endOffset], gap2, item, data2], viewport]) => {
|
|
3178
|
+
const { row: rowGap, column: columnGap } = gap2;
|
|
3179
|
+
const { height: itemHeight, width: itemWidth } = item;
|
|
3180
|
+
const { width: viewportWidth } = viewport;
|
|
3181
|
+
if (totalCount2 === 0 || viewportWidth === 0) {
|
|
3182
|
+
return INITIAL_GRID_STATE;
|
|
3183
|
+
}
|
|
3184
|
+
if (itemWidth === 0) {
|
|
3185
|
+
return buildProbeGridState(buildItems(0, 0, data2));
|
|
3186
|
+
}
|
|
3187
|
+
const perRow = itemsPerRow(viewportWidth, itemWidth, columnGap);
|
|
3188
|
+
let startIndex = perRow * floor((startOffset + rowGap) / (itemHeight + rowGap));
|
|
3189
|
+
let endIndex = perRow * ceil((endOffset + rowGap) / (itemHeight + rowGap)) - 1;
|
|
3190
|
+
endIndex = min(totalCount2 - 1, max(endIndex, perRow - 1));
|
|
3191
|
+
startIndex = min(endIndex, max(0, startIndex));
|
|
3192
|
+
const items = buildItems(startIndex, endIndex, data2);
|
|
3193
|
+
const { top, bottom } = gridLayout(viewport, gap2, item, items);
|
|
3194
|
+
const rowCount = ceil(totalCount2 / perRow);
|
|
3195
|
+
const totalHeight = rowCount * itemHeight + (rowCount - 1) * rowGap;
|
|
3196
|
+
const offsetBottom = totalHeight - bottom;
|
|
3197
|
+
return { items, offsetTop: top, offsetBottom, top, bottom, itemHeight, itemWidth };
|
|
3198
|
+
})
|
|
3199
|
+
),
|
|
3200
|
+
gridState
|
|
3201
|
+
);
|
|
3202
|
+
connect(
|
|
3203
|
+
pipe(
|
|
3204
|
+
data,
|
|
3205
|
+
filter((data2) => data2 !== void 0),
|
|
3206
|
+
map((data2) => data2.length)
|
|
3207
|
+
),
|
|
3208
|
+
totalCount
|
|
3209
|
+
);
|
|
3210
|
+
connect(
|
|
3211
|
+
pipe(
|
|
3212
|
+
viewportDimensions,
|
|
3213
|
+
map(({ height }) => height)
|
|
3214
|
+
),
|
|
3215
|
+
viewportHeight
|
|
3216
|
+
);
|
|
3217
|
+
connect(
|
|
3218
|
+
pipe(
|
|
3219
|
+
combineLatest(viewportDimensions, itemDimensions, gridState, gap),
|
|
3220
|
+
map(([viewportDimensions2, item, { items }, gap2]) => {
|
|
3221
|
+
const { top, bottom } = gridLayout(viewportDimensions2, gap2, item, items);
|
|
3222
|
+
return [top, bottom];
|
|
3223
|
+
}),
|
|
3224
|
+
distinctUntilChanged(tupleComparator)
|
|
3225
|
+
),
|
|
3226
|
+
listBoundary
|
|
3227
|
+
);
|
|
3228
|
+
const endReached = streamFromEmitter(
|
|
3229
|
+
pipe(
|
|
3230
|
+
duc(gridState),
|
|
3231
|
+
filter(({ items }) => items.length > 0),
|
|
3232
|
+
withLatestFrom(totalCount),
|
|
3233
|
+
filter(([{ items }, totalCount2]) => items[items.length - 1].index === totalCount2 - 1),
|
|
3234
|
+
map(([, totalCount2]) => totalCount2 - 1),
|
|
3235
|
+
distinctUntilChanged()
|
|
3236
|
+
)
|
|
3237
|
+
);
|
|
3238
|
+
const startReached = streamFromEmitter(
|
|
3239
|
+
pipe(
|
|
3240
|
+
duc(gridState),
|
|
3241
|
+
filter(({ items }) => {
|
|
3242
|
+
return items.length > 0 && items[0].index === 0;
|
|
3243
|
+
}),
|
|
3244
|
+
mapTo(0),
|
|
3245
|
+
distinctUntilChanged()
|
|
3246
|
+
)
|
|
3247
|
+
);
|
|
3248
|
+
const rangeChanged = streamFromEmitter(
|
|
3249
|
+
pipe(
|
|
3250
|
+
duc(gridState),
|
|
3251
|
+
filter(({ items }) => items.length > 0),
|
|
3252
|
+
map(({ items }) => {
|
|
3253
|
+
return {
|
|
3254
|
+
startIndex: items[0].index,
|
|
3255
|
+
endIndex: items[items.length - 1].index
|
|
3256
|
+
};
|
|
3257
|
+
}),
|
|
3258
|
+
distinctUntilChanged(rangeComparator)
|
|
3259
|
+
)
|
|
3260
|
+
);
|
|
3261
|
+
connect(rangeChanged, scrollSeek.scrollSeekRangeChanged);
|
|
3262
|
+
connect(
|
|
3263
|
+
pipe(
|
|
3264
|
+
scrollToIndex,
|
|
3265
|
+
withLatestFrom(viewportDimensions, itemDimensions, totalCount, gap),
|
|
3266
|
+
map(([location, viewport, item, totalCount2, gap2]) => {
|
|
3267
|
+
const normalLocation = normalizeIndexLocation(location);
|
|
3268
|
+
const { align, behavior, offset } = normalLocation;
|
|
3269
|
+
let index = normalLocation.index;
|
|
3270
|
+
if (index === "LAST") {
|
|
3271
|
+
index = totalCount2 - 1;
|
|
3272
|
+
}
|
|
3273
|
+
index = max(0, index, min(totalCount2 - 1, index));
|
|
3274
|
+
let top = itemTop(viewport, gap2, item, index);
|
|
3275
|
+
if (align === "end") {
|
|
3276
|
+
top = round(top - viewport.height + item.height);
|
|
3277
|
+
} else if (align === "center") {
|
|
3278
|
+
top = round(top - viewport.height / 2 + item.height / 2);
|
|
3279
|
+
}
|
|
3280
|
+
if (offset) {
|
|
3281
|
+
top += offset;
|
|
3282
|
+
}
|
|
3283
|
+
return { top, behavior };
|
|
3284
|
+
})
|
|
3285
|
+
),
|
|
3286
|
+
scrollTo
|
|
3287
|
+
);
|
|
3288
|
+
const totalListHeight = statefulStreamFromEmitter(
|
|
3289
|
+
pipe(
|
|
3290
|
+
gridState,
|
|
3291
|
+
map((gridState2) => {
|
|
3292
|
+
return gridState2.offsetBottom + gridState2.bottom;
|
|
3293
|
+
})
|
|
3294
|
+
),
|
|
3295
|
+
0
|
|
3296
|
+
);
|
|
3297
|
+
connect(
|
|
3298
|
+
pipe(
|
|
3299
|
+
windowViewportRect,
|
|
3300
|
+
map((viewportInfo) => ({ width: viewportInfo.visibleWidth, height: viewportInfo.visibleHeight }))
|
|
3301
|
+
),
|
|
3302
|
+
viewportDimensions
|
|
3303
|
+
);
|
|
3304
|
+
return {
|
|
3305
|
+
data,
|
|
3306
|
+
totalCount,
|
|
3307
|
+
viewportDimensions,
|
|
3308
|
+
itemDimensions,
|
|
3309
|
+
scrollTop,
|
|
3310
|
+
scrollHeight,
|
|
3311
|
+
overscan,
|
|
3312
|
+
scrollBy,
|
|
3313
|
+
scrollTo,
|
|
3314
|
+
scrollToIndex,
|
|
3315
|
+
smoothScrollTargetReached,
|
|
3316
|
+
windowViewportRect,
|
|
3317
|
+
windowScrollTo,
|
|
3318
|
+
useWindowScroll,
|
|
3319
|
+
customScrollParent,
|
|
3320
|
+
windowScrollContainerState,
|
|
3321
|
+
deviation,
|
|
3322
|
+
scrollContainerState,
|
|
3323
|
+
footerHeight,
|
|
3324
|
+
headerHeight,
|
|
3325
|
+
initialItemCount,
|
|
3326
|
+
gap,
|
|
3327
|
+
...scrollSeek,
|
|
3328
|
+
gridState,
|
|
3329
|
+
totalListHeight,
|
|
3330
|
+
...stateFlags,
|
|
3331
|
+
startReached,
|
|
3332
|
+
endReached,
|
|
3333
|
+
rangeChanged,
|
|
3334
|
+
propsReady,
|
|
3335
|
+
...log
|
|
3336
|
+
};
|
|
3337
|
+
},
|
|
3338
|
+
tup(sizeRangeSystem, domIOSystem, stateFlagsSystem, scrollSeekSystem, propsReadySystem, windowScrollerSystem, loggerSystem)
|
|
3339
|
+
);
|
|
3340
|
+
function gridLayout(viewport, gap, item, items) {
|
|
3341
|
+
const { height: itemHeight } = item;
|
|
3342
|
+
if (itemHeight === void 0 || items.length === 0) {
|
|
3343
|
+
return { top: 0, bottom: 0 };
|
|
3344
|
+
}
|
|
3345
|
+
const top = itemTop(viewport, gap, item, items[0].index);
|
|
3346
|
+
const bottom = itemTop(viewport, gap, item, items[items.length - 1].index) + itemHeight;
|
|
3347
|
+
return { top, bottom };
|
|
3348
|
+
}
|
|
3349
|
+
function itemTop(viewport, gap, item, index) {
|
|
3350
|
+
const perRow = itemsPerRow(viewport.width, item.width, gap.column);
|
|
3351
|
+
const rowCount = floor(index / perRow);
|
|
3352
|
+
const top = rowCount * item.height + max(0, rowCount - 1) * gap.row;
|
|
3353
|
+
return top > 0 ? top + gap.row : top;
|
|
3354
|
+
}
|
|
3355
|
+
function itemsPerRow(viewportWidth, itemWidth, gap) {
|
|
3356
|
+
return max(1, floor((viewportWidth + gap) / (itemWidth + gap)));
|
|
3357
|
+
}
|
|
3358
|
+
const gridComponentPropsSystem = /* @__PURE__ */ system(() => {
|
|
3359
|
+
const itemContent = statefulStream((index) => `Item ${index}`);
|
|
3360
|
+
const components = statefulStream({});
|
|
3361
|
+
const context = statefulStream(null);
|
|
3362
|
+
const itemClassName = statefulStream("virtuoso-grid-item");
|
|
3363
|
+
const listClassName = statefulStream("virtuoso-grid-list");
|
|
3364
|
+
const computeItemKey = statefulStream(identity);
|
|
3365
|
+
const headerFooterTag = statefulStream("div");
|
|
3366
|
+
const scrollerRef = statefulStream(noop);
|
|
3367
|
+
const distinctProp = (propName, defaultValue = null) => {
|
|
3368
|
+
return statefulStreamFromEmitter(
|
|
3369
|
+
pipe(
|
|
3370
|
+
components,
|
|
3371
|
+
map((components2) => components2[propName]),
|
|
3372
|
+
distinctUntilChanged()
|
|
3373
|
+
),
|
|
3374
|
+
defaultValue
|
|
3375
|
+
);
|
|
3376
|
+
};
|
|
3377
|
+
return {
|
|
3378
|
+
context,
|
|
3379
|
+
itemContent,
|
|
3380
|
+
components,
|
|
3381
|
+
computeItemKey,
|
|
3382
|
+
itemClassName,
|
|
3383
|
+
listClassName,
|
|
3384
|
+
headerFooterTag,
|
|
3385
|
+
scrollerRef,
|
|
3386
|
+
FooterComponent: distinctProp("Footer"),
|
|
3387
|
+
HeaderComponent: distinctProp("Header"),
|
|
3388
|
+
ListComponent: distinctProp("List", "div"),
|
|
3389
|
+
ItemComponent: distinctProp("Item", "div"),
|
|
3390
|
+
ScrollerComponent: distinctProp("Scroller", "div"),
|
|
3391
|
+
ScrollSeekPlaceholder: distinctProp("ScrollSeekPlaceholder", "div")
|
|
3392
|
+
};
|
|
3393
|
+
});
|
|
3394
|
+
const combinedSystem$1 = /* @__PURE__ */ system(([gridSystem2, gridComponentPropsSystem2]) => {
|
|
3395
|
+
return { ...gridSystem2, ...gridComponentPropsSystem2 };
|
|
3396
|
+
}, tup(gridSystem, gridComponentPropsSystem));
|
|
3397
|
+
const GridItems = /* @__PURE__ */ React.memo(function GridItems2() {
|
|
3398
|
+
const gridState = useEmitterValue$1("gridState");
|
|
3399
|
+
const listClassName = useEmitterValue$1("listClassName");
|
|
3400
|
+
const itemClassName = useEmitterValue$1("itemClassName");
|
|
3401
|
+
const itemContent = useEmitterValue$1("itemContent");
|
|
3402
|
+
const computeItemKey = useEmitterValue$1("computeItemKey");
|
|
3403
|
+
const isSeeking = useEmitterValue$1("isSeeking");
|
|
3404
|
+
const scrollHeightCallback = usePublisher$1("scrollHeight");
|
|
3405
|
+
const ItemComponent = useEmitterValue$1("ItemComponent");
|
|
3406
|
+
const ListComponent = useEmitterValue$1("ListComponent");
|
|
3407
|
+
const ScrollSeekPlaceholder = useEmitterValue$1("ScrollSeekPlaceholder");
|
|
3408
|
+
const context = useEmitterValue$1("context");
|
|
3409
|
+
const itemDimensions = usePublisher$1("itemDimensions");
|
|
3410
|
+
const gridGap = usePublisher$1("gap");
|
|
3411
|
+
const log = useEmitterValue$1("log");
|
|
3412
|
+
const listRef = useSize((el) => {
|
|
3413
|
+
const scrollHeight = el.parentElement.parentElement.scrollHeight;
|
|
3414
|
+
scrollHeightCallback(scrollHeight);
|
|
3415
|
+
const firstItem = el.firstChild;
|
|
3416
|
+
if (firstItem) {
|
|
3417
|
+
itemDimensions(firstItem.getBoundingClientRect());
|
|
3418
|
+
}
|
|
3419
|
+
gridGap({
|
|
3420
|
+
row: resolveGapValue("row-gap", getComputedStyle(el).rowGap, log),
|
|
3421
|
+
column: resolveGapValue("column-gap", getComputedStyle(el).columnGap, log)
|
|
3422
|
+
});
|
|
3423
|
+
});
|
|
3424
|
+
return createElement(
|
|
3425
|
+
ListComponent,
|
|
3426
|
+
{
|
|
3427
|
+
ref: listRef,
|
|
3428
|
+
className: listClassName,
|
|
3429
|
+
...contextPropIfNotDomElement(ListComponent, context),
|
|
3430
|
+
style: { paddingTop: gridState.offsetTop, paddingBottom: gridState.offsetBottom },
|
|
3431
|
+
"data-test-id": "virtuoso-item-list"
|
|
3432
|
+
},
|
|
3433
|
+
gridState.items.map((item) => {
|
|
3434
|
+
const key = computeItemKey(item.index, item.data, context);
|
|
3435
|
+
return isSeeking ? createElement(ScrollSeekPlaceholder, {
|
|
3436
|
+
key,
|
|
3437
|
+
...contextPropIfNotDomElement(ScrollSeekPlaceholder, context),
|
|
3438
|
+
index: item.index,
|
|
3439
|
+
height: gridState.itemHeight,
|
|
3440
|
+
width: gridState.itemWidth
|
|
3441
|
+
}) : createElement(
|
|
3442
|
+
ItemComponent,
|
|
3443
|
+
{ ...contextPropIfNotDomElement(ItemComponent, context), className: itemClassName, "data-index": item.index, key },
|
|
3444
|
+
itemContent(item.index, item.data, context)
|
|
3445
|
+
);
|
|
3446
|
+
})
|
|
3447
|
+
);
|
|
3448
|
+
});
|
|
3449
|
+
const Header = React.memo(function VirtuosoHeader2() {
|
|
3450
|
+
const Header2 = useEmitterValue$1("HeaderComponent");
|
|
3451
|
+
const headerHeight = usePublisher$1("headerHeight");
|
|
3452
|
+
const headerFooterTag = useEmitterValue$1("headerFooterTag");
|
|
3453
|
+
const ref = useSize((el) => headerHeight(correctItemSize(el, "height")));
|
|
3454
|
+
const context = useEmitterValue$1("context");
|
|
3455
|
+
return Header2 ? createElement(headerFooterTag, { ref }, createElement(Header2, contextPropIfNotDomElement(Header2, context))) : null;
|
|
3456
|
+
});
|
|
3457
|
+
const Footer = React.memo(function VirtuosoGridFooter() {
|
|
3458
|
+
const Footer2 = useEmitterValue$1("FooterComponent");
|
|
3459
|
+
const footerHeight = usePublisher$1("footerHeight");
|
|
3460
|
+
const headerFooterTag = useEmitterValue$1("headerFooterTag");
|
|
3461
|
+
const ref = useSize((el) => footerHeight(correctItemSize(el, "height")));
|
|
3462
|
+
const context = useEmitterValue$1("context");
|
|
3463
|
+
return Footer2 ? createElement(headerFooterTag, { ref }, createElement(Footer2, contextPropIfNotDomElement(Footer2, context))) : null;
|
|
3464
|
+
});
|
|
3465
|
+
const Viewport$1 = ({ children }) => {
|
|
3466
|
+
const ctx = useContext(VirtuosoGridMockContext);
|
|
3467
|
+
const itemDimensions = usePublisher$1("itemDimensions");
|
|
3468
|
+
const viewportDimensions = usePublisher$1("viewportDimensions");
|
|
3469
|
+
const viewportRef = useSize((el) => {
|
|
3470
|
+
viewportDimensions(el.getBoundingClientRect());
|
|
3471
|
+
});
|
|
3472
|
+
React.useEffect(() => {
|
|
3473
|
+
if (ctx) {
|
|
3474
|
+
viewportDimensions({ height: ctx.viewportHeight, width: ctx.viewportWidth });
|
|
3475
|
+
itemDimensions({ height: ctx.itemHeight, width: ctx.itemWidth });
|
|
3476
|
+
}
|
|
3477
|
+
}, [ctx, viewportDimensions, itemDimensions]);
|
|
3478
|
+
return /* @__PURE__ */ jsx("div", { style: viewportStyle, ref: viewportRef, children });
|
|
3479
|
+
};
|
|
3480
|
+
const WindowViewport$1 = ({ children }) => {
|
|
3481
|
+
const ctx = useContext(VirtuosoGridMockContext);
|
|
3482
|
+
const windowViewportRect = usePublisher$1("windowViewportRect");
|
|
3483
|
+
const itemDimensions = usePublisher$1("itemDimensions");
|
|
3484
|
+
const customScrollParent = useEmitterValue$1("customScrollParent");
|
|
3485
|
+
const viewportRef = useWindowViewportRectRef(windowViewportRect, customScrollParent);
|
|
3486
|
+
React.useEffect(() => {
|
|
3487
|
+
if (ctx) {
|
|
3488
|
+
itemDimensions({ height: ctx.itemHeight, width: ctx.itemWidth });
|
|
3489
|
+
windowViewportRect({ offsetTop: 0, visibleHeight: ctx.viewportHeight, visibleWidth: ctx.viewportWidth });
|
|
3490
|
+
}
|
|
3491
|
+
}, [ctx, windowViewportRect, itemDimensions]);
|
|
3492
|
+
return /* @__PURE__ */ jsx("div", { ref: viewportRef, style: viewportStyle, children });
|
|
3493
|
+
};
|
|
3494
|
+
const GridRoot = /* @__PURE__ */ React.memo(function GridRoot2({ ...props }) {
|
|
3495
|
+
const useWindowScroll = useEmitterValue$1("useWindowScroll");
|
|
3496
|
+
const customScrollParent = useEmitterValue$1("customScrollParent");
|
|
3497
|
+
const TheScroller = customScrollParent || useWindowScroll ? WindowScroller$1 : Scroller$1;
|
|
3498
|
+
const TheViewport = customScrollParent || useWindowScroll ? WindowViewport$1 : Viewport$1;
|
|
3499
|
+
return /* @__PURE__ */ jsx(TheScroller, { ...props, children: /* @__PURE__ */ jsxs(TheViewport, { children: [
|
|
3500
|
+
/* @__PURE__ */ jsx(Header, {}),
|
|
3501
|
+
/* @__PURE__ */ jsx(GridItems, {}),
|
|
3502
|
+
/* @__PURE__ */ jsx(Footer, {})
|
|
3503
|
+
] }) });
|
|
3504
|
+
});
|
|
3505
|
+
const {
|
|
3506
|
+
Component: Grid,
|
|
3507
|
+
usePublisher: usePublisher$1,
|
|
3508
|
+
useEmitterValue: useEmitterValue$1,
|
|
3509
|
+
useEmitter: useEmitter$1
|
|
3510
|
+
} = /* @__PURE__ */ systemToComponent(
|
|
3511
|
+
combinedSystem$1,
|
|
3512
|
+
{
|
|
3513
|
+
optional: {
|
|
3514
|
+
context: "context",
|
|
3515
|
+
totalCount: "totalCount",
|
|
3516
|
+
overscan: "overscan",
|
|
3517
|
+
itemContent: "itemContent",
|
|
3518
|
+
components: "components",
|
|
3519
|
+
computeItemKey: "computeItemKey",
|
|
3520
|
+
data: "data",
|
|
3521
|
+
initialItemCount: "initialItemCount",
|
|
3522
|
+
scrollSeekConfiguration: "scrollSeekConfiguration",
|
|
3523
|
+
headerFooterTag: "headerFooterTag",
|
|
3524
|
+
listClassName: "listClassName",
|
|
3525
|
+
itemClassName: "itemClassName",
|
|
3526
|
+
useWindowScroll: "useWindowScroll",
|
|
3527
|
+
customScrollParent: "customScrollParent",
|
|
3528
|
+
scrollerRef: "scrollerRef"
|
|
3529
|
+
},
|
|
3530
|
+
methods: {
|
|
3531
|
+
scrollTo: "scrollTo",
|
|
3532
|
+
scrollBy: "scrollBy",
|
|
3533
|
+
scrollToIndex: "scrollToIndex"
|
|
3534
|
+
},
|
|
3535
|
+
events: {
|
|
3536
|
+
isScrolling: "isScrolling",
|
|
3537
|
+
endReached: "endReached",
|
|
3538
|
+
startReached: "startReached",
|
|
3539
|
+
rangeChanged: "rangeChanged",
|
|
3540
|
+
atBottomStateChange: "atBottomStateChange",
|
|
3541
|
+
atTopStateChange: "atTopStateChange"
|
|
3542
|
+
}
|
|
3543
|
+
},
|
|
3544
|
+
GridRoot
|
|
3545
|
+
);
|
|
3546
|
+
const Scroller$1 = /* @__PURE__ */ buildScroller({ usePublisher: usePublisher$1, useEmitterValue: useEmitterValue$1, useEmitter: useEmitter$1 });
|
|
3547
|
+
const WindowScroller$1 = /* @__PURE__ */ buildWindowScroller({ usePublisher: usePublisher$1, useEmitterValue: useEmitterValue$1, useEmitter: useEmitter$1 });
|
|
3548
|
+
function resolveGapValue(property, value, log) {
|
|
3549
|
+
if (value !== "normal" && !(value == null ? void 0 : value.endsWith("px"))) {
|
|
3550
|
+
log(`${property} was not resolved to pixel value correctly`, value, LogLevel.WARN);
|
|
3551
|
+
}
|
|
3552
|
+
if (value === "normal") {
|
|
3553
|
+
return 0;
|
|
3554
|
+
}
|
|
3555
|
+
return parseInt(value ?? "0", 10);
|
|
3556
|
+
}
|
|
3557
|
+
const VirtuosoGrid = Grid;
|
|
3558
|
+
const tableComponentPropsSystem = /* @__PURE__ */ system(() => {
|
|
3559
|
+
const itemContent = statefulStream((index) => /* @__PURE__ */ jsxs("td", { children: [
|
|
3560
|
+
"Item $",
|
|
3561
|
+
index
|
|
3562
|
+
] }));
|
|
3563
|
+
const context = statefulStream(null);
|
|
3564
|
+
const fixedHeaderContent = statefulStream(null);
|
|
3565
|
+
const fixedFooterContent = statefulStream(null);
|
|
3566
|
+
const components = statefulStream({});
|
|
3567
|
+
const computeItemKey = statefulStream(identity);
|
|
3568
|
+
const scrollerRef = statefulStream(noop);
|
|
3569
|
+
const distinctProp = (propName, defaultValue = null) => {
|
|
3570
|
+
return statefulStreamFromEmitter(
|
|
3571
|
+
pipe(
|
|
3572
|
+
components,
|
|
3573
|
+
map((components2) => components2[propName]),
|
|
3574
|
+
distinctUntilChanged()
|
|
3575
|
+
),
|
|
3576
|
+
defaultValue
|
|
3577
|
+
);
|
|
3578
|
+
};
|
|
3579
|
+
return {
|
|
3580
|
+
context,
|
|
3581
|
+
itemContent,
|
|
3582
|
+
fixedHeaderContent,
|
|
3583
|
+
fixedFooterContent,
|
|
3584
|
+
components,
|
|
3585
|
+
computeItemKey,
|
|
3586
|
+
scrollerRef,
|
|
3587
|
+
TableComponent: distinctProp("Table", "table"),
|
|
3588
|
+
TableHeadComponent: distinctProp("TableHead", "thead"),
|
|
3589
|
+
TableFooterComponent: distinctProp("TableFoot", "tfoot"),
|
|
3590
|
+
TableBodyComponent: distinctProp("TableBody", "tbody"),
|
|
3591
|
+
TableRowComponent: distinctProp("TableRow", "tr"),
|
|
3592
|
+
ScrollerComponent: distinctProp("Scroller", "div"),
|
|
3593
|
+
EmptyPlaceholder: distinctProp("EmptyPlaceholder"),
|
|
3594
|
+
ScrollSeekPlaceholder: distinctProp("ScrollSeekPlaceholder"),
|
|
3595
|
+
FillerRow: distinctProp("FillerRow")
|
|
3596
|
+
};
|
|
3597
|
+
});
|
|
3598
|
+
const combinedSystem = /* @__PURE__ */ system(([listSystem2, propsSystem]) => {
|
|
3599
|
+
return { ...listSystem2, ...propsSystem };
|
|
3600
|
+
}, tup(listSystem, tableComponentPropsSystem));
|
|
3601
|
+
const DefaultScrollSeekPlaceholder = ({ height }) => /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { style: { height } }) });
|
|
3602
|
+
const DefaultFillerRow = ({ height }) => /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { style: { height, padding: 0, border: 0 } }) });
|
|
3603
|
+
const Items = /* @__PURE__ */ React.memo(function VirtuosoItems2() {
|
|
3604
|
+
const listState = useEmitterValue("listState");
|
|
3605
|
+
const sizeRanges = usePublisher("sizeRanges");
|
|
3606
|
+
const useWindowScroll = useEmitterValue("useWindowScroll");
|
|
3607
|
+
const customScrollParent = useEmitterValue("customScrollParent");
|
|
3608
|
+
const windowScrollContainerStateCallback = usePublisher("windowScrollContainerState");
|
|
3609
|
+
const _scrollContainerStateCallback = usePublisher("scrollContainerState");
|
|
3610
|
+
const scrollContainerStateCallback = customScrollParent || useWindowScroll ? windowScrollContainerStateCallback : _scrollContainerStateCallback;
|
|
3611
|
+
const itemContent = useEmitterValue("itemContent");
|
|
3612
|
+
const trackItemSizes = useEmitterValue("trackItemSizes");
|
|
3613
|
+
const itemSize = useEmitterValue("itemSize");
|
|
3614
|
+
const log = useEmitterValue("log");
|
|
3615
|
+
const { callbackRef, ref } = useChangedListContentsSizes(
|
|
3616
|
+
sizeRanges,
|
|
3617
|
+
itemSize,
|
|
3618
|
+
trackItemSizes,
|
|
3619
|
+
scrollContainerStateCallback,
|
|
3620
|
+
log,
|
|
3621
|
+
void 0,
|
|
3622
|
+
customScrollParent
|
|
3623
|
+
);
|
|
3624
|
+
const [deviation, setDeviation] = React.useState(0);
|
|
3625
|
+
useEmitter("deviation", (value) => {
|
|
3626
|
+
if (deviation !== value) {
|
|
3627
|
+
ref.current.style.marginTop = `${value}px`;
|
|
3628
|
+
setDeviation(value);
|
|
3629
|
+
}
|
|
3630
|
+
});
|
|
3631
|
+
const EmptyPlaceholder = useEmitterValue("EmptyPlaceholder");
|
|
3632
|
+
const ScrollSeekPlaceholder = useEmitterValue("ScrollSeekPlaceholder") || DefaultScrollSeekPlaceholder;
|
|
3633
|
+
const FillerRow = useEmitterValue("FillerRow") || DefaultFillerRow;
|
|
3634
|
+
const TableBodyComponent = useEmitterValue("TableBodyComponent");
|
|
3635
|
+
const TableRowComponent = useEmitterValue("TableRowComponent");
|
|
3636
|
+
const computeItemKey = useEmitterValue("computeItemKey");
|
|
3637
|
+
const isSeeking = useEmitterValue("isSeeking");
|
|
3638
|
+
const paddingTopAddition = useEmitterValue("paddingTopAddition");
|
|
3639
|
+
const firstItemIndex = useEmitterValue("firstItemIndex");
|
|
3640
|
+
const statefulTotalCount = useEmitterValue("statefulTotalCount");
|
|
3641
|
+
const context = useEmitterValue("context");
|
|
3642
|
+
if (statefulTotalCount === 0 && EmptyPlaceholder) {
|
|
3643
|
+
return createElement(EmptyPlaceholder, contextPropIfNotDomElement(EmptyPlaceholder, context));
|
|
3644
|
+
}
|
|
3645
|
+
const paddingTop = listState.offsetTop + paddingTopAddition + deviation;
|
|
3646
|
+
const paddingBottom = listState.offsetBottom;
|
|
3647
|
+
const paddingTopEl = paddingTop > 0 ? /* @__PURE__ */ jsx(FillerRow, { height: paddingTop }, "padding-top") : null;
|
|
3648
|
+
const paddingBottomEl = paddingBottom > 0 ? /* @__PURE__ */ jsx(FillerRow, { height: paddingBottom }, "padding-bottom") : null;
|
|
3649
|
+
const items = listState.items.map((item) => {
|
|
3650
|
+
const index = item.originalIndex;
|
|
3651
|
+
const key = computeItemKey(index + firstItemIndex, item.data, context);
|
|
3652
|
+
if (isSeeking) {
|
|
3653
|
+
return createElement(ScrollSeekPlaceholder, {
|
|
3654
|
+
...contextPropIfNotDomElement(ScrollSeekPlaceholder, context),
|
|
3655
|
+
key,
|
|
3656
|
+
index: item.index,
|
|
3657
|
+
height: item.size,
|
|
3658
|
+
type: item.type || "item"
|
|
3659
|
+
});
|
|
3660
|
+
}
|
|
3661
|
+
return createElement(
|
|
3662
|
+
TableRowComponent,
|
|
3663
|
+
{
|
|
3664
|
+
...contextPropIfNotDomElement(TableRowComponent, context),
|
|
3665
|
+
key,
|
|
3666
|
+
"data-index": index,
|
|
3667
|
+
"data-known-size": item.size,
|
|
3668
|
+
"data-item-index": item.index,
|
|
3669
|
+
item: item.data,
|
|
3670
|
+
style: { overflowAnchor: "none" }
|
|
3671
|
+
},
|
|
3672
|
+
itemContent(item.index, item.data, context)
|
|
3673
|
+
);
|
|
3674
|
+
});
|
|
3675
|
+
return createElement(
|
|
3676
|
+
TableBodyComponent,
|
|
3677
|
+
{ ref: callbackRef, "data-test-id": "virtuoso-item-list", ...contextPropIfNotDomElement(TableBodyComponent, context) },
|
|
3678
|
+
[paddingTopEl, ...items, paddingBottomEl]
|
|
3679
|
+
);
|
|
3680
|
+
});
|
|
3681
|
+
const Viewport = ({ children }) => {
|
|
3682
|
+
const ctx = useContext(VirtuosoMockContext);
|
|
3683
|
+
const viewportHeight = usePublisher("viewportHeight");
|
|
3684
|
+
const fixedItemHeight = usePublisher("fixedItemHeight");
|
|
3685
|
+
const viewportRef = useSize(compose(viewportHeight, (el) => correctItemSize(el, "height")));
|
|
3686
|
+
React.useEffect(() => {
|
|
3687
|
+
if (ctx) {
|
|
3688
|
+
viewportHeight(ctx.viewportHeight);
|
|
3689
|
+
fixedItemHeight(ctx.itemHeight);
|
|
3690
|
+
}
|
|
3691
|
+
}, [ctx, viewportHeight, fixedItemHeight]);
|
|
3692
|
+
return /* @__PURE__ */ jsx("div", { style: viewportStyle, ref: viewportRef, "data-viewport-type": "element", children });
|
|
3693
|
+
};
|
|
3694
|
+
const WindowViewport = ({ children }) => {
|
|
3695
|
+
const ctx = useContext(VirtuosoMockContext);
|
|
3696
|
+
const windowViewportRect = usePublisher("windowViewportRect");
|
|
3697
|
+
const fixedItemHeight = usePublisher("fixedItemHeight");
|
|
3698
|
+
const customScrollParent = useEmitterValue("customScrollParent");
|
|
3699
|
+
const viewportRef = useWindowViewportRectRef(windowViewportRect, customScrollParent);
|
|
3700
|
+
React.useEffect(() => {
|
|
3701
|
+
if (ctx) {
|
|
3702
|
+
fixedItemHeight(ctx.itemHeight);
|
|
3703
|
+
windowViewportRect({ offsetTop: 0, visibleHeight: ctx.viewportHeight, visibleWidth: 100 });
|
|
3704
|
+
}
|
|
3705
|
+
}, [ctx, windowViewportRect, fixedItemHeight]);
|
|
3706
|
+
return /* @__PURE__ */ jsx("div", { ref: viewportRef, style: viewportStyle, "data-viewport-type": "window", children });
|
|
3707
|
+
};
|
|
3708
|
+
const TableRoot = /* @__PURE__ */ React.memo(function TableVirtuosoRoot(props) {
|
|
3709
|
+
const useWindowScroll = useEmitterValue("useWindowScroll");
|
|
3710
|
+
const customScrollParent = useEmitterValue("customScrollParent");
|
|
3711
|
+
const fixedHeaderHeight = usePublisher("fixedHeaderHeight");
|
|
3712
|
+
const fixedFooterHeight = usePublisher("fixedFooterHeight");
|
|
3713
|
+
const fixedHeaderContent = useEmitterValue("fixedHeaderContent");
|
|
3714
|
+
const fixedFooterContent = useEmitterValue("fixedFooterContent");
|
|
3715
|
+
const context = useEmitterValue("context");
|
|
3716
|
+
const theadRef = useSize(compose(fixedHeaderHeight, (el) => correctItemSize(el, "height")));
|
|
3717
|
+
const tfootRef = useSize(compose(fixedFooterHeight, (el) => correctItemSize(el, "height")));
|
|
3718
|
+
const TheScroller = customScrollParent || useWindowScroll ? WindowScroller : Scroller;
|
|
3719
|
+
const TheViewport = customScrollParent || useWindowScroll ? WindowViewport : Viewport;
|
|
3720
|
+
const TheTable = useEmitterValue("TableComponent");
|
|
3721
|
+
const TheTHead = useEmitterValue("TableHeadComponent");
|
|
3722
|
+
const TheTFoot = useEmitterValue("TableFooterComponent");
|
|
3723
|
+
const theHead = fixedHeaderContent ? React.createElement(
|
|
3724
|
+
TheTHead,
|
|
3725
|
+
{
|
|
3726
|
+
key: "TableHead",
|
|
3727
|
+
style: { zIndex: 1, position: "sticky", top: 0 },
|
|
3728
|
+
ref: theadRef,
|
|
3729
|
+
...contextPropIfNotDomElement(TheTHead, context)
|
|
3730
|
+
},
|
|
3731
|
+
fixedHeaderContent()
|
|
3732
|
+
) : null;
|
|
3733
|
+
const theFoot = fixedFooterContent ? React.createElement(
|
|
3734
|
+
TheTFoot,
|
|
3735
|
+
{
|
|
3736
|
+
key: "TableFoot",
|
|
3737
|
+
style: { zIndex: 1, position: "sticky", bottom: 0 },
|
|
3738
|
+
ref: tfootRef,
|
|
3739
|
+
...contextPropIfNotDomElement(TheTFoot, context)
|
|
3740
|
+
},
|
|
3741
|
+
fixedFooterContent()
|
|
3742
|
+
) : null;
|
|
3743
|
+
return /* @__PURE__ */ jsx(TheScroller, { ...props, children: /* @__PURE__ */ jsx(TheViewport, { children: React.createElement(TheTable, { style: { borderSpacing: 0 }, ...contextPropIfNotDomElement(TheTable, context) }, [
|
|
3744
|
+
theHead,
|
|
3745
|
+
/* @__PURE__ */ jsx(Items, {}, "TableBody"),
|
|
3746
|
+
theFoot
|
|
3747
|
+
]) }) });
|
|
3748
|
+
});
|
|
3749
|
+
const {
|
|
3750
|
+
Component: Table,
|
|
3751
|
+
usePublisher,
|
|
3752
|
+
useEmitterValue,
|
|
3753
|
+
useEmitter
|
|
3754
|
+
} = /* @__PURE__ */ systemToComponent(
|
|
3755
|
+
combinedSystem,
|
|
3756
|
+
{
|
|
3757
|
+
required: {},
|
|
3758
|
+
optional: {
|
|
3759
|
+
context: "context",
|
|
3760
|
+
followOutput: "followOutput",
|
|
3761
|
+
firstItemIndex: "firstItemIndex",
|
|
3762
|
+
itemContent: "itemContent",
|
|
3763
|
+
fixedHeaderContent: "fixedHeaderContent",
|
|
3764
|
+
fixedFooterContent: "fixedFooterContent",
|
|
3765
|
+
overscan: "overscan",
|
|
3766
|
+
increaseViewportBy: "increaseViewportBy",
|
|
3767
|
+
totalCount: "totalCount",
|
|
3768
|
+
topItemCount: "topItemCount",
|
|
3769
|
+
initialTopMostItemIndex: "initialTopMostItemIndex",
|
|
3770
|
+
components: "components",
|
|
3771
|
+
groupCounts: "groupCounts",
|
|
3772
|
+
atBottomThreshold: "atBottomThreshold",
|
|
3773
|
+
atTopThreshold: "atTopThreshold",
|
|
3774
|
+
computeItemKey: "computeItemKey",
|
|
3775
|
+
defaultItemHeight: "defaultItemHeight",
|
|
3776
|
+
fixedItemHeight: "fixedItemHeight",
|
|
3777
|
+
itemSize: "itemSize",
|
|
3778
|
+
scrollSeekConfiguration: "scrollSeekConfiguration",
|
|
3779
|
+
data: "data",
|
|
3780
|
+
initialItemCount: "initialItemCount",
|
|
3781
|
+
initialScrollTop: "initialScrollTop",
|
|
3782
|
+
alignToBottom: "alignToBottom",
|
|
3783
|
+
useWindowScroll: "useWindowScroll",
|
|
3784
|
+
customScrollParent: "customScrollParent",
|
|
3785
|
+
scrollerRef: "scrollerRef",
|
|
3786
|
+
logLevel: "logLevel"
|
|
3787
|
+
},
|
|
3788
|
+
methods: {
|
|
3789
|
+
scrollToIndex: "scrollToIndex",
|
|
3790
|
+
scrollIntoView: "scrollIntoView",
|
|
3791
|
+
scrollTo: "scrollTo",
|
|
3792
|
+
scrollBy: "scrollBy"
|
|
3793
|
+
},
|
|
3794
|
+
events: {
|
|
3795
|
+
isScrolling: "isScrolling",
|
|
3796
|
+
endReached: "endReached",
|
|
3797
|
+
startReached: "startReached",
|
|
3798
|
+
rangeChanged: "rangeChanged",
|
|
3799
|
+
atBottomStateChange: "atBottomStateChange",
|
|
3800
|
+
atTopStateChange: "atTopStateChange",
|
|
3801
|
+
totalListHeightChanged: "totalListHeightChanged",
|
|
3802
|
+
itemsRendered: "itemsRendered",
|
|
3803
|
+
groupIndices: "groupIndices"
|
|
3804
|
+
}
|
|
3805
|
+
},
|
|
3806
|
+
TableRoot
|
|
3807
|
+
);
|
|
3808
|
+
const Scroller = /* @__PURE__ */ buildScroller({ usePublisher, useEmitterValue, useEmitter });
|
|
3809
|
+
const WindowScroller = /* @__PURE__ */ buildWindowScroller({ usePublisher, useEmitterValue, useEmitter });
|
|
3810
|
+
const TableVirtuoso = Table;
|
|
3811
|
+
export {
|
|
3812
|
+
GroupedVirtuoso,
|
|
3813
|
+
LogLevel,
|
|
3814
|
+
TableVirtuoso,
|
|
3815
|
+
Virtuoso,
|
|
3816
|
+
VirtuosoGrid,
|
|
3817
|
+
VirtuosoGridMockContext,
|
|
3818
|
+
VirtuosoMockContext
|
|
3819
|
+
};
|