React Widget Dashboard Framework
The `di-widgets-framework` is a React-based library for creating interactive, customizable widget dashboards with integrated drag-and-drop functionality. Currently at version 1.9.6, it offers components like `WidgetPalette` for widget selection and `WidgetSettingsPanel` for extensive configuration, including styling, behavior, and type-specific options. This framework differentiates itself through dynamic loading of widget types from a backend API, built-in search for widgets, and a comprehensive settings panel supporting various widget categories (e.g., search, filter, results, analytics, header, footer, text, agent). While no explicit release cadence is stated, the versioning indicates active maintenance and development. It ships with TypeScript types for enhanced developer experience.
Common errors
-
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
cause This typically occurs when a React component is imported incorrectly (e.g., trying to default import a named export, or using CommonJS `require` in an ESM context).fixEnsure all components are imported using named ES module syntax, like `import { ComponentName } from 'di-widgets-framework';`, and that your build setup supports ES Modules. -
TypeError: Cannot read properties of undefined (reading 'title') (or similar property of a widget object)
cause A `Widget` object (or a nested property of it) expected by a component like `WidgetSettingsPanel` is `undefined` or `null`, often due to missing data or incorrect state management.fixBefore rendering components that rely on complex objects, ensure the data (e.g., the `widget` prop) is valid and complete. Implement defensive coding with optional chaining (`?.`) or conditional rendering. -
Failed to load resource: the server responded with a status of 404 (Not Found) - for widgetBackendUrl API calls
cause The backend API specified by `widgetBackendUrl` is inaccessible, the URL is incorrect, or the specific endpoint does not exist or is not configured correctly on the server.fixVerify the `widgetBackendUrl` value for typos and ensure your backend service is running and accessible at that exact URL. Confirm that the required API endpoints are correctly implemented and exposed.
Warnings
- gotcha Omitting the `widgetBackendUrl` prop for components like `WidgetPalette` and `WidgetSettingsPanel` defaults to relative API calls. This can lead to unexpected '404 Not Found' errors or network failures in non-root deployments or server-side rendering (SSR) environments.
- gotcha The `WidgetSettingsPanel` component has critical required props: `pageId` (string) and `widget` (an object conforming to the `Widget` interface). Failure to provide valid values for these will result in runtime errors and prevent the panel from rendering or functioning correctly.
- gotcha As a React framework, `di-widgets-framework` depends on `react` and `react-dom` as peer dependencies. Incompatible versions (e.g., using an older React with a newer framework, or vice-versa) can lead to runtime issues such as 'Invalid hook call' errors.
- gotcha While the library ships with TypeScript types, incorrect usage or misconfiguration of your `tsconfig.json` can lead to type errors during compilation. For example, importing types as values (e.g., `import { Widget } from '...'`) rather than using `import type`.
Install
-
npm install dp-widgets-framework -
yarn add dp-widgets-framework -
pnpm add dp-widgets-framework
Imports
- WidgetPalette
const WidgetPalette = require('di-widgets-framework').WidgetPalette;import { WidgetPalette } from 'di-widgets-framework'; - WidgetSettingsPanel
import WidgetSettingsPanel from 'di-widgets-framework/WidgetSettingsPanel';
import { WidgetSettingsPanel } from 'di-widgets-framework'; - Widget (Type)
import { Widget } from 'di-widgets-framework';import type { Widget } from 'di-widgets-framework';
Quickstart
import React from 'react';
import { WidgetPalette, WidgetDashboard } from 'di-widgets-framework';
function App() {
// In a real application, you might fetch available widgets dynamically
const availableWidgetTypes = [
{ id: 'search', name: 'Search Input', description: 'Search input widget' },
{ id: 'filter', name: 'Data Filter', description: 'Filter/facet widget' },
{ id: 'results', name: 'Results Display', description: 'Results display widget' },
{ id: 'analytics', name: 'Analytics Chart', description: 'Analytics/charts widget' },
];
return (
<div style={{ display: 'flex', height: '100vh', padding: '20px' }}>
<div style={{ width: '25%', paddingRight: '20px', borderRight: '1px solid #eee' }}>
<h3>Widget Palette</h3>
<WidgetPalette
widgetBackendUrl="http://localhost:3001"
// In a real app, you might pass availableWidgetTypes as a prop if not fetched by backend
/>
</div>
<div style={{ flex: 1, paddingLeft: '20px' }}>
<h3>Dashboard Area</h3>
{/* WidgetDashboard component would be used here to render dropped widgets */}
{/* Example: <WidgetDashboard backendUrl="http://localhost:3001" /> */}
<p>Drag widgets from the palette onto this area.</p>
</div>
</div>
);
}
export default App;