Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-intersection-observer

Package Overview
Dependencies
Maintainers
1
Versions
160
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-intersection-observer - npm Package Compare versions

Comparing version 1.0.1 to 1.1.0

.babelrc.js

201

es/index.js

@@ -1,36 +0,11 @@

'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _intersection = require('./intersection');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
import React, { Component, createElement } from 'react'; // eslint-disable-line no-unused-vars
import PropTypes from 'prop-types';
import { observe, unobserve } from './intersection';
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
const isFunction = func => typeof func === 'function';
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // eslint-disable-line no-unused-vars
var isFunction = function isFunction(func) {
return typeof func === 'function';
};
/**

@@ -45,126 +20,100 @@ * Monitors scroll, and triggers the children function with updated props

*/
class Observer extends Component {
constructor(...args) {
var _temp;
var Observer = function (_Component) {
_inherits(Observer, _Component);
return _temp = super(...args), this.state = {
inView: false
}, this.node = null, this.handleNode = node => {
if (this.node) unobserve(this.node);
this.node = node;
this.observeNode();
}, this.handleChange = inView => this.setState({ inView }), _temp;
}
function Observer() {
var _ref;
var _temp, _this, _ret;
_classCallCheck(this, Observer);
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
componentWillUpdate(nextProps, nextState) {
if (!!this.props.onChange && nextState !== this.state) {
this.props.onChange(nextState.inView);
}
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Observer.__proto__ || Object.getPrototypeOf(Observer)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
inView: false
}, _this.node = null, _this.handleNode = function (node) {
if (_this.node) (0, _intersection.unobserve)(_this.node);
_this.node = node;
_this.observeNode();
}, _this.handleChange = function (inView) {
return _this.setState({ inView: inView });
}, _temp), _possibleConstructorReturn(_this, _ret);
}
_createClass(Observer, [{
key: 'componentWillUpdate',
value: function componentWillUpdate(nextProps, nextState) {
if (!!this.props.onChange && nextState !== this.state) {
this.props.onChange(nextState.inView);
}
componentDidUpdate(prevProps, prevState) {
// If a IntersectionObserver option changed, reinit the observer
if (prevProps.rootMargin !== this.props.rootMargin || prevProps.root !== this.props.root || prevProps.threshold !== this.props.threshold) {
unobserve(this.node);
this.observeNode();
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate(prevProps, prevState) {
// If a IntersectionObserver option changed, reinit the observer
if (prevProps.rootMargin !== this.props.rootMargin || prevProps.root !== this.props.root || prevProps.threshold !== this.props.threshold) {
(0, _intersection.unobserve)(this.node);
this.observeNode();
}
if (prevState.inView !== this.state.inView) {
if (this.state.inView && this.props.triggerOnce) {
(0, _intersection.unobserve)(this.node);
this.node = null;
}
}
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
if (this.node) {
(0, _intersection.unobserve)(this.node);
if (prevState.inView !== this.state.inView) {
if (this.state.inView && this.props.triggerOnce) {
unobserve(this.node);
this.node = null;
}
}
}, {
key: 'observeNode',
value: function observeNode() {
if (!this.node) return;
var _props = this.props,
threshold = _props.threshold,
root = _props.root,
rootMargin = _props.rootMargin,
rootId = _props.rootId;
}
(0, _intersection.observe)(this.node, this.handleChange, {
threshold: threshold,
root: root,
rootMargin: rootMargin
}, rootId);
componentWillUnmount() {
if (this.node) {
unobserve(this.node);
this.node = null;
}
}, {
key: 'render',
value: function render() {
var _props2 = this.props,
children = _props2.children,
render = _props2.render,
tag = _props2.tag,
triggerOnce = _props2.triggerOnce,
threshold = _props2.threshold,
root = _props2.root,
rootId = _props2.rootId,
rootMargin = _props2.rootMargin,
props = _objectWithoutProperties(_props2, ['children', 'render', 'tag', 'triggerOnce', 'threshold', 'root', 'rootId', 'rootMargin']);
}
var inView = this.state.inView;
observeNode() {
if (!this.node) return;
const { threshold, root, rootMargin, rootId } = this.props;
observe(this.node, this.handleChange, {
threshold,
root,
rootMargin
}, rootId);
}
render() {
const _props = this.props,
{
children,
render,
tag,
triggerOnce,
threshold,
root,
rootId,
rootMargin
} = _props,
props = _objectWithoutProperties(_props, ['children', 'render', 'tag', 'triggerOnce', 'threshold', 'root', 'rootId', 'rootMargin']);
return (0, _react.createElement)(tag, _extends({}, props, {
ref: this.handleNode
}),
// If render is a function, use it to render content when in view
inView && isFunction(render) ? render() : null,
// If children is a function, render it with the current inView status.
// Otherwise always render children. Assume onChange is being used outside, to control the the state of children.
isFunction(children) ? children(inView) : children);
}
}]);
const { inView } = this.state;
return Observer;
}(_react.Component);
return createElement(tag, _extends({}, props, {
ref: this.handleNode
}),
// If render is a function, use it to render content when in view
inView && isFunction(render) ? render() : null,
// If children is a function, render it with the current inView status.
// Otherwise always render children. Assume onChange is being used outside, to control the the state of children.
isFunction(children) ? children(inView) : children);
}
}
Observer.propTypes = {
/** Element tag to use for the wrapping */
tag: _propTypes2.default.node,
tag: PropTypes.node,
/** Children should be either a function or a node */
children: _propTypes2.default.oneOfType([_propTypes2.default.func, _propTypes2.default.node]),
children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
/** Only trigger the inView callback once */
triggerOnce: _propTypes2.default.bool,
triggerOnce: PropTypes.bool,
/** Number between 0 and 1 indicating the the percentage that should be visible before triggering. Can also be an array of numbers, to create multiple trigger points. */
threshold: _propTypes2.default.oneOfType([_propTypes2.default.arrayOf(_propTypes2.default.number), _propTypes2.default.number]),
threshold: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), PropTypes.number]),
/** The HTMLElement that is used as the viewport for checking visibility of the target. Defaults to the browser viewport if not specified or if null.*/
root: _propTypes2.default.object,
root: PropTypes.object,
/** Margin around the root. Can have values similar to the CSS margin property, e.g. "10px 20px 30px 40px" (top, right, bottom, left). */
rootMargin: _propTypes2.default.string,
rootMargin: PropTypes.string,
/** Unique identifier for the root element - This is used to identify the IntersectionObserver instance, so it can be reused.
* If you defined a root element, without adding an id, it will create a new instance for all components. */
rootId: _propTypes2.default.string,
rootId: PropTypes.string,
/** Call this function whenever the in view state changes */
onChange: _propTypes2.default.func,
onChange: PropTypes.func,
/** Use render method to only render content when inView */
render: _propTypes2.default.func
render: PropTypes.func
};

@@ -176,2 +125,2 @@ Observer.defaultProps = {

};
exports.default = Observer;
export default Observer;

@@ -1,12 +0,4 @@

"use strict";
const INSTANCE_MAP = new Map();
const OBSERVER_MAP = new Map();
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.observe = observe;
exports.unobserve = unobserve;
exports.destroy = destroy;
var INSTANCE_MAP = new Map();
var OBSERVER_MAP = new Map();
/**

@@ -22,19 +14,14 @@ * Monitor element, and trigger callback when element becomes visible

*/
function observe(element, callback) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
threshold: 0
};
var rootId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
var threshold = options.threshold,
root = options.root,
rootMargin = options.rootMargin;
export function observe(element, callback, options = {
threshold: 0
}, rootId = null) {
const { threshold, root, rootMargin } = options;
if (!element || !callback) return;
var observerId = rootMargin ? threshold + "_" + rootMargin : "" + threshold;
let observerId = rootMargin ? `${threshold}_${rootMargin}` : `${threshold}`;
if (root) {
observerId = rootId ? rootId + "_" + observerId : null;
observerId = rootId ? `${rootId}_${observerId}` : null;
}
var observerInstance = observerId ? OBSERVER_MAP.get(observerId) : null;
let observerInstance = observerId ? OBSERVER_MAP.get(observerId) : null;
if (!observerInstance) {

@@ -45,7 +32,7 @@ observerInstance = new IntersectionObserver(onChange, options);

var instance = {
callback: callback,
const instance = {
callback,
visible: false,
options: options,
observerId: observerId,
options,
observerId,
observer: !observerId ? observerInstance : undefined

@@ -66,12 +53,9 @@ };

*/
function unobserve(element) {
export function unobserve(element) {
if (!element) return;
if (INSTANCE_MAP.has(element)) {
var _INSTANCE_MAP$get = INSTANCE_MAP.get(element),
observerId = _INSTANCE_MAP$get.observerId,
observer = _INSTANCE_MAP$get.observer;
const { observerId, observer } = INSTANCE_MAP.get(element);
const observerInstance = observerId ? OBSERVER_MAP.get(observerId) : observer;
var observerInstance = observerId ? OBSERVER_MAP.get(observerId) : observer;
if (observerInstance) {

@@ -82,5 +66,5 @@ observerInstance.unobserve(element);

// Check if we are stilling observing any elements with the same threshold.
var itemsLeft = false;
let itemsLeft = false;
if (observerId) {
INSTANCE_MAP.forEach(function (item, key) {
INSTANCE_MAP.forEach((item, key) => {
if (item && item.observerId === observerId && key !== element) {

@@ -106,4 +90,4 @@ itemsLeft = true;

**/
function destroy() {
OBSERVER_MAP.forEach(function (observer) {
export function destroy() {
OBSERVER_MAP.forEach(observer => {
observer.disconnect();

@@ -117,16 +101,13 @@ });

function onChange(changes) {
changes.forEach(function (intersection) {
changes.forEach(intersection => {
if (INSTANCE_MAP.has(intersection.target)) {
var isIntersecting = intersection.isIntersecting,
intersectionRatio = intersection.intersectionRatio,
target = intersection.target;
const { isIntersecting, intersectionRatio, target } = intersection;
const instance = INSTANCE_MAP.get(target);
const options = instance.options;
var instance = INSTANCE_MAP.get(target);
var options = instance.options;
let inView;
var inView = void 0;
if (Array.isArray(options.threshold)) {
// If threshold is an array, check if any of them intersects. This just triggers the onChange event multiple times.
inView = options.threshold.some(function (threshold) {
inView = options.threshold.some(threshold => {
return instance.visible ? intersectionRatio > threshold : intersectionRatio >= threshold;

@@ -155,6 +136,6 @@ });

exports.default = {
observe: observe,
unobserve: unobserve,
destroy: destroy
export default {
observe,
unobserve,
destroy
};
{
"name": "react-intersection-observer",
"version": "1.0.1",
"version": "1.1.0",
"description": "Monitor if a component is inside the viewport, using IntersectionObserver API",

@@ -42,34 +42,19 @@ "main": "lib/index.js",

},
"babel": {
"presets": [
"env",
"react",
"stage-2"
],
"env": {
"es": {
"presets": [
[
"env",
{
"modules": false
}
],
"react",
"stage-2"
]
}
}
},
"eslintConfig": {
"extends": [
"insilico",
"prettier",
"prettier/react"
"insilico"
]
},
"babel": {
"presets": [
"./.babelrc.js"
]
},
"jest": {
"testEnvironment": "node",
"snapshotSerializers": [
"<rootDir>/node_modules/enzyme-to-json/serializer"
"enzyme-to-json/serializer"
],
"setupFiles": [
"<rootDir>/jest-setup.js"
]

@@ -83,8 +68,8 @@ },

"devDependencies": {
"@storybook/addon-actions": "^3.1.9",
"@storybook/addon-options": "^3.1.6",
"@storybook/react": "^3.1.9",
"@storybook/addon-actions": "^3.2.11",
"@storybook/addon-options": "^3.2.10",
"@storybook/react": "^3.2.11",
"babel-cli": "^6.24.1",
"babel-core": "^6.25.0",
"babel-jest": "^21.0.0",
"babel-jest": "^21.2.0",
"babel-preset-env": "^1.6.0",

@@ -94,17 +79,17 @@ "babel-preset-react": "^6.24.1",

"concurrently": "3.5.0",
"enzyme": "^2.9.1",
"enzyme-to-json": "^1.5.1",
"eslint": "^4.3.0",
"eslint-config-insilico": "^4.1.1",
"eslint-config-prettier": "^2.3.0",
"enzyme": "^3.0.0",
"enzyme-adapter-react-16": "^1.0.0",
"enzyme-to-json": "^3.0.1",
"eslint": "^4.7.2",
"eslint-config-insilico": "^5.0.0",
"husky": "^0.14.3",
"intersection-observer": "^0.4.0",
"jest": "^21.0.0",
"lint-staged": "^4.0.2",
"prettier": "^1.5.3",
"prop-types": "^15.5.10",
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-test-renderer": "^15.6.1"
"jest": "^21.2.0",
"lint-staged": "^4.2.3",
"prettier": "^1.7.0",
"prop-types": "^15.6.0",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-test-renderer": "^16.0.0"
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc