Convert Figma logo to code with AI

ctrlplusb logoreact-sizeme

Make your React Components aware of their width and height!

1,942
92
1,942
32

Top Related Projects

React components for efficiently rendering large lists and tabular data

📏 Compute measurements of a React component.

A React.js component for using @desandro's Masonry

Component-wrapper for collapse animation with react-motion for elements with variable (and dynamic) height

A draggable and resizable grid layout with responsive breakpoints, for React.

Quick Overview

React-SizeMe is a React component that allows you to easily make your components responsive to their own size. It provides a higher-order component (HOC) and a render prop component that injects size information (width and height) into your components, enabling them to adapt their rendering based on their current dimensions.

Pros

  • Easy integration with existing React components
  • Supports both HOC and render prop patterns
  • Provides accurate size measurements, including sub-pixel precision
  • Offers performance optimizations like debouncing and size change thresholds

Cons

  • Adds an extra wrapper element around your component
  • May impact performance if overused or not configured properly
  • Limited to measuring only direct parent container size
  • Requires additional setup for server-side rendering

Code Examples

  1. Using the HOC pattern:
import { withSize } from 'react-sizeme'

const MyComponent = ({ size }) => (
  <div>
    My width is {size.width}px and my height is {size.height}px
  </div>
)

export default withSize()(MyComponent)
  1. Using the render prop pattern:
import { SizeMe } from 'react-sizeme'

const MyComponent = () => (
  <SizeMe>
    {({ size }) => (
      <div>
        My width is {size.width}px and my height is {size.height}px
      </div>
    )}
  </SizeMe>
)
  1. Configuring options:
import { withSize } from 'react-sizeme'

const MyComponent = ({ size }) => (
  <div>
    My width is {size.width}px
  </div>
)

export default withSize({
  monitorWidth: true,
  monitorHeight: false,
  refreshRate: 16,
  refreshMode: 'debounce'
})(MyComponent)

Getting Started

  1. Install the package:

    npm install react-sizeme
    
  2. Import and use in your React component:

    import React from 'react'
    import { withSize } from 'react-sizeme'
    
    const MyComponent = ({ size }) => (
      <div>
        Current width: {size.width}px
      </div>
    )
    
    export default withSize()(MyComponent)
    
  3. Use the wrapped component in your app:

    import MyComponent from './MyComponent'
    
    const App = () => (
      <div>
        <MyComponent />
      </div>
    )
    

Competitor Comparisons

React components for efficiently rendering large lists and tabular data

Pros of react-virtualized

  • Comprehensive solution for rendering large lists and tabular data
  • Offers multiple components for different use cases (List, Grid, Table, etc.)
  • Highly performant with efficient rendering of only visible items

Cons of react-virtualized

  • Steeper learning curve due to its extensive API and features
  • May be overkill for simpler use cases or smaller datasets
  • Requires more setup and configuration compared to react-sizeme

Code Comparison

react-virtualized:

import { List } from 'react-virtualized';

<List
  width={300}
  height={300}
  rowCount={1000}
  rowHeight={20}
  rowRenderer={({ index, key, style }) => (
    <div key={key} style={style}>Row {index}</div>
  )}
/>

react-sizeme:

import { withSize } from 'react-sizeme';

const SizedComponent = withSize()(({ size }) => (
  <div>Width: {size.width}, Height: {size.height}</div>
));

While react-virtualized focuses on efficiently rendering large datasets, react-sizeme is primarily used for tracking component dimensions. react-virtualized offers more complex functionality for list and grid rendering, whereas react-sizeme provides a simpler API for size-aware components. The choice between the two depends on the specific requirements of your project, with react-virtualized being more suitable for large data sets and react-sizeme for general size-based optimizations.

📏 Compute measurements of a React component.

Pros of react-measure

  • More comprehensive measurement options, including scroll width/height and client width/height
  • Supports measuring multiple dimensions simultaneously
  • Provides a render prop API for more flexibility in usage

Cons of react-measure

  • Slightly more complex API compared to react-sizeme
  • May have a higher performance overhead due to more extensive measurements
  • Less frequently updated (last update was in 2019)

Code Comparison

react-measure:

<Measure
  bounds
  onResize={contentRect => {
    this.setState({ dimensions: contentRect.bounds })
  }}
>
  {({ measureRef }) => (
    <div ref={measureRef}>
      {/* Your content here */}
    </div>
  )}
</Measure>

react-sizeme:

import { withSize } from 'react-sizeme'

const MyComponent = ({ size }) => (
  <div>Width: {size.width}, Height: {size.height}</div>
)

export default withSize()(MyComponent)

Both libraries provide ways to measure component dimensions, but react-measure offers more granular control and measurement options, while react-sizeme provides a simpler API with a higher-order component approach. The choice between them depends on the specific requirements of your project and the level of control you need over measurements.

A React.js component for using @desandro's Masonry

Pros of react-masonry-component

  • Specifically designed for creating masonry layouts in React applications
  • Integrates well with existing React components and lifecycle methods
  • Provides a simple API for creating responsive masonry grids

Cons of react-masonry-component

  • Limited to masonry layouts, less versatile than react-sizeme
  • May require additional configuration for complex layouts
  • Less actively maintained compared to react-sizeme

Code Comparison

react-masonry-component:

import Masonry from 'react-masonry-component';

<Masonry
  elementType={'ul'}
  options={masonryOptions}
  disableImagesLoaded={false}
  updateOnEachImageLoad={false}
>
  {items.map(item => <li key={item.id}>{item.content}</li>)}
</Masonry>

react-sizeme:

import { withSize } from 'react-sizeme';

const MyComponent = ({ size }) => (
  <div>Width: {size.width}, Height: {size.height}</div>
);

export default withSize()(MyComponent);

react-sizeme is more versatile, allowing for size-aware components beyond just masonry layouts. It provides a higher-order component for easy integration with existing React components. react-masonry-component, on the other hand, offers a more specialized solution for creating masonry grids with less setup required for that specific use case.

Component-wrapper for collapse animation with react-motion for elements with variable (and dynamic) height

Pros of react-collapse

  • Specifically designed for collapsible content, providing a more tailored solution for this use case
  • Offers smooth animations and transitions for collapsing/expanding elements
  • Includes built-in accessibility features for better user experience

Cons of react-collapse

  • Limited to collapsing functionality, less versatile than react-sizeme
  • May require additional setup for more complex sizing scenarios
  • Potentially higher learning curve for developers unfamiliar with collapse-specific APIs

Code Comparison

react-collapse:

<Collapse isOpened={isOpened}>
  <div>Collapsible content here</div>
</Collapse>

react-sizeme:

<SizeMe>
  {({ size }) => (
    <div>Content with size: {size.width}x{size.height}</div>
  )}
</SizeMe>

Summary

react-collapse is a specialized solution for creating collapsible content with smooth animations and accessibility features. It's ideal for projects that specifically need collapsing functionality. However, it's less versatile than react-sizeme, which offers broader sizing capabilities for various elements.

react-sizeme provides a more general-purpose solution for tracking and responding to element size changes. It's more flexible and can be used in a wider range of scenarios, but it may require additional work to achieve the same collapsing functionality as react-collapse.

Choose react-collapse for dedicated collapsible content needs, and react-sizeme for more general element sizing requirements in React applications.

A draggable and resizable grid layout with responsive breakpoints, for React.

Pros of react-grid-layout

  • Provides a complete grid system with dragging and resizing capabilities
  • Offers responsive breakpoints for different screen sizes
  • Includes built-in collision detection and prevention

Cons of react-grid-layout

  • More complex setup and configuration required
  • Heavier library with more dependencies
  • May be overkill for simpler layout needs

Code Comparison

react-grid-layout:

import GridLayout from 'react-grid-layout';

<GridLayout
  className="layout"
  layout={layout}
  cols={12}
  rowHeight={30}
  width={1200}
>
  {children}
</GridLayout>

react-sizeme:

import { withSize } from 'react-sizeme';

const SizedComponent = withSize()(({ size }) => (
  <div>Width: {size.width}, Height: {size.height}</div>
));

react-grid-layout is a comprehensive solution for creating dynamic, resizable grid layouts in React applications. It offers advanced features like dragging, resizing, and responsive breakpoints, making it suitable for complex dashboard-like interfaces.

On the other hand, react-sizeme is a lightweight library focused on providing size information for React components. It's simpler to use and integrate, making it ideal for scenarios where you only need to track component dimensions without the full grid functionality.

Choose react-grid-layout for feature-rich, interactive grid layouts, and react-sizeme for basic size tracking and simpler layout adjustments.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

 

Make your React Components aware of their width and/or height!

 

npm MIT License Travis Codecov

  • Hyper Responsive Components!
  • Performant.
  • Easy to use.
  • Extensive browser support.
  • Supports functional and class Component types.
  • Tiny bundle size.
  • Demo: https://4mkpc.csb.app/

Use it via the render prop pattern (supports children or render prop):

import { SizeMe } from 'react-sizeme'

function MyApp() {
  return <SizeMe>{({ size }) => <div>My width is {size.width}px</div>}</SizeMe>
}

Or, via a higher order component:

import { withSize } from 'react-sizeme'

function MyComponent({ size }) {
  return <div>My width is {size.width}px</div>
}

export default withSize()(MyComponent)

 


TOCs

 


Intro

Give your Components the ability to have render logic based on their height and/or width. Responsive design on the Component level. This allows you to create highly reusable components that can adapt to wherever they are rendered.

Check out a working demo here: https://4mkpc.csb.app/

 


Installation

Firstly, ensure you have the required peer dependencies:

npm install react react-dom

Note: We require >=react@0.14.0 and >=react-dom@0.14.0

npm install react-sizeme

 


Configuration

The following configuration options are available. Please see the usage docs for how to pass these configuration values into either the component or higher order function.

  • monitorWidth (boolean, default: true)

    If true, then any changes to your Components rendered width will cause an recalculation of the "size" prop which will then be be passed into your Component.

  • monitorHeight (boolean, default: false)

    If true, then any changes to your Components rendered height will cause an recalculation of the "size" prop which will then be be passed into your Component.

    PLEASE NOTE: that this is set to false by default

  • refreshRate (number, default: 16)

    The maximum frequency, in milliseconds, at which size changes should be recalculated when changes in your Component's rendered size are being detected. This should not be set to lower than 16.

  • refreshMode (string, default: 'throttle')

    The mode in which refreshing should occur. Valid values are "debounce" and "throttle".

    "throttle" will eagerly measure your component and then wait for the refreshRate to pass before doing a new measurement on size changes.

    "debounce" will wait for a minimum of the refreshRate before it does a measurement check on your component.

    "debounce" can be useful in cases where your component is animated into the DOM.

    NOTE: When using "debounce" mode you may want to consider disabling the placeholder as this adds an extra delay in the rendering time of your component.

  • noPlaceholder (boolean, default: false)

    By default we render a "placeholder" component initially so we can try and "prefetch" the expected size for your component. This is to avoid any unnecessary deep tree renders. If you feel this is not an issue for your component case and you would like to get an eager render of your component then disable the placeholder using this config option.

    NOTE: You can set this globally. See the docs on first render.

 


Component Usage

We provide a "render props pattern" based component. You can import it like so:

import { SizeMe } from 'react-sizeme'

You then provide it either a render or children prop containing a function/component that will receive a size prop (an object with width and height properties):

<SizeMe>{({ size }) => <div>My width is {size.width}px</div>}</SizeMe>

or

<SizeMe render={({ size }) => <div>My width is {size.width}px</div>} />

To provide configuration you simply add any customisation as props. For example:

<SizeMe
  monitorHeight
  refreshRate={32}
  render={({ size }) => <div>My width is {size.width}px</div>}
/>

 


HOC Usage

We provide you with a higher order component function called withSize. You can import it like so:

import { withSize } from 'react-sizeme'

Firstly, you have to call the withSize function, passing in an optional configuration object should you wish to customise the behaviour:

const withSizeHOC = withSize()

You can then use the returned Higher Order Component to decorate any of your existing Components with the size awareness ability:

const SizeAwareComponent = withSizeHOC(MyComponent)

Your component will then receive a size prop (an object with width and height properties).

Note that the values could be undefined based on the configuration you provided (e.g. you explicitly do not monitor either of the dimensions)

Below is a full example:

import { withSize } from 'react-sizeme'

class MyComponent extends Component {
  render() {
    const { width, height } = this.props.size

    return (
      <div>
        My size is {width || -1}px x {height || -1}px
      </div>
    )
  }
}

export default withSize({ monitorHeight: true })(MyComponent)

onSize callback alternative usage

The higher order component also allows an alternative usage where you provide an onSize callback function.

This allows the "parent" to manage the size value rather than your component, which can be useful in specific circumstances.

Below is an example of it's usage.

Firstly, create a component you wish to know the size of:

import { withSize } from 'react-sizeme'

function MyComponent({ message }) {
  return <div>{message}</div>
}

export default withSize()(MyComponent)

Now create a "parent" component providing it a onSize callback function to the size aware component:

class ParentComponent extends React.Component {
  onSize = (size) => {
    console.log('MyComponent has a width of', size.width)
  }

  render() {
    return <MyComponent message="Hello world" onSize={this.onSize} />
  }
}

 


Under the hood

It can be useful to understand the rendering workflow should you wish to debug any issues we may be having.

In order to size your component we have a bit of a chicken/egg scenario. We can't know the width/height of your Component until it is rendered. This can lead wasteful rendering cycles should you choose to render your components based on their width/height.

Therefore for the first render of your component we actually render a lightweight placeholder in place of your component in order to obtain the width/height. If your component was being passed a className or style prop then these will be applied to the placeholder so that it can more closely resemble your actual components dimensions.

So the first dimensions that are passed to your component may not be "correct" dimensions, however, it should quickly receive the "correct" dimensions upon render.

Should you wish to avoid the render of a placeholder and have an eager render of your component then you can use the noPlaceholder configuration option. Using this configuration value your component will be rendered directly, however, the size prop may contain undefined for width and height until your component completes its first render.

 


Examples

Loading different child components based on size

import React from 'react'
import LargeChildComponent from './LargeChildComponent'
import SmallChildComponent from './SmallChildComponent'
import sizeMe from 'react-sizeme'

function MyComponent(props) {
  const { width, height } = props.size

  const ToRenderChild = height > 600 ? LargeChildComponent : SmallChildComponent

  return (
    <div>
      <h1>
        My size is {width}x{height}
      </div>
      <ToRenderChild />
    </div>
  )
}

export default sizeMe({ monitorHeight: true })(MyComponent)

EXTRA POINTS! Combine the above with a code splitting API (e.g. Webpack's System.import) to avoid unnecessary code downloads for your clients. Zing!

 


Server Side Rendering

Okay, I am gonna be up front here and tell you that using this library in an SSR context is most likely a bad idea. If you insist on doing so you then you should take the time to make yourself fully aware of any possible repercussions you application may face.

A standard sizeMe configuration involves the rendering of a placeholder component. After the placeholder is mounted to the DOM we extract it's dimension information and pass it on to your actual component. We do this in order to avoid any unnecessary render cycles for possibly deep component trees. Whilst this is useful for a purely client side set up, this is less than useful for an SSR context as the delivered page will contain empty placeholders. Ideally you want actual content to be delivered so that users without JS can still have an experience, or SEO bots can scrape your website.

To avoid the rendering of placeholders in this context you can make use of the noPlaceholders global configuration value. Setting this flag will disables any placeholder rendering. Instead your wrapped component will be rendered directly - however it's initial render will contain no values within the size prop (i.e. width, and height will be null).

import sizeMe from 'react-sizeme'

// This is a global variable. i.e. will be the default for all instances.
sizeMe.noPlaceholders = true

Note: if you only partialy server render your application you may want to use the component level configuration that allows disabling placeholders per component (e.g. sizeMe({ noPlaceholder: true }))

It is up to you to decide how you would like to initially render your component then. When your component is sent to the client and mounted to the DOM SizeMe will calculate and send the dimensions to your component as normal. I suggest you tread very carefully with how you use this updated information and do lots of testing using various screen dimensions. Try your best to avoid unnecessary re-rendering of your components, for the sake of your users.

If you come up with any clever strategies for this please do come share them with us! :)

 


Extreme Appreciation!

We make use of the awesome element-resize-detector library. This library makes use of an scroll/object based event strategy which outperforms window resize event listening dramatically. The original idea for this approach comes from another library, namely css-element-queries by Marc J. Schmidt. I recommend looking into these libraries for history, specifics, and more examples. I love them for the work they did, whithout which this library would not be possible. :sparkling_heart:

 


Backers

Thank goes to all our backers! [Become a backer].

NPM DownloadsLast 30 Days