0.9.3 • Published 1 year ago

@stanko/react-window v0.9.3

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

ReactWindow

npm version npm downloads

React components that simplify the management of window and body event listeners.

Instead of manually adding (and removing) listeners using useEffect, ReactWindow allows you to attach them in a more intuitive way:

// for window listeners
<ReactWindow
  onClick={() => {
    console.log("Hello world!");
  }}
/>

Demo and Changelog

The library is inspired by svelte and is available with the following features:

  • Simplifies management of window (and body) event listeners.
  • Attaches a single event per listener type (if you have multiple instances of ReactWindow with onClick in your app, only a single click event will be attached).
  • Supports conditional rendering.
  • Supports capture and passive listener options.
  • Tiny - around 0.5 kB minified and gzipped.
  • Fully typed.

Usage

Get it from npm:

$ npm install --save @stanko/react-window

Import and use it in your React app:

ReactWindow base example

import ReactWindow from "@stanko/react-window";

function Example() {
  return (
    <ReactWindow
      onClick={() => {
        console.log("Hello world!");
      }}
      onScroll={() => {
        console.log(`Wheeeeee! ${window.scrollY}px`);
      }}
    />
  );
}

ReactBody base example

ReactBody works same as ReactWindow but attaches listeners to document.body instead of window.

import { ReactBody } from "@stanko/react-window";

function Example() {
  return (
    <ReactBody
      onClick={() => {
        console.log("Hello!");
      }}
    />
  );
}

Conditional rendering

import { useState } from "react";
import ReactWindow from "@stanko/react-window";

function Example() {
  const [listenForScroll, setListenForScroll] = useState(true);

  return (
    <div>
      <button
        onClick={() => {
          setListenForScroll(!listenForScroll);
        }}
      >
        {listenForScroll ? "Disable" : "Enable"} scroll listener
      </button>

      {listenForScroll && (
        <ReactWindow
          onScrollPassive={() => {
            console.log(`Wheeeeee! ${window.scrollY}px`);
          }}
        />
      )}
    </div>
  );
}

Listener options

React Window supports capture and options listener options. These options can be set using the [onEventName]Capture and [onEventName]Passive variations.

For example, to set capture option for onClick, you would use onClickCapture.

And to set passive option for onScroll, you would use onScrollPassive.

Gotchas

There are a couple of gotchas to keep in mind when working with React Window:

Events are only added on mount

Events are only added on mount and removed on unmount. This means that if you change your handler dynamically, nothing will happen.

In other words, avoid the following pattern:

<ReactWindow
  onClick={
    someCondition ? () => {
      console.log("handling the event in one way");
    } : () => {
      console.log("handling the event in a different way");
    }
  }
/>

This behavior is intentional, as it improves performance and eliminates the need for unnecessary rerenders.

Double click

React Window uses onDblClick to match the native event name, which differs from the built-in React version that uses onDoubleClick.

Supported events

React Window has full TypeScript support and your IDE should provide you with an autocomplete.

Visual Studio autocomplete for ReactWindow

Here's a list of all supported events for reference:

Misc

EventCapture variant
onLoadonLoadCapture
onSelectonSelectCapture
onErroronErrorCapture

Scroll / Wheel

EventCapture variantPassive variant
onScrollonScrollCaptureonScrollPassive
onWheelonWheelCaptureonWheelPassive

Focus / Blur

EventCapture variant
onFocusonFocusCapture
onBluronBlurCapture

Keyboard

EventCapture variant
onKeyDownonKeyDownCapture
onKeyUponKeyUpCapture

Mouse

EventCapture variant
onAuxClickonAuxClickCapture
onClickonClickCapture
onDblClickonDblClickCapture
onContextMenuonContextMenuCapture
onDragonDragCapture
onDragEndonDragEndCapture
onDragEnteronDragEnterCapture
onDragExitonDragExitCapture
onDragLeaveonDragLeaveCapture
onDragOveronDragOverCapture
onDragStartonDragStartCapture
onDroponDropCapture
onMouseDownonMouseDownCapture
onMouseMoveonMouseMoveCapture
onMouseOutonMouseOutCapture
onMouseOveronMouseOverCapture
onMouseUponMouseUpCapture
onMouseEnter
onMouseLeave

Touch

EventCapture variantPassive variant
onTouchCancelonTouchCancelCapture
onTouchEndonTouchEndCapture
onTouchMoveonTouchMoveCaptureonTouchMovePassive
onTouchStartonTouchStartCaptureonTouchStartPassive

Pointer

EventCapture variant
onPointerDownonPointerDownCapture
onPointerMoveonPointerMoveCapture
onPointerUponPointerUpCapture
onPointerCancelonPointerCancelCapture
onPointerEnteronPointerEnterCapture
onPointerLeaveonPointerLeaveCapture
onPointerOveronPointerOverCapture
onPointerOutonPointerOutCapture
onGotPointerCaptureonGotPointerCaptureCapture
onLostPointerCaptureonLostPointerCaptureCapture

Animation

EventCapture variant
onAnimationStartonAnimationStartCapture
onAnimationEndonAnimationEndCapture
onAnimationIterationonAnimationIterationCapture
onAnimationCancelonAnimationCancelCapture

Transition

EventCapture variant
onTransitionStartonTransitionStartCapture
onTransitionEndonTransitionEndCapture
onTransitionRunonTransitionRunCapture
onTransitionCancelonTransitionCancelCapture

Development

Install dependencies and run npm start. It will spin up a development server on http://localhost:8000

0.9.3

1 year ago

0.9.2

1 year ago

0.9.1

1 year ago

0.9.0

1 year ago