react-cool-virtual
Advanced tools
Comparing version 0.0.22 to 0.0.23
# react-cool-virtual | ||
## 0.0.23 | ||
### Patch Changes | ||
- [#80](https://github.com/wellyshen/react-cool-virtual/pull/80) [`48ab76f`](https://github.com/wellyshen/react-cool-virtual/commit/48ab76f782eb229acf58895970adce61b7017696) Thanks [@wellyshen](https://github.com/wellyshen)! - fix: dynamic size scroll jumping | ||
## 0.0.22 | ||
@@ -4,0 +10,0 @@ |
@@ -186,2 +186,3 @@ 'use strict'; | ||
var scrollOffsetRef = react.useRef(0); | ||
var prevMeasureIdxRef = react.useRef(-1); | ||
var prevVStopRef = react.useRef(); | ||
@@ -445,3 +446,3 @@ var outerRef = react.useRef(null); | ||
if (measuredSize !== size || start !== prevEnd) { | ||
if (isScrolling && start < scrollOffset) scrollTo(scrollOffset + measuredSize - size); | ||
if (i < prevMeasureIdxRef.current && start < scrollOffset) scrollTo(scrollOffset + measuredSize - size); | ||
msDataRef.current[i] = getMeasure(i, measuredSize); | ||
@@ -452,2 +453,3 @@ handleScroll(scrollOffset, isScrolling, uxScrolling); | ||
prevMeasureIdxRef.current = i; | ||
(_rosRef$current$get = rosRef.current.get(target)) == null ? void 0 : _rosRef$current$get.disconnect(); | ||
@@ -454,0 +456,0 @@ rosRef.current.set(target, ro); |
@@ -1,2 +0,2 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var r,e,t=require("react");(e=r||(r={})).auto="auto",e.start="start",e.center="center",e.end="end";var n=function(r){return.5>r?4*r*r*r:(r-1)*(2*r-2)*(2*r-2)+1},u=function(r){return"number"==typeof r&&!Number.isNaN(r)},c=function(){return void 0!==performance?performance.now():Date.now()},o=function(r){var e=t.useRef(r);return e.current=r,e},i=function(r,e){var n=t.useRef(),u=o(r),i=t.useCallback((function(){n.current&&(cancelAnimationFrame(n.current),n.current=void 0)}),[]),a=t.useCallback((function(r){c()-r>=e?u.current():n.current=requestAnimationFrame((function(){return a(r)}))}),[u,e]);return[t.useCallback((function(){i(),a(c())}),[i,a]),i]},a="undefined"!=typeof window?t.useLayoutEffect:t.useEffect;exports.default=function(e){var s=e.itemCount,f=e.ssrItemCount,l=e.itemSize,v=void 0===l?50:l;l=e.horizontal;var d=e.overscanCount,h=void 0===d?1:d;d=e.useIsScrolling;var m=e.scrollDuration,g=void 0===m?500:m;m=void 0===(m=e.scrollEasingFunction)?n:m;var b=e.loadMoreThreshold,R=void 0===b?15:b;b=e.isItemLoaded;var p=e.loadMore,S=e.onScroll;e=e.onResize;var x=t.useState((function(){return function(r,e){if(!e)return[];var t=u(e)?[0,e-1]:e;e=t[1];var n=[];for(t=t[0];t<=e;t+=1)n[t]={index:t,start:0,width:0,size:u(r)?r:r(t,0),measureRef:function(){return null}};return n}(v,f)})),w=x[0],z=x[1],k=t.useRef(!1),C=t.useRef(!1),I=t.useRef(!1),M=t.useRef(0),y=t.useRef(new Map),F=t.useRef(0),O=t.useRef(),E=t.useRef(null),L=t.useRef(null),T=t.useRef({width:0,height:0}),A=t.useRef([]),q=t.useRef(!0),j=t.useRef(),N=t.useRef(b),D=o(p),_=o(m),B=o(v),P=o(d),G=o(S),H=o(e),J=l?"width":"height",K=l?"marginLeft":"marginTop",Q=l?"scrollLeft":"scrollTop",U=t.useCallback((function(r){var e,t=B.current;return null!=(e=t=u(t)?t:t(r,T.current.width))?e:50}),[B]),V=t.useCallback((function(r,e){var t,n=(null==(t=A.current[r-1])?void 0:t.end)||0;return{idx:r,start:n,end:n+e,size:e}}),[]),W=t.useCallback((function(r){void 0===r&&(r=!0);for(var e=0;e<s;e+=1)A.current[e]=V(e,r&&A.current[e]?A.current[e].size:U(e))}),[U,V,s]),X=t.useCallback((function(r){var e=A.current,t=0;if(k.current&&!C.current)for(;t<e.length&&e[t].start<((null==(n=e[t+1])?void 0:n.start)||0)&&e[t].start<r;){var n;t+=1}else t=function(r,e,t,n){for(;r<=e;){var u=(r+e)/2|0,c=n(u);if(t<c)e=u-1;else{if(!(t>c))return u;r=u+1}}return 0<r?r-1:0}(0,e.length-1,r,(function(r){return e[r].start}));for(var u=e[n=t].start;n<e.length&&u<r+T.current[J];){var c;u+=(null==(c=e[n+=1])?void 0:c.size)||0}return r=Math.max(t-h,0),c=e[r].start,{oStart:r,oStop:Math.min(n+h,e.length)-1,vStart:t,vStop:n-1,margin:c,innerSize:e[e.length-1].end-c}}),[h,J]),Y=t.useCallback((function(r,e){if(E.current){var t=F.current,n=(r=u(r)?{offset:r}:r).offset;if(r=r.smooth,u(n)&&n!==t)if(q.current=!1,r){var o=c();j.current=requestAnimationFrame((function r(){var u=Math.min((c()-o)/g,1);E.current[Q]=_.current(u)*(n-t)+t,1>u?j.current=requestAnimationFrame(r):e&&e()}))}else E.current[Q]=n,e&&e()}}),[_,g,Q]),Z=t.useCallback((function(e,t){var n=u(e)?{index:e}:e,c=n.index,o=n.align;if(o=void 0===o?r.auto:o,n=n.smooth,u(c)&&(C.current=!0,k.current&&W(),c=A.current[Math.max(0,Math.min(c,s-1))])){var i=c.start,a=c.end;c=c.size;var f=F.current,l=T.current[J];k.current&&f<=i&&f+l>=a&&t&&t();var v=i-l+c;switch(o){case r.start:f=i;break;case r.center:f=i-l/2+c/2;break;case r.end:f=v;break;default:f>=i?f=i:f+l<=a&&(f=v)}Y({offset:f,smooth:n},(function(){k.current?M.current<=10&&(f>=i||f+l<=a)?(setTimeout((function(){return Z(e,t)})),M.current+=1):(t&&t(),M.current=0):t&&t()}))}}),[s,W,Y,J]),$=(l=i((function(){return nr(F.current)}),150))[0],rr=l[1],er=(l=i((function(){C.current=!1,q.current=!0;for(var r=y.current.size-w.length,e=y.current[Symbol.iterator](),t=0;t<r;t+=1)y.current.delete(e.next().value[0])}),150))[0],tr=l[1],nr=t.useCallback((function(r,e,t){if(L.current)if(!D.current||I.current||N.current&&N.current(0)||D.current({startIndex:0,stopIndex:R-1,loadIndex:0,scrollOffset:r,userScroll:q.current}),I.current=!0,s){var n=X(r),u=n.oStart,c=n.oStop,o=n.vStart,i=n.vStop,a=n.margin;n=n.innerSize,L.current.style[K]=a+"px",L.current.style[J]=n+"px";var f=[];n=function(n){var u=A.current,c=u[n],o=c.start,i=c.size;f.push({index:n,start:o-a,size:i,width:T.current.width,isScrolling:t||void 0,measureRef:function(c){c&&new ResizeObserver((function(c,a){var s,f,l=(c=c[0].target).getBoundingClientRect()[J];if(l){var v=(null==(s=u[n-1])?void 0:s.end)||0;l===i&&o===v||(e&&o<r&&Y(r+l-i),A.current[n]=V(n,l),nr(r,e,t),k.current=!0),null==(f=y.current.get(c))||f.disconnect(),y.current.set(c,a)}else a.disconnect()})).observe(c)}})};for(var l=u;l<=c;l+=1)n(l);z((function(r){return function(r,e,t){if(r.length!==e.length)return!0;for(var n=function(n){if(Object.keys(r[n]).some((function(u){return!t[u]&&r[n][u]!==e[n][u]})))return{v:!0}},u=0;u<r.length;u+=1){var c=n(u);if("object"==typeof c)return c.v}return!1}(r,f,{measureRef:!0})?f:r})),e&&(G.current&&G.current({overscanStartIndex:u,overscanStopIndex:c,visibleStartIndex:o,visibleStopIndex:i,scrollOffset:r,scrollForward:r>F.current,userScroll:q.current}),c=(u=Math.floor((i+1)/R))*R,!D.current||i===O.current||N.current&&N.current(u)||D.current({startIndex:c,stopIndex:c+R-1,loadIndex:u,scrollOffset:r,userScroll:q.current}),O.current=i,t&&$(),er())}else z([])}),[X,V,s,D,R,K,G,$,er,Y,J]);return function(r,e,t){var n=o(e);a((function(){if(!r.current)return function(){return null};var e=new ResizeObserver((function(r){r=r[0].contentRect,n.current({width:r.width,height:r.height})}));return e.observe(r.current),function(){return e.disconnect()}}),[n,r].concat(t))}(E,(function(r){var e,t,n=T.current.width===r.width,u=null==(e=A.current[A.current.length-1])?void 0:e.end;T.current=r,W(n),nr(F.current),H.current&&H.current(r),r=null==(t=A.current[A.current.length-1])?void 0:t.end,(t=!n&&r/u)&&Y(F.current*t)}),[s,nr,W,H,Y]),a((function(){var r=E.current;if(!r)return function(){return null};var e=function(r){r=r.target[Q];var e=P.current;e="function"==typeof e?e(Math.abs(r-F.current)):e,nr(r,!0,e),F.current=r};r.addEventListener("scroll",e,{passive:!0});var t=y.current;return function(){rr(),tr(),j.current&&(cancelAnimationFrame(j.current),j.current=void 0),r.removeEventListener("scroll",e),t.forEach((function(r){return r.disconnect()})),t.clear()}}),[rr,tr,nr,Q,P]),{outerRef:E,innerRef:L,items:w,scrollTo:Y,scrollToItem:Z}}; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var r,e,t=require("react");(e=r||(r={})).auto="auto",e.start="start",e.center="center",e.end="end";var n=function(r){return.5>r?4*r*r*r:(r-1)*(2*r-2)*(2*r-2)+1},u=function(r){return"number"==typeof r&&!Number.isNaN(r)},c=function(){return void 0!==performance?performance.now():Date.now()},o=function(r){var e=t.useRef(r);return e.current=r,e},i=function(r,e){var n=t.useRef(),u=o(r),i=t.useCallback((function(){n.current&&(cancelAnimationFrame(n.current),n.current=void 0)}),[]),a=t.useCallback((function(r){c()-r>=e?u.current():n.current=requestAnimationFrame((function(){return a(r)}))}),[u,e]);return[t.useCallback((function(){i(),a(c())}),[i,a]),i]},a="undefined"!=typeof window?t.useLayoutEffect:t.useEffect;exports.default=function(e){var s=e.itemCount,f=e.ssrItemCount,l=e.itemSize,v=void 0===l?50:l;l=e.horizontal;var d=e.overscanCount,h=void 0===d?1:d;d=e.useIsScrolling;var m=e.scrollDuration,g=void 0===m?500:m;m=void 0===(m=e.scrollEasingFunction)?n:m;var R=e.loadMoreThreshold,b=void 0===R?15:R;R=e.isItemLoaded;var p=e.loadMore,S=e.onScroll;e=e.onResize;var x=t.useState((function(){return function(r,e){if(!e)return[];var t=u(e)?[0,e-1]:e;e=t[1];var n=[];for(t=t[0];t<=e;t+=1)n[t]={index:t,start:0,width:0,size:u(r)?r:r(t,0),measureRef:function(){return null}};return n}(v,f)})),w=x[0],z=x[1],k=t.useRef(!1),C=t.useRef(!1),I=t.useRef(!1),M=t.useRef(0),y=t.useRef(new Map),F=t.useRef(0),O=t.useRef(-1),E=t.useRef(),L=t.useRef(null),T=t.useRef(null),A=t.useRef({width:0,height:0}),q=t.useRef([]),j=t.useRef(!0),N=t.useRef(),D=t.useRef(R),_=o(p),B=o(m),P=o(v),G=o(d),H=o(S),J=o(e),K=l?"width":"height",Q=l?"marginLeft":"marginTop",U=l?"scrollLeft":"scrollTop",V=t.useCallback((function(r){var e,t=P.current;return null!=(e=t=u(t)?t:t(r,A.current.width))?e:50}),[P]),W=t.useCallback((function(r,e){var t,n=(null==(t=q.current[r-1])?void 0:t.end)||0;return{idx:r,start:n,end:n+e,size:e}}),[]),X=t.useCallback((function(r){void 0===r&&(r=!0);for(var e=0;e<s;e+=1)q.current[e]=W(e,r&&q.current[e]?q.current[e].size:V(e))}),[V,W,s]),Y=t.useCallback((function(r){var e=q.current,t=0;if(k.current&&!C.current)for(;t<e.length&&e[t].start<((null==(n=e[t+1])?void 0:n.start)||0)&&e[t].start<r;){var n;t+=1}else t=function(r,e,t,n){for(;r<=e;){var u=(r+e)/2|0,c=n(u);if(t<c)e=u-1;else{if(!(t>c))return u;r=u+1}}return 0<r?r-1:0}(0,e.length-1,r,(function(r){return e[r].start}));for(var u=e[n=t].start;n<e.length&&u<r+A.current[K];){var c;u+=(null==(c=e[n+=1])?void 0:c.size)||0}return r=Math.max(t-h,0),c=e[r].start,{oStart:r,oStop:Math.min(n+h,e.length)-1,vStart:t,vStop:n-1,margin:c,innerSize:e[e.length-1].end-c}}),[h,K]),Z=t.useCallback((function(r,e){if(L.current){var t=F.current,n=(r=u(r)?{offset:r}:r).offset;if(r=r.smooth,u(n)&&n!==t)if(j.current=!1,r){var o=c();N.current=requestAnimationFrame((function r(){var u=Math.min((c()-o)/g,1);L.current[U]=B.current(u)*(n-t)+t,1>u?N.current=requestAnimationFrame(r):e&&e()}))}else L.current[U]=n,e&&e()}}),[B,g,U]),$=t.useCallback((function(e,t){var n=u(e)?{index:e}:e,c=n.index,o=n.align;if(o=void 0===o?r.auto:o,n=n.smooth,u(c)&&(C.current=!0,k.current&&X(),c=q.current[Math.max(0,Math.min(c,s-1))])){var i=c.start,a=c.end;c=c.size;var f=F.current,l=A.current[K];k.current&&f<=i&&f+l>=a&&t&&t();var v=i-l+c;switch(o){case r.start:f=i;break;case r.center:f=i-l/2+c/2;break;case r.end:f=v;break;default:f>=i?f=i:f+l<=a&&(f=v)}Z({offset:f,smooth:n},(function(){k.current?M.current<=10&&(f>=i||f+l<=a)?(setTimeout((function(){return $(e,t)})),M.current+=1):(t&&t(),M.current=0):t&&t()}))}}),[s,X,Z,K]),rr=(l=i((function(){return ur(F.current)}),150))[0],er=l[1],tr=(l=i((function(){C.current=!1,j.current=!0;for(var r=y.current.size-w.length,e=y.current[Symbol.iterator](),t=0;t<r;t+=1)y.current.delete(e.next().value[0])}),150))[0],nr=l[1],ur=t.useCallback((function(r,e,t){if(T.current)if(!_.current||I.current||D.current&&D.current(0)||_.current({startIndex:0,stopIndex:b-1,loadIndex:0,scrollOffset:r,userScroll:j.current}),I.current=!0,s){var n=Y(r),u=n.oStart,c=n.oStop,o=n.vStart,i=n.vStop,a=n.margin;n=n.innerSize,T.current.style[Q]=a+"px",T.current.style[K]=n+"px";var f=[];n=function(n){var u=q.current,c=u[n],o=c.start,i=c.size;f.push({index:n,start:o-a,size:i,width:A.current.width,isScrolling:t||void 0,measureRef:function(c){c&&new ResizeObserver((function(c,a){var s,f,l=(c=c[0].target).getBoundingClientRect()[K];if(l){var v=(null==(s=u[n-1])?void 0:s.end)||0;l===i&&o===v||(n<O.current&&o<r&&Z(r+l-i),q.current[n]=W(n,l),ur(r,e,t),k.current=!0),O.current=n,null==(f=y.current.get(c))||f.disconnect(),y.current.set(c,a)}else a.disconnect()})).observe(c)}})};for(var l=u;l<=c;l+=1)n(l);z((function(r){return function(r,e,t){if(r.length!==e.length)return!0;for(var n=function(n){if(Object.keys(r[n]).some((function(u){return!t[u]&&r[n][u]!==e[n][u]})))return{v:!0}},u=0;u<r.length;u+=1){var c=n(u);if("object"==typeof c)return c.v}return!1}(r,f,{measureRef:!0})?f:r})),e&&(H.current&&H.current({overscanStartIndex:u,overscanStopIndex:c,visibleStartIndex:o,visibleStopIndex:i,scrollOffset:r,scrollForward:r>F.current,userScroll:j.current}),c=(u=Math.floor((i+1)/b))*b,!_.current||i===E.current||D.current&&D.current(u)||_.current({startIndex:c,stopIndex:c+b-1,loadIndex:u,scrollOffset:r,userScroll:j.current}),E.current=i,t&&rr(),tr())}else z([])}),[Y,W,s,_,b,Q,H,rr,tr,Z,K]);return function(r,e,t){var n=o(e);a((function(){if(!r.current)return function(){return null};var e=new ResizeObserver((function(r){r=r[0].contentRect,n.current({width:r.width,height:r.height})}));return e.observe(r.current),function(){return e.disconnect()}}),[n,r].concat(t))}(L,(function(r){var e,t,n=A.current.width===r.width,u=null==(e=q.current[q.current.length-1])?void 0:e.end;A.current=r,X(n),ur(F.current),J.current&&J.current(r),r=null==(t=q.current[q.current.length-1])?void 0:t.end,(t=!n&&r/u)&&Z(F.current*t)}),[s,ur,X,J,Z]),a((function(){var r=L.current;if(!r)return function(){return null};var e=function(r){r=r.target[U];var e=G.current;e="function"==typeof e?e(Math.abs(r-F.current)):e,ur(r,!0,e),F.current=r};r.addEventListener("scroll",e,{passive:!0});var t=y.current;return function(){er(),nr(),N.current&&(cancelAnimationFrame(N.current),N.current=void 0),r.removeEventListener("scroll",e),t.forEach((function(r){return r.disconnect()})),t.clear()}}),[er,nr,ur,U,G]),{outerRef:L,innerRef:T,items:w,scrollTo:Z,scrollToItem:$}}; | ||
//# sourceMappingURL=index.cjs.production.min.js.map |
@@ -182,2 +182,3 @@ import { useRef, useCallback, useLayoutEffect, useEffect, useState } from 'react'; | ||
var scrollOffsetRef = useRef(0); | ||
var prevMeasureIdxRef = useRef(-1); | ||
var prevVStopRef = useRef(); | ||
@@ -441,3 +442,3 @@ var outerRef = useRef(null); | ||
if (measuredSize !== size || start !== prevEnd) { | ||
if (isScrolling && start < scrollOffset) scrollTo(scrollOffset + measuredSize - size); | ||
if (i < prevMeasureIdxRef.current && start < scrollOffset) scrollTo(scrollOffset + measuredSize - size); | ||
msDataRef.current[i] = getMeasure(i, measuredSize); | ||
@@ -448,2 +449,3 @@ handleScroll(scrollOffset, isScrolling, uxScrolling); | ||
prevMeasureIdxRef.current = i; | ||
(_rosRef$current$get = rosRef.current.get(target)) == null ? void 0 : _rosRef$current$get.disconnect(); | ||
@@ -450,0 +452,0 @@ rosRef.current.set(target, ro); |
@@ -186,2 +186,3 @@ (function (global, factory) { | ||
var scrollOffsetRef = react.useRef(0); | ||
var prevMeasureIdxRef = react.useRef(-1); | ||
var prevVStopRef = react.useRef(); | ||
@@ -445,3 +446,3 @@ var outerRef = react.useRef(null); | ||
if (measuredSize !== size || start !== prevEnd) { | ||
if (isScrolling && start < scrollOffset) scrollTo(scrollOffset + measuredSize - size); | ||
if (i < prevMeasureIdxRef.current && start < scrollOffset) scrollTo(scrollOffset + measuredSize - size); | ||
msDataRef.current[i] = getMeasure(i, measuredSize); | ||
@@ -452,2 +453,3 @@ handleScroll(scrollOffset, isScrolling, uxScrolling); | ||
prevMeasureIdxRef.current = i; | ||
(_rosRef$current$get = rosRef.current.get(target)) == null ? void 0 : _rosRef$current$get.disconnect(); | ||
@@ -454,0 +456,0 @@ rosRef.current.set(target, ro); |
@@ -1,2 +0,2 @@ | ||
"use strict";!function(r,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],e):e((r="undefined"!=typeof globalThis?globalThis:r||self).ReactCoolVirtual={},r.React)}(this,(function(r,e){var t,n;(n=t||(t={})).auto="auto",n.start="start",n.center="center",n.end="end";var u=function(r){return.5>r?4*r*r*r:(r-1)*(2*r-2)*(2*r-2)+1},c=function(r){return"number"==typeof r&&!Number.isNaN(r)},o=function(){return void 0!==performance?performance.now():Date.now()},i=function(r){var t=e.useRef(r);return t.current=r,t},a=function(r,t){var n=e.useRef(),u=i(r),c=e.useCallback((function(){n.current&&(cancelAnimationFrame(n.current),n.current=void 0)}),[]),a=e.useCallback((function(r){o()-r>=t?u.current():n.current=requestAnimationFrame((function(){return a(r)}))}),[u,t]);return[e.useCallback((function(){c(),a(o())}),[c,a]),c]},s="undefined"!=typeof window?e.useLayoutEffect:e.useEffect;r.useVirtual=function(r){var n=r.itemCount,f=r.ssrItemCount,l=r.itemSize,d=void 0===l?50:l;l=r.horizontal;var v=r.overscanCount,h=void 0===v?1:v;v=r.useIsScrolling;var m=r.scrollDuration,g=void 0===m?500:m;m=void 0===(m=r.scrollEasingFunction)?u:m;var b=r.loadMoreThreshold,p=void 0===b?15:b;b=r.isItemLoaded;var R=r.loadMore,x=r.onScroll;r=r.onResize;var S=e.useState((function(){return function(r,e){if(!e)return[];var t=c(e)?[0,e-1]:e;e=t[1];var n=[];for(t=t[0];t<=e;t+=1)n[t]={index:t,start:0,width:0,size:c(r)?r:r(t,0),measureRef:function(){return null}};return n}(d,f)})),w=S[0],z=S[1],C=e.useRef(!1),k=e.useRef(!1),y=e.useRef(!1),I=e.useRef(0),M=e.useRef(new Map),T=e.useRef(0),F=e.useRef(),O=e.useRef(null),E=e.useRef(null),L=e.useRef({width:0,height:0}),A=e.useRef([]),j=e.useRef(!0),q=e.useRef(),N=e.useRef(b),D=i(R),V=i(m),_=i(d),B=i(v),P=i(x),G=i(r),H=l?"width":"height",J=l?"marginLeft":"marginTop",K=l?"scrollLeft":"scrollTop",Q=e.useCallback((function(r){var e,t=_.current;return null!=(e=t=c(t)?t:t(r,L.current.width))?e:50}),[_]),U=e.useCallback((function(r,e){var t,n=(null==(t=A.current[r-1])?void 0:t.end)||0;return{idx:r,start:n,end:n+e,size:e}}),[]),W=e.useCallback((function(r){void 0===r&&(r=!0);for(var e=0;e<n;e+=1)A.current[e]=U(e,r&&A.current[e]?A.current[e].size:Q(e))}),[Q,U,n]),X=e.useCallback((function(r){var e=A.current,t=0;if(C.current&&!k.current)for(;t<e.length&&e[t].start<((null==(n=e[t+1])?void 0:n.start)||0)&&e[t].start<r;){var n;t+=1}else t=function(r,e,t,n){for(;r<=e;){var u=(r+e)/2|0,c=n(u);if(t<c)e=u-1;else{if(!(t>c))return u;r=u+1}}return 0<r?r-1:0}(0,e.length-1,r,(function(r){return e[r].start}));for(var u=e[n=t].start;n<e.length&&u<r+L.current[H];){var c;u+=(null==(c=e[n+=1])?void 0:c.size)||0}return r=Math.max(t-h,0),c=e[r].start,{oStart:r,oStop:Math.min(n+h,e.length)-1,vStart:t,vStop:n-1,margin:c,innerSize:e[e.length-1].end-c}}),[h,H]),Y=e.useCallback((function(r,e){if(O.current){var t=T.current,n=(r=c(r)?{offset:r}:r).offset;if(r=r.smooth,c(n)&&n!==t)if(j.current=!1,r){var u=o();q.current=requestAnimationFrame((function r(){var c=Math.min((o()-u)/g,1);O.current[K]=V.current(c)*(n-t)+t,1>c?q.current=requestAnimationFrame(r):e&&e()}))}else O.current[K]=n,e&&e()}}),[V,g,K]),Z=e.useCallback((function(r,e){var u=c(r)?{index:r}:r,o=u.index,i=u.align;if(i=void 0===i?t.auto:i,u=u.smooth,c(o)&&(k.current=!0,C.current&&W(),o=A.current[Math.max(0,Math.min(o,n-1))])){var a=o.start,s=o.end;o=o.size;var f=T.current,l=L.current[H];C.current&&f<=a&&f+l>=s&&e&&e();var d=a-l+o;switch(i){case t.start:f=a;break;case t.center:f=a-l/2+o/2;break;case t.end:f=d;break;default:f>=a?f=a:f+l<=s&&(f=d)}Y({offset:f,smooth:u},(function(){C.current?10>=I.current&&(f>=a||f+l<=s)?(setTimeout((function(){return Z(r,e)})),I.current+=1):(e&&e(),I.current=0):e&&e()}))}}),[n,W,Y,H]),$=(l=a((function(){return nr(T.current)}),150))[0],rr=l[1],er=(l=a((function(){k.current=!1,j.current=!0;for(var r=M.current.size-w.length,e=M.current[Symbol.iterator](),t=0;t<r;t+=1)M.current.delete(e.next().value[0])}),150))[0],tr=l[1],nr=e.useCallback((function(r,e,t){if(E.current)if(!D.current||y.current||N.current&&N.current(0)||D.current({startIndex:0,stopIndex:p-1,loadIndex:0,scrollOffset:r,userScroll:j.current}),y.current=!0,n){var u=X(r),c=u.oStart,o=u.oStop,i=u.vStart,a=u.vStop,s=u.margin;u=u.innerSize,E.current.style[J]=s+"px",E.current.style[H]=u+"px";var f=[];u=function(n){var u=A.current,c=u[n],o=c.start,i=c.size;f.push({index:n,start:o-s,size:i,width:L.current.width,isScrolling:t||void 0,measureRef:function(c){c&&new ResizeObserver((function(c,a){var s,f,l=(c=c[0].target).getBoundingClientRect()[H];if(l){var d=(null==(s=u[n-1])?void 0:s.end)||0;l===i&&o===d||(e&&o<r&&Y(r+l-i),A.current[n]=U(n,l),nr(r,e,t),C.current=!0),null==(f=M.current.get(c))||f.disconnect(),M.current.set(c,a)}else a.disconnect()})).observe(c)}})};for(var l=c;l<=o;l+=1)u(l);z((function(r){return function(r,e,t){if(r.length!==e.length)return!0;for(var n=function(n){if(Object.keys(r[n]).some((function(u){return!t[u]&&r[n][u]!==e[n][u]})))return{v:!0}},u=0;u<r.length;u+=1){var c=n(u);if("object"==typeof c)return c.v}return!1}(r,f,{measureRef:!0})?f:r})),e&&(P.current&&P.current({overscanStartIndex:c,overscanStopIndex:o,visibleStartIndex:i,visibleStopIndex:a,scrollOffset:r,scrollForward:r>T.current,userScroll:j.current}),o=(c=Math.floor((a+1)/p))*p,!D.current||a===F.current||N.current&&N.current(c)||D.current({startIndex:o,stopIndex:o+p-1,loadIndex:c,scrollOffset:r,userScroll:j.current}),F.current=a,t&&$(),er())}else z([])}),[X,U,n,D,p,J,P,$,er,Y,H]);return function(r,e,t){var n=i(e);s((function(){if(!r.current)return function(){return null};var e=new ResizeObserver((function(r){r=r[0].contentRect,n.current({width:r.width,height:r.height})}));return e.observe(r.current),function(){return e.disconnect()}}),[n,r].concat(t))}(O,(function(r){var e,t,n=L.current.width===r.width,u=null==(e=A.current[A.current.length-1])?void 0:e.end;L.current=r,W(n),nr(T.current),G.current&&G.current(r),r=null==(t=A.current[A.current.length-1])?void 0:t.end,(t=!n&&r/u)&&Y(T.current*t)}),[n,nr,W,G,Y]),s((function(){var r=O.current;if(!r)return function(){return null};var e=function(r){r=r.target[K];var e=B.current;e="function"==typeof e?e(Math.abs(r-T.current)):e,nr(r,!0,e),T.current=r};r.addEventListener("scroll",e,{passive:!0});var t=M.current;return function(){rr(),tr(),q.current&&(cancelAnimationFrame(q.current),q.current=void 0),r.removeEventListener("scroll",e),t.forEach((function(r){return r.disconnect()})),t.clear()}}),[rr,tr,nr,K,B]),{outerRef:O,innerRef:E,items:w,scrollTo:Y,scrollToItem:Z}},Object.defineProperty(r,"__esModule",{value:!0})})); | ||
"use strict";!function(r,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],e):e((r="undefined"!=typeof globalThis?globalThis:r||self).ReactCoolVirtual={},r.React)}(this,(function(r,e){var t,n;(n=t||(t={})).auto="auto",n.start="start",n.center="center",n.end="end";var u=function(r){return.5>r?4*r*r*r:(r-1)*(2*r-2)*(2*r-2)+1},c=function(r){return"number"==typeof r&&!Number.isNaN(r)},o=function(){return void 0!==performance?performance.now():Date.now()},i=function(r){var t=e.useRef(r);return t.current=r,t},a=function(r,t){var n=e.useRef(),u=i(r),c=e.useCallback((function(){n.current&&(cancelAnimationFrame(n.current),n.current=void 0)}),[]),a=e.useCallback((function(r){o()-r>=t?u.current():n.current=requestAnimationFrame((function(){return a(r)}))}),[u,t]);return[e.useCallback((function(){c(),a(o())}),[c,a]),c]},s="undefined"!=typeof window?e.useLayoutEffect:e.useEffect;r.useVirtual=function(r){var n=r.itemCount,f=r.ssrItemCount,l=r.itemSize,d=void 0===l?50:l;l=r.horizontal;var v=r.overscanCount,h=void 0===v?1:v;v=r.useIsScrolling;var m=r.scrollDuration,g=void 0===m?500:m;m=void 0===(m=r.scrollEasingFunction)?u:m;var b=r.loadMoreThreshold,p=void 0===b?15:b;b=r.isItemLoaded;var R=r.loadMore,x=r.onScroll;r=r.onResize;var S=e.useState((function(){return function(r,e){if(!e)return[];var t=c(e)?[0,e-1]:e;e=t[1];var n=[];for(t=t[0];t<=e;t+=1)n[t]={index:t,start:0,width:0,size:c(r)?r:r(t,0),measureRef:function(){return null}};return n}(d,f)})),w=S[0],z=S[1],C=e.useRef(!1),k=e.useRef(!1),y=e.useRef(!1),I=e.useRef(0),M=e.useRef(new Map),T=e.useRef(0),F=e.useRef(-1),O=e.useRef(),E=e.useRef(null),L=e.useRef(null),A=e.useRef({width:0,height:0}),j=e.useRef([]),q=e.useRef(!0),N=e.useRef(),D=e.useRef(b),V=i(R),_=i(m),B=i(d),P=i(v),G=i(x),H=i(r),J=l?"width":"height",K=l?"marginLeft":"marginTop",Q=l?"scrollLeft":"scrollTop",U=e.useCallback((function(r){var e,t=B.current;return null!=(e=t=c(t)?t:t(r,A.current.width))?e:50}),[B]),W=e.useCallback((function(r,e){var t,n=(null==(t=j.current[r-1])?void 0:t.end)||0;return{idx:r,start:n,end:n+e,size:e}}),[]),X=e.useCallback((function(r){void 0===r&&(r=!0);for(var e=0;e<n;e+=1)j.current[e]=W(e,r&&j.current[e]?j.current[e].size:U(e))}),[U,W,n]),Y=e.useCallback((function(r){var e=j.current,t=0;if(C.current&&!k.current)for(;t<e.length&&e[t].start<((null==(n=e[t+1])?void 0:n.start)||0)&&e[t].start<r;){var n;t+=1}else t=function(r,e,t,n){for(;r<=e;){var u=(r+e)/2|0,c=n(u);if(t<c)e=u-1;else{if(!(t>c))return u;r=u+1}}return 0<r?r-1:0}(0,e.length-1,r,(function(r){return e[r].start}));for(var u=e[n=t].start;n<e.length&&u<r+A.current[J];){var c;u+=(null==(c=e[n+=1])?void 0:c.size)||0}return r=Math.max(t-h,0),c=e[r].start,{oStart:r,oStop:Math.min(n+h,e.length)-1,vStart:t,vStop:n-1,margin:c,innerSize:e[e.length-1].end-c}}),[h,J]),Z=e.useCallback((function(r,e){if(E.current){var t=T.current,n=(r=c(r)?{offset:r}:r).offset;if(r=r.smooth,c(n)&&n!==t)if(q.current=!1,r){var u=o();N.current=requestAnimationFrame((function r(){var c=Math.min((o()-u)/g,1);E.current[Q]=_.current(c)*(n-t)+t,1>c?N.current=requestAnimationFrame(r):e&&e()}))}else E.current[Q]=n,e&&e()}}),[_,g,Q]),$=e.useCallback((function(r,e){var u=c(r)?{index:r}:r,o=u.index,i=u.align;if(i=void 0===i?t.auto:i,u=u.smooth,c(o)&&(k.current=!0,C.current&&X(),o=j.current[Math.max(0,Math.min(o,n-1))])){var a=o.start,s=o.end;o=o.size;var f=T.current,l=A.current[J];C.current&&f<=a&&f+l>=s&&e&&e();var d=a-l+o;switch(i){case t.start:f=a;break;case t.center:f=a-l/2+o/2;break;case t.end:f=d;break;default:f>=a?f=a:f+l<=s&&(f=d)}Z({offset:f,smooth:u},(function(){C.current?10>=I.current&&(f>=a||f+l<=s)?(setTimeout((function(){return $(r,e)})),I.current+=1):(e&&e(),I.current=0):e&&e()}))}}),[n,X,Z,J]),rr=(l=a((function(){return ur(T.current)}),150))[0],er=l[1],tr=(l=a((function(){k.current=!1,q.current=!0;for(var r=M.current.size-w.length,e=M.current[Symbol.iterator](),t=0;t<r;t+=1)M.current.delete(e.next().value[0])}),150))[0],nr=l[1],ur=e.useCallback((function(r,e,t){if(L.current)if(!V.current||y.current||D.current&&D.current(0)||V.current({startIndex:0,stopIndex:p-1,loadIndex:0,scrollOffset:r,userScroll:q.current}),y.current=!0,n){var u=Y(r),c=u.oStart,o=u.oStop,i=u.vStart,a=u.vStop,s=u.margin;u=u.innerSize,L.current.style[K]=s+"px",L.current.style[J]=u+"px";var f=[];u=function(n){var u=j.current,c=u[n],o=c.start,i=c.size;f.push({index:n,start:o-s,size:i,width:A.current.width,isScrolling:t||void 0,measureRef:function(c){c&&new ResizeObserver((function(c,a){var s,f,l=(c=c[0].target).getBoundingClientRect()[J];if(l){var d=(null==(s=u[n-1])?void 0:s.end)||0;l===i&&o===d||(n<F.current&&o<r&&Z(r+l-i),j.current[n]=W(n,l),ur(r,e,t),C.current=!0),F.current=n,null==(f=M.current.get(c))||f.disconnect(),M.current.set(c,a)}else a.disconnect()})).observe(c)}})};for(var l=c;l<=o;l+=1)u(l);z((function(r){return function(r,e,t){if(r.length!==e.length)return!0;for(var n=function(n){if(Object.keys(r[n]).some((function(u){return!t[u]&&r[n][u]!==e[n][u]})))return{v:!0}},u=0;u<r.length;u+=1){var c=n(u);if("object"==typeof c)return c.v}return!1}(r,f,{measureRef:!0})?f:r})),e&&(G.current&&G.current({overscanStartIndex:c,overscanStopIndex:o,visibleStartIndex:i,visibleStopIndex:a,scrollOffset:r,scrollForward:r>T.current,userScroll:q.current}),o=(c=Math.floor((a+1)/p))*p,!V.current||a===O.current||D.current&&D.current(c)||V.current({startIndex:o,stopIndex:o+p-1,loadIndex:c,scrollOffset:r,userScroll:q.current}),O.current=a,t&&rr(),tr())}else z([])}),[Y,W,n,V,p,K,G,rr,tr,Z,J]);return function(r,e,t){var n=i(e);s((function(){if(!r.current)return function(){return null};var e=new ResizeObserver((function(r){r=r[0].contentRect,n.current({width:r.width,height:r.height})}));return e.observe(r.current),function(){return e.disconnect()}}),[n,r].concat(t))}(E,(function(r){var e,t,n=A.current.width===r.width,u=null==(e=j.current[j.current.length-1])?void 0:e.end;A.current=r,X(n),ur(T.current),H.current&&H.current(r),r=null==(t=j.current[j.current.length-1])?void 0:t.end,(t=!n&&r/u)&&Z(T.current*t)}),[n,ur,X,H,Z]),s((function(){var r=E.current;if(!r)return function(){return null};var e=function(r){r=r.target[Q];var e=P.current;e="function"==typeof e?e(Math.abs(r-T.current)):e,ur(r,!0,e),T.current=r};r.addEventListener("scroll",e,{passive:!0});var t=M.current;return function(){er(),nr(),N.current&&(cancelAnimationFrame(N.current),N.current=void 0),r.removeEventListener("scroll",e),t.forEach((function(r){return r.disconnect()})),t.clear()}}),[er,nr,ur,Q,P]),{outerRef:E,innerRef:L,items:w,scrollTo:Z,scrollToItem:$}},Object.defineProperty(r,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=index.umd.production.min.js.map |
{ | ||
"name": "react-cool-virtual", | ||
"version": "0.0.22", | ||
"version": "0.0.23", | ||
"description": "A tiny React hook for rendering large datasets like a breeze.", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -35,7 +35,7 @@ <h4 align="center"><code><strong>🚧 Work in progress, most APIs are done. Not production ready yet, but you can try it!</strong></code></h4> | ||
- 🛹 Out of the box [smooth scrolling](#smooth-scrolling) and the effect is DIY-able. | ||
- ⛳ Provides `isScrolling` indicator to you for [performance optimization](#performance-optimization) or other purposes. | ||
- ⛳ Provides `isScrolling` indicator to you for [performance optimization](#use-isscrolling-indicator) or other purposes. | ||
- 🗄️ Supports [server-side rendering (SSR)](#server-side-rendering-ssr) for a fast [FP + FCP](https://developers.google.com/web/updates/2019/02/rendering-on-the-web#server-rendering) and better [SEO](https://developers.google.com/web/updates/2019/02/rendering-on-the-web#server-rendering). | ||
- 📜 Supports [TypeScript](#working-in-typescript) type definition. | ||
- 🎛 Super flexible [API](#api) design, built with DX in mind. | ||
- 🦔 Tiny size ([~ 2.8kB gzipped](https://bundlephobia.com/result?p=react-cool-virtual)). No external dependencies, aside for the `react`. | ||
- 🦔 Tiny size ([~ 2.7kB gzipped](https://bundlephobia.com/result?p=react-cool-virtual)). No external dependencies, aside for the `react`. | ||
@@ -295,3 +295,3 @@ ## Why? | ||
<div | ||
style={{ width: "300px", height: "400px", overflow: "auto" }} | ||
style={{ width: "100%", height: "400px", overflow: "auto" }} | ||
ref={outerRef} | ||
@@ -566,8 +566,96 @@ > | ||
> 💡 Please note, when using the `ssrItemCount`, the initial items will be the SSR items but it has no impact to the UX. In addition, you might notice that some styles (i.e. width, start) of the SSR items are set to `0`. It's by design, because there's no way to get the outer's size on SSR. However, you can make up these styles based on environment if you need. | ||
> 💡 Please note, when using the `ssrItemCount`, the initial items will be the SSR items but it has no impact to the UX. In addition, you might notice that some styles (i.e. width, start) of the SSR items are `0`. It's by design, because there's no way to know the outer's size on SSR. However, you can make up these styles based on the environments if you need. | ||
## Performance Optimization | ||
Coming soon... | ||
Items are re-rendered whenever the user scrolls. If your item is a **heavy data component**, there're two strategies for performance optimizing. | ||
### Use [React.memo](https://reactjs.org/docs/react-api.html#reactmemo) | ||
When working with **non-dynamic size**, we can extract the item to it's own component and wrap it with `React.memo`. It shallowly compares the current props and the next props to avoid unnecessary re-renders. | ||
```js | ||
import { memo } from "react"; | ||
import useVirtual from "react-cool-virtual"; | ||
const MemoizedItem = memo(({ height, ...rest }) => { | ||
// Some many heavy computing here... 🤪 | ||
return ( | ||
<div {...rest} style={{ height: `${height}px` }}> | ||
🐳 Am I heavy? | ||
</div> | ||
); | ||
}); | ||
const List = () => { | ||
const { outerRef, innerRef, items } = useVirtual({ | ||
itemCount: 1000, | ||
itemSize: 75, | ||
}); | ||
return ( | ||
<div | ||
style={{ width: "300px", height: "300px", overflow: "auto" }} | ||
ref={outerRef} | ||
> | ||
<div ref={innerRef}> | ||
{items.map(({ index, size }) => ( | ||
<MemoizedItem key={index} height={size} /> | ||
))} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
``` | ||
### Use `isScrolling` Indicator | ||
If the above solution can't meet your case or you're working with **dynamic size**. React Cool Virtual supplies you an `isScrolling` indicator that allows you to replace the heavy component with a light one while the user is scrolling. | ||
```js | ||
import { forwardRef } from "react"; | ||
import useVirtual from "react-cool-virtual"; | ||
const HeavyItem = forwardRef((props, ref) => { | ||
// Some many heavy computing here... 🤪 | ||
return ( | ||
<div {...props} ref={ref}> | ||
🐳 Am I heavy? | ||
</div> | ||
); | ||
}); | ||
const LightItem = (props) => <div {...props}>🦐 I believe I can fly...</div>; | ||
const List = () => { | ||
const { outerRef, innerRef, items } = useVirtual({ | ||
itemCount: 1000, | ||
useIsScrolling: true, // Just use it (default = false) | ||
// or | ||
useIsScrolling: (speed) => speed > 50, // Use it based on the scroll speed (more user friendly) | ||
}); | ||
return ( | ||
<div | ||
style={{ width: "300px", height: "300px", overflow: "auto" }} | ||
ref={outerRef} | ||
> | ||
<div ref={innerRef}> | ||
{items.map(({ index, isScrolling, measureRef }) => | ||
isScrolling ? ( | ||
<LightItem key={index} /> | ||
) : ( | ||
<HeavyItem key={index} ref={measureRef} /> | ||
) | ||
)} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
``` | ||
> 💡 Well... the `isScrolling` can also be used in many other ways, please use your imagination 🤗. | ||
## How to Share A `ref`? | ||
@@ -574,0 +662,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
286937
1591
761