|

React Broken Layouter

A lightweight React utility for creating responsive masonry-style layouts with automatic height estimation and column distribution.

Features

🎯

Simple and intuitive API

Easy to integrate and use with a straightforward API design

πŸ“±

Responsive column-based layout

Adapts to different screen sizes with customizable breakpoints

πŸ“

Automatic height estimation

Intelligently calculates optimal item placement

🎨

Customizable gap between items

Control spacing between elements for the perfect layout

πŸ”„

Support for dynamic content

Handles changing content gracefully

πŸš€

Zero dependencies

Lightweight with no external dependencies except React

πŸ“¦

TypeScript support

Full TypeScript type definitions included

πŸ› οΈ

Utility functions

Helpful utilities for common layout tasks

Environment Compatibility

This component is primarily designed for client-side use in React applications. While it doesn't use React hooks, it relies on client-side calculations for optimal layout and height estimation.

Recommended Usage

  • βœ…Client-side React applications
  • βœ…Browser environments
  • βœ…React 17+ and React 18+
  • βœ…Next.js client components (with 'use client' directive)
  • βœ…Client-side rendered pages

Server Component Usage

To use this component with server components in frameworks like Next.js, follow these guidelines:

Using 'use client' directive
"use client"; import Layouter from "react-broken-layouter";

Provide explicit heights via getHeight or estimateHeight props to ensure consistent layout:

Providing explicit heights
<Layouter cols={3} items={items} render={Item} getHeight={(item) => item.height} // Provide explicit heights />

Not Recommended

  • ❌Server Components without 'use client' directive
  • ❌Server-side rendering without proper client-side hydration
  • ❌Static site generation without client-side JavaScript

Considerations

  • ⚠️Height estimation is most accurate in client environments
  • ⚠️For server-side rendering, consider providing explicit heights via `getHeight` or `estimateHeight` props
  • ⚠️Dynamic content may require client-side re-rendering for optimal layout

Installation

npm
npm install react-broken-layouter
yarn
yarn add react-broken-layouter

Usage

Basic Example

A simple setup with a fixed number of columns:

Basic Example
import Layouter from "react-broken-layouter"; const items = [ { id: 1, content: "Item 1" }, { id: 2, content: "Item 2" }, // ... ]; const Item = ({ item }) => ( <div style={{ padding: "1rem", background: "#f0f0f0" }}>{item.content}</div> ); export default function App() { return ( <Layouter cols={3} // Fixed column count items={items} render={Item} // Render component gap={16} // Space between items getId={(item) => item.id} // Unique key for each item /> ); }

Custom Render

You can provide a custom render function that returns a component to display each item:

Custom Render
const YourComponent = ({ item }) => ( <div style={{ padding: "1rem", background: "#e0e0e0" }}>{item.content}</div> ); <Layouter cols={3} // Fixed column count items={items} render={(props) => <YourComponent {...props} />} // Custom render function gap={16} // Space between items getId={(item) => item.id} // Unique key for each item />;
Note: The render prop expects a component that accepts an item prop. Using a function allows dynamic rendering while maintaining compatibility.

Responsive Layout with breakpoints

Use the breakpoints prop to override the default cols value based on screen width, ideal for responsive layouts:

Responsive Layout
<Layouter cols={1} // Default to 1 column (e.g., for mobile) items={items} render={Item} gap={16} getId={(item) => item.id} breakpoints={{ 768: { cols: 2 }, 1024: { cols: 3 }, 1440: { cols: 4 }, }} />

This dynamically sets:

  • 1 column below 768px (using cols)
  • 2 columns from 768px to 1023px
  • 3 columns from 1024px to 1439px
  • 4 columns at 1440px and above

Responsive Visualization

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
< 768px: 1 col768-1023px: 2 cols1024-1439px: 3 cols>= 1440px: 4 cols

Props

PropTypeRequiredDefaultDescription
colsnumberβœ“-Default number of columns (overridden by breakpoints if provided)
breakpoints{ [width: number]: { cols: number } }--Map of viewport widths to column counts for responsive behavior
itemsany[]βœ“-List of items to display
renderReact.FC<{ item: any }>βœ“-Component to render each item (can be a function returning a component)
gapnumber-16Gap between items (px)
getId(item: any) => string | number--Optional function to get unique ID for each item
getHeight(item: any) => number--Exact item height (for layout optimization)
estimateHeight(item: any) => number--Estimate item height if exact value isn't available
mediaHeightnumber--Additional height buffer (e.g., for images or media content)

Utility Functions

These utility functions simplify common tasks like height estimation and ID generation:

heightEstimator

Estimates the total height based on an array of strings or numbers. Useful for calculating content heights.

heightEstimator Example
import { heightEstimator } from "react-broken-layouter"; // Example usage const content = ["Hello", "World", 100]; const estimatedHeight = heightEstimator(content); // Returns: (5 * 0.35) + (5 * 0.35) + 100 = 103.5

getRandomId

Generates a random string ID. Useful for creating unique keys when none are provided.

getRandomId Example
import { getRandomId } from "react-broken-layouter"; // Example usage const uniqueId = getRandomId(); // Returns something like: "x7f9k2m"

isObject

Checks if a value is a plain object (not an array or null).

isObject Example
import { isObject } from "react-broken-layouter"; // Example usage isObject({}); // true isObject([]); // false isObject(null); // false isObject("string"); // false

Experimental Features

Note: These features are experimental and may not work perfectly in all scenarios. Test thoroughly with your use case.

Height Estimation

The height estimation features (getHeight and estimateHeight) are currently experimental and may be subject to change in future versions. These features provide ways to control the height of items in the layout:

  • getHeight: Allows you to provide exact heights for items
  • estimateHeight: Lets you implement custom height estimation logic

How It Works

The Layouter component:

  1. Estimates the height of each item based on content length
  2. Distributes items across columns to maintain balanced heights
  3. Renders items in a responsive grid layout
1. Height Estimation
β†’
120px
2. Column Distribution
3. Responsive Rendering
Small
1 column
Large
col 1
col 2
col 3

Development

Fateful Installation & Development
# Install dependencies npm install # Run development build npm run dev # Build for production npm run build

License & Contributing

MIT Β© Hassan Mohamed

Contributing

We'd love to improve React Broken Layouter with your help! Contributions are welcomeβ€”please feel free to submit a Pull Request or open an issue to discuss your ideas.