React Grid Layout - AntStack
prasadbhat.png Prasad Bhat
7 min read Aug 5, 2021

Building Customizable Dashboard Widgets Using React Grid Layout

We use drag and drop in our interfaces everyday like google keep, gmail, trello etc., It gives more flexibility to the apps for moving data around the application with user interaction. So I came across this feature in one of our clients where they needed draggable and resizable cards/widgets which store the information. As we were building the application using React, I had to look for libraries/packages which support React. This brings us to why React Grid Layout was the choice for this project. So, before I take you into how you can use it to build a customizable dashboard, let’s understand why React.

Why We Used React Grid Layout?

After some digging I found some packages like React DnD and react-draggable which provide drag and drop functionality . But we needed both draggable and also resizable widgets. I found this very handy and helpful package called react-grid-layout which serves both of our requirements. React Grid Layout is helpful when a user wants to build something like a dashboard with draggable and resizable widgets.

Github link : https://github.com/react-grid-layout/react-grid-layout

Unlike other packages it supports breakpoints and it is responsive which helps developers to eliminate writing the extra code for mobile and web platforms. The breakpoints can be auto-generated or given by the user. We can also add or remove the widgets without rebuilding the whole grid layout.

Some of the features of react-grid-layout are :

  • Resizable widgets
  • Responsive breakpoints
  • Separate layouts per responsive breakpoint
  • Compatible with server-rendered apps
  • Draggable widgets
  • No Vertical Compacting (Free Movement)
  • Resizable Handles
  • Prevent Collision

Pros of React Grid Layout

  1. It combines drag-and-drop and resizing functionality in a single package.
  2. It supports breakpoints for different screen sizes, eliminating the need for additional code to make layouts mobile-friendly.
  3. It allows developers to define custom breakpoints for better control over responsiveness.
  4. It efficiently handles complex grid layouts with multiple widgets while optimizing performance.

Creating Customizable Dashboard Widgets

Before diving into the process of building the dashboard with Reach Grid Layout, let me lay down the requirements.

Prerequisites

  • HTML
  • CSS
  • Javascript
  • React
  • Basic knowledge of css grid layout and break points

Implementation

Install the package in your react application :

npm i react-grid-layout

We need to import the Responsive component and WidthProvider HOC from react-grid-layout.

import { Responsive, WidthProvider } from "react-grid-layout"

So to make the layout responsive to screen size , We need to provide the Responsive component as a parameter to the WidthProvider HOC. Then the grid layout will be automatically responsive when the user changes his screen size.

const ResponsiveReactGridLayout = WidthProvider(Responsive)

We need to import default styles of react-grid-layout to make it work as expected. Also we can override the styles of grid layout by mentioning class name to the layout.

import "react-grid-layout/css/styles.css"
import "react-resizable/css/styles.css"

So now we need to render the layout. The layout is an array where we predefine its position. The layout array consists of several objects. Each object will determine the initial position, height, width of the widget which we are rendering. This Object contains mainly five parameters . They are :

  • “i” : id of the particular card, it specifies in which card the position is going to change.
  • “x” : Position of the component in the x-axis.
  • “y” : Position of the component in the y-axis.
  • “h” : Height of the card in grid format.
  • “w” : Width of the card in grid format.

We will predefine this layout and keep it in a state called widgetArray.

const [widgetArray, setWidgetArray] = useState([
  { i: "widget1", x: 0, y: 0, w: 2, h: 2 },
  { i: "widget2", x: 2, y: 2, w: 2, h: 2 },
  { i: "widget3", x: 4, y: 4, w: 2, h: 2 },
])

This array can be modified by adding, deleting or changing the position of the objects using the setWidgetArray function.

By rendering the ResponsiveReactGridLayout component inside our component we can check how the layout is rendered inside our application.

<ResponsiveReactGridLayout
        onLayoutChange={handleModify}
        verticalCompact={true}
        layout={layouts}
        breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }}
        preventCollision={false}
        cols={{ lg: 8, md: 8, sm: 4, xs: 2, xxs: 2 }}
        autoSize={true}
        margin={{
          lg: [20, 20],
          md: [20, 20],
          sm: [20, 20],
          xs: [20, 20],
          xxs: [20, 20],
        }}
      >

When using Responsive react grid layout , it is best to supply as many breakpoints as possible, especially the largest one. If the largest is provided, RGL will attempt to interpolate the rest.

React grid layout has several properties where we can modify the widgets however we want. Some of them are :

  • breakpoints : This is where you mention the screen size.
  • onLayoutChange : This is a function where you will get the previous and new layout array which can be used to persist the position of the widgets.
  • preventCollision : Grid items or widgets in our case won’t change when being dragged over if we mention this as true.
  • resizeHandles : It defines where the draggable handle should be placed. Its values will look like this : ‘s’ , ‘n’ , ‘e’, ‘w’ , ‘se’, ‘sw’, ’ne’ and ‘nw’
  • isDraggable : It is a boolean value. We can keep a toggle for the widgets whether they can be draggable or not by applying logic.
  • isResizable : It is a boolean value. When we pass the value as false to this property , we can not resize the widgets.

It is possible to supply default mappings via the data-grid property on individual items, so that they would be taken into account within layout interpolation.

In our case we are supplying the default mappings using the state widgetArray and looping the array in data-grid .

{widgetArray?.map((widget, index) => {
          return (
            <div
              className="reactGridItem"
              key={index}
              data-grid={{
                x: widget?.x,
                y: widget?.y,
                w: widget?.w,
                h: widget?.h,
                i: widget.i,
                minW: 2,
                maxW: Infinity,
                minH: 2,
                maxH: Infinity,
                isDraggable: true,
                isResizable: true,
              }}
            >

Here we can also bound the widget height and width using minH,maxH and minW and maxW. isDraggable and isResizable props can be mentioned in grid-item which helps us in writing the logic for widget view mode and widget edit mode. Also we can add or delete widgets by removing the objects from the widgetArray.

Get the full code here.

There are several use cases for React grid layout. Check them here:

React Grid Layout

Examples

FAQs

1. Why are My Widgets Overlapping?

Incorrect or conflicting layout prop values (x, y, w, h) may cause this. Validate and adjust them.

2. Can I Disable Dragging or Resizing for Specific Widgets?

Yes, React Grid Layout allows you to use the isDraggable and isResizable properties at the widget level. You can set these to false for specific widgets to prevent them from being dragged or resized.

3. How Can I Persist the Widget Layout Across Sessions?

You can use the onLayoutChange property to capture the updated layout whenever widgets are moved or resized. Save the updated layout in your database or local storage and reload it when the dashboard initializes.

4. How Can I Dynamically Add or Remove Widgets?

You can dynamically modify the widgetArray state. To add a widget, append a new object with i, x, y, w, and h properties to the array. To remove a widget, filter the array to exclude the widget with the matching i property.

Application Modernization Icon

Explore limitless possibilities with AntStack's frontend development capabilities. Empowering your business to achieve your most audacious goals. Build better.

Talk to us

Author(s)

Tags

Your Digital Journey deserves a great story.

Build one with us.

Recommended Blogs

Cookies Icon

These cookies are used to collect information about how you interact with this website and allow us to remember you. We use this information in order to improve and customize your browsing experience and for analytics and metrics about our visitors on this website.

If you decline, your information won’t be tracked when you visit this website. A single cookie will be used in your browser to remember your preference not to be tracked.

Talk to us