Dashboard Components
The components every dashboard, chat chart, and share page renders, and the settings that control them.
Every dashboard widget, every chart the copilot draws in chat, and every public share page render through one component library. A widget stores a JSON spec that lists components and binds each figure to a query on one of your tables. The copilot writes the spec for you; you can also edit it as JSON.
There is no visual settings panel. Ask the copilot ("show negatives in brackets", "make the chart taller") or edit the widget JSON.
Components
| Component | Use it for |
|---|---|
Metric | A KPI tile: value, delta against a comparison period, optional sparkline and target bar |
BarChart | Comparisons by category or period; stacked, horizontal, or signed (negatives below zero) |
LineChart | Trends over time, with comparison, budget, and forecast series |
AreaChart | Cumulative or stacked trends over time |
ComboChart | Bars and lines on one chart, with an optional right axis |
PieChart | Share of a total, as a donut with at most 5 slices plus Other |
BarList | Rankings: top customers, vendors, or spend categories |
WaterfallChart | Bridges: MRR movements, cash bridge, budget-to-actual walk |
DataTable | Row-level tables and statement layouts with subtotals and totals |
PivotTable | Cross-tabs with row groups, subtotals, and totals |
VarianceTable | Budget vs actual with variance and variance percent |
CohortHeatmap | Retention or revenue by cohort and period |
DateRangeFilter | Period presets (MTD, QTD, YTD, fiscal) and a compare toggle |
SearchInput, Select | Filters that other components read |
Stack, Grid, Card, Heading, Text, Badge, Callout, Button | Layout and text |
Header
Every titled figure has the same header:
- Title, with an info icon when
definitionis set. - One muted line: period, currency, and
basis(for exampleJan–Sep 2026 · USD · Accrual), plus the comparison period when compare is on. as of HH:MMfor the last load, and a Stale chip when the figure shows the last good result after a failed load.- Actions: Export CSV, and Open data (not shown on public share pages).
Header props: subtitle, definition, basis, showAsOf, actions
(export, open).
Number formats
A format is a legacy string (currency, compact_currency, percent,
number) or an object:
| Field | Values |
|---|---|
kind | currency, percent, pp, number, integer, months, days, ratio |
currency | ISO-4217 code, for example EUR |
scale | auto ($1.24M), none (exact), thousands, millions, billions |
decimals | 0 to 4 |
negative | minus (-$1,200) or parentheses (($1,200)) |
signDisplay | auto or always |
Missing values show —. A percent change on a zero base shows N/M. KPI
tiles and chart axes use compact scale; tables show exact values.
Colors
Specs name color tokens, never hex values:
- Series:
series-1toseries-8(chart-1tochart-5still work). - Status:
positive,negative,neutral,warning. Use these for deltas, variances, and thresholds. A series can use them only withrole: 'variance'. - Roles:
compare(gray, dashed) andforecast(dashed after the forecast start).
thresholds color a value when it matches a rule:
{ op: 'lt'|'lte'|'gt'|'gte'|'between', value, value2?, color, label? }, at most 8.
Dashboard settings
Each dashboard has one set of display defaults. A component format overrides
them field by field.
| Setting | Values | Default |
|---|---|---|
locale | BCP-47 tag, for example en-GB | en-US |
currency | ISO-4217 code | USD |
negative | minus or parentheses | minus |
fiscalYearStartMonth | 1 to 12 | 1 |
density | compact or comfortable | compact |
The currency setting changes display only. It does not convert amounts.
Public share links
A published dashboard shows live data to anyone with the link. The public page does not receive table IDs, filter values, or queries. Each figure asks the server for its data by widget, and the server runs only the queries stored in that widget. Results are cached for 60 seconds, and the page refreshes every 5 minutes. Revoking the link stops all public loads.
Adding a component
For contributors adding a component to the library:
- Add the props schema and description to the catalog group in
packages/json-render/src/schemas/components/, and register it incatalog.ts. Reuse the shared settings vocabulary (numberFormat,colorToken,thresholds, header props) instead of new enums. - List any prop that holds data in
FIGURE_PROPS(check.ts) so specs with static figures are rejected, and add lint rules inlint.tswhen the component has usage rules. - Add the Studio component under
packages/json-render/src/react/components/and register it inregistry.tsx. UsePanel,EmptyState,LoadError, and the format context so headers, states, and numbers stay consistent. - Add a rule to the catalog prompt (
prompt.ts) only when the model needs guidance, and keep the prompt-budget test green. - Add table-driven tests for the schema, lint rules, and component.
Loopfour