@manggala31/react-dashboard-grid
v1.1.0
Published
Production-ready, customizable drag-and-drop dashboard grid component for React, Inertia.js, and Next.js applications.
Maintainers
Readme
@manggala31/react-dashboard-grid
Production-ready, customizable drag-and-drop dashboard grid component for React, Laravel Inertia.js, and Next.js applications.
Table of Contents
- Overview
- Key Features
- Installation
- Quick Start
- Framework Integrations
- API Reference
- Styling & Custom Themes
- License
Overview
@manggala31/react-dashboard-grid is a modular, drag-and-drop dashboard grid framework. It allows users to position, resize, reorder, and persist customizable metric cards, chart containers, and analytics widgets. It bridges server-side widget configuration APIs (such as manggala/laravel-dashboard-builder) with a fluid React frontend UI.
Key Features
- Responsive Grid Layout: 12-column responsive layout engine with configurable row heights and cell gaps.
- Drag & Drop Reordering: Native HTML5 / pointer interaction for moving widgets across grid coordinates.
- Layout State Persistence: Serialize layout coordinate state (JSON) to save user dashboard configurations to database or local storage.
- Widget Customization: Supports custom title headers, action menus, refresh triggers, and custom component content.
- Zero Heavy Dependencies: Lightweight footprint, optimized for React 18, React 19, Next.js, and Inertia.js.
Installation
# Using npm
npm install @manggala31/react-dashboard-grid
# Using yarn
yarn add @manggala31/react-dashboard-grid
# Using pnpm
pnpm add @manggala31/react-dashboard-grid
# Using bun
bun add @manggala31/react-dashboard-gridQuick Start
import React, { useState } from 'react';
import { DashboardGrid, WidgetConfig } from '@manggala31/react-dashboard-grid';
import '@manggala31/react-dashboard-grid/styles.css';
const initialWidgets: WidgetConfig[] = [
{
id: 'widget-revenue',
title: 'Monthly Revenue',
colSpan: 4,
rowSpan: 2,
content: (
<div className="metric-content">
<h2>$45,280</h2>
<span className="badge positive">+12.5% vs last month</span>
</div>
),
},
{
id: 'widget-users',
title: 'Active Subscribers',
colSpan: 4,
rowSpan: 2,
content: (
<div className="metric-content">
<h2>1,420</h2>
<span className="badge positive">+8.3% growth</span>
</div>
),
},
{
id: 'widget-orders',
title: 'Pending Orders',
colSpan: 4,
rowSpan: 2,
content: (
<div className="metric-content">
<h2>38</h2>
<span className="badge warning">Needs processing</span>
</div>
),
},
];
export default function AnalyticsDashboardPage() {
const [widgets, setWidgets] = useState<WidgetConfig[]>(initialWidgets);
const handleLayoutChange = (updatedWidgets: WidgetConfig[]) => {
setWidgets(updatedWidgets);
console.log('Saved layout state:', JSON.stringify(updatedWidgets));
};
return (
<div className="container">
<h1>Analytics Overview</h1>
<DashboardGrid
widgets={widgets}
cols={12}
isEditable
onLayoutChange={handleLayoutChange}
/>
</div>
);
}API Reference
<DashboardGrid> Props
| Prop | Type | Default | Description |
|---|---|---|---|
| widgets | WidgetConfig[] | Required | Array of widget configuration objects. |
| cols | number | 12 | Grid column count. |
| isEditable | boolean | true | Enable drag-and-drop reordering. |
| onLayoutChange | (widgets: WidgetConfig[]) => void | undefined | Callback invoked when widget positions are updated. |
| className | string | '' | Custom container CSS class. |
WidgetConfig Interface
export interface WidgetConfig {
id: string;
title?: string;
colSpan?: number;
rowSpan?: number;
content: React.ReactNode;
headerActions?: React.ReactNode;
}Styling & Custom Themes
Default layout colors and borders can be customized via CSS variables:
:root {
--dashboard-grid-gap: 16px;
--widget-card-bg: #ffffff;
--widget-card-border: #e2e8f0;
--widget-card-text: #0f172a;
--widget-card-radius: 12px;
}License
MIT License © Ilham Hatta Manggala
