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 🙏

© 2026 – Pkg Stats / Ryan Hefner

di-widgets-framework

v1.3.1

Published

A React framework for creating customizable widget dashboards with drag-and-drop functionality

Readme

Widget Framework Components Documentation

Table of Contents

  1. WidgetPalette
  2. WidgetSettingsPanel
  3. WidgetDashboard
  4. Widget (Type Interface)
  5. SavedPages
  6. DashboardPages

WidgetPalette

A draggable widget palette component that displays available widget types and allows users to drag them onto the dashboard.

Props

| Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | widgetBackendUrl | string | No | undefined | Base URL for the backend API. If not provided, uses relative URLs |

Features

  • Search Functionality: Built-in search to filter widgets by name or description
  • Drag & Drop: Widgets can be dragged from the palette to the dashboard
  • Dynamic Loading: Fetches available widget types from the backend API
  • Icon Mapping: Displays appropriate icons for each widget type

Usage Example

npm install di-widgets-framework

import { WidgetPalette } from 'di-widgets-framework';

function App() {
  return (
    <WidgetPalette 
      widgetBackendUrl="http://localhost:3001" 
    />
  );
}

Widget Types Supported

  • search: Search input widget (12x2 grid)
  • filter: Filter/facet widget (3x8 grid)
  • results: Results display widget (9x8 grid)
  • analytics: Analytics/charts widget (6x4 grid)
  • header: Header section widget (12x2 grid)
  • footer: Footer section widget (12x2 grid)
  • text: Text content widget (6x2 grid)
  • agent: AI agent interaction widget (6x4 grid)

WidgetSettingsPanel

A comprehensive settings panel for configuring widget properties including styling, behavior, and type-specific options.

Props

| Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | pageId | string | Yes | - | The ID of the page containing the widget | | widget | Widget | Yes | - | The widget object to configure | | onClose | () => void | Yes | - | Callback function when the panel is closed | | onWidgetUpdate | () => void | No | undefined | Callback function when widget is updated | | widgetBackendUrl | string | No | undefined | Base URL for the backend API | | agentIds | string[] | No | undefined | Array of available agent IDs for dropdown selection |

Features

Common Settings (All Widgets)

  • Title: Widget display title
  • Show Header: Toggle widget header visibility
  • Resizable: Enable/disable widget resizing
  • Draggable: Enable/disable widget dragging
  • Styling Options:
    • Background color (color picker + text input)
    • Border radius (none, rounded, large, extra-large)
    • Padding (small, medium, large, extra-large)
    • Text color (color picker + text input)
    • Font size (custom CSS values)
    • Text alignment (left, center, right)

Search Widget Settings

  • Placeholder Text: Search input placeholder
  • Minimum Characters: Required characters before search (1-10)
  • Search Delay: Debounce delay in milliseconds (0-1000)
  • Auto Focus: Automatically focus the search input
  • Voice Search: Enable voice search functionality
  • Recent Searches: Show recent search history
  • Maximum Recent Searches: Number of recent searches to store
  • Facets Configuration: Enable and configure search facets

Results Widget Settings

  • Layout Type: Grid, list, or table display
  • Items Per Page: 5, 10, 20, 50, or 100 items
  • Infinite Scroll: Enable infinite scrolling
  • Show Pagination: Display pagination controls
  • Hide Relevance: Hide relevance scores
  • Title Template: Field to use for result titles
  • Metadata Fields: Configure displayed metadata

Filter Widget Settings

  • Show Clear Button: Display clear all filters button
  • Collapsible Sections: Make filter sections collapsible
  • Default Expanded: Default expansion state for sections
  • Facets Configuration: Configure filter facets

Agent Widget Settings

  • Agent Type: Chatbot Agent, Bar Chart Agent, or Pie Chart Agent
  • Agent ID: Unique identifier for the agent (dropdown if agentIds prop provided, otherwise text input)
  • Query: Custom query for non-chatbot agents

Code Settings (Search Widget)

  • Custom Widget Code: JavaScript code editor for custom functionality

Usage Example

import { WidgetSettingsPanel } from 'di-widgets-framework';

function MyComponent() {
  const [selectedWidget, setSelectedWidget] = useState(null);
  const agentIds = ['agent-1', 'agent-2', 'chatbot-agent']; // Optional: provide agent IDs
  
  return (
    <WidgetSettingsPanel
      pageId="page-123"
      widget={selectedWidget}
      onClose={() => setSelectedWidget(null)}
      onWidgetUpdate={handleWidgetUpdate}
      widgetBackendUrl="http://localhost:3001"
      agentIds={agentIds}
    />
  );
}

WidgetDashboard

The main dashboard component that provides a drag-and-drop grid layout for widgets with editing capabilities.

Props

| Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | pageId | string | Yes | - | The ID of the page to display | | isEditing | boolean | Yes | - | Whether the dashboard is in edit mode | | selectedWidget | Widget \| null | No | null | Currently selected widget | | onWidgetSelect | (widget: Widget \| null) => void | No | undefined | Callback when a widget is selected | | refreshKey | number | No | undefined | Key to trigger data refresh | | widgetBackendUrl | string | No | undefined | Base URL for the backend API |

Features

  • Grid Layout: 12-column responsive grid system using react-grid-layout
  • Drag & Drop: Accept widgets from the palette and arrange existing widgets
  • Editing Mode: Toggle between view and edit modes
  • Widget Selection: Click to select widgets for configuration
  • Auto-save: Automatically saves layout changes with debouncing (2-second delay)
  • Widget Management: Add, remove, and configure widgets
  • Responsive: Adjusts to container width
  • Collision Prevention: Prevents widgets from overlapping

Layout Configuration

  • Columns: 12-column grid
  • Row Height: 50px per row
  • Margins: 8px between widgets
  • Minimum Size: 3 columns wide, 2 rows high

Required CSS Imports

To use the WidgetDashboard component, you must import the following CSS files:

import "@copilotkit/react-ui/styles.css";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";

Usage Example

import { WidgetDashboard } from 'di-widgets-framework';
import "@copilotkit/react-ui/styles.css";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";

function Dashboard() {
  const [isEditing, setIsEditing] = useState(false);
  const [selectedWidget, setSelectedWidget] = useState(null);
  
  return (
    <WidgetDashboard
      pageId="page-123"
      isEditing={isEditing}
      selectedWidget={selectedWidget}
      onWidgetSelect={setSelectedWidget}
      widgetBackendUrl="http://localhost:3001"
    />
  );
}

Widget (Type Interface)

The core widget data structure used throughout the framework.

Interface Definition

interface Widget {
  id: string;                    // Unique widget identifier
  page_id: string;              // ID of the containing page
  type: string;                 // Widget type (search, filter, results, etc.)
  title: string;                // Display title
  position_x: number;           // Grid X position (0-11)
  position_y: number;           // Grid Y position
  width: number;                // Grid width (1-12)
  height: number;               // Grid height in rows
  config: any;                  // Widget-specific configuration
  category_id?: string;         // Optional category identifier
  is_resizable: boolean;        // Whether widget can be resized
  is_draggable: boolean;        // Whether widget can be dragged
}

Widget Configuration Examples

Search Widget Config

{
  placeholder: "Search...",
  minCharacters: 3,
  searchDelay: 300,
  autoFocus: true,
  voiceSearch: false,
  recentSearches: true,
  maxRecentSearches: 5,
  facets: {
    enabled: true,
    fields: [
      { field: "category", displayName: "Category", order: 1, enabled: true }
    ]
  }
}

Results Widget Config

{
  layout: {
    type: "grid",
    itemsPerPage: 10,
    infiniteScroll: false
  },
  showPagination: true,
  hideRelevance: false,
  titleTemplate: "filename",
  metadata: {
    fields: ["author", "date", "category"]
  }
}

Styling Config

{
  styles: {
    backgroundColor: "#ffffff",
    textColor: "#000000",
    fontSize: "14px",
    padding: "medium",
    borderRadius: "rounded",
    alignment: "left"
  },
  showHeader: true
}

SavedPages

A page management component for listing, creating, and managing saved widget pages.

Props

| Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | onEditPage | (pageId: string) => void | Yes | - | Callback function when a page is selected for editing | | widgetBackendUrl | string | No | undefined | Base URL for the backend API |

Features

  • Page Listing: Grid view of all saved pages
  • Search: Filter pages by title
  • Create Pages: Modal dialog for creating new pages
  • Edit Pages: Navigation to page editor
  • Delete Pages: Remove existing pages
  • Public/Private: Configure page visibility

Page Properties

  • Title: Page display name
  • Public Status: Whether the page is publicly accessible
  • Creation Date: When the page was created
  • Owner: Page owner identifier

Usage Example

import { SavedPages } from 'di-widgets-framework';

function PageManager() {
  const handleEditPage = (pageId) => {
    // Navigate to page editor
    router.push(`/editor/${pageId}`);
  };
  
  return (
    <SavedPages 
      onEditPage={handleEditPage}
      widgetBackendUrl="http://localhost:3001"
    />
  );
}

Create Page Modal

The component includes a modal for creating new pages with:

  • Title Input: Required page title
  • Public Checkbox: Make page publicly accessible
  • Validation: Ensures title is provided
  • Error Handling: Displays creation errors

API Integration

All components integrate with a backend API and require the following endpoints:

Required Endpoints

  • GET /api/pages - List all pages
  • GET /api/pages/{id} - Get specific page with widgets
  • POST /api/pages - Create new page
  • PUT /api/pages/{id} - Update page and widgets
  • DELETE /api/pages/{id} - Delete page
  • GET /api/widgets/types - Get available widget types

Authentication

Components assume API authentication is handled at the application level through:

  • HTTP headers
  • Cookies
  • URL parameters
  • Environment configuration

Error Handling

All components include:

  • Loading states with spinners
  • Error boundaries with user-friendly messages
  • Retry mechanisms for failed requests
  • Graceful degradation when APIs are unavailable

Styling and Theming

Components use Tailwind CSS classes and support:

  • Dark/Light Mode: Automatic theme detection
  • Custom Colors: Configurable through CSS variables
  • Responsive Design: Mobile-first responsive layouts
  • Accessibility: ARIA labels and keyboard navigation

CSS Dependencies

Required CSS imports for WidgetDashboard:

import "@copilotkit/react-ui/styles.css";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";

DashboardPages

A tab-based dashboard component that displays all saved pages in non-edit mode, with each page rendered in a separate tab using the WidgetDashboard component.

Props

| Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | widgetBackendUrl | string | No | undefined | Base URL for the backend API. If not provided, uses relative URLs |

Features

  • Tab Interface: Each saved page appears as a separate tab with the page title as the tab name
  • Non-Edit Mode: All WidgetDashboard components are rendered in view-only mode (isEditing={false})
  • Dynamic Loading: Fetches saved pages from the backend API using /api/pages?view=list
  • Error Handling: Proper loading states and error messages
  • Responsive Design: Tabs adjust to accommodate any number of pages
  • Empty State: Shows helpful message when no pages are found

Usage Example

import { DashboardPages } from 'di-widgets-framework';

function App() {
  return (
    <DashboardPages 
      widgetBackendUrl="http://localhost:3001" 
    />
  );
}

Component Behavior

  1. Loading State: Shows spinner while fetching pages
  2. Tab Creation: Creates a tab for each saved page using the page title
  3. Default Tab: Automatically selects the first page as the default active tab
  4. Widget Rendering: Each tab content renders a WidgetDashboard component in non-edit mode
  5. Error Handling: Displays error messages if API calls fail

Required API Endpoints

  • GET /api/pages?view=list - List all saved pages with basic information

API Response Format

Expected response from /api/pages?view=list:

[
  {
    "id": "page-123",
    "title": "My Dashboard",
    "owner_id": "user-456",
    "is_public": false,
    "allowed_domains": [],
    "theme_id": null
  }
]

Styling

  • Uses consistent tab styling with the framework's design system
  • Supports responsive breakpoints for different screen sizes
  • Includes proper spacing and visual hierarchy
  • Tab titles are truncated with ellipsis for long names and show full title on hover

Best Practices

  1. Performance: Use refreshKey prop to trigger selective re-renders
  2. State Management: Lift state up to parent components when needed
  3. Error Boundaries: Wrap components in error boundaries
  4. Loading States: Show loading indicators during API calls
  5. Accessibility: Ensure keyboard navigation and screen reader support
  6. Responsive Design: Test on different screen sizes
  7. API Error Handling: Implement retry logic and user feedback