UNPKG

react-tiny-virtual-list

Version:

A tiny but mighty list virtualization component, with zero dependencies 💪

2 lines (1 loc) • 10.5 kB
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react"),require("prop-types")):"function"==typeof define&&define.amd?define(["exports","react","prop-types"],e):e(t.VirtualList={},t.React,t.PropTypes)}(this,function(t,e,i){"use strict";function o(t,e){function i(){this.constructor=t}s(t,e),t.prototype=null===e?Object.create(e):(i.prototype=e.prototype,new i)}function n(t,e){var i={};for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&e.indexOf(o)<0&&(i[o]=t[o]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols)for(var n=0,o=Object.getOwnPropertySymbols(t);n<o.length;n++)e.indexOf(o[n])<0&&(i[o[n]]=t[o[n]]);return i}var r,s=function(t,e){return(s=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i])})(t,e)},l=function(){return(l=Object.assign||function(t){for(var e,i=1,o=arguments.length;i<o;i++){e=arguments[i];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])}return t}).apply(this,arguments)};!function(t){t.AUTO="auto",t.START="start",t.CENTER="center",t.END="end"}(r||(r={})),function(t){t.HORIZONTAL="horizontal",t.VERTICAL="vertical"}(t.ScrollDirection||(t.ScrollDirection={}));var a;!function(t){t.OBSERVED="observed",t.REQUESTED="requested"}(a||(a={}));var c,f,d,u,h,p=(c={},c[t.ScrollDirection.VERTICAL]="scrollTop",c[t.ScrollDirection.HORIZONTAL]="scrollLeft",c),m=(f={},f[t.ScrollDirection.VERTICAL]="height",f[t.ScrollDirection.HORIZONTAL]="width",f),S=(d={},d[t.ScrollDirection.VERTICAL]="top",d[t.ScrollDirection.HORIZONTAL]="left",d),I=(u={},u[t.ScrollDirection.VERTICAL]="marginTop",u[t.ScrollDirection.HORIZONTAL]="marginLeft",u),g=(h={},h[t.ScrollDirection.VERTICAL]="marginBottom",h[t.ScrollDirection.HORIZONTAL]="marginRight",h),z=function(){function t(t){var e=t.itemCount,i=t.itemSizeGetter,o=t.estimatedItemSize;this.itemSizeGetter=i,this.itemCount=e,this.estimatedItemSize=o,this.itemSizeAndPositionData={},this.lastMeasuredIndex=-1}return t.prototype.updateConfig=function(t){var e=t.itemCount,i=t.itemSizeGetter,o=t.estimatedItemSize;null!=e&&(this.itemCount=e),null!=o&&(this.estimatedItemSize=o),null!=i&&(this.itemSizeGetter=i)},t.prototype.getLastMeasuredIndex=function(){return this.lastMeasuredIndex},t.prototype.getSizeAndPositionForIndex=function(t){if(t<0||t>=this.itemCount)throw Error("Requested index "+t+" is outside of range 0.."+this.itemCount);if(t>this.lastMeasuredIndex){for(var e=this.getSizeAndPositionOfLastMeasuredItem(),i=e.offset+e.size,o=this.lastMeasuredIndex+1;o<=t;o++){var n=this.itemSizeGetter(o);if(null==n||isNaN(n))throw Error("Invalid size returned for index "+o+" of value "+n);this.itemSizeAndPositionData[o]={offset:i,size:n},i+=n}this.lastMeasuredIndex=t}return this.itemSizeAndPositionData[t]},t.prototype.getSizeAndPositionOfLastMeasuredItem=function(){return this.lastMeasuredIndex>=0?this.itemSizeAndPositionData[this.lastMeasuredIndex]:{offset:0,size:0}},t.prototype.getTotalSize=function(){var t=this.getSizeAndPositionOfLastMeasuredItem();return t.offset+t.size+(this.itemCount-this.lastMeasuredIndex-1)*this.estimatedItemSize},t.prototype.getUpdatedOffsetForIndex=function(t){var e=t.align,i=void 0===e?r.START:e,o=t.containerSize,n=t.currentOffset,s=t.targetIndex;if(o<=0)return 0;var l,a=this.getSizeAndPositionForIndex(s),c=a.offset,f=c-o+a.size;switch(i){case r.END:l=f;break;case r.CENTER:l=c-(o-a.size)/2;break;case r.START:l=c;break;default:l=Math.max(f,Math.min(c,n))}var d=this.getTotalSize();return Math.max(0,Math.min(d-o,l))},t.prototype.getVisibleRange=function(t){var e=t.containerSize,i=t.offset,o=t.overscanCount;if(0===this.getTotalSize())return{};var n=i+e,r=this.findNearestItem(i);if(void 0===r)throw Error("Invalid offset "+i+" specified");var s=this.getSizeAndPositionForIndex(r);i=s.offset+s.size;for(var l=r;i<n&&l<this.itemCount-1;)l++,i+=this.getSizeAndPositionForIndex(l).size;return o&&(r=Math.max(0,r-o),l=Math.min(l+o,this.itemCount-1)),{start:r,stop:l}},t.prototype.resetItem=function(t){this.lastMeasuredIndex=Math.min(this.lastMeasuredIndex,t-1)},t.prototype.findNearestItem=function(t){if(isNaN(t))throw Error("Invalid offset "+t+" specified");t=Math.max(0,t);var e=this.getSizeAndPositionOfLastMeasuredItem(),i=Math.max(0,this.lastMeasuredIndex);return e.offset>=t?this.binarySearch({high:i,low:0,offset:t}):this.exponentialSearch({index:i,offset:t})},t.prototype.binarySearch=function(t){for(var e=t.low,i=t.high,o=t.offset,n=0,r=0;e<=i;){if(n=e+Math.floor((i-e)/2),(r=this.getSizeAndPositionForIndex(n).offset)===o)return n;r<o?e=n+1:r>o&&(i=n-1)}return e>0?e-1:0},t.prototype.exponentialSearch=function(t){for(var e=t.index,i=t.offset,o=1;e<this.itemCount&&this.getSizeAndPositionForIndex(e).offset<i;)e+=o,o*=2;return this.binarySearch({high:Math.min(e,this.itemCount-1),low:Math.floor(e/2),offset:i})},t}(),y={overflow:"auto",willChange:"transform",WebkitOverflowScrolling:"touch"},v={position:"relative",width:"100%",minHeight:"100%"},T={position:"absolute",top:0,left:0,width:"100%"},O=l({},T,{position:"sticky"}),A=function(s){function c(){var t=null!==s&&s.apply(this,arguments)||this;return t.itemSizeGetter=function(e){return function(i){return t.getSize(i,e)}},t.sizeAndPositionManager=new z({itemCount:t.props.itemCount,itemSizeGetter:t.itemSizeGetter(t.props.itemSize),estimatedItemSize:t.getEstimatedItemSize()}),t.state={offset:t.props.scrollOffset||null!=t.props.scrollToIndex&&t.getOffsetForIndex(t.props.scrollToIndex)||0,scrollChangeReason:a.REQUESTED},t.styleCache={},t.getRef=function(e){t.rootNode=e},t.handleScroll=function(e){var i=t.props.onScroll,o=t.getNodeOffset();o<0||t.state.offset===o||e.target!==t.rootNode||(t.setState({offset:o,scrollChangeReason:a.OBSERVED}),"function"==typeof i&&i(o,e))},t}return o(c,s),c.prototype.componentDidMount=function(){var t=this.props,e=t.scrollOffset,i=t.scrollToIndex;this.rootNode.addEventListener("scroll",this.handleScroll,{passive:!0}),null!=e?this.scrollTo(e):null!=i&&this.scrollTo(this.getOffsetForIndex(i))},c.prototype.componentWillReceiveProps=function(t){var e=this.props,i=e.estimatedItemSize,o=e.itemCount,n=e.itemSize,r=e.scrollOffset,s=e.scrollToAlignment,l=e.scrollToIndex,c=t.scrollToIndex!==l||t.scrollToAlignment!==s,f=t.itemCount!==o||t.itemSize!==n||t.estimatedItemSize!==i;t.itemSize!==n&&this.sizeAndPositionManager.updateConfig({itemSizeGetter:this.itemSizeGetter(t.itemSize)}),t.itemCount===o&&t.estimatedItemSize===i||this.sizeAndPositionManager.updateConfig({itemCount:t.itemCount,estimatedItemSize:this.getEstimatedItemSize(t)}),f&&this.recomputeSizes(),t.scrollOffset!==r?this.setState({offset:t.scrollOffset||0,scrollChangeReason:a.REQUESTED}):"number"==typeof t.scrollToIndex&&(c||f)&&this.setState({offset:this.getOffsetForIndex(t.scrollToIndex,t.scrollToAlignment,t.itemCount),scrollChangeReason:a.REQUESTED})},c.prototype.componentDidUpdate=function(t,e){var i=this.state,o=i.offset,n=i.scrollChangeReason;e.offset!==o&&n===a.REQUESTED&&this.scrollTo(o)},c.prototype.componentWillUnmount=function(){this.rootNode.removeEventListener("scroll",this.handleScroll)},c.prototype.scrollTo=function(e){var i=this.props.scrollDirection,o=void 0===i?t.ScrollDirection.VERTICAL:i;this.rootNode[p[o]]=e},c.prototype.getOffsetForIndex=function(e,i,o){void 0===i&&(i=this.props.scrollToAlignment),void 0===o&&(o=this.props.itemCount);var n=this.props.scrollDirection,r=void 0===n?t.ScrollDirection.VERTICAL:n;return(e<0||e>=o)&&(e=0),this.sizeAndPositionManager.getUpdatedOffsetForIndex({align:i,containerSize:this.props[m[r]],currentOffset:this.state&&this.state.offset||0,targetIndex:e})},c.prototype.recomputeSizes=function(t){void 0===t&&(t=0),this.styleCache={},this.sizeAndPositionManager.resetItem(t)},c.prototype.render=function(){var i=this,o=this.props,r=(o.estimatedItemSize,o.height),s=o.overscanCount,a=void 0===s?3:s,c=o.renderItem,f=(o.itemCount,o.itemSize,o.onItemsRendered),d=(o.onScroll,o.scrollDirection),u=void 0===d?t.ScrollDirection.VERTICAL:d,h=(o.scrollOffset,o.scrollToIndex,o.scrollToAlignment,o.stickyIndices),p=o.style,S=o.width,I=n(o,["estimatedItemSize","height","overscanCount","renderItem","itemCount","itemSize","onItemsRendered","onScroll","scrollDirection","scrollOffset","scrollToIndex","scrollToAlignment","stickyIndices","style","width"]),g=this.state.offset,z=this.sizeAndPositionManager.getVisibleRange({containerSize:this.props[m[u]]||0,offset:g,overscanCount:a}),T=z.start,O=z.stop,A=[],x=l({},y,p,{height:r,width:S}),C=l({},v,(E={},E[m[u]]=this.sizeAndPositionManager.getTotalSize(),E));if(null!=h&&0!==h.length&&(h.forEach(function(t){return A.push(c({index:t,style:i.getStyle(t,!0)}))}),u===t.ScrollDirection.HORIZONTAL&&(C.display="flex")),void 0!==T&&void 0!==O){for(var R=T;R<=O;R++)null!=h&&h.includes(R)||A.push(c({index:R,style:this.getStyle(R,!1)}));"function"==typeof f&&f({startIndex:T,stopIndex:O})}return e.createElement("div",l({ref:this.getRef},I,{style:x}),e.createElement("div",{style:C},A));var E},c.prototype.getNodeOffset=function(){var e=this.props.scrollDirection,i=void 0===e?t.ScrollDirection.VERTICAL:e;return this.rootNode[p[i]]},c.prototype.getEstimatedItemSize=function(t){return void 0===t&&(t=this.props),t.estimatedItemSize||"number"==typeof t.itemSize&&t.itemSize||50},c.prototype.getSize=function(t,e){return"function"==typeof e?e(t):Array.isArray(e)?e[t]:e},c.prototype.getStyle=function(e,i){var o=this.styleCache[e];if(o)return o;var n=this.props.scrollDirection,r=void 0===n?t.ScrollDirection.VERTICAL:n,s=this.sizeAndPositionManager.getSizeAndPositionForIndex(e),a=s.size,c=s.offset;return this.styleCache[e]=i?l({},O,(f={},f[m[r]]=a,f[I[r]]=c,f[g[r]]=-(c+a),f.zIndex=1,f)):l({},T,(d={},d[m[r]]=a,d[S[r]]=c,d));var f,d},c.defaultProps={overscanCount:3,scrollDirection:t.ScrollDirection.VERTICAL,width:"100%"},c.propTypes={estimatedItemSize:i.number,height:i.oneOfType([i.number,i.string]).isRequired,itemCount:i.number.isRequired,itemSize:i.oneOfType([i.number,i.array,i.func]).isRequired,onScroll:i.func,onItemsRendered:i.func,overscanCount:i.number,renderItem:i.func.isRequired,scrollOffset:i.number,scrollToIndex:i.number,scrollToAlignment:i.oneOf([r.AUTO,r.START,r.CENTER,r.END]),scrollDirection:i.oneOf([t.ScrollDirection.HORIZONTAL,t.ScrollDirection.VERTICAL]),stickyIndices:i.arrayOf(i.number),style:i.object,width:i.oneOfType([i.number,i.string])},c}(e.PureComponent);t.default=A,Object.defineProperty(t,"__esModule",{value:!0})});