5 min read Aug 5, 2021 Building Customizable Dashboard Widgets Using React Grid Layout
Prasad Bhat

5 min read

2021-08-05

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. 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

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

Topics

Share this blog

This website stores cookies on your computer.

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.