@waysnx/ui-dashboard
v0.2.11
Published
Enterprise-grade dashboard framework from WaysNX - widgets, layout system, and dashboard infrastructure without opinion on chart libraries
Maintainers
Readme
@waysnx/ui-dashboard
🤖 AI agents & LLMs: See LLM.md (shipped with this package) for a structured integration guide — widgets, KPI cards, chart-agnostic layout, and persistence utilities.
Enterprise-grade dashboard framework from WaysNX - Build modern dashboards without chart library opinions
Overview
@waysnx/ui-dashboard is a production-ready React component library for building enterprise dashboards. It provides the infrastructure and layout components you need without dictating which charting library you use.
Key Features
- 📦 Chart-Agnostic: Works with Recharts, Chart.js, ECharts, ApexCharts, Nivo, Highcharts, or custom charts
- 🎨 Fully Themeable: CSS variables-based design system with light, dark, and high-contrast themes
- ♿ WCAG AA Accessible: Built with accessibility best practices
- 🔧 Extensible: Widget registry system for custom widget types
- 💾 Persistent: Save and restore dashboard layouts and filters
- 📱 Responsive: Mobile-first responsive design
- 🎯 Performance: Tree-shakable exports, optimized for production
- 🔐 Secure: Built-in HTML sanitization for safe content rendering
- 📚 TypeScript: Fully typed with strict TypeScript support
Installation
npm install @waysnx/ui-dashboard @waysnx/ui-core @waysnx/ui-feedback @waysnx/ui-layout react react-domOr with yarn:
yarn add @waysnx/ui-dashboard @waysnx/ui-core @waysnx/ui-feedback @waysnx/ui-layout react react-domQuick Start
import React from 'react';
import {
Dashboard,
DashboardHeader,
DashboardToolbar,
Widget,
WidgetGrid,
StatCard,
DashboardFilterBar,
DashboardProvider
} from '@waysnx/ui-dashboard';
export default function MyDashboard() {
return (
<Dashboard title="Sales Dashboard" config={{ theme: 'light' }}>
<DashboardHeader
title="Sales Analytics"
subtitle="Real-time metrics"
/>
<DashboardToolbar
left={<DashboardSearch placeholder="Search..." />}
right={<button>Export</button>}
/>
<WidgetGrid columns={{ xs: 1, sm: 2, md: 3, lg: 4 }}>
<StatCard
data={{
label: 'Total Revenue',
value: '$1.2M',
trend: 'up',
change: 15,
color: '#4caf50'
}}
/>
<Widget title="Sales Chart">
{/* Use your favorite chart library */}
<BarChart data={data} />
</Widget>
</WidgetGrid>
</Dashboard>
);
}Core Components
Dashboard
Main dashboard container that provides layout and context.
<Dashboard
title="Analytics"
description="Real-time data"
config={{
theme: 'dark',
enablePersistence: true,
enableAutoRefresh: true
}}
>
{/* Dashboard content */}
</Dashboard>Widget
Reusable dashboard panel for any content.
<Widget
title="Revenue"
subtitle="Last 30 days"
loading={isLoading}
error={error}
toolbar={<RefreshButton />}
>
<Chart data={data} />
</Widget>Layout Components
WidgetGrid- Responsive grid layoutWidgetRow- Horizontal layoutWidgetColumn- Vertical layoutWidgetContainer- Generic container
<WidgetGrid columns={{ xs: 1, md: 2, lg: 3 }} gap={16}>
<Widget>Chart 1</Widget>
<Widget>Chart 2</Widget>
<Widget>Chart 3</Widget>
</WidgetGrid>WidgetGrid Responsive Breakpoints
The columns prop uses a mobile-first approach. Each breakpoint applies at its minimum width:
| Breakpoint | Min-width | Example |
|---|---|---|
| xs | 0 (base) | xs: 1 → 1 column on mobile |
| sm | 576px | sm: 2 → 2 columns on small tablets |
| md | 768px | md: 3 → 3 columns on tablets |
| lg | 1024px | lg: 4 → 4 columns on desktop |
| xl | 1280px | xl: 5 → 5 columns on large screens |
All breakpoints are optional. Only specified breakpoints generate media queries.
// 1 col mobile → 2 col tablet → 4 col desktop → 5 col large
<WidgetGrid columns={{ xs: 1, sm: 2, md: 3, lg: 4, xl: 5 }} gap={16}>
...
</WidgetGrid>
// Auto-fit mode — columns auto-adjust based on minWidth
<WidgetGrid autoFit minWidth={300} gap={16}>
...
</WidgetGrid>WidgetColumn — span and flex Props
WidgetColumn supports two sizing modes:
| Prop | Type | Use case |
|------|------|----------|
| flex | string \| number | Proportional sizing in flex layouts (default: 1) |
| span | number | Grid column span (1-12) for CSS Grid layouts — takes precedence over flex |
// Flex mode — proportional columns inside WidgetRow
<WidgetRow gap={16}>
<WidgetColumn flex={2}>Wide content</WidgetColumn>
<WidgetColumn flex={1}>Narrow content</WidgetColumn>
</WidgetRow>
// Span mode — 12-column grid system inside WidgetGrid
<WidgetGrid columns={{ lg: 12 }} gap={16}>
<WidgetColumn span={4}><StatCard ... /></WidgetColumn>
<WidgetColumn span={4}><StatCard ... /></WidgetColumn>
<WidgetColumn span={4}><StatCard ... /></WidgetColumn>
<WidgetColumn span={8}><ChartWidget ... /></WidgetColumn>
<WidgetColumn span={4}><Widget ... /></WidgetColumn>
</WidgetGrid>KPI Components
Display key metrics and performance indicators.
<StatCard
data={{
label: 'Total Sales',
value: '$5.2M',
trend: 'up',
change: 12,
status: 'success'
}}
/>Custom Trend Icons
Override the default SVG trend icons with any ReactNode:
// Text arrows
<StatCard
data={salesData}
trendIcons={{ up: "↗", down: "↘", neutral: "→" }}
/>
// Icon components (Lucide, FontAwesome, etc.)
import { TrendingUp, TrendingDown, Minus } from 'lucide-react';
<StatCard
data={salesData}
trendIcons={{
up: <TrendingUp size={14} />,
down: <TrendingDown size={14} />,
neutral: <Minus size={14} />,
}}
/>The trendIcons prop is optional — without it, built-in SVG arrows are used (↗ up-right, ↘ down-right, → right). The SVGs inherit color from the parent element via currentColor, so they automatically match the trend color styling.
<MetricCard
data={{
label: 'Conversion Rate',
actual: 3.5,
target: 5,
progress: 70,
unit: '%'
}}
/>
<ProgressCard
label="Project Completion"
progress={85}
type="circular"
status="success"
/>Specialized Widgets
ChartWidget- Chart container (works with any chart library)TableWidget- Table containerFormWidget- Form containerMarkdownWidget- Markdown contentHtmlWidget- Safe HTML rendering
Filters & Search
<DashboardFilterBar
filters={[
{ id: 'status', label: 'Status', type: 'select', options: [...] },
{ id: 'date', label: 'Date Range', type: 'daterange' }
]}
sticky
showClearAll
/>
<DashboardSearch
placeholder="Search dashboards..."
debounceDelay={300}
suggestions={suggestions}
onChange={(value) => handleSearch(value)}
/>Hooks
useDashboard
Access dashboard context and state.
const {
theme,
setTheme,
filters,
setFilters,
layout,
isRefreshing,
widgets
} = useDashboard();useWidget
Widget-specific operations.
const {
widget,
isSelected,
updateWidget,
removeWidget,
duplicateWidget
} = useWidget('widget-id');useRefresh
Manage refresh state and auto-refresh.
const {
isRefreshing,
refresh,
startAutoRefresh,
stopAutoRefresh
} = useRefresh({
enabled: true,
interval: '1m',
callback: () => fetchData()
});useFullscreen
Manage fullscreen mode.
const {
isFullscreen,
toggleFullscreen,
enterFullscreen,
exitFullscreen
} = useFullscreen(ref);useDashboardFilters
Filter management.
const {
filters,
setFilter,
removeFilter,
clearFilters
} = useDashboardFilters();Persistence
Save and restore dashboard state.
import {
saveLayout,
loadLayout,
saveDashboard,
loadDashboard,
clearDashboard
} from '@waysnx/ui-dashboard';
// Save layout
saveLayout('dashboard-1', layout);
// Load layout
const savedLayout = loadLayout('dashboard-1');
// Save entire dashboard state
saveDashboard({
id: 'dashboard-1',
name: 'Analytics',
filters: {},
layout: {},
widgets: {},
theme: 'light',
createdAt: Date.now(),
updatedAt: Date.now()
});
// Clear all data
clearDashboard('dashboard-1');Widget Registry
Extend dashboard with custom widgets.
import { widgetRegistry } from '@waysnx/ui-dashboard';
// Register custom widget
widgetRegistry.register({
type: 'custom-metric',
component: CustomMetricWidget,
displayName: 'Custom Metric',
category: 'metrics',
icon: <Icon />
});
// Get registered widget
const widget = widgetRegistry.get('custom-metric');
// Get all widgets by category
const metrics = widgetRegistry.getByCategory('metrics');Export Utilities
Export dashboard data in various formats.
import {
exportDashboardAsPNG,
exportDashboardAsPDF,
exportDataAsCSV,
exportDataAsExcel,
printDashboard
} from '@waysnx/ui-dashboard';
// Export as PNG (requires html2canvas)
await exportDashboardAsPNG(element, 'dashboard.png');
// Export as PDF (requires jspdf)
await exportDashboardAsPDF(element, 'dashboard.pdf');
// Export data as CSV
exportDataAsCSV(data, 'export.csv');
// Print dashboard
printDashboard(element);Theming
Dashboard uses CSS variables for theming. All colors and sizes are customizable.
:root {
/* Light theme (default) */
--dashboard-bg-primary: #ffffff;
--dashboard-text-primary: #212121;
--dashboard-border-color: #e0e0e0;
--dashboard-status-success: #4caf50;
--dashboard-status-error: #f44336;
/* ... and more */
}
[data-dashboard-theme="dark"] {
--dashboard-bg-primary: #1e1e1e;
--dashboard-text-primary: #f5f5f5;
/* ... dark theme overrides */
}Change theme programmatically:
const { theme, setTheme } = useDashboard();
setTheme('dark'); // 'light' | 'dark' | 'highContrast' | 'enterprise'Accessibility
All components are WCAG AA compliant:
- ✅ Semantic HTML
- ✅ ARIA labels and roles
- ✅ Keyboard navigation
- ✅ Screen reader support
- ✅ Focus management
- ✅ High contrast support
- ✅ Reduced motion support
- ✅ Font scaling — all text (including StatCard values/percentages, MetricCard values, and widget content) scales with
--wx-accessibility-font-scalefrom@waysnx/ui-accessibility. Font sizes use--wx-font-size-*tokens orcalc(px * var(--wx-accessibility-font-scale, 1))so KPI numbers scale alongside their labels when users adjust text size.
Examples
Executive Dashboard
<Dashboard title="Executive Overview">
<WidgetGrid columns={{ lg: 4 }}>
<StatCard data={revenueKPI} />
<StatCard data={profitKPI} />
<StatCard data={growthKPI} />
<StatCard data={customersKPI} />
</WidgetGrid>
<WidgetGrid columns={{ lg: 2 }}>
<ChartWidget title="Revenue Trend">
<LineChart data={data} />
</ChartWidget>
<ChartWidget title="Market Share">
<PieChart data={data} />
</ChartWidget>
</WidgetGrid>
</Dashboard>Analytics Dashboard
<Dashboard title="Analytics">
<DashboardToolbar
left={<DashboardSearch />}
right={<DateRangePicker />}
/>
<WidgetGrid columns={{ lg: 3 }}>
<ChartWidget title="Traffic Sources">
<BarChart data={data} />
</ChartWidget>
<ChartWidget title="User Engagement">
<AreaChart data={data} />
</ChartWidget>
<ChartWidget title="Conversion Flow">
<FunnelChart data={data} />
</ChartWidget>
</WidgetGrid>
</Dashboard>Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
Performance
- Fully tree-shakable
- ~15KB gzipped (including CSS)
- Zero runtime dependencies (peer dependencies only)
- Optimized for production builds
Security
- Built-in HTML sanitization using DOMPurify
- No eval or dynamic code execution
- XSS protection for user-generated content
License
Apache License 2.0 - see LICENSE for details
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
Support
Related Packages
- @waysnx/ui-core - Core UI components
- @waysnx/ui-feedback - Feedback components
- @waysnx/ui-layout - Layout components
- @waysnx/ui-form-builder - Form builder
- @waysnx/ui-grid-builder - Grid builder
Made with ❤️ by WaysNX Technologies
