Sparkline
Compact, axis-less trend glyph for KPI rows, balance cards, and inline stats.
"use client";import { Sparkline } from "@reva/ui";const data = [13, 15, 14, 16, 15, 14, 16, 18, 17, 20, 19, 22, 24, 23, 25, 24, 22, 21, 22, 21, 20, 21];export function SparklineHeroDemo() {return ( <div className="w-64"> <Sparkline data={data} label="Portfolio value trend" /> </div>);}Usage
import { Sparkline } from "@reva/ui";
<Sparkline data={[4, 6, 5, 8, 7, 10, 9, 13]} />Sparkline is a thin wrapper around Recharts that renders a compact trend glyph — no axes, grid, tooltip, or legend. Pass a plain number[] and it maps each value to an evenly spaced point. It fills its container's width and takes a fixed height (default 40px), so size it from the parent.
Accent is the default
variant defaults to accent (Reva brand gold), the design system's single-series colour, so you don't need to pass it. You can still write variant="accent" explicitly if you prefer — it's equivalent to omitting it. Reach for the other variants only when the series carries meaning (see below).
Customisation
Variants
Five variants map onto the chart role tokens — accent (default, gold), primary (amber), neutral (brass/olive), positive (fern), negative (mulberry). Colour comes entirely from the --chart-{variant}-* tokens and flips with colour mode automatically.
accent
primary
neutral
positive
negative
<Sparkline data={data} variant="positive" endDot />Types
The type prop switches the render between area (default), line, and bar.
area (default)
line
bar
<Sparkline data={data} type="line" />Examples
In a card
Pair a taller sparkline with a KPI header — title, value, and a delta — to build a balance or markets card. Set height to size the glyph (here 80); the chart fills the card's width. The positive variant and the constructive delta share the fern family, so the trend line and its label read as one.
$52,219.00
0.17%
+$90.00
"use client";import { TrendUp } from "@phosphor-icons/react/ssr";import { Card, CardContent, CardHeader, CardTitle, HStack, Sparkline, Text, VStack } from "@reva/ui";const series = [28, 38, 42, 41, 44, 46, 45, 47, 46, 45, 46, 48, 52, 58, 64, 69, 70, 66, 64, 66];export function SparklineCardDemo() {return ( <Card size="sm" className="w-full max-w-lg"> <CardHeader> <HStack justify="between" align="start" gap={3}> <VStack gap={1}> <CardTitle>Dow Futures</CardTitle> <Text size="xs" weight="medium" color="muted-foreground"> $52,219.00 </Text> </VStack> <VStack gap={1} align="end"> <HStack gap={1} align="center" className="text-constructive-fg-default"> <TrendUp weight="bold" className="size-4" /> <Text size="sm" weight="semibold"> 0.17% </Text> </HStack> <Text size="xs" weight="medium" color="muted-foreground"> +$90.00 </Text> </VStack> </HStack> </CardHeader> <CardContent> <Sparkline data={series} variant="positive" height={80} label="Dow Futures intraday trend, up 0.17%" /> </CardContent> </Card>);}Ticker tiles
A row of compact ticker cards: a name, price, symbol, and trend above a full-bleed sparkline. The chart breaks out of the card's padding to meet the side and bottom edges — a negative -mb-4 inset on the size="sm" card, with the card's own overflow-hidden clipping the corners. Direction drives everything chromatic at once: the positive / negative sparkline variant, the constructive / destructive delta text, and the trend icon — so a glance down the row reads as gains and losses.
GBP/USD
1.3419
GBPUSD=X
+0.29%
FTSE 100
9,705.08
^FTSE
+0.51%
GBP/EUR
1.1417
GBPEUR=X
-0.19%
"use client";import { TrendDown, TrendUp } from "@phosphor-icons/react/ssr";import { Card, CardContent, HStack, Sparkline, Text, VStack } from "@reva/ui";const tickers = [{ name: "GBP/USD", price: "1.3419", symbol: "GBPUSD=X", change: "+0.29%", direction: "up", data: [9, 11, 12, 11, 13, 14, 13, 15, 17, 18, 17, 16, 17, 16, 17, 16] },{ name: "FTSE 100", price: "9,705.08", symbol: "^FTSE", change: "+0.51%", direction: "up", data: [8, 11, 9, 13, 12, 15, 13, 16, 14, 12, 13, 15, 14, 17, 19, 20] },{ name: "GBP/EUR", price: "1.1417", symbol: "GBPEUR=X", change: "-0.19%", direction: "down", data: [20, 19, 20, 18, 17, 18, 16, 15, 16, 14, 13, 14, 12, 11, 12, 13] },];export function SparklineTickerRowDemo() {return ( <HStack gap={4} align="stretch" className="w-full"> {tickers.map((ticker) => { const positive = ticker.direction === "up"; const TrendIcon = positive ? TrendUp : TrendDown; const trendColor = positive ? "text-constructive-fg-default" : "text-destructive-fg-default"; return ( <Card key={ticker.name} size="sm" className="min-w-0 flex-1 gap-2!"> <CardContent> <VStack gap={1}> <HStack justify="between" align="center" gap={2}> <Text size="xs" weight="medium">{ticker.name}</Text> <Text size="xs" weight="medium">{ticker.price}</Text> </HStack> <HStack justify="between" align="center" gap={2}> <Text size="xs" color="muted-foreground">{ticker.symbol}</Text> <HStack gap={1} align="center" className={trendColor}> <Text size="xs" weight="medium">{ticker.change}</Text> <TrendIcon weight="bold" className="size-3" /> </HStack> </HStack> </VStack> </CardContent> <Sparkline data={ticker.data} variant={positive ? "positive" : "negative"} height={40} className="-mb-4" label={`${ticker.name} trend, ${ticker.change}`} /> </Card> ); })} </HStack>);}Series that carry meaning
Use positive / negative for inflows versus drawdowns, and bar for discrete period contributions.
Inflows
Drawdown
<Sparkline data={inflows} variant="positive" type="bar" />Props
| Prop | Type | Default | Description |
|---|---|---|---|
data | number[] | — | Required. Series to plot; mapped to evenly spaced points. |
type | "area" | "line" | "bar" | "area" | Render type. |
variant | "accent" | "primary" | "neutral" | "positive" | "negative" | "accent" | Chart variant; accent is the implicit default. |
endDot | boolean | false | Dot on the final point (area/line; ignored for bar). |
height | number | 40 | Fixed pixel height; width fills the container. |
strokeWidth | number | 2 | Line/area stroke width. |
domain | [number, number] | auto | Fixed y-scale so a row of sparklines shares a baseline. |
label | string | — | Sets role="img" + aria-label; omitted means decorative (aria-hidden). |
className | string | — | Sizing / spacing hook. |