npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

draggable-dashboard

v1.4.7

Published

A comprehensive, mobile-responsive dashboard component with drag-and-drop functionality, built with React and optimized for all device sizes using a powerful 12x12 grid system.

Readme

📊 DraggableDashboard - A Fully Responsive Grid-Based Dashboard

A comprehensive, mobile-responsive dashboard component with drag-and-drop functionality, built with React and optimized for all device sizes using a powerful 12x12 grid system.

🚀 Features

📱 True Responsive Grid System

  • Unified 12x12 Grid: The dashboard maintains a consistent 12x12 grid across all devices—desktop, tablet, and mobile.
  • Adaptive Cell Sizing: Grid cells automatically resize to fit the available screen width, ensuring the layout is always proportional and fully visible.
  • Touch-Friendly Interactions: Optimized for touch devices, with edit mode automatically disabled on mobile for a seamless viewing experience.
  • Parent Container Scrolling: The dashboard's height grows with its content, using the main browser scrollbar for a natural scrolling experience without nested scrollbars.

⚙️ Advanced Functionality

  • Full State Persistence: The entire dashboard state—including tile positions, sizes, and any added or deleted tiles—is automatically saved to IndexedDB.
  • Dynamic Theming: Switch between light and dark themes on the fly for a customized look and feel.
  • Predefined Layouts: Instantly arrange tiles into clean, organized layouts (Column, Row, or Free Arrange) with the click of a button.
  • Interactive Editing:
    • Drag & drop tiles to new positions (desktop/tablet).
    • Resize tiles with snap-to-grid functionality.
    • Add/delete tiles with confirmation modals.
  • Multiple Tile Types: Supports Tables, Charts, Images, Number cards, and custom-rendered content.

🛠️ Installation

npm install
npm start

📱 Responsive Behavior

The dashboard no longer uses hardcoded breakpoints to change layouts. Instead, it relies on a single, unified 12x12 grid that works everywhere:

  • Desktop & Tablet: Full drag, drop, and resize functionality is enabled. The grid cells are larger for more design flexibility.
  • Mobile (<= 575px): editMode is automatically disabled. The 12x12 grid scales down to fit the screen width, providing a proportional, read-only view. The dashboard content scrolls vertically with the main page.

🎨 Theme Support

Theming is handled dynamically within the component for a seamless transition between modes.

Light Theme

  • Clean, light-gray background (#f8fafc).
  • Black text and titles for high contrast.
  • Blue accent colors for interactive elements.

Dark Theme

  • Deep, semi-transparent blue background (rgba(0, 16, 39, 0.95)).
  • Solid dark blue tile backgrounds (rgb(0, 16, 39)).
  • White text and titles.
  • Subtle, light-white grid borders that are visible in dark mode.

🔧 API Reference

DraggableDashboard Props

<DraggableDashboard
  tiles={tiles}                 // Array of tile objects (state managed by parent)
  setTiles={setTiles}             // React state setter to update the tiles array
  dashboardId="unique-id"         // Unique ID for IndexedDB persistence
  onDeleteTile={handleDelete}     // Callback to delete a tile from the parent's state
  renderTable={renderTable}       // Render function for 'TABLE' type tiles
  renderChart={renderChart}       // Render function for 'CHART' type tiles
  renderImage={renderImage}       // Render function for 'IMAGE' type tiles
  renderNumber={renderNumber}     // Render function for 'NUMBER' type tiles
  renderTileContent={renderCustom}// Render function for 'CUSTOM' type tiles
  AddTileModal={AddTileModal}     // Component for the "Add Tile" modal
  DeleteTileModal={DeleteModal}   // Component for the "Delete Tile" modal
  SVG={SVG}                       // Component for rendering SVG icons
  Button={Button}                 // Custom Button component
  theme="light"                   // Theme: 'light' or 'dark'
  editMode={true}                 // Toggles edit functionality (drag/resize/controls)
/>

Tile Object Structure

The tile object defines the content and its position on the 12x12 grid.

{
  id: 'unique-tile-id',
  title: 'Tile Title',
  type: 'TABLE' | 'CHART' | 'IMAGE' | 'NUMBER' | 'CUSTOM',
  // --- Type-specific properties ---
  reportId: 'report-id',          // For TABLE or CHART tiles
  chartConfigId: 'config-id',     // For CHART tiles
  imageUrl: '/path/to/image.png',   // For IMAGE tiles
  numberValue: 12345,             // For NUMBER tiles
  // --- Grid Layout Properties ---
  x: 0,       // X position on the grid (0-11)
  y: 0,       // Y position on the grid (0-11)
  w: 4,       // Width in grid units (1-12)
  h: 3        // Height in grid units (1-12)
}

🎯 Usage Example

The recommended pattern is to manage the tiles array in a parent component and let useEffect handle persistence.

import React, { useState, useEffect } from 'react';
import { DraggableDashboard } from './lib/components';
import { getDashboardTiles, setDashboardTiles } from './lib/components/dashboard/dashboardTileDB';

function MyDashboard() {
  const [tiles, setTiles] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const dashboardId = 'my-dashboard';

  // On mount, load tiles from IndexedDB or use defaults
  useEffect(() => {
    getDashboardTiles(dashboardId).then(savedTiles => {
      if (savedTiles && savedTiles.length > 0) {
        setTiles(savedTiles);
      } else {
        setTiles(/** your default tiles array **/);
      }
      setIsLoading(false);
    });
  }, []);

  // On any change, save the entire tiles array to IndexedDB
  useEffect(() => {
    if (!isLoading) {
      setDashboardTiles(dashboardId, tiles);
    }
  }, [tiles, isLoading]);

  if (isLoading) return <div>Loading...</div>;

  return (
    <DraggableDashboard
      tiles={tiles}
      setTiles={setTiles}
      dashboardId={dashboardId}
      // ... other props
    />
  );
}

🎨 Customization

While the core theme is handled dynamically, you can still use CSS to customize specific elements. The component adds theme classes .dashboard-theme-light and .dashboard-theme-dark to the main container for easy targeting.

/* Example: Customize tile border radius in light mode */
.dashboard-theme-light .dashboard-tile {
  border-radius: 12px;
}

/* Example: Customize tile header font in dark mode */
.dashboard-theme-dark .tile-header {
  font-family: 'Georgia', serif;
}

🚀 Performance

  • Efficient Re-renders: Uses React.memo and state management best practices to minimize unnecessary re-renders.
  • Optimized Grid Calculation: The grid and cell sizes are calculated efficiently on resize.
  • Smooth Animations: Leverages CSS transitions for fluid drag and resize animations.

🔧 Development

Project Structure

src/
├── lib/
│   └── components/
│       └── dashboard/
│           ├── DraggableDashboard.js    # Main component
│           ├── DraggableDashboard.css   # Styles
│           └── dashboardTileDB.js       # Full dashboard state storage (IndexedDB)
├── DashboardDemo.js                     # Demo application
└── App.js                               # Main app

Running the Demo

# Install dependencies
npm install

# Start development server
npm start

📄 License

MIT


Built with ❤️ using React and modern web technologies