react-scrollsense
Version:
A lightweight scroll sensor to solve your react scroll into viewport issues.
3 lines (2 loc) • 10.8 kB
JavaScript
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react/jsx-runtime"),e=require("lodash"),n=require("react"),i=require("./pack.b563688a.js");function o(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var r=o(n);function s(t,e,n){let i=e[t];i?(i.fn=n.fn,i.options=n.options):e[t]=n}function l(t){return t.endsWith("%")?"percentage":"pixel"}function a(t){var e=t.trim().split(" ");if(1==e.length){var n=parseInt(e[0]);return{type:new Array(4).fill(l(e[0])),margin:[n,n,n,n]}}if(2==e.length){var i=parseInt(e[1]),o=parseInt(e[0]);return{type:[l(o),l(i),l(o),l(i)],margin:[o,i,o,i]}}return 4==e.length?{type:[l(e[0]),l(e[1]),l(e[2]),l(e[3])],margin:[parseInt(e[0]),parseInt(e[1]),parseInt(e[2]),parseInt(e[3])]}:null}function c(t,e,n){return"pixel"===t?e:e*n}!function(){if(global.window){if("function"==typeof window.CustomEvent)return!1;t.prototype=window.Event.prototype,window.CustomEvent=t}function t(t,e){e=e||{bubbles:!1,cancelable:!1,detail:void 0};var n=document.createEvent("CustomEvent");return n.initCustomEvent(t,e.bubbles,e.cancelable,e.detail),n}}(),String.prototype.endsWith||(String.prototype.endsWith=function(t){return-1!==this.indexOf(t,this.length-t.length)});const h=r.default.createContext(null);h.displayName="NativeScrollSense";class g extends r.default.Component{constructor(t){super(t),this.options=null,this.i=0,this.wndHeight=0,this.wndWidth=0,this.scrollEntryItems=[],this.getOverflowParent=t=>{var e=t.parentNode,n=!1,i=!1,o=getComputedStyle(e).overflow.split(" ");return 2==o.length?(this.isOverflow(o[0])&&(n=!0),this.isOverflow(o[1])&&(i=!0)):1==o.length&&this.isOverflow(o[0])&&(n=i=!0),n||i?{el:e,xOverflow:n,yOverflow:i}:"body"==e.tagName.toLowerCase()?null:this.getOverflowParent(e)},this.triggerDocumentScroll=null,this.setOptions(),this.onScroll=e.throttle(this.onScroll.bind(this),this.options.delay),this.handleScroll=this.handleScroll.bind(this),this.onResize=this.onResize.bind(this),this.onViewportChange=this.onViewportChange.bind(this),this.addTrackingFn=this.addTrackingFn.bind(this),this.removeTracking=this.removeTracking.bind(this),this.updateTrackingFn=this.updateTrackingFn.bind(this),this.wndHeight=window.innerHeight,this.wndWidth=window.innerWidth}setOptions(){let t={rootMargin:null,delay:100};var e;console.log(this.props),this.props.config&&(this.props.config.delay&&(t.delay="number"==typeof(e=this.props.config.delay)?e:(e=e.trim()).endsWith("ms")?parseInt(e.substring(0,e.indexOf("ms"))):e.endsWith("s")?1e3*parseInt(e.substring(0,e.indexOf("s"))):void 0),this.props.config.rootMargin?t.rootMargin=a(this.props.config.rootMargin):t.rootMargin=a("0 0 0 0")),this.options=t}isOverflow(t){return"auto"==t||"scroll"==t}addTrackingFn(t,e,n){let i={};n&&(i=n),void 0===i.continuous&&(i.continuous=!0),i.continuous?i.continuous=!0:i.continuous=!1;let o=parseInt(t.getAttribute("data-scroll-id"));var r;r=o,(isNaN(parseFloat(r))||!isFinite(r))&&(t.setAttribute("data-scroll-id",this.i),o=this.i++);let l=this.getOverflowParent(t);if(l&&l.el){l.el.addEventListener("scroll",this.onScroll);let t=!1,n=Object.keys(this.scrollEntryItems);for(let e=0;e<n.length;e++){const i=n[e];this.scrollEntryItems[i].el==l.el&&(t=!0)}t||(l.el.dispatchEvent(new CustomEvent("scroll")),s(o,this.scrollEntryItems,{fn:e,el:l.el,isShowing:!1,options:{rootMargin:i.rootMargin?a(i.rootMargin):this.options.rootMargin},overflowParent:null,isActive:!0,isScrollContainer:!0,isTriggered:!1,continuous:i.continuous}),o=this.i++)}else if(!this.triggerDocumentScroll){let t=document.createEvent("Event");t.initEvent("scroll",!0,!0),document.dispatchEvent(t),this.triggerDocumentScroll=!0}let c={fn:e,el:t,isShowing:!1,options:{rootMargin:i.rootMargin?a(i.rootMargin):this.options.rootMargin},overflowParent:l,isActive:!0,isTriggered:!1,continuous:i.continuous,isScrollContainer:!1};return s(o,this.scrollEntryItems,c),{pause:()=>{c.isActive=!1,c.overflowParent&&c.overflowParent.el.dispatchEvent(new CustomEvent("scroll"))},resume:()=>{c.isActive=!0,c.overflowParent&&c.overflowParent.el.dispatchEvent(new CustomEvent("scroll"))}}}updateTrackingFn(t,e,n){let i=Object.keys(this.scrollEntryItems);for(let o=0;o<i.length;o++){let r=i[o];const s=this.scrollEntryItems[r];s.el==t&&(e&&(s.fn=e),n&&n.rootMargin&&(s.options.rootMargin=a(n.rootMargin),s.overflowParent.el.dispatchEvent(new CustomEvent("scroll"))))}}removeTracking(t){if(e.isElement(t)){let e=Object.keys(this.scrollEntryItems);for(let n=0;n<e.length;n++){let i=e[n];if(this.scrollEntryItems[i].el==t)return void this.scrollEntryItems.splice(n,1)}}}getScrollTop(){return window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0}getScrollLeft(){return window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0}handleScroll(t){if(t.target==document)for(let t=0;t<this.scrollEntryItems.length;t++){const n=this.scrollEntryItems[t];if(!n.continuous&&n.isTriggered&&!n.isScrollContainer)continue;if(!n.isActive||n.overflowParent)continue;let i=0,o=0,r=this.wndWidth,s=this.wndHeight;if(n.options&&n.options.rootMargin){var e=n.options.rootMargin;i+=c(e.type[3],e.margin[3],r),o+=c(e.type[0],e.margin[0],s),r-=c(e.type[1],e.margin[1],r),s-=c(e.type[2],e.margin[2],r)}const l=n.el.getBoundingClientRect();if(l.top<s&&l.bottom>o&&l.left<r&&l.right>i){if(n.isScrollContainer&&!n.isShowing){n.isShowing=!0,n.el.dispatchEvent(new CustomEvent("scroll"));continue}n.isShowing||(n.isShowing=!0,n.isTriggered=!0),n.fn({isIntersecting:!0,boundingClientRect:l,time:0,target:n.el,wndWidth:this.wndWidth,wndHeight:this.wndHeight,scrollTop:document.scrollingElement.scrollTop,scrollLeft:document.scrollingElement.scrollLeft,get intersectionInPixels(){return{x:this.scrollLeft,y:this.scrollTop,width:34,height:34}}})}else n.isShowing&&(n.isShowing=!1,n.fn({isIntersecting:!1,target:n.el}))}else{let e=t.target,n=e.getBoundingClientRect(),i=Object.keys(this.scrollEntryItems);for(let t=0;t<i.length;t++){const o=i[t],r=this.scrollEntryItems[o];if(!r.continuous&&r.isTriggered)continue;if(!r.overflowParent)continue;if(!r.isActive)continue;let s=n.top,l=n.left,a=n.right,c=n.bottom;const h=r.el.getBoundingClientRect();this.wndHeight>n.top&&n.bottom>0&&this.wndWidth>n.left&&n.right>0&&h.top<Math.min(this.wndHeight,c)&&h.bottom>Math.max(s,0)&&h.left<Math.min(this.wndWidth,a)&&h.right>Math.max(l,0)?(r.isShowing||(r.isShowing=!0),r.fn({isIntersecting:!0,boundingClientRect:h,time:0,target:r.el,scrolledWidth:this.wndWidth-h.left,scrolledHeight:this.wndHeight-h.top,scrollTop:e.scrollTop,scrollLeft:e.scrollLeft})):r.isShowing&&(r.isShowing=!1,r.fn({isIntersecting:!1,target:r.el}))}}}onScroll(t){requestAnimationFrame((()=>{this.handleScroll(t)}))}onResize(){this.wndHeight=window.innerHeight,this.wndWidth=window.innerWidth}onViewportChange(){this.setState({refreshToggle:!this.state.refreshToggle})}componentDidMount(){window.addEventListener("scroll",this.onScroll,{passive:!0}),window.addEventListener("resize",this.onResize),window.addEventListener("viewportchanged",this.onViewportChange)}componentWillUnmount(){window.removeEventListener("scroll",this.onScroll),window.removeEventListener("resize",this.onResize),window.removeEventListener("viewportchanged",this.onViewportChange)}render(){let e={addTracking:this.addTrackingFn,updateTracking:this.updateTrackingFn,removeTracking:this.removeTracking,sensorType:"native"};return t.jsx(h.Provider,Object.assign({value:e},{children:this.props.children}),void 0)}}exports.default=g,exports.useScrollSense=function(){const t=n.useContext(h),e=n.useRef({});if(!t)throw new Error("No event based sensor has found. Did you add ScrollSense provider component?");return t&&"native"!==t.sensorType&&i.error(i.errorStrings.nativeConnectWithWrongProvider),n.useMemo((()=>({onIntersection:(n,o,r)=>{let s=n.getAttribute("data-scroll-id");if(e.current[s]&&e.current[s].fn!=o)return e.current[s].fn=o,e.current[s].tracker;const l=t.addTracking(n,(t=>{let n=e.current[t.target.getAttribute("data-scroll-id")].fn;i.isRafAvailable?window.requestAnimationFrame((e=>{n(t)})):n(t)}),r);return s=n.getAttribute("data-scroll-id"),e.current[s]={fn:o,tracker:l},l},detach:e=>{t.removeTracking(e)}})),[t])},exports.withScrollSense=function(e){return{viaCallback:function(n){return function(e,n){var o;return o=class extends r.default.Component{constructor(t){super(t),this.isComplete=!1,this.isRafAvailable=i.isRafAvailable(),this.config=null,this.ioRecords=[],this.onIntersection=this.onIntersection.bind(this),this.config={rootMargin:n&&n.rootMargin||"0px"},this.props.rootMargin&&(this.config.rootMargin=this.props.rootMargin)}onIntersection(t,e,n){if(!this.isComplete)return void i.warn("Component still not mounted. To add an element to the tracking list, element must be mounted");let o=!1,r=Object.assign({},this.config);return n&&n.rootMargin&&(r.rootMargin=n.rootMargin,o=!0),t?(this.ioRecords.push({el:t,fn:e,config:r,flags:{isRootMarginSet:o}}),this.context.addTracking(t,e,{rootMargin:this.config.rootMargin})):(i.warn("There is no dom element to attach the scroll sense"),null)}updateIObservers(t){for(let e=0;e<this.ioRecords.length;e++){const n=this.ioRecords[e];this.context.updateTracking(n.el,null,{rootMargin:n.flags.isRootMarginSet?n.config.rootMargin:n.config.rootMargin=t})}}componentDidUpdate(t){let e=!1;this.props.rootMargin&&t.rootMargin!=this.props.rootMargin&&(this.config.rootMargin=this.props.rootMargin,e=!0),e&&this.updateIObservers(this.config.rootMargin)}componentDidMount(){this.isComplete=!0}render(){return t.jsx(e,Object.assign({},this.props,{onIntersection:this.onIntersection}),void 0)}},o.contextType=h,o}(e,n)},viaProps:function(n,o){return function(e,n,o){var s;return(s=class extends r.default.Component{constructor(t){super(t),this.showTrue={show:!0},this.showFalse={show:!1},this.ref=r.default.createRef(),this.config={rootMargin:o&&o.rootMargin||"0px 0px"},this.state={scrollInfo:{isIntersecting:!1},sensorProxy:null},t.rootMargin&&(this.config.rootMargin=t.rootMargin)}componentDidMount(){let t=this,e=this.ref.current.children[0];if(e){const n=this.context.addTracking(e,(e=>{t.setState({scrollInfo:e})}),{rootMargin:this.config.rootMargin});this.setState({sensorProxy:n})}else i.warn("There is no dom element to attach the scroll sense")}componentDidUpdate(t){let e=!1;this.props.rootMargin!=t.rootMargin&&(this.config.rootMargin=this.props.rootMargin,e=!0),e&&this.context.updateTracking(this.ref.current.children[0],(t=>{this.setState({scrollInfo:t})}),{rootMargin:this.config.rootMargin})}render(){let i=n(this.state.scrollInfo);return console.log("rendera",this.props),t.jsx("div",Object.assign({ref:this.ref},{children:t.jsx(e,Object.assign({},this.props,i,this.state.sensorProxy),void 0)}),void 0)}}).contextType=h,s}(e,o,n)}}};
//# sourceMappingURL=index.js.map