Skip to content

guitarino/resize-sensor--react

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Resize Sensor for React

A React component based on work by procurios. It is an element that triggers a callback whenever the size (width or height) of its container changes. See Preact version here.

How to install it

npm install --save resize-sensor--react

How to use it

import React from 'react';
import ResizeSensor from 'resize-sensor--react';

import 'resize-sensor--react/build/resize-sensor.css';

class App extends React.Component {
  constructor() {
    super();
    this.state = {w: 0, h: 0};
  }
  render() {
    return (
      <div style={{width: '50vw', height: '50vh', position: 'relative'}}>
        <ResizeSensor
          onResize={(w,h) => this.setState({w: w, h: h})}
        />
        <div>Width: {this.state.w}px</div>
        <div>Height: {this.state.h}px</div>
      </div>
    );
  }
}

<ResizeSensor /> will create hidden elements that will fill up all available container's width and height, and, will listen to the width / height changes of the container. Once the change is detected, onResize prop will get triggered.

Note 1: the container should either have position: relative or position: absolute defined on it.

Note 2: you will need to include the styles located at resize-sensor--react/build/resize-sensor.css. With webpack, you can use style-loader that allows requiring CSS assets in JS as shown above. Or, you can reference it from your sass file as @import '~resize-sensor--react/build/resize-sensor.css'.

See Demo

To see a little demo, do the following

git clone https://github.com/guitarino/resize-sensor--react.git .
npm install
npm run demo-webpack

In another terminal / cmd

npm run demo-server

This will tell you the URL address where you'll see a little demo. By changing the browser window size, you can confirm that size change gets reported. By clicking the Toggle another example button, you can also confirm that element size gets updated even if the size changed while the element was not visible. You can also play around with the code under demo/src and it should automatically re-bundle.

You can also verify that server-side rendering will work by running

npm run try-ssr

Note, when running SSR, requiring CSS stylesheets from your JS will cause errors, but that can be solved by excluding those assets via this babel plugin.

Support

IE9+, Edge, Safari, Chrome, Firefox

How it works

It works very efficiently, without dirty checking; instead, it's based on listening to the scroll events. The way it works is as follows:

  1. Inside ResizeSensor, there's elements that serve as triggers for expansion and contraction. Expansion and contraction triggers each have a child.

  2. For contraction, the child is 2x bigger than container, and the child's scroll position is set to the bottom right corner. When contracted, the bottom right corner position changes, which triggers a scroll event.

  3. For expansion, the child is slightly (1px) bigger than container, and, again, the child's scroll position is set to the bottom right corner. This implies that there's actually a scrollbar on the container. When container expands even slightly (by 1px), the scrollbar disappears, which changes the scroll position, which triggers a scroll event.

  4. Whenever a scroll event is triggered, the children's sizes are readjusted so that we can start listening again.

  5. Also, there's a possibility that an element becomes hidden and then reappears after some time, and it's possible that the container's size have changed over that time. For that case, there's also a kind of a visibility sensor, which triggers an update whenever the element becomes visible. It's based on CSS3 animations: there's actually an animation that does nothing, yet it gets shown every time the element becomes visible, and animation-start event listener is added so we can listen to it.

  6. On IE9, none of that actually happens, and instead, onresize event is directly attached on the resize sensor. The reason for that is because animation-start is not supported on IE9, which makes it impossible to listen to visibility.

Acknowledgements

Kudos to procurios and marcj for coming up and / or improving on this method.

License

MIT

About

A React component that triggers a callback whenever the size (width or height) of its container changes.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published