M
MetricUI

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.

Revenue
$0
Accounts
0
Revenue by Region
<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
ValueBehavior
trueAuto-export. Charts export their source data array. KPI cards export a single-row value. DataTables export all rows.
falseDisable 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:

ActionChartsKPI CardsDataTable
Save as image4x DPI PNG of the full card (title + chart + legend)4x DPI PNG of the card4x DPI PNG of the visible table
Download CSVSource data array as CSV with filter metadata headerSingle row: title, value, comparisonsAll rows as CSV with filter metadata header
Copy to clipboardImage copied to clipboard (PNG)Formatted value string copied as textImage 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,3800

The 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.

PropTypeDefaultDescription
titlestring"Chart"Title used in the exported filename.
targetRefRefObject<HTMLElement>(required)Ref to the DOM element to capture for PNG export.
dataRecord<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.
copyValuestringFormatted value for clipboard copy (used by KPI cards instead of image).
densebooleanfalseCompact mode for smaller cards.
classNamestringAdditional 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.