feat: export Recharts theme preset for consuming apps
Add rechartsTheme config object that maps design tokens to Recharts component props, ensuring visual consistency without adding Recharts as a dependency. Also export CHART_COLORS, ChartSeries, and DataPoint types for public use. Document charting strategy in COMPONENT_GUIDE.md. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -104,6 +104,10 @@ import { GlobalFilterProvider, useGlobalFilters } from '@cameleer/design-system'
|
|||||||
// Utils
|
// Utils
|
||||||
import { hashColor } from '@cameleer/design-system'
|
import { hashColor } from '@cameleer/design-system'
|
||||||
|
|
||||||
|
// Recharts theme (for advanced charts — treemap, radar, heatmap, etc.)
|
||||||
|
import { rechartsTheme, CHART_COLORS } from '@cameleer/design-system'
|
||||||
|
import type { ChartSeries, DataPoint } from '@cameleer/design-system'
|
||||||
|
|
||||||
// Styles (once, at app root)
|
// Styles (once, at app root)
|
||||||
import '@cameleer/design-system/style.css'
|
import '@cameleer/design-system/style.css'
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
- Time series → **LineChart**, **AreaChart**
|
- Time series → **LineChart**, **AreaChart**
|
||||||
- Categorical comparison → **BarChart**
|
- Categorical comparison → **BarChart**
|
||||||
- Inline trend → **Sparkline**
|
- Inline trend → **Sparkline**
|
||||||
|
- Advanced charts (treemap, radar, heatmap, pie, etc.) → **Recharts** with `rechartsTheme` (see [Charting Strategy](#charting-strategy))
|
||||||
- Event log → **EventFeed**
|
- Event log → **EventFeed**
|
||||||
- Processing pipeline (Gantt view) → **ProcessorTimeline**
|
- Processing pipeline (Gantt view) → **ProcessorTimeline**
|
||||||
- Processing pipeline (flow diagram) → **RouteFlow**
|
- Processing pipeline (flow diagram) → **RouteFlow**
|
||||||
@@ -160,6 +161,53 @@ StatCard strip (top, recalculates per scope)
|
|||||||
URL-driven progressive filtering: /agents → /agents/:appId → /agents/:appId/:instanceId
|
URL-driven progressive filtering: /agents → /agents/:appId → /agents/:appId/:instanceId
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Charting Strategy
|
||||||
|
|
||||||
|
The design system includes built-in **AreaChart**, **BarChart**, **LineChart**, and **Sparkline** components for standard use cases. For advanced chart types (treemap, radar, heatmap, pie, sankey, etc.), consuming apps should use **Recharts** directly with the design system's theme preset for visual consistency.
|
||||||
|
|
||||||
|
**Recharts is the app's dependency, not the design system's.** The design system only exports a theme config object.
|
||||||
|
|
||||||
|
### Setup in consuming app
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install recharts
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage with theme preset
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { rechartsTheme, CHART_COLORS } from '@cameleer/design-system'
|
||||||
|
import {
|
||||||
|
ResponsiveContainer, LineChart, Line,
|
||||||
|
CartesianGrid, XAxis, YAxis, Tooltip, Legend,
|
||||||
|
} from 'recharts'
|
||||||
|
|
||||||
|
<ResponsiveContainer width="100%" height={300}>
|
||||||
|
<LineChart data={data}>
|
||||||
|
<CartesianGrid {...rechartsTheme.cartesianGrid} />
|
||||||
|
<XAxis dataKey="name" {...rechartsTheme.xAxis} />
|
||||||
|
<YAxis {...rechartsTheme.yAxis} />
|
||||||
|
<Tooltip {...rechartsTheme.tooltip} />
|
||||||
|
<Legend {...rechartsTheme.legend} />
|
||||||
|
<Line dataKey="value" stroke={CHART_COLORS[0]} strokeWidth={2} dot={false} />
|
||||||
|
<Line dataKey="other" stroke={CHART_COLORS[1]} strokeWidth={2} dot={false} />
|
||||||
|
</LineChart>
|
||||||
|
</ResponsiveContainer>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exports
|
||||||
|
|
||||||
|
| Export | Description |
|
||||||
|
|--------|-------------|
|
||||||
|
| `rechartsTheme.cartesianGrid` | Dashed gridlines, subtle stroke |
|
||||||
|
| `rechartsTheme.xAxis` | Mono font axis ticks, subtle color |
|
||||||
|
| `rechartsTheme.yAxis` | Mono font axis ticks, no axis line |
|
||||||
|
| `rechartsTheme.tooltip` | Surface bg, border, shadow, monospace values |
|
||||||
|
| `rechartsTheme.legend` | Matching text size and color |
|
||||||
|
| `rechartsTheme.colors` | The 8 `CHART_COLORS` (CSS variables with light/dark support) |
|
||||||
|
| `CHART_COLORS` | Array of `var(--chart-1)` through `var(--chart-8)` |
|
||||||
|
| `ChartSeries` / `DataPoint` | Type interfaces for chart data |
|
||||||
|
|
||||||
## Component Index
|
## Component Index
|
||||||
|
|
||||||
| Component | Layer | When to use |
|
| Component | Layer | When to use |
|
||||||
|
|||||||
@@ -41,3 +41,7 @@ export { SplitPane } from './SplitPane/SplitPane'
|
|||||||
export { Tabs } from './Tabs/Tabs'
|
export { Tabs } from './Tabs/Tabs'
|
||||||
export { ToastProvider, useToast } from './Toast/Toast'
|
export { ToastProvider, useToast } from './Toast/Toast'
|
||||||
export { TreeView } from './TreeView/TreeView'
|
export { TreeView } from './TreeView/TreeView'
|
||||||
|
|
||||||
|
// Chart utilities for consumers using Recharts or custom charts
|
||||||
|
export { CHART_COLORS } from './_chart-utils'
|
||||||
|
export type { ChartSeries, DataPoint } from './_chart-utils'
|
||||||
|
|||||||
@@ -11,3 +11,4 @@ export { BreadcrumbProvider, useBreadcrumb } from './providers/BreadcrumbProvide
|
|||||||
export type { BreadcrumbItem } from './providers/BreadcrumbProvider'
|
export type { BreadcrumbItem } from './providers/BreadcrumbProvider'
|
||||||
export * from './utils/hashColor'
|
export * from './utils/hashColor'
|
||||||
export * from './utils/timePresets'
|
export * from './utils/timePresets'
|
||||||
|
export * from './utils/rechartsTheme'
|
||||||
|
|||||||
71
src/design-system/utils/rechartsTheme.ts
Normal file
71
src/design-system/utils/rechartsTheme.ts
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import { CHART_COLORS } from '../composites/_chart-utils'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-configured Recharts prop objects that match the design system's
|
||||||
|
* chart styling. Spread these onto Recharts sub-components:
|
||||||
|
*
|
||||||
|
* ```tsx
|
||||||
|
* import { rechartsTheme, CHART_COLORS } from '@cameleer/design-system'
|
||||||
|
* import { LineChart, Line, CartesianGrid, XAxis, YAxis, Tooltip, Legend } from 'recharts'
|
||||||
|
*
|
||||||
|
* <LineChart data={data}>
|
||||||
|
* <CartesianGrid {...rechartsTheme.cartesianGrid} />
|
||||||
|
* <XAxis dataKey="name" {...rechartsTheme.xAxis} />
|
||||||
|
* <YAxis {...rechartsTheme.yAxis} />
|
||||||
|
* <Tooltip {...rechartsTheme.tooltip} />
|
||||||
|
* <Legend {...rechartsTheme.legend} />
|
||||||
|
* <Line stroke={CHART_COLORS[0]} strokeWidth={2} dot={false} />
|
||||||
|
* </LineChart>
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export const rechartsTheme = {
|
||||||
|
colors: CHART_COLORS,
|
||||||
|
|
||||||
|
cartesianGrid: {
|
||||||
|
stroke: 'var(--border-subtle)',
|
||||||
|
strokeDasharray: '3 3',
|
||||||
|
vertical: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
xAxis: {
|
||||||
|
tick: { fontSize: 9, fontFamily: 'var(--font-mono)', fill: 'var(--text-faint)' },
|
||||||
|
axisLine: { stroke: 'var(--border-subtle)' },
|
||||||
|
tickLine: false as const,
|
||||||
|
},
|
||||||
|
|
||||||
|
yAxis: {
|
||||||
|
tick: { fontSize: 9, fontFamily: 'var(--font-mono)', fill: 'var(--text-faint)' },
|
||||||
|
axisLine: false as const,
|
||||||
|
tickLine: false as const,
|
||||||
|
},
|
||||||
|
|
||||||
|
tooltip: {
|
||||||
|
contentStyle: {
|
||||||
|
background: 'var(--bg-surface)',
|
||||||
|
border: '1px solid var(--border)',
|
||||||
|
borderRadius: 'var(--radius-sm)',
|
||||||
|
boxShadow: 'var(--shadow-md)',
|
||||||
|
fontSize: 11,
|
||||||
|
padding: '6px 10px',
|
||||||
|
},
|
||||||
|
labelStyle: {
|
||||||
|
color: 'var(--text-muted)',
|
||||||
|
fontSize: 11,
|
||||||
|
marginBottom: 4,
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: 'var(--text-primary)',
|
||||||
|
fontFamily: 'var(--font-mono)',
|
||||||
|
fontSize: 11,
|
||||||
|
padding: 0,
|
||||||
|
},
|
||||||
|
cursor: { stroke: 'var(--text-faint)' },
|
||||||
|
},
|
||||||
|
|
||||||
|
legend: {
|
||||||
|
wrapperStyle: {
|
||||||
|
fontSize: 11,
|
||||||
|
color: 'var(--text-secondary)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as const
|
||||||
Reference in New Issue
Block a user