Skip to content

Lightweight typescript library to detect React elements visibility

License

Notifications You must be signed in to change notification settings

ukorvl/react-on-screen

Repository files navigation

react-on-screen logo

Lightweight typescript library to detect React elements visibility

Build Npm version License: MIT Minified size

Table of contents

Getting started

npm

$ npm i @ukorvl/react-on-screen

yarn

yarn add @ukorvl/react-on-screen

CDN

<script src="https://unpkg.com/@ukorvl/react-on-screen/build/react-on-screen.standalone.js"></script>

The standalone version creates window.ReactOnScreen object with all exports from esm version.

Note, that react package is not included into standalone version, but is required. Standalone version requires global React variable to work as expected.

Usage

This library is using Intersection observer API under the hood, so you may need to polyfill it. More information about Intersection observer API browser support at caniuse.

Render props

import { OnScreen } from '@ukorvl/react-on-screen';

const MyComponent = () => (
  <OnScreen>
    {({isOnScreen, ref}) => (
      <div ref={ref}>
        {isOnScreen ? 'On screen!' : 'Not on screen'}
      </div>
    )}
  </OnScreen>
)

Hook

import useOnScreen from '@ukorvl/react-on-screen';

const MyComponent = () => {
  const ref = useRef<T>(null);
  const {isOnScreen} = useOnScreen({ref});

  return (
    <div ref={ref}>{isOnScreen ? 'On screen!' : 'Not on screen'}</div>
  )
}

HOC

import { WithOnScreen } from '@ukorvl/react-on-screen';

const List = forwardRef(function List({isOnScreen, ...restProps}: ListProps, ref) {
  return (
    <ul ref={ref} className={isOnScreen ? 'my-class' : ''} {...restProps}>
      <li>Something</li>
        {'...'}
    </ul>
  )
})

export const ListWithOnScreen = WithOnScreen(List, {threshold: 0.5, margin: '4rem'});

API

useOnScreen hook parameters.

Name Default Description
threshold 0 Could be a single number from 0 to 1, or array of numbers. If you only want to detect when visibility passes the 50% mark, you can use a value of 0.5. Set 1 to consider visibility only if all element is on the screen. If array of thresholds is provided, visibility detection will be triggered every time visibility passes one of provided thresholds.
margin undefined Could be any valid css margin value. This value serves to grow or shrink each side of the target element's bounding box before computing is it visible or not.
once false Triggers visibility detection only once. Once target element becomes visible, visibility detection will be disabled.
initialVisibility false Initial isOnScreen value. Could be useful when working with elements that are on the screen at the first render, and we don't want to wait for InersectionObserver initialization to do some actions.

OnScreen and WithOnScreen components have the same api, except ref. useOnScreen consumes target element ref as a parameter, but components deal with target element in a different way.

License

MIT