react-intersection-observer-hook
Advanced tools
Comparing version 2.0.6 to 2.1.0
@@ -7,4 +7,61 @@ 'use strict'; | ||
function createObserverCache() { | ||
var cachesByRoot = new Map(); | ||
var entryCallbacks = new Map(); | ||
function getObserver(_ref) { | ||
var root = _ref.root, | ||
rootMargin = _ref.rootMargin, | ||
threshold = _ref.threshold; | ||
var cacheByRoot = cachesByRoot.get(root); | ||
if (!cacheByRoot) { | ||
cacheByRoot = new Map(); | ||
cachesByRoot.set(root, cacheByRoot); | ||
} | ||
var cacheKey = JSON.stringify({ | ||
rootMargin: rootMargin, | ||
threshold: threshold | ||
}); | ||
var observer = cacheByRoot.get(cacheKey); | ||
if (!observer) { | ||
observer = new IntersectionObserver(function (entries) { | ||
entries.forEach(function (entry) { | ||
var callback = entryCallbacks.get(entry.target); | ||
callback == null ? void 0 : callback(entry); | ||
}); | ||
}, { | ||
root: root, | ||
rootMargin: rootMargin, | ||
threshold: threshold | ||
}); | ||
cacheByRoot.set(cacheKey, observer); | ||
} | ||
return { | ||
observe: function observe(node, callback) { | ||
var _observer; | ||
entryCallbacks.set(node, callback); | ||
(_observer = observer) == null ? void 0 : _observer.observe(node); | ||
}, | ||
unobserve: function unobserve(node) { | ||
var _observer2; | ||
entryCallbacks["delete"](node); | ||
(_observer2 = observer) == null ? void 0 : _observer2.unobserve(node); | ||
} | ||
}; | ||
} | ||
return { | ||
getObserver: getObserver | ||
}; | ||
} | ||
var DEFAULT_ROOT_MARGIN = '0px'; | ||
var DEFAULT_THRESHOLD = [0]; // For more info: | ||
var DEFAULT_THRESHOLD = [0]; | ||
var observerCache = /*#__PURE__*/createObserverCache(); // For more info: | ||
// https://developers.google.com/web/updates/2016/04/intersectionobserver | ||
@@ -26,54 +83,45 @@ // https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API | ||
var observe = react.useCallback(function () { | ||
var node = nodeRef.current; | ||
if (!node) { | ||
setEntry(undefined); | ||
return; | ||
} | ||
var observer = observerCache.getObserver({ | ||
root: rootRef.current, | ||
rootMargin: rootMargin, | ||
threshold: threshold | ||
}); | ||
observer.observe(node, function (observedEntry) { | ||
setEntry(observedEntry); | ||
}); | ||
observerRef.current = observer; | ||
}, [rootMargin, threshold]); | ||
var unobserve = react.useCallback(function () { | ||
// Disconnect the current observer (if there is one) | ||
var currentObserver = observerRef.current; | ||
currentObserver == null ? void 0 : currentObserver.disconnect(); | ||
observerRef.current = null; | ||
}, []); | ||
var observe = react.useCallback(function () { | ||
var node = nodeRef.current; | ||
if (node) { | ||
var root = rootRef.current; | ||
var options = { | ||
root: root, | ||
rootMargin: rootMargin, | ||
threshold: threshold | ||
}; // Create a observer for current "node" with given options. | ||
currentObserver == null ? void 0 : currentObserver.unobserve(node); | ||
} | ||
var observer = new IntersectionObserver(function (_ref) { | ||
var newEntry = _ref[0]; | ||
setEntry(newEntry); | ||
}, options); | ||
observer.observe(node); | ||
observerRef.current = observer; | ||
} | ||
}, [rootMargin, threshold]); | ||
var initializeObserver = react.useCallback(function () { | ||
observerRef.current = null; | ||
}, []); // React will call the ref callback with the DOM element when the component mounts, | ||
// and call it with null when it unmounts. | ||
// So, we don't need an useEffect etc to unobserve nodes. | ||
// When nodeRef.current is null, it will be unobserved and observe function | ||
// won't do anything. | ||
var refCallback = react.useCallback(function (node) { | ||
unobserve(); | ||
nodeRef.current = node; | ||
observe(); | ||
}, [observe, unobserve]); | ||
var refCallback = react.useCallback(function (node) { | ||
nodeRef.current = node; | ||
initializeObserver(); | ||
}, [initializeObserver]); | ||
var rootRefCallback = react.useCallback(function (rootNode) { | ||
unobserve(); | ||
rootRef.current = rootNode; | ||
initializeObserver(); | ||
}, [initializeObserver]); | ||
react.useEffect(function () { | ||
// After React 18, StrictMode unmounts and mounts components to be sure | ||
// if they are resilient effects being mounted and destroyed multiple times. | ||
// This a behavior to be sure nothing breaks when off-screen components | ||
// can preserve their state with future React versions. | ||
// So in StrictMode, React unmounts the component, clean-up of this useEffect gets triggered and | ||
// we stop observing the node. But we need to start observing after component re-mounts with its preserved state. | ||
// So to handle this case, we call initializeObserver here. | ||
// https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#updates-to-strict-mode | ||
initializeObserver(); | ||
return function () { | ||
// We disconnect the observer on unmount to prevent memory leaks etc. | ||
unobserve(); | ||
}; | ||
}, [initializeObserver, unobserve]); | ||
observe(); | ||
}, [observe, unobserve]); | ||
return [refCallback, { | ||
@@ -80,0 +128,0 @@ entry: entry, |
@@ -1,2 +0,2 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),r=[0];function n(n){var t,u,l=null!=(t=null==n?void 0:n.rootMargin)?t:"0px",o=null!=(u=null==n?void 0:n.threshold)?u:r,i=e.useRef(null),s=e.useRef(null),c=e.useRef(null),a=e.useState(),f=a[0],v=a[1],b=e.useCallback((function(){var e=c.current;null==e||e.disconnect(),c.current=null}),[]),p=e.useCallback((function(){var e=i.current;if(e){var r=new IntersectionObserver((function(e){v(e[0])}),{root:s.current,rootMargin:l,threshold:o});r.observe(e),c.current=r}}),[l,o]),d=e.useCallback((function(){b(),p()}),[p,b]),h=e.useCallback((function(e){i.current=e,d()}),[d]),y=e.useCallback((function(e){s.current=e,d()}),[d]);return e.useEffect((function(){return d(),function(){b()}}),[d,b]),[h,{entry:f,rootRef:y}]}function t(){return(t=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var n=arguments[r];for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(e[t]=n[t])}return e}).apply(this,arguments)}exports.useIntersectionObserver=n,exports.useTrackVisibility=function(r){var u,l=n(r),o=l[0],i=l[1],s=Boolean(null==(u=i.entry)?void 0:u.isIntersecting),c=e.useState(s),a=c[0];return s&&!a&&(0,c[1])(!0),[o,t({},i,{isVisible:s,wasEverVisible:a})]}; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");function r(){var e=new Map,r=new Map;return{getObserver:function(n){var t=n.root,o=n.rootMargin,u=n.threshold,l=e.get(t);l||(l=new Map,e.set(t,l));var s=JSON.stringify({rootMargin:o,threshold:u}),i=l.get(s);return i||(i=new IntersectionObserver((function(e){e.forEach((function(e){var n=r.get(e.target);null==n||n(e)}))}),{root:t,rootMargin:o,threshold:u}),l.set(s,i)),{observe:function(e,n){var t;r.set(e,n),null==(t=i)||t.observe(e)},unobserve:function(e){var n;r.delete(e),null==(n=i)||n.unobserve(e)}}}}}var n=[0],t=r();function o(r){var o,u,l=null!=(o=null==r?void 0:r.rootMargin)?o:"0px",s=null!=(u=null==r?void 0:r.threshold)?u:n,i=e.useRef(null),a=e.useRef(null),c=e.useRef(null),v=e.useState(),f=v[0],b=v[1],g=e.useCallback((function(){var e=i.current;if(e){var r=t.getObserver({root:a.current,rootMargin:l,threshold:s});r.observe(e,(function(e){b(e)})),c.current=r}else b(void 0)}),[l,s]),h=e.useCallback((function(){var e=c.current,r=i.current;r&&(null==e||e.unobserve(r)),c.current=null}),[]);return[e.useCallback((function(e){h(),i.current=e,g()}),[g,h]),{entry:f,rootRef:e.useCallback((function(e){h(),a.current=e,g()}),[g,h])}]}function u(){return(u=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var n=arguments[r];for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(e[t]=n[t])}return e}).apply(this,arguments)}exports.useIntersectionObserver=o,exports.useTrackVisibility=function(r){var n,t=o(r),l=t[0],s=t[1],i=Boolean(null==(n=s.entry)?void 0:n.isIntersecting),a=e.useState(i),c=a[0];return i&&!c&&(0,a[1])(!0),[l,u({},s,{isVisible:i,wasEverVisible:c})]}; | ||
//# sourceMappingURL=react-intersection-observer-hook.cjs.production.min.js.map |
@@ -1,5 +0,62 @@ | ||
import { useRef, useState, useCallback, useEffect } from 'react'; | ||
import { useRef, useState, useCallback } from 'react'; | ||
function createObserverCache() { | ||
var cachesByRoot = new Map(); | ||
var entryCallbacks = new Map(); | ||
function getObserver(_ref) { | ||
var root = _ref.root, | ||
rootMargin = _ref.rootMargin, | ||
threshold = _ref.threshold; | ||
var cacheByRoot = cachesByRoot.get(root); | ||
if (!cacheByRoot) { | ||
cacheByRoot = new Map(); | ||
cachesByRoot.set(root, cacheByRoot); | ||
} | ||
var cacheKey = JSON.stringify({ | ||
rootMargin: rootMargin, | ||
threshold: threshold | ||
}); | ||
var observer = cacheByRoot.get(cacheKey); | ||
if (!observer) { | ||
observer = new IntersectionObserver(function (entries) { | ||
entries.forEach(function (entry) { | ||
var callback = entryCallbacks.get(entry.target); | ||
callback == null ? void 0 : callback(entry); | ||
}); | ||
}, { | ||
root: root, | ||
rootMargin: rootMargin, | ||
threshold: threshold | ||
}); | ||
cacheByRoot.set(cacheKey, observer); | ||
} | ||
return { | ||
observe: function observe(node, callback) { | ||
var _observer; | ||
entryCallbacks.set(node, callback); | ||
(_observer = observer) == null ? void 0 : _observer.observe(node); | ||
}, | ||
unobserve: function unobserve(node) { | ||
var _observer2; | ||
entryCallbacks["delete"](node); | ||
(_observer2 = observer) == null ? void 0 : _observer2.unobserve(node); | ||
} | ||
}; | ||
} | ||
return { | ||
getObserver: getObserver | ||
}; | ||
} | ||
var DEFAULT_ROOT_MARGIN = '0px'; | ||
var DEFAULT_THRESHOLD = [0]; // For more info: | ||
var DEFAULT_THRESHOLD = [0]; | ||
var observerCache = /*#__PURE__*/createObserverCache(); // For more info: | ||
// https://developers.google.com/web/updates/2016/04/intersectionobserver | ||
@@ -21,54 +78,45 @@ // https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API | ||
var observe = useCallback(function () { | ||
var node = nodeRef.current; | ||
if (!node) { | ||
setEntry(undefined); | ||
return; | ||
} | ||
var observer = observerCache.getObserver({ | ||
root: rootRef.current, | ||
rootMargin: rootMargin, | ||
threshold: threshold | ||
}); | ||
observer.observe(node, function (observedEntry) { | ||
setEntry(observedEntry); | ||
}); | ||
observerRef.current = observer; | ||
}, [rootMargin, threshold]); | ||
var unobserve = useCallback(function () { | ||
// Disconnect the current observer (if there is one) | ||
var currentObserver = observerRef.current; | ||
currentObserver == null ? void 0 : currentObserver.disconnect(); | ||
observerRef.current = null; | ||
}, []); | ||
var observe = useCallback(function () { | ||
var node = nodeRef.current; | ||
if (node) { | ||
var root = rootRef.current; | ||
var options = { | ||
root: root, | ||
rootMargin: rootMargin, | ||
threshold: threshold | ||
}; // Create a observer for current "node" with given options. | ||
currentObserver == null ? void 0 : currentObserver.unobserve(node); | ||
} | ||
var observer = new IntersectionObserver(function (_ref) { | ||
var newEntry = _ref[0]; | ||
setEntry(newEntry); | ||
}, options); | ||
observer.observe(node); | ||
observerRef.current = observer; | ||
} | ||
}, [rootMargin, threshold]); | ||
var initializeObserver = useCallback(function () { | ||
observerRef.current = null; | ||
}, []); // React will call the ref callback with the DOM element when the component mounts, | ||
// and call it with null when it unmounts. | ||
// So, we don't need an useEffect etc to unobserve nodes. | ||
// When nodeRef.current is null, it will be unobserved and observe function | ||
// won't do anything. | ||
var refCallback = useCallback(function (node) { | ||
unobserve(); | ||
nodeRef.current = node; | ||
observe(); | ||
}, [observe, unobserve]); | ||
var refCallback = useCallback(function (node) { | ||
nodeRef.current = node; | ||
initializeObserver(); | ||
}, [initializeObserver]); | ||
var rootRefCallback = useCallback(function (rootNode) { | ||
unobserve(); | ||
rootRef.current = rootNode; | ||
initializeObserver(); | ||
}, [initializeObserver]); | ||
useEffect(function () { | ||
// After React 18, StrictMode unmounts and mounts components to be sure | ||
// if they are resilient effects being mounted and destroyed multiple times. | ||
// This a behavior to be sure nothing breaks when off-screen components | ||
// can preserve their state with future React versions. | ||
// So in StrictMode, React unmounts the component, clean-up of this useEffect gets triggered and | ||
// we stop observing the node. But we need to start observing after component re-mounts with its preserved state. | ||
// So to handle this case, we call initializeObserver here. | ||
// https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#updates-to-strict-mode | ||
initializeObserver(); | ||
return function () { | ||
// We disconnect the observer on unmount to prevent memory leaks etc. | ||
unobserve(); | ||
}; | ||
}, [initializeObserver, unobserve]); | ||
observe(); | ||
}, [observe, unobserve]); | ||
return [refCallback, { | ||
@@ -75,0 +123,0 @@ entry: entry, |
{ | ||
"name": "react-intersection-observer-hook", | ||
"version": "2.0.6", | ||
"version": "2.1.0", | ||
"license": "MIT", | ||
@@ -5,0 +5,0 @@ "author": "onderonur", |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
52160
15
326