UNPKG

@kohlmannj/react-scroll-percentage

Version:

Monitor the scroll percentage of a component inside the viewport, using the IntersectionObserver API.

2 lines (1 loc) 5.1 kB
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react"),require("@kohlmannj/react-intersection-observer")):"function"==typeof define&&define.amd?define(["exports","react","@kohlmannj/react-intersection-observer"],t):t((e=e||self).ReactScrollPercentage={},e.React,e.Observer)}(this,function(e,r,l){"use strict";var f="default"in r?r.default:r;function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function i(e,t,r){return t&&n(e.prototype,t),r&&n(e,r),e}function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function c(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&u(e,t)}function s(e){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){return(u=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function p(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function d(e,t){return!t||"object"!=typeof t&&"function"!=typeof t?p(e):t}l=l&&l.hasOwnProperty("default")?l.default:l;var t=!1,h=!1,g=new Set;function w(){h||(h=!0,requestAnimationFrame(v))}function v(){h=!1,g.forEach(function(e){return e()})}function m(e){t||t||(window.addEventListener("scroll",w),t=!0),g.add(e)}function y(e){g.delete(e),g.size||t&&(g.clear(),window.removeEventListener("scroll",w),t=!1)}var b=function(e){function h(){var e,u;o(this,h);for(var t=arguments.length,r=new Array(t),n=0;n<t;n++)r[n]=arguments[n];return a(p(p(u=d(this,(e=s(h)).call.apply(e,[this].concat(r))))),"state",{percentage:0,percentageOfViewport:0}),a(p(p(u)),"handleScroll",function(){var e=u.props,t=e.forwardedRef,r=e.rootMargin,n=e.threshold;if(t&&t.current){var o=t.current.getBoundingClientRect(),i=h.calculatePercentages(o,r,n),a=i.percentage,c=i.percentageOfViewport;a!==u.state.percentage&&u.setState({percentage:a}),c!==u.state.percentageOfViewport&&u.setState({percentageOfViewport:c})}}),u}return c(h,r.PureComponent),i(h,[{key:"componentDidMount",value:function(){this.handleScroll(),this.props.inView&&this.monitorScroll(this.props.inView)}},{key:"componentDidUpdate",value:function(e,t){!this.props.onChange||t.percentage===this.state.percentage&&e.inView===this.props.inView||this.props.onChange(this.state.percentage,this.props.inView,this.state.percentageOfViewport),e.inView!==this.props.inView&&this.monitorScroll(this.props.inView)}},{key:"componentWillUnmount",value:function(){this.monitorScroll(!1)}},{key:"monitorScroll",value:function(e){e?m(this.handleScroll):(0<this.state.percentage&&this.state.percentage<1&&this.handleScroll(),y(this.handleScroll))}},{key:"render",value:function(){var e=this.props,t=e.children,r=e.inView,n=e.forwardedRef,o=this.state,i=o.percentage,a=o.percentageOfViewport;return("function"==typeof t?t({inView:r,forwardedRef:n,percentage:i,percentageOfViewport:a}):t)||null}}],[{key:"viewportHeight",value:function(){return window.parent?window.parent.innerHeight:window.innerHeight||0}},{key:"getRootMarginOffsetTerm",value:function(e,t){var r=e.value,n=e.unit;switch(n){case"px":return r;case"%":return r/100*t;default:throw new Error("'".concat(n,"' units not supported"))}}},{key:"calculatePercentages",value:function(e,t){var r=2<arguments.length&&void 0!==arguments[2]?arguments[2]:0,n=function(){var e=(0<arguments.length&&void 0!==arguments[0]?arguments[0]:"0px").split(/\s+/).map(function(e){var t=/^(-?\d*\.?\d+)(px|%)$/.exec(e);if(!t)throw new Error("rootMargin must be specified in pixels or percent");return{value:parseFloat(t[1]),unit:t[2]}});return e[1]=e[1]||e[0],e[2]=e[2]||e[0],e[3]=e[3]||e[1],e}(t),o=n[0],i=n[2],a=h.viewportHeight(),c=r*a*.25-h.getRootMarginOffsetTerm(o,a),u=r*a*.25-h.getRootMarginOffsetTerm(i,a),l=1-Math.max(0,Math.min(1,(e.bottom-c)/(a+e.height-u-c))),f=Math.max(c,e.top),s=Math.min(a-u,e.bottom),p=0-c+a-u;return{percentage:l,percentageOfViewport:Math.max(0,Math.min(1,(s-f)/p))}}}]),h}();a(b,"defaultProps",{threshold:0});var O=function(e){function t(){return o(this,t),d(this,s(t).apply(this,arguments))}return c(t,r.PureComponent),i(t,[{key:"render",value:function(){var e=this.props,n=e.children,o=e.onChange,t=e.root,r=e.rootId,i=e.rootMargin,a=e.forwardedRef,c=e.threshold,u=e.triggerOnce;return f.createElement(l,{forwardedRef:a,root:t,rootId:r,rootMargin:i,threshold:c,triggerOnce:u},function(e){var t=e.inView,r=e.forwardedRef;return f.createElement(b,{forwardedRef:r,inView:t,onChange:o,rootMargin:i,threshold:c},n)})}}]),t}();a(O,"defaultProps",{forwardedRef:r.createRef(),threshold:0,triggerOnce:!1}),e.ScrollPercentageCalculator=b,e.ScrollPercentageObserver=O,Object.defineProperty(e,"__esModule",{value:!0})});