React component library for computing and tracking DOM element measurements using ResizeObserver
npx @tessl/cli install tessl/npm-react-measure@2.5.0React Measure is a React component library for computing and tracking DOM element measurements using the ResizeObserver API. It provides both a Measure component and a withContentRect higher-order component that enable developers to track and respond to size changes in React components.
npm install react-measure or yarn add react-measureimport Measure from 'react-measure';
import { withContentRect } from 'react-measure';For CommonJS:
const Measure = require('react-measure').default;
const { withContentRect } = require('react-measure');import React, { Component } from 'react';
import Measure from 'react-measure';
class ResponsiveComponent extends Component {
state = {
dimensions: { width: -1, height: -1 }
};
render() {
const { width, height } = this.state.dimensions;
return (
<Measure
bounds
onResize={contentRect => {
this.setState({ dimensions: contentRect.bounds });
}}
>
{({ measureRef }) => (
<div ref={measureRef}>
<p>Width: {width}px, Height: {height}px</p>
{width > 500 && <p>Wide layout content</p>}
</div>
)}
</Measure>
);
}
}React Measure is built around several key components:
Core component that wraps children and provides measurement capabilities via render props pattern. Handles ResizeObserver lifecycle and provides measurement data through a children function.
/**
* React component that provides element measurement capabilities via render props
* @param {Object} props - Component props
* @param {boolean} [props.client] - Include client measurements
* @param {boolean} [props.offset] - Include offset measurements
* @param {boolean} [props.scroll] - Include scroll measurements
* @param {boolean} [props.bounds] - Include bounds measurements
* @param {boolean} [props.margin] - Include margin measurements
* @param {Object|Function} [props.innerRef] - Ref to access internal element
* @param {Function} [props.onResize] - Callback when dimensions change
* @param {Function} props.children - Render prop function
* @returns {React.ReactElement}
*/
function Measure(props);
// Render prop function receives:
// {
// measureRef: function - Must be passed to measured element as ref
// measure: function - Programmatically trigger measurement
// contentRect: object - Current measurements
// }Higher-order component that provides measurement functionality to wrapped components. Accepts measurement types as configuration and injects measurement data as props.
/**
* Higher-order component that provides measurement functionality
* @param {string|string[]} [types] - Measurement types: 'client', 'offset', 'scroll', 'bounds', 'margin'
* @returns {Function} - Function that accepts a component and returns wrapped component
*/
function withContentRect(types);
// Returns function that wraps components with measurement props:
// - measureRef: function to attach to measured element
// - measure: function to programmatically measure
// - contentRect: object with current measurements
// Plus all original Measure component props are available// contentRect object structure returned by measurements
const contentRect = {
// ResizeObserver entry (when available)
entry: {
width: 0, // number
height: 0, // number
top: 0, // number
left: 0, // number
bottom: 0, // number
right: 0 // number
},
// Client measurements (when client: true)
client: {
top: 0, // number - clientTop
left: 0, // number - clientLeft
width: 0, // number - clientWidth
height: 0 // number - clientHeight
},
// Offset measurements (when offset: true)
offset: {
top: 0, // number - offsetTop
left: 0, // number - offsetLeft
width: 0, // number - offsetWidth
height: 0 // number - offsetHeight
},
// Scroll measurements (when scroll: true)
scroll: {
top: 0, // number - scrollTop
left: 0, // number - scrollLeft
width: 0, // number - scrollWidth
height: 0 // number - scrollHeight
},
// Bounds measurements (when bounds: true)
bounds: {
top: 0, // number - from getBoundingClientRect()
right: 0, // number
bottom: 0, // number
left: 0, // number
width: 0, // number
height: 0 // number
},
// Margin measurements (when margin: true)
margin: {
top: 0, // number - from getComputedStyle()
right: 0, // number
bottom: 0, // number
left: 0 // number
}
};