Skip to content

Rect

Measures DOM elements (aka. bounding client rect). See also Element.getBoundingClientRect()

Installation

From the command line in your project directory, run npm install @reach/rect or yarn add @reach/rect. Then import the component or hook that you need:

npm install @reach/rect# oryarn add @reach/rect
import Rect, { useRect } from "@reach/rect";

Component API

useRect

function useRect<T extends HTMLElement = HTMLElement>(nodeRef: React.RefObject<T>, observe: boolean = true, onChange?: (rect: DOMRect) => void): null | DOMRect

Hook that observes and returns the measurements (ClientRect) of a DOM element. Pass it the ref that placed on the element to be measured.

If observe is false, the element's rect will no longer be observed, pass it true again and it will. This is mostly used for things like popovers and animations, so you can usually observe when you need to, and stop observing when you don't.

function Example() {  // your own ref  const ref = useRef();  // pass it in to be observered  const rect = useRect(ref);  return (    <div>      <pre>{JSON.stringify(rect, null, 2)}</pre>      <div        // and then place the ref        ref={ref}        contentEditable        style={{          display: "inline-block",          padding: 10,          border: "solid 1px",        }}        dangerouslySetInnerHTML={{          __html: "Edit this to change the size!",        }}      />    </div>  );}

Rect

Render prop component for use in class components to observe element measurements.

Rect Props

PropTypeRequired
childrenfunctrue
observeboolfalse
onChangefuncfalse
Rect children

children(args: { rect: DOMRect | null; ref: React.Ref<any> }): JSX.Element

A function that calls back to you with a ref to place on an element and the rect measurements of the dom node.

Note: On the first render rect will be null because we can't measure a node that has not yet been rendered. Make sure your code accounts for this.

Rect observe

observe?: boolean

Tells Rect to observe the position of the node or not. While observing, the children render prop may call back very quickly (especially while scrolling) so it can be important for performance to avoid observing when you don't need to.

This is typically used for elements that pop over other elements (like a dropdown menu), so you don't need to observe all the time, only when the popup is active.

Pass true to observe, false to ignore.

<Rect observe={false}>  {({ rect, ref }) => (    <div ref={ref}>      <div>Will not measure the element when false</div>      <div>        Edit this code and change it to <code>true</code>      </div>      <pre>{JSON.stringify(rect, null, 2)}</pre>    </div>  )}</Rect>
Rect onChange

onChange?(rect: DOMRect): void

Calls back whenever the rect of the element changes.

<Rect onChange={rect => console.log(rect)}/>  {({ rect, ref }) => (    <div ref={ref}/>  )}</Rect>