Candlestick chart
SOL · USDC
Usage
Import the component and the stylesheet once. See Getting started to install the package.
import { CandlestickChartCard } from '@lilt-ui/charts/finance';
import '@lilt-ui/charts/styles.css';<CandlestickChartCard
title="SOL · USDC"
data={candles}
x="date"
open="open"
high="high"
low="low"
close="close"
volume="volume"
valueFormat={{ style: 'currency', currency: 'USD' }}
/>Omit title to leave out the visible title. Set header={false} to remove the whole header, and use aria-label to name a chart inside your own card. legend={false} removes the legend independently. surface="ghost" controls only the visual frame. See Card composition.
Data
Each row needs a low at or below its open and close, and a high at or above them; Lilt throws on a candle that breaks that rule rather than drawing it wrong. The headline is the latest close and the chip is the change from the first open to the last close. A rising candle (close at or above open) takes --lilt-candle-up, a falling one --lilt-candle-down; both follow your positive and negative tokens. Every candle draws into a handful of paths, so years of history stay fast.
// One row per period: its open, high, low, close, and optionally volume.
const candles = [
{ date: new Date('2026-08-20'), open: 243.1, high: 246.4, low: 241.8, close: 245.2, volume: 2410000 },
{ date: new Date('2026-08-21'), open: 245.2, high: 247.0, low: 243.9, close: 244.6, volume: 1980000 },
];
<CandlestickChartCard
title="SOL · USDC"
data={candles}
x="date" // a Date or number field
open="open" // numeric fields; TypeScript rejects anything else
high="high"
low="low"
close="close"
volume="volume" // optional: adds a linked volume pane
/>For a working period select, pass ranges. Each range brings its own data and delta.
<CandlestickChartCard
title="SOL · USDC"
ranges={[
{ id: '1m', label: '1M', data: lastMonth },
{ id: '3m', label: '3M', data: lastQuarter },
{ id: '1y', label: '1Y', data: lastYear },
]}
defaultRange="3m"
x="date"
open="open"
high="high"
low="low"
close="close"
/>Props
Every prop CandlestickChartCard accepts, in the order you are likely to reach for them.
| Prop | Type | Description |
|---|---|---|
title | string | Optional visible title. Omit to render no title. Also supplies the accessible name unless aria-label is set. |
data | Row[] | One row per x position. Omit when using ranges. |
x | key of Row | Text, number, or Date field for the x axis. |
open | key of Row | Numeric field holding each period’s open. |
high | key of Row | Numeric field holding each period’s high. |
low | key of Row | Numeric field holding each period’s low. |
close | key of Row | Numeric field holding each period’s close. Drives the headline and pills. |
volume | key of Row | Numeric field holding traded volume, drawn as a linked pane colored by direction. |
display | 'candle' | 'hollow' | 'ohlc' | 'area' | Filled candles (default), hollow rising bodies, OHLC bars, or an area of the close colored by direction. |
scale | 'linear' | 'log' | Log spaces prices by ratio, so a doubling looks the same at any level. |
label | string | Names the price in hover. Defaults to Price. |
live | boolean | Follow the newest candle as rows arrive, with a control to return to it. |
volumeHeight | number | Height of the volume pane in pixels. Defaults to 64. |
depth | boolean | Draws each body as a solid block whose front spans exactly open to close. OHLC bars and the area stay flat. |
header | boolean | Defaults to true. False removes the whole header: title, headline, delta and period controls, with no reserved space. Pass data directly when your app owns period selection. |
aria-label | string | Accessible chart name, independent of the visible title. Falls back to title, then a generic chart name. |
delta | number | Fractional change for the chip: 0.082 shows +8.2%. |
deltaTone | 'default' | 'inverse' | 'neutral' | Use inverse when a decrease is good. |
range | string | Static period label in the header. |
ranges | { id, label, data, delta?, headline? }[] | Turns the period label into a select. Each range swaps the data. |
valueFormat | Intl.NumberFormatOptions | Formats the headline, tiles, and axis, e.g. currency. |
legend | false | 'tiles' | 'inline' | 'list' | 'pills' | 'bars' | False removes the legend without changing the data. How the legend under the plot lays out: value tiles (default), a compact inline key, list rows, tinted pills, or bars that also draw each value against the largest. |
legendSwatch | 'square' | 'dot' | 'line' | The mark beside each legend label. Defaults to a rounded square. |
height | number | Plot height in pixels. Defaults to 240. |
axis | 'minimal' | 'dots' | 'inline' | 'ruler' | 'classic' | 'segmented' | { x, y } | Axis preset. Minimal (default) labels only the x ends and has no grid. Set one per axis with `{ x, y }`; a segmented axis can take a `gradient` to read as a range. |
hover | 'pills' | 'tooltip' | 'strip' | 'headline' | The one readout for the hovered point: pills on the axes (default), a tooltip with every series, a strip docked above the plot, or the headline and tiles alone. |
hoverStyle | 'soft' | 'solid' | 'accent' | How the pills or tooltip look. Soft (default) is surface glass; accent tints it with the hovered series. |
pillPosition | 'auto' | 'mark' | 'axis' | Where the value pill sits: above the hovered mark, or on the y axis. Auto picks mark when there are no y labels. |
tooltipIndicator | 'square' | 'dot' | 'line' | Series marker on each tooltip row, with hover="tooltip". Square by default. |
background | 'dots' | 'grid' | 'lines' | 'none' | Texture behind the marks. Dots by default, with a hover spotlight. |
surface | 'elevated' | 'outline' | 'ghost' | Card treatment. Ghost removes the visual frame only; header and legend are independent controls. |
palette | 'iris' | 'cobalt' | 'emerald' | Series colors. Iris by default; explicit series colors still win. |
axisInset | number | Padding between the plot edges and axis labels or pills. |
loading | boolean | Shows a neutral loading skeleton, not data. |
loadingStyle | 'shimmer' | 'draw' | 'breathe' | Shimmer sweeps a highlight over still shapes; draw reveals them in order; breathe lets them settle. Follows the selected look, including depth, and respects reduced motion. |
empty | 'dots' | 'shape' | ReactElement | null | What the card shows when the period has no data. Dots (default) gathers a quiet dot field around the message; shape lays the chart’s own outline behind it. Pass `<ChartEmpty>` with your own words, any element of your own, or null for nothing. Both looks stay still, so empty never reads as loading, and the headline reads a dash, never zero. |
compare | boolean | 'headline' | 'badge' | Drag across the plot to compare two points in time. True or headline reads the change in the headline; badge reads it in the card’s tab and leaves the headline at rest. |
sync | string | Link hover and pins with every card that uses the same name, matched by x value. A click pins them all, with a ghost pin on the others; Alt-click pins one card only. |
numberStyle | 'count' | 'pop' | 'slide' | 'roll' | 'flow' | 'scramble' | How the headline animates when its value changes. Count (default) counts to the new value. |
motion | 'auto' | 'none' | None turns off decorative motion; reduced motion does this automatically. |
defaultRange | string | Initial range id; defaults to the first supplied range. |
locale | string | Locale used for number formatting. Defaults to en-US. |
formatValue | (value: number) => string | Custom value text, taking precedence over valueFormat. |
formatAxisValue | (value: number) => string | Custom compact axis value text. |
formatX | (value: string | number | Date) => string | Custom x label text. |
xType | 'category' | 'number' | 'time' | Override inferred x type. Use time for numeric Unix timestamps in milliseconds. |
spotlight | boolean | Highlight the inspected position in the plot background. Defaults to true. |
badge | ReactNode | Content in the tab above the card. A comparison badge can replace this while a comparison is active. |
className | string | Additional class on the card frame. |
style | CSSProperties | ChartStyle | Inline styles and scoped --lilt-* chart variables. |
pillValue | 'series' | 'stack' | Read an individual series value (default) or its stacked height. Has no effect when the card has no stacked series. |
decimate | boolean | Defaults to true. Line and Area marks retain at most four observations per pixel column. Other marks draw every row; inspection and summaries always read the full data. |
headline | number | Override the resting headline; an active range headline takes precedence. |