New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

react-scroll-percentage

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-scroll-percentage - npm Package Compare versions

Comparing version 3.1.0 to 4.0.0

index.d.ts

108

package.json
{
"name": "react-scroll-percentage",
"version": "3.1.0",
"version": "4.0.0",
"description": "Monitor the scroll percentage of a component inside the viewport, using the IntersectionObserver API.",

@@ -9,6 +9,2 @@ "main": "dist/react-scroll-percentage.cjs.js",

"unpkg": "dist/react-scroll-percentage.umd.min.js",
"files": [
"dist/*",
"src/*"
],
"author": "Daniel Schmidt",

@@ -28,103 +24,9 @@ "repository": {

],
"scripts": {
"build": "rm -rf dist && npm run build:lib && npm run build:flow",
"build:lib": "run-p rollup:*",
"build:storybook": "build-storybook --output-dir example",
"build:flow": "node scripts/create-flow",
"dev": "concurrently -k -r 'jest --watch' 'npm run storybook'",
"lint": "eslint {src,stories,tests}/.",
"rollup:es": "rollup -c --environment FORMAT:es",
"rollup:cjs": "rollup -c --environment FORMAT:cjs",
"rollup:umd": "rollup -c --environment FORMAT:umd",
"rollup:umd.min": "rollup -c --environment MINIFY,FORMAT:umd",
"prepare": "npm run build",
"pretty": "prettier '**/*.{js,json,md,ts}' --write",
"storybook": "start-storybook -p 9000",
"test": "jest"
},
"husky": {
"hooks": {
"pre-commit": "flow status && lint-staged",
"post-commit": "git update-index --again"
}
},
"lint-staged": {
"*.{js,json,css,md,ts}": [
"prettier --write",
"git add"
],
"src/**/*.js": [
"eslint",
"jest --findRelatedTests",
"flow force-recheck --focus"
]
},
"eslintConfig": {
"extends": [
"insilico"
]
},
"jest": {
"testEnvironment": "jsdom",
"snapshotSerializers": [
"enzyme-to-json/serializer"
],
"setupFiles": [
"<rootDir>/scripts/jest-setup.js"
]
},
"dependencies": {
"invariant": "^2.2.4",
"react-intersection-observer": "^6.4.0"
"@babel/runtime": "^7.4.5",
"react-intersection-observer": "^8.23.0"
},
"peerDependencies": {
"react": "^15.0.0 || ^16.0.0"
},
"devDependencies": {
"@babel/cli": "^7.2.3",
"@babel/core": "^7.2.2",
"@babel/plugin-external-helpers": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.2.3",
"@babel/plugin-proposal-decorators": "^7.2.3",
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
"@babel/plugin-proposal-function-sent": "^7.1.0",
"@babel/plugin-proposal-json-strings": "^7.0.0",
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/preset-env": "^7.2.3",
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@babel/runtime": "^7.0.0",
"@storybook/addon-actions": "^4.1.4",
"@storybook/addon-options": "^4.1.4",
"@storybook/react": "^4.1.4",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^23.6.0",
"babel-loader": "^8.0.5",
"concurrently": "^4.0.1",
"enzyme": "^3.8.0",
"enzyme-adapter-react-16": "^1.7.1",
"enzyme-to-json": "^3.3.4",
"eslint": "^5.12.0",
"eslint-config-insilico": "^6.0.0",
"flow-bin": "^0.89.0",
"flow-copy-source": "^2.0.2",
"husky": "^1.3.1",
"intersection-observer": "^0.5.0",
"jest": "^23.6.0",
"lint-staged": "^8.1.0",
"npm-run-all": "^4.1.3",
"prettier": "^1.14.3",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"react-test-renderer": "^16.7.0",
"rollup": "^1.0.2",
"rollup-plugin-babel": "^4.2.0",
"rollup-plugin-commonjs": "^9.1.8",
"rollup-plugin-node-resolve": "^4.0.0",
"rollup-plugin-replace": "^2.0.0",
"rollup-plugin-uglify": "^6.0.0"
"react": "^15.0.0 || ^16.0.0 || ^17.0.0"
}
}
}
# react-scroll-percentage
[![Greenkeeper badge](https://badges.greenkeeper.io/thebuilder/react-scroll-percentage.svg)](https://greenkeeper.io/)
[![Travis](https://travis-ci.org/thebuilder/react-scroll-percentage.svg?branch=master)](https://travis-ci.org/thebuilder/react-scroll-percentage)
[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
[![npm](https://img.shields.io/npm/v/react-scroll-percentage.svg)](https://www.npmjs.com/package/react-scroll-percentage)
[![Version Badge][npm-version-svg]][package-url]
[![GZipped size][npm-minzip-svg]][bundlephobia-url]
[![Build Status][travis-svg]][travis-url]
[![Coverage Statu][coveralls-svg]][coveralls-url]
[![dependency status][deps-svg]][deps-url]
[![dev dependency status][dev-deps-svg]][dev-deps-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]
[![Greenkeeper badge][greenkeeper-svg]][greenkeeper-url]
[![styled with prettier][prettier-svg]][prettier-url]
React component that reports the current scroll percentage of a element inside
the viewport. It uses [React Intersection
Observer](https://github.com/thebuilder/react-intersection-observer) to only
report the percentage when the element is inside the viewport.
the viewport. Contains both a [Hooks](#hooks), [render props](#render-props) and
[plain children](#plain-children) implementation.
```js
import ScrollPercentage from 'react-scroll-percentage'
;<ScrollPercentage>
{percentage => (
<h2>{`Percentage scrolled: ${percentage.toPrecision(2)}%.`}</h2>
)}
</ScrollPercentage>
```
## Features
## Demo
- 🎣 **Hooks or Component API** - With `useCrollPercentage` it's easier than
ever to monitor elements
- ⚡️ **Optimized performance** - Uses
[React Intersection Observer](https://github.com/thebuilder/react-intersection-observer)
to only update when elements are inside the viewport
- 🌳 **Tree-shakeable** - Only include the parts you use
See https://thebuilder.github.io/react-scroll-percentage/ for a demo.
## Installation

@@ -40,58 +41,133 @@

## Props
> ⚠️ You also want to add the
> [intersection-observer](https://www.npmjs.com/package/react-scroll-percentage)
> polyfill for full browser support. Check out adding the [polyfill](#polyfill)
> for details about how you can include it.
The **`<ScrollPercentage />`** accepts the following props:
## Usage
| Name | Type | Default | Required | Description |
| --------- | ----------------------------------------------- | ------- | -------- | ----------------------------------------------------------------------------------------- |
| tag | Node | 'div' | true | Element tag to use for the wrapping component |
| children | ((percentage: number, inView: boolean) => Node) | | true | Children should be either a function or a node |
| threshold | Number | 0 | false | Number between 0 and 1 indicating the percentage that should be visible before triggering |
| onChange | (percentage: number, inView: boolean) => void | | false | Call this function whenever the in view state changes |
| innerRef | (element: ?HTMLElement) => void | | false | Get a reference to the inner DOM node |
### Hooks 🎣
## Example code
#### `useScrollPercentage`
### Render prop
```js
const [ref, percentage] = useScrollPercentage(options)
```
The basic usage pass a function as the child. It will be called whenever the
state changes, with the current value of `percentage` and `inView`.
Call the `useScrollPercentage` hook, with the (optional) [options](#options) you
need. It will return an array containing a `ref`, the current scroll
`percentage` and the current
[`IntersectionObserverEntry`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserverEntry).
Assign the `ref` to the DOM element you want to monitor, and the hook will
report the status.
> Note that <ScrollPercentage> will still render a wrapping element (default is a `<div>`).
> You can change to element by setting `tag`, and any excess props like `className` will be passed to the element
```jsx
import React from 'react'
import { useScrollPercentage } from 'react-scroll-percentage'
```js
import ScrollPercentage from 'react-scroll-percentage'
;<ScrollPercentage>
{(percentage, inView) => (
<h2>{`Percentage scrolled: ${percentage.toPrecision(2)}%.`}</h2>
)}
</ScrollPercentage>
const Component = () => {
const [ref, percentage] = useScrollPercentage({
/* Optional options */
threshold: 0,
})
return (
<div ref={ref}>
<h2>{`Percentage scrolled: ${percentage.toPrecision(2)}%.`}</h2>
</div>
)
}
```
### OnChange callback
### Render props
You can monitor the onChange method, and control the state in your own
component. The child node will always be rendered.
To use the `<ScrollPercentage>` component, you pass it a function. It will be
called whenever the user scrolls the viewport, with the new value of
`percentage`. In addition to the `percentage`, children also receives a `ref`
that should be set on the containing DOM element.
```js
import ScrollPercentage from 'react-scroll-percentage'
;<ScrollPercentage
onChange={(percentage, inView) => console.log(percentage, inView)}
>
<h2>Plain children are always rendered. Use onChange to monitor state.</h2>
</ScrollPercentage>
If you need it, you can also access the
[`IntersectionObserverEntry`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserverEntry)
on `entry`, giving you access to all the details about the current intersection
state.
```jsx
import { ScrollPercentage } from 'react-scroll-percentage'
const Component = () => (
<ScrollPercentage>
{({ percentage, ref, entry }) => (
<div ref={ref}>
<h2>{`Percentage scrolled: ${percentage.toPrecision(2)}%.`}</h2>
</div>
)}
</ScrollPercentage>
)
export default Component
```
## Polyfills
### Plain children
### Intersection Observer
You can pass any element to the `<ScrollPercentage />`, and it will handle
creating the wrapping DOM element. Add a handler to the `onChange` method, and
control the state in your own component. Any extra props you add the
`<ScrollPercentage />` will be passed to the HTML element, allowing you set the
`className`, `style`, etc.
```jsx
import { ScrollPercentage } from 'react-scroll-percentage'
const Component = () => (
<ScrollPercentage
as="div"
onChange={(percentage, entry) => console.log('Percentage:', percentage)}
>
<h2>Plain children are always rendered. Use onChange to monitor state.</h2>
</ScrollPercentage>
)
export default Component
```
> ⚠️ When rendering a plain child, make sure you keep your HTML output semantic.
> Change the `as` to match the context, and add a `className` to style the
> `<ScrollPercentage />`. The component does not support Ref Forwarding, so if
> you need a `ref` to the HTML element, use the Render Props version instead.
### Options
Provide these as props on the **`<ScrollPercentage />`** component and as the
options argument for the hooks.
| Name | Type | Default | Required | Description |
| --------------- | ------- | ------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **root** | Element | window | false | The Element that is used as the viewport for checking visibility of the target. Defaults to the browser viewport (`window`) if not specified or if null. |
| **rootMargin** | string | '0px' | false | Margin around the root. Can have values similar to the CSS margin property, e.g. "10px 20px 30px 40px" (top, right, bottom, left). |
| **threshold** | number | 0 | false | Number between 0 and 1 indicating the percentage that should be visible before triggering. |
| **triggerOnce** | boolean | false | false | Only trigger this method once |
### ScrollPercentage Props
The **`<ScrollPercentage />`** component also accepts the following props:
| Name | Type | Default | Required | Description |
| ------------ | ------------------------------------------------------------ | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **as** | `string` | 'div' | false | Render the wrapping element as this element. Defaults to `div`. |
| **children** | `({ref, percentage, entry}) => React.ReactNode`, `ReactNode` | | true | Children expects a function that receives an object containing the `percentage` boolean and a `ref` that should be assigned to the element root. Alternatively pass a plain child, to have the `<InView />` deal with the wrapping element. You will also get the `IntersectionObserverEntry` as `entry, giving you more details. |
| **onChange** | `(percentage, entry) => void` | | false | Call this function whenever the in view state changes. It will receive the `percentage` value, alongside the current `IntersectionObserverEntry`. |
## Intersection Observer
[Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)
is the API is used to determine if an element is inside the viewport or not. Browser support is pretty good, but Safari is still missing support.
is the API is used to determine if an element is inside the viewport or not.
[Browser support is pretty good](http://caniuse.com/#feat=intersectionobserver) -
With
[Safari adding support in 12.1](https://webkit.org/blog/8718/new-webkit-features-in-safari-12-1/),
all major browsers now support Intersection Observers natively.
> [Can i use intersectionobserver?](https://caniuse.com/#feat=intersectionobserver)
### Polyfill
You can import the
[polyfill](https://www.npmjs.com/package/react-intersection-observer) directly or use
[polyfill](https://www.npmjs.com/package/intersection-observer) directly or use
a service like [polyfill.io](https://polyfill.io/v2/docs/) to add it when

@@ -110,37 +186,42 @@ needed.

If you are using Webpack (or similar) you could use [dynamic
imports](https://webpack.js.org/api/module-methods/#import-), to load the
Polyfill only if needed. A basic implementation could look something like this:
If you are using Webpack (or similar) you could use
[dynamic imports](https://webpack.js.org/api/module-methods/#import-), to load
the Polyfill only if needed. A basic implementation could look something like
this:
```js
loadPolyfills()
.then(() => /* Render React application now that your Polyfills are ready */)
/**
* Do feature detection, to figure out which polyfills needs to be imported.
**/
function loadPolyfills() {
const polyfills = []
if (!supportsIntersectionObserver()) {
polyfills.push(import('intersection-observer'))
* Do feature detection, to figure out which polyfills needs to be imported.
**/
async function loadPolyfills() {
if (typeof window.IntersectionObserver === 'undefined') {
await import('intersection-observer')
}
return Promise.all(polyfills)
}
function supportsIntersectionObserver() {
return (
'IntersectionObserver' in global &&
'IntersectionObserverEntry' in global &&
'intersectionRatio' in IntersectionObserverEntry.prototype
)
}
```
### requestAnimationFrame
To optimize scroll updates,
[requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame)
is used. Make sure your target browsers support it, or include the required
polyfill.
[package-url]: https://npmjs.org/package/react-scroll-percentage
[npm-version-svg]: https://img.shields.io/npm/v/react-scroll-percentage.svg
[npm-minzip-svg]: https://img.shields.io/bundlephobia/minzip/react.svg
[bundlephobia-url]: https://bundlephobia.com/result?p=react-scroll-percentage
[travis-svg]: https://travis-ci.org/thebuilder/react-scroll-percentage.svg
[travis-url]: https://travis-ci.org/thebuilder/react-scroll-percentage
[coveralls-svg]:
https://coveralls.io/repos/github/thebuilder/react-scroll-percentage/badge.svg?branch=master
[coveralls-url]:
https://coveralls.io/github/thebuilder/react-scroll-percentage?branch=master
[deps-svg]: https://david-dm.org/thebuilder/react-scroll-percentage.svg
[deps-url]: https://david-dm.org/thebuilder/react-scroll-percentage
[dev-deps-svg]:
https://david-dm.org/thebuilder/react-scroll-percentage/dev-status.svg
[dev-deps-url]:
https://david-dm.org/thebuilder/react-scroll-percentage#info=devDependencies
[license-image]: http://img.shields.io/npm/l/react-scroll-percentage.svg
[license-url]: LICENSE
[downloads-image]: http://img.shields.io/npm/dm/react-scroll-percentage.svg
[downloads-url]: http://npm-stat.com/charts.html?package=react-scroll-percentage
[greenkeeper-svg]:
https://badges.greenkeeper.io/thebuilder/react-scroll-percentage.svg
[greenkeeper-url]: https://greenkeeper.io/
[prettier-svg]: https://img.shields.io/badge/styled_with-prettier-ff69b4.svg
[prettier-url]: https://github.com/prettier/prettier

Sorry, the diff of this file is not supported yet

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