System
Export
One-click image, CSV, and clipboard export for every component. Enable globally via MetricProvider or per-component with the exportable prop.
Overview
The Export system adds a small download icon to any card or chart. Clicking it opens a dropdown with three actions:
- Save as image — captures a 4x DPI PNG using modern-screenshot (handles oklch, color-mix, lab CSS).
- Download CSV — exports the component's source data as a CSV file with filter metadata.
- Copy to clipboard — copies the image (charts) or formatted value (KPI cards) to the clipboard.
CardShell automatically renders ExportButton when export is enabled — you rarely need to import it directly.
Live Demo
Hover over any component below to reveal the export button. Click it to open the dropdown with Save as image, Download CSV, and Copy to clipboard.
<MetricProvider theme="indigo" exportable>
<MetricGrid>
<KpiCard title="Revenue" value={142800} format="currency" />
<KpiCard title="Accounts" value={1248} format="number" />
<BarChart
data={salesByRegion}
index="region"
categories={["revenue"]}
title="Revenue by Region"
format="currency"
/>
</MetricGrid>
</MetricProvider>Global Setup
Enable export on every component by setting exportable on MetricProvider. All KpiCards, charts, and DataTables will show the export button.
import { MetricProvider } from "metricui";
<MetricProvider theme="emerald" exportable>
{/* All components now show export buttons */}
<KpiCard title="Revenue" value={142800} format="currency" />
<AreaChart data={data} index="month" categories={["revenue"]} />
<DataTable data={rows} columns={cols} />
</MetricProvider>Per-Component Override
Override the global setting on any individual component. Set exportable={false} to disable on a specific component, or pass a config object to customize.
{/* Global export is on, but disable for this card */}
<KpiCard title="Internal Score" value={87} exportable={false} />
{/* Global export is off, but enable for just this chart */}
<AreaChart
data={data}
index="month"
categories={["revenue"]}
exportable
/>
{/* Override CSV data with custom rows */}
<BarChart
data={chartData}
index="region"
categories={["sales"]}
exportable={{ data: customCsvRows }}
/>
{/* KPI cards export the raw numeric value by default (142800, not "142.8K"). */}
{/* Override with { data } to add context columns: */}
<KpiCard
title="Revenue"
value={142800}
format="currency"
exportable={{ data: [{ revenue: 142800, period: "Q1 2026", region: "US" }] }}
/>ExportableConfig Type
The exportable prop accepts a union type:
type ExportableConfig = boolean | { data: Record<string, unknown>[] };
// true — auto-export (charts export source data, KPIs export single value)
// false — disable export on this component
// { data: rows[] } — override with custom CSV data| Value | Behavior |
|---|---|
true | Auto-export. Charts export their source data array. KPI cards export a single-row value. DataTables export all rows. |
false | Disable export on this component, even if MetricProvider has exportable enabled. |
{ data: rows[] } | Enable export with custom CSV data. The rows you provide are used instead of the component's source data. |
Export Behavior
Each export action works differently depending on the component type:
| Action | Charts | KPI Cards | DataTable |
|---|---|---|---|
| Save as image | 4x DPI PNG of the full card (title + chart + legend) | 4x DPI PNG of the card | 4x DPI PNG of the visible table |
| Download CSV | Source data array as CSV with filter metadata header | Single row: title, value, comparisons | All rows as CSV with filter metadata header |
| Copy to clipboard | Image copied to clipboard (PNG) | Formatted value string copied as text | Image copied to clipboard (PNG), falls back to CSV text |
Image capture uses the modern-screenshot library which correctly handles modern CSS features like oklch(), color-mix(), and lab() that html2canvas cannot.
Filenames
Exported files get clean, human-readable filenames that include context:
// Pattern: "Title — Filters — Date.ext"
"Revenue — US, EU — Mar 24, 2026.png"
"Monthly Signups — Pro — Mar 24, 2026.csv"
"Conversion Funnel — Mar 24, 2026.png"The title comes from the component's title prop. Active filter selections are included automatically. Special characters are stripped for filesystem safety.
Filter Metadata
CSV exports include a metadata header comment with the active filter context at the time of export. This makes it easy to know exactly what slice of data was exported.
# Period: Mar 1, 2026 – Mar 24, 2026 · Region: US, EU · Exported Mar 24, 2026, 2:30 PM
month,revenue,users
Jan,142800,3200
Feb,156200,3450
Mar,168400,3800The metadata includes the active period, dimension filters, and cross-filter selection. It is built automatically from FilterContext and CrossFilterContext.
Props (ExportButton)
ExportButton is typically auto-rendered by CardShell. If you need to render it manually, import it from @/components/ui/ExportButton.
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | "Chart" | Title used in the exported filename. |
targetRef | RefObject<HTMLElement> | (required) | Ref to the DOM element to capture for PNG export. |
data | Record<string, unknown>[] | — | Raw data for CSV export. If not provided, the CSV option is hidden. |
columns | { key: string; header?: string }[] | — | Column definitions for CSV export. Auto-inferred from data keys if omitted. |
copyValue | string | — | Formatted value for clipboard copy (used by KPI cards instead of image). |
dense | boolean | false | Compact mode for smaller cards. |
className | string | — | Additional CSS classes on the wrapper. |
Notes
- Export is disabled by default. Enable it globally via MetricProvider or per-component with the exportable prop.
- CardShell auto-renders ExportButton when export is enabled — you rarely need to import it directly.
- KPI cards export the raw numeric value by default (e.g. 142800, not "142.8K"). Override with exportable={{ data: rows }} to customize CSV columns.
- Image capture uses modern-screenshot, not html2canvas. This correctly handles oklch(), color-mix(), lab(), and CSS custom properties.
- PNG exports render at 4x device pixel ratio for crisp screenshots on retina displays.
- CSV exports include a filter metadata header comment with period, dimensions, and cross-filter context.
- The export dropdown renders via React portal to avoid clipping by overflow:hidden containers.
- Copy to clipboard uses the Clipboard API. For charts it copies a PNG image; for KPI cards it copies the formatted text value.
- Filenames are sanitized — special characters (<>:"/\|?*) are stripped for cross-platform filesystem compatibility.
- The export button appears on hover with a smooth opacity transition. It is always accessible via keyboard focus.