Stock quotePro
A quote that answers how it is doing in one look, with a drag across the chart to measure any move and a price alert drawn on the line.
On this page
Installation
Usage
import { StockQuote } from "@/components/ui/chatcn/pro/stock-quote"
<StockQuote
symbol="HLVM"
name="Halvorsen Marine"
exchange="Oslo Børs"
currency="NOK"
price={price}
previousClose={210.4}
series={series}
yearRange={[168.35, 231.75]}
market={{ state: "open" }}
onAlertChange={(price) => saveAlert(price)}
/>Pass a series per range key, oldest first; the card fetches nothing. On 1D the change is measured against previousClose, drawn as a dotted line; on longer ranges it is measured from the first point. The price rolls digit by digit with Number flow when it updates, and only the digits that changed move.
Hover or scrub to read any point. Press and drag across the chart, or hold Shift with the arrow keys, to measure: the span fills green or red, both ends get a mark, and the header reads the change between them with the two dates. Releasing a tap clears it; Escape clears it from the keyboard.
The stats table takes the usual figures (open, day range, volume, market cap, P/E, dividend yield) or your own stats, and the 52 week range is a bar with today's range on it and a tick for now. With onAlertChange the one action is Set alert: a stepper picks the price while a dashed line follows it on the chart, and a saved alert stays in the footer. Next to the free ticker-card, this adds the measure, the stats, extended hours and alerts. Render it inside the card your host draws for a widget answer. It fills the width it is given, so a comfortable max width (around 28 rem) comes from the card, and it follows the host theme through the kit tokens. Pass onExpand where the host can go full screen.
Examples
States
Props
| Prop | Type | Notes |
|---|---|---|
symbol, name, exchange | string | The header |
price, previousClose | number | Last price and yesterday's close |
currency, locale, decimals | Default USD, en-GB, 2 | |
series | Record<string, (number | { t, v })[]> | History per range key |
ranges, range, defaultRange, onRangeChange | Range chips | |
market | { state: "open" | "closed" | "pre" | "post", label? } | |
extended | { price, state?: "pre" | "post" } | Extended hours line |
open, dayRange, yearRange, volume, marketCap, pe, dividendYield | Default stats | |
stats | { label, value }[] | Your own stats instead |
delayed, updated | ReactNode | Footer notes; delayed shows in amber |
alert, defaultAlert, onAlertChange | number | null | Price alert. A rejection keeps the editor open |
status | "ready" | "loading" | "error" | Default ready |
onRetry, onExpand, disabled | ||
labels | Partial<…Labels> | Every string the widget writes, for translation |
Labels
labels covers range names (labels.ranges), market states (labels.market), stat names, the measure readout (between(from, to)), the alert editor, every error and the spoken change (change(direction, amount, percent)). Numbers and money come from Intl in locale.
Keyboard
| Key | Action |
|---|---|
| Tab | Chart, range chips, then Set alert |
| ArrowLeft, ArrowRight | Scrub the chart one point |
| Shift with ArrowLeft or ArrowRight | Measure from where you are |
| Home, End | First or last point |
| Escape | Clear the scrub or the measure |
| ArrowUp, ArrowDown in the alert field | Step the alert price |
| Enter in the alert field | Save the alert |
Accessibility
- The chart is a slider with the low and high in its name; its value text reads the point, or the measured span with the change in words.
- Direction is never color alone: an arrow and a sign come with every change, and screen readers hear up or down.
- The 52 week bar is described in words: low, high and now.
- Range chips are a native radio group named with the full period.
Motion
Digits roll in 300 ms on a price update and never while you scrub. The alert editor enters with a 180 ms fade from 0.96. Reduced motion swaps digits with a short fade.