Building Customizable Dashboard Widgets Using React Grid Layout

Author

AWS Certified Cloud Practitioner + Full Stack dev

Building Customizable Dashboard Widgets Using React Grid Layout

August 05, 2021

react-grid-layoutreact

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

Antstack Blog Post
Antstack Blog Post

Are you planning to go to serverless? AntStack is a cloud computing service and consulting company primarily focusing on Serverless Computing. We help companies get up and running with serverless, and we’ll make sure that there are no limits.

Keep track of our socials and connect with us - LinkedIn

event bannerevent bannerevent banner