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

react-peekaboo

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-peekaboo - npm Package Compare versions

Comparing version 0.3.0 to 0.4.0

dist/index.esm.js.map

24

dist/index.d.ts

@@ -1,16 +0,8 @@

import { Component } from 'react';
import IO from './IO';
import Scroll from './Scroll';
import { Props } from './types';
export { IO, Props, Scroll };
export declare class InView extends Component<Props> {
static defaultProps: {
enabled: boolean;
offsetBottom: number;
offsetLeft: number;
offsetRight: number;
offsetTop: number;
throttle: number;
};
render(): import("react").ComponentElement<Props, Scroll> | import("react").ComponentElement<Pick<Props, "enabled" | "children" | "offsetBottom" | "offsetLeft" | "offsetRight" | "offsetTop" | "onChange">, IO>;
}
import { RefCallback } from 'react';
import { ChangeHandler, Options as PeekabooOptions, SetupHandler } from 'dom-peekaboo';
export declare type Options = PeekabooOptions & {
enabled?: boolean;
};
export declare function usePeekaboo<E extends HTMLElement>(setup: SetupHandler, onChange: ChangeHandler, options?: Options): RefCallback<E>;
export declare function useIntersectionChange<E extends HTMLElement>(onChange: ChangeHandler, options?: Options): RefCallback<E>;
export declare function useIntersecting<E extends HTMLElement>(options?: Options): [RefCallback<E>, boolean];

@@ -1,288 +0,2 @@

import _classCallCheck from '@babel/runtime/helpers/esm/classCallCheck';
import _createClass from '@babel/runtime/helpers/esm/createClass';
import _possibleConstructorReturn from '@babel/runtime/helpers/esm/possibleConstructorReturn';
import _getPrototypeOf from '@babel/runtime/helpers/esm/getPrototypeOf';
import _inherits from '@babel/runtime/helpers/esm/inherits';
import { Component, createElement } from 'react';
import _slicedToArray from '@babel/runtime/helpers/esm/slicedToArray';
import throttleFunc from 'lodash.throttle';
var defaultProps = {
enabled: true,
offsetBottom: 0,
offsetLeft: 0,
offsetRight: 0,
offsetTop: 0,
throttle: 100
};
var supported;
function intersectionObserverSupported() {
if (supported === undefined) {
supported = typeof window !== 'undefined' && 'IntersectionObserver' in window;
}
return supported;
}
function io(_ref) {
var element = _ref.element,
offsetBottom = _ref.offsetBottom,
offsetLeft = _ref.offsetLeft,
offsetRight = _ref.offsetRight,
offsetTop = _ref.offsetTop,
onChange = _ref.onChange;
var rootMargin = "".concat(offsetBottom, "px ").concat(offsetLeft, "px ").concat(offsetTop, "px ").concat(offsetRight, "px");
var observer = new IntersectionObserver(function (_ref2) {
var _ref3 = _slicedToArray(_ref2, 1),
entry = _ref3[0];
onChange(entry.isIntersecting);
}, {
root: null,
rootMargin: rootMargin
});
observer.observe(element);
return function () {
observer.unobserve(element);
};
}
function isElementInDocument(element) {
return 'isConnected' in element ? element.isConnected : document.body.contains(element);
}
function isElementIntersecting(element, _ref4) {
var offsetBottom = _ref4.offsetBottom,
offsetLeft = _ref4.offsetLeft,
offsetRight = _ref4.offsetRight,
offsetTop = _ref4.offsetTop;
if (!isElementInDocument(element)) {
return false;
}
var rect = element.getBoundingClientRect();
var adjustedBottom = rect.bottom + offsetBottom;
var adjustedLeft = rect.left - offsetLeft;
var adjustedRight = rect.right + offsetRight;
var adjustedTop = rect.top - offsetTop;
return adjustedBottom >= 0 && adjustedLeft <= window.innerWidth && adjustedRight >= 0 && adjustedTop <= window.innerHeight;
}
function scroll(_ref5) {
var element = _ref5.element,
offsetBottom = _ref5.offsetBottom,
offsetLeft = _ref5.offsetLeft,
offsetRight = _ref5.offsetRight,
offsetTop = _ref5.offsetTop,
onChange = _ref5.onChange,
throttle = _ref5.throttle;
var prevInViewport;
var checkViewport = function checkViewport() {
var isInViewport = element ? isElementIntersecting(element, {
offsetBottom: offsetBottom,
offsetLeft: offsetLeft,
offsetRight: offsetRight,
offsetTop: offsetTop
}) : false;
if (isInViewport !== prevInViewport) {
prevInViewport = isInViewport;
onChange(isInViewport);
}
};
var eventHandler = throttleFunc(checkViewport, throttle);
checkViewport();
window.addEventListener('scroll', eventHandler);
window.addEventListener('resize', eventHandler);
return function () {
window.removeEventListener('scroll', eventHandler);
window.removeEventListener('resize', eventHandler);
};
}
var IO =
/*#__PURE__*/
function (_Component) {
_inherits(IO, _Component);
function IO() {
var _this;
_classCallCheck(this, IO);
_this = _possibleConstructorReturn(this, _getPrototypeOf(IO).apply(this, arguments));
_this.state = {
element: null
};
_this.childRef = function (element) {
_this.setState({
element: element
});
};
_this.teardown = null;
_this.setup = function () {
if (_this.props.enabled && _this.state.element) {
var _this$props = _this.props,
offsetBottom = _this$props.offsetBottom,
offsetLeft = _this$props.offsetLeft,
offsetRight = _this$props.offsetRight,
offsetTop = _this$props.offsetTop,
onChange = _this$props.onChange;
_this.teardown = io({
element: _this.state.element,
offsetBottom: offsetBottom,
offsetLeft: offsetLeft,
offsetRight: offsetRight,
offsetTop: offsetTop,
onChange: onChange
});
}
};
_this.safeTeardown = function () {
if (_this.teardown) {
_this.teardown();
_this.teardown = null;
}
};
return _this;
}
_createClass(IO, [{
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps, prevState) {
if (prevProps.children !== this.props.children || prevProps.enabled !== this.props.enabled || prevProps.offsetBottom !== this.props.offsetBottom || prevProps.offsetLeft !== this.props.offsetLeft || prevProps.offsetRight !== this.props.offsetRight || prevProps.offsetTop !== this.props.offsetTop || prevProps.onChange !== this.props.onChange || prevState.element !== this.state.element) {
this.safeTeardown();
this.setup();
}
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.safeTeardown();
}
}, {
key: "render",
value: function render() {
return this.props.children(this.childRef);
}
}]);
return IO;
}(Component);
IO.defaultProps = defaultProps;
var Scroll =
/*#__PURE__*/
function (_Component) {
_inherits(Scroll, _Component);
function Scroll() {
var _this;
_classCallCheck(this, Scroll);
_this = _possibleConstructorReturn(this, _getPrototypeOf(Scroll).apply(this, arguments));
_this.state = {
element: null
};
_this.childRef = function (element) {
_this.setState({
element: element
});
};
_this.teardown = null;
_this.setup = function () {
if (_this.props.enabled && _this.state.element) {
var _this$props = _this.props,
offsetBottom = _this$props.offsetBottom,
offsetLeft = _this$props.offsetLeft,
offsetRight = _this$props.offsetRight,
offsetTop = _this$props.offsetTop,
onChange = _this$props.onChange,
throttle = _this$props.throttle;
_this.teardown = scroll({
offsetBottom: offsetBottom,
offsetLeft: offsetLeft,
offsetRight: offsetRight,
offsetTop: offsetTop,
onChange: onChange,
element: _this.state.element,
throttle: throttle
});
}
};
_this.safeTeardown = function () {
if (_this.teardown) {
_this.teardown();
_this.teardown = null;
}
};
return _this;
}
_createClass(Scroll, [{
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps, prevState) {
if (prevProps.children !== this.props.children || prevProps.enabled !== this.props.enabled || prevProps.offsetBottom !== this.props.offsetBottom || prevProps.offsetLeft !== this.props.offsetLeft || prevProps.offsetRight !== this.props.offsetRight || prevProps.offsetTop !== this.props.offsetTop || prevProps.onChange !== this.props.onChange || prevProps.throttle !== this.props.throttle || prevState.element !== this.state.element) {
this.safeTeardown();
this.setup();
}
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.safeTeardown();
}
}, {
key: "render",
value: function render() {
return this.props.children(this.childRef);
}
}]);
return Scroll;
}(Component);
Scroll.defaultProps = defaultProps;
var InView =
/*#__PURE__*/
function (_Component) {
_inherits(InView, _Component);
function InView() {
_classCallCheck(this, InView);
return _possibleConstructorReturn(this, _getPrototypeOf(InView).apply(this, arguments));
}
_createClass(InView, [{
key: "render",
value: function render() {
if (!intersectionObserverSupported()) {
return createElement(Scroll, this.props);
}
return createElement(IO, this.props);
}
}]);
return InView;
}(Component);
InView.defaultProps = defaultProps;
export { IO, InView, Scroll };
import{useState as r,useEffect as o}from"react";import{peekaboo as n}from"dom-peekaboo";function t(n,t,e){void 0===e&&(e={});var i=r(null),u=i[0],f=i[1];return o(function(){if(u&&!1!==e.enabled)return n(u,t,e)},[u,t,e]),f}function e(r,o){return void 0===o&&(o={}),t(n,r,o)}function i(o){void 0===o&&(o={});var e=r(!1),i=e[0];return[t(n,e[1],o),i]}export{i as useIntersecting,e as useIntersectionChange,t as usePeekaboo};
//# sourceMappingURL=index.esm.js.map

@@ -1,296 +0,2 @@

'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var _classCallCheck = _interopDefault(require('@babel/runtime/helpers/classCallCheck'));
var _createClass = _interopDefault(require('@babel/runtime/helpers/createClass'));
var _possibleConstructorReturn = _interopDefault(require('@babel/runtime/helpers/possibleConstructorReturn'));
var _getPrototypeOf = _interopDefault(require('@babel/runtime/helpers/getPrototypeOf'));
var _inherits = _interopDefault(require('@babel/runtime/helpers/inherits'));
var react = require('react');
var _slicedToArray = _interopDefault(require('@babel/runtime/helpers/slicedToArray'));
var throttleFunc = _interopDefault(require('lodash.throttle'));
var defaultProps = {
enabled: true,
offsetBottom: 0,
offsetLeft: 0,
offsetRight: 0,
offsetTop: 0,
throttle: 100
};
var supported;
function intersectionObserverSupported() {
if (supported === undefined) {
supported = typeof window !== 'undefined' && 'IntersectionObserver' in window;
}
return supported;
}
function io(_ref) {
var element = _ref.element,
offsetBottom = _ref.offsetBottom,
offsetLeft = _ref.offsetLeft,
offsetRight = _ref.offsetRight,
offsetTop = _ref.offsetTop,
onChange = _ref.onChange;
var rootMargin = "".concat(offsetBottom, "px ").concat(offsetLeft, "px ").concat(offsetTop, "px ").concat(offsetRight, "px");
var observer = new IntersectionObserver(function (_ref2) {
var _ref3 = _slicedToArray(_ref2, 1),
entry = _ref3[0];
onChange(entry.isIntersecting);
}, {
root: null,
rootMargin: rootMargin
});
observer.observe(element);
return function () {
observer.unobserve(element);
};
}
function isElementInDocument(element) {
return 'isConnected' in element ? element.isConnected : document.body.contains(element);
}
function isElementIntersecting(element, _ref4) {
var offsetBottom = _ref4.offsetBottom,
offsetLeft = _ref4.offsetLeft,
offsetRight = _ref4.offsetRight,
offsetTop = _ref4.offsetTop;
if (!isElementInDocument(element)) {
return false;
}
var rect = element.getBoundingClientRect();
var adjustedBottom = rect.bottom + offsetBottom;
var adjustedLeft = rect.left - offsetLeft;
var adjustedRight = rect.right + offsetRight;
var adjustedTop = rect.top - offsetTop;
return adjustedBottom >= 0 && adjustedLeft <= window.innerWidth && adjustedRight >= 0 && adjustedTop <= window.innerHeight;
}
function scroll(_ref5) {
var element = _ref5.element,
offsetBottom = _ref5.offsetBottom,
offsetLeft = _ref5.offsetLeft,
offsetRight = _ref5.offsetRight,
offsetTop = _ref5.offsetTop,
onChange = _ref5.onChange,
throttle = _ref5.throttle;
var prevInViewport;
var checkViewport = function checkViewport() {
var isInViewport = element ? isElementIntersecting(element, {
offsetBottom: offsetBottom,
offsetLeft: offsetLeft,
offsetRight: offsetRight,
offsetTop: offsetTop
}) : false;
if (isInViewport !== prevInViewport) {
prevInViewport = isInViewport;
onChange(isInViewport);
}
};
var eventHandler = throttleFunc(checkViewport, throttle);
checkViewport();
window.addEventListener('scroll', eventHandler);
window.addEventListener('resize', eventHandler);
return function () {
window.removeEventListener('scroll', eventHandler);
window.removeEventListener('resize', eventHandler);
};
}
var IO =
/*#__PURE__*/
function (_Component) {
_inherits(IO, _Component);
function IO() {
var _this;
_classCallCheck(this, IO);
_this = _possibleConstructorReturn(this, _getPrototypeOf(IO).apply(this, arguments));
_this.state = {
element: null
};
_this.childRef = function (element) {
_this.setState({
element: element
});
};
_this.teardown = null;
_this.setup = function () {
if (_this.props.enabled && _this.state.element) {
var _this$props = _this.props,
offsetBottom = _this$props.offsetBottom,
offsetLeft = _this$props.offsetLeft,
offsetRight = _this$props.offsetRight,
offsetTop = _this$props.offsetTop,
onChange = _this$props.onChange;
_this.teardown = io({
element: _this.state.element,
offsetBottom: offsetBottom,
offsetLeft: offsetLeft,
offsetRight: offsetRight,
offsetTop: offsetTop,
onChange: onChange
});
}
};
_this.safeTeardown = function () {
if (_this.teardown) {
_this.teardown();
_this.teardown = null;
}
};
return _this;
}
_createClass(IO, [{
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps, prevState) {
if (prevProps.children !== this.props.children || prevProps.enabled !== this.props.enabled || prevProps.offsetBottom !== this.props.offsetBottom || prevProps.offsetLeft !== this.props.offsetLeft || prevProps.offsetRight !== this.props.offsetRight || prevProps.offsetTop !== this.props.offsetTop || prevProps.onChange !== this.props.onChange || prevState.element !== this.state.element) {
this.safeTeardown();
this.setup();
}
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.safeTeardown();
}
}, {
key: "render",
value: function render() {
return this.props.children(this.childRef);
}
}]);
return IO;
}(react.Component);
IO.defaultProps = defaultProps;
var Scroll =
/*#__PURE__*/
function (_Component) {
_inherits(Scroll, _Component);
function Scroll() {
var _this;
_classCallCheck(this, Scroll);
_this = _possibleConstructorReturn(this, _getPrototypeOf(Scroll).apply(this, arguments));
_this.state = {
element: null
};
_this.childRef = function (element) {
_this.setState({
element: element
});
};
_this.teardown = null;
_this.setup = function () {
if (_this.props.enabled && _this.state.element) {
var _this$props = _this.props,
offsetBottom = _this$props.offsetBottom,
offsetLeft = _this$props.offsetLeft,
offsetRight = _this$props.offsetRight,
offsetTop = _this$props.offsetTop,
onChange = _this$props.onChange,
throttle = _this$props.throttle;
_this.teardown = scroll({
offsetBottom: offsetBottom,
offsetLeft: offsetLeft,
offsetRight: offsetRight,
offsetTop: offsetTop,
onChange: onChange,
element: _this.state.element,
throttle: throttle
});
}
};
_this.safeTeardown = function () {
if (_this.teardown) {
_this.teardown();
_this.teardown = null;
}
};
return _this;
}
_createClass(Scroll, [{
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps, prevState) {
if (prevProps.children !== this.props.children || prevProps.enabled !== this.props.enabled || prevProps.offsetBottom !== this.props.offsetBottom || prevProps.offsetLeft !== this.props.offsetLeft || prevProps.offsetRight !== this.props.offsetRight || prevProps.offsetTop !== this.props.offsetTop || prevProps.onChange !== this.props.onChange || prevProps.throttle !== this.props.throttle || prevState.element !== this.state.element) {
this.safeTeardown();
this.setup();
}
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.safeTeardown();
}
}, {
key: "render",
value: function render() {
return this.props.children(this.childRef);
}
}]);
return Scroll;
}(react.Component);
Scroll.defaultProps = defaultProps;
var InView =
/*#__PURE__*/
function (_Component) {
_inherits(InView, _Component);
function InView() {
_classCallCheck(this, InView);
return _possibleConstructorReturn(this, _getPrototypeOf(InView).apply(this, arguments));
}
_createClass(InView, [{
key: "render",
value: function render() {
if (!intersectionObserverSupported()) {
return react.createElement(Scroll, this.props);
}
return react.createElement(IO, this.props);
}
}]);
return InView;
}(react.Component);
InView.defaultProps = defaultProps;
exports.IO = IO;
exports.InView = InView;
exports.Scroll = Scroll;
var e=require("react"),r=require("dom-peekaboo");function t(r,t,o){void 0===o&&(o={});var n=e.useState(null),u=n[0],a=n[1];return e.useEffect(function(){if(u&&!1!==o.enabled)return r(u,t,o)},[u,t,o]),a}exports.useIntersecting=function(o){void 0===o&&(o={});var n=e.useState(!1),u=n[0];return[t(r.peekaboo,n[1],o),u]},exports.useIntersectionChange=function(e,o){return void 0===o&&(o={}),t(r.peekaboo,e,o)},exports.usePeekaboo=t;
//# sourceMappingURL=index.js.map
{
"name": "react-peekaboo",
"description": "React component that notifies when its child enters or exits the viewport",
"version": "0.3.0",
"description": "React hooks for monitoring an element's intersection with the viewport",
"version": "0.4.0",
"license": "MIT",

@@ -31,58 +31,42 @@ "author": "Wyatt Johnston <w@wyatt.page>",

"lint-staged": {
"**/*.{js,jsx,ts,tsx,md}": [
"prettier --write",
"git add"
]
"*.{js,jsx,ts,tsx,md}": "prettier --write"
},
"scripts": {
"build": "tsc && rollup -c",
"ci": "npm run test:e2e:ci",
"dev": "cross-env NODE_ENV=dev next dev",
"prebuild": "rimraf compiled dist",
"prepublishOnly": "npm run test && npm run build",
"test": "npm run test:e2e",
"test:e2e": "start-server-and-test dev \"http://localhost:3000/list|http://localhost:3000/ref-swap\" test:jest:e2e",
"test:e2e:ci": "start-server-and-test dev \"http://localhost:3000/list|http://localhost:3000/ref-swap\" test:jest:e2e:ci",
"test:jest:e2e": "jest -c jest.config.e2e.js",
"test:jest:e2e:ci": "cross-env CI=true jest -c jest.config.e2e.js --runInBand",
"typecheck": "tsc"
"build": "microbundle build --jsx React.createElement",
"dev": "cross-env NODE_ENV=development next dev",
"prebuild": "rimraf dist",
"test": "jest",
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"@babel/core": "^7.4.0",
"@babel/plugin-proposal-class-properties": "^7.4.0",
"@babel/plugin-transform-runtime": "^7.4.0",
"@babel/preset-env": "^7.4.2",
"@babel/preset-react": "^7.0.0",
"@babel/preset-typescript": "^7.3.3",
"@types/jest": "^24.0.11",
"@babel/core": "^7.11.6",
"@babel/plugin-proposal-class-properties": "^7.10.4",
"@babel/plugin-transform-runtime": "^7.11.5",
"@babel/preset-env": "^7.11.5",
"@babel/preset-react": "^7.10.4",
"@babel/preset-typescript": "^7.10.4",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.0.2",
"@types/jest": "^26.0.13",
"@types/lodash.throttle": "^4.1.6",
"@types/react": "^16.8.8",
"@types/react-dom": "^16.8.3",
"@zeit/next-typescript": "^1.1.1",
"babel-jest": "^24.5.0",
"cross-env": "^5.2.0",
"husky": "^1.3.1",
"jest": "^24.5.0",
"jest-puppeteer": "^4.1.0",
"lint-staged": "^8.1.5",
"next": "^8.0.3",
"prettier": "^1.16.4",
"puppeteer": "^1.13.0",
"react": "^16.8.5",
"react-dom": "^16.8.5",
"rimraf": "^2.6.3",
"rollup": "^1.7.2",
"rollup-plugin-babel": "^4.3.2",
"rollup-plugin-commonjs": "^9.2.1",
"rollup-plugin-node-resolve": "^4.0.1",
"start-server-and-test": "^1.7.12",
"typescript": "^3.3.4000"
"@types/react": "^16.9.49",
"babel-jest": "^26.3.0",
"cross-env": "^7.0.2",
"husky": "^4.3.0",
"jest": "^26.4.2",
"lint-staged": "^10.3.0",
"microbundle": "^0.12.3",
"prettier": "^2.1.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"rimraf": "^3.0.2",
"typescript": "^4.0.2"
},
"dependencies": {
"@babel/runtime": "^7.0.0",
"dom-peekaboo": "^0.1.0",
"lodash.throttle": "^4.1.1"
},
"peerDependencies": {
"react": ">=16"
"react": ">=16.8.0"
}
}
# `react-peekaboo`
[![Build Status](https://cloud.drone.io/api/badges/wpj/react-peekaboo/status.svg)](https://cloud.drone.io/wpj/react-peekaboo)
[![CI Status](https://github.com/wpj/react-peekaboo/workflows/CI/badge.svg)](https://github.com/wpj/react-peekaboo/actions)
React component that notifies you when its child enters or exits the viewport.
Under the hood, it uses the `IntersectionObserver` API in supported environments
and falls back to listening for `scroll` and `resize` events in combination with
`getBoundingClientRect` in unsupported environments.
React hooks for monitoring an element's intersection with the viewport.

@@ -13,28 +10,27 @@ ## Installation

```
yarn add react-peekaboo
npm install react-peekaboo
```
Or
```
npm install --save react-peekaboo
```
## Usage
```jsx
```tsx
import React, { useState } from 'react';
import { InView } from 'react-peekaboo';
import { useIntersecting, useIntersectionChange } from 'react-peekaboo';
function Example() {
const [isInViewport, setIsInViewport] = useState(false);
function UseIntersectionExample() {
let [ref, isIntersecting] = useIntersecting<HTMLDivElement>();
return (
<InView onChange={setIsInViewport}>
{ref => (
<div ref={ref}>I am {isInViewport ? 'visible' : 'not visible'}.</div>
)}
</InView>
<div ref={ref}>I am {isIntersecting ? 'visible' : 'not visible'}.</div>
);
}
function UseIntersectionChangeExample() {
let [isIntersecting, onChange] = useState<boolean>(false);
let ref = useIntersectionChange<HTMLDivElement>(onChange);
return (
<div ref={ref}>I am {isIntersecting ? 'visible' : 'not visible'}.</div>
);
}
```

@@ -44,166 +40,72 @@

### `InView`
### Options
#### Props
All functions accept a common set of options:
##### `children: (ref: React.Ref<any>) => JSX.Element`
- `enabled?: boolean`: Enables/disables running the side effect that calculates
the element's intersection status. (default: `true`)
Render prop that accepts a ref as its parameter. You must apply the ref to a DOM
element.
- `offsetBottom?: number`: Number of pixels to add to the bottom of the area
checked against when computing element intersection. (default: `0`)
##### `enabled: boolean`
- `offsetLeft?: number`: Number of pixels to add to the left of the area checked
against when computing element intersection. (default: `0`)
Enables/disables running the viewport-check side effect.
- `offsetRight?: number`: Number of pixels to add to the right of the area
checked against when computing element intersection. (default: `0`)
Default: `true`
- `offsetTop?: number`: Number of pixels to add to the top of the area checked
against when computing element intersection. (default: `0`)
##### `offsetBottom?: number`
- `throttle?: number`: Number of ms to throttle scroll events (only applies in
environments that don't support IntersectionObserver or when using
`useScrollIntersection`/`useScrollIntersectionChangeCallback`). (default:
`100`)
Number of pixels to add to the bottom of the area checked against when computing
in view elements.
### Exports
Default: `0`
#### `useIntersecting`
##### `offsetLeft?: number`
Type: `(options: Options) => [RefCallback, boolean]`
Number of pixels to add to the left of the area checked against when computing
in view elements.
Returns a ref and the element's intersection status using IntersectionObserver
or `scroll`/`resize` event listeners and `getBoundingClientRect` in unsupported
environments.
Default: `0`
The ref returned must be attached to a DOM node.
##### `offsetRight?: number`
#### `useIntersectionChange`
Number of pixels to add to the right of the area checked against when computing
in view elements.
Type:
Default: `0`
```typescript
(onChange: (isIntersecting: boolean) => void, options: Options) => RefCallback;
```
##### `offsetTop?: number`
Runs a callback that receives the element's intersection status each time it
changes using IntersectionObserver or `scroll`/`resize` event listeners and
`getBoundingClientRect` in unsupported environments.
Number of pixels to add to the top of the area checked against when computing in
view elements.
Returns a ref that must be attached to a DOM node.
Default: `0`
#### `usePeekaboo`
##### `onChange: (isInviewPort: boolean) => void`
Type:
Callback that's invoked each time the wrapped element enters or exits the
viewport.
```typescript
type SetupHandler = (
element: HTMLElement,
onChange: (isIntersecting: boolean) => void,
options?: Options,
) => TeardownHandler;
##### `throttle?: number`
(
setup: SetupHandler,
onChange: (isIntersecting: boolean) => void,
options?: Options,
) => RefCallback;
```
Number of ms to throttle scroll events (only applies in environments that don't
support IntersectionObserver).
Default: `100`
### `IO`
#### Props
##### `children: (ref: React.Ref<any>) => JSX.Element`
Render prop that accepts a ref as its parameter. You must apply the ref to a DOM
element.
##### `enabled: boolean`
Enables/disables running the viewport-check side effect.
Default: `true`
##### `offsetBottom?: number`
Number of pixels to add to the bottom of the area checked against when computing
in view elements.
Default: `0`
##### `offsetLeft?: number`
Number of pixels to add to the left of the area checked against when computing
in view elements.
Default: `0`
##### `offsetRight?: number`
Number of pixels to add to the right of the area checked against when computing
in view elements.
Default: `0`
##### `offsetTop?: number`
Number of pixels to add to the top of the area checked against when computing in
view elements.
Default: `0`
##### `onChange: (isInviewPort: boolean) => void`
Callback that's invoked each time the wrapped element enters or exits the
viewport.
### `Scroll`
##### `children: (ref: React.Ref<any>) => JSX.Element`
Render prop that accepts a ref as its parameter. You must apply the ref to a DOM
element.
##### `enabled: boolean`
Enables/disables running the viewport-check side effect.
Default: `true`
##### `offsetBottom?: number`
Number of pixels to add to the bottom of the area checked against when computing
in view elements.
Default: `0`
##### `offsetLeft?: number`
Number of pixels to add to the left of the area checked against when computing
in view elements.
Default: `0`
##### `offsetRight?: number`
Number of pixels to add to the right of the area checked against when computing
in view elements.
Default: `0`
##### `offsetTop?: number`
Number of pixels to add to the top of the area checked against when computing in
view elements.
Default: `0`
##### `onChange: (isInviewPort: boolean) => void`
Callback that's invoked each time the wrapped element enters or exits the
viewport.
##### `throttle?: number`
Number of ms to throttle scroll events.
Default: `100`
## Caveats
- This module considers edge-adjacent intersections (when the target element is
directly above/below/beside the viewport) to be in viewport. If you only want
to consider elements with pixels in the viewport as visible, you can configure
`offsetBottom`/`offsetLeft`/`offsetRight`/`offsetTop` to be `-1`.
- IntersectionObserver ignores `rootMargin` in iframe contexts, which means that
offsets will be ignored.
- https://w3c.github.io/IntersectionObserver/#dom-intersectionobserver-rootmargin
- https://developers.google.com/web/updates/2016/04/intersectionobserver#iframe_magic
Uses `setup` to run `onChange` when the element's intersection status changes.
You can pass `scroll`, `io`, or `peekaboo` from `dom-peekaboo` or implement our
own setup function.
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