OptionChain
StableCalls on the left, puts on the right, strike in the middle, as a real table.
Also known as options chain, options table
Install with npm install @tattva/ui (setup), or copy the code from the kit in Downloads.
Pick a price
Expiry 30 OctSpot 24,342.00
| Calls | Strike | Puts | ||||
|---|---|---|---|---|---|---|
| OI | IV | Price | Price | IV | OI | |
| 1.20 L | 13.2% | In the money. | 24,200 | 15.1% | 98.00 L | |
| 5.30 L | 13.5% | In the money. | 24,250 | 14.9% | 92.00 L | |
| 9.40 L | 13.8% | In the money. | 24,300 | 14.7% | 86.00 L | |
| 13.50 L | 14.1% | 24,350 At the money | In the money. | 14.5% | 80.00 L | |
| 17.60 L | 14.4% | 24,400 | In the money. | 14.3% | 74.00 L | |
| 21.70 L | 14.7% | 24,450 | In the money. | 14.1% | 68.00 L | |
| 25.80 L | 15.0% | — | 24,500 | In the money. | 13.9% | 62.00 L |
Tap a price to choose it.
function Example() {
const [pick, setPick] = useState<ChainPick | null>(null);
return (
<OptionChain ariaLabel="NIFTY option chain" expiryLabel="Expiry 30 Oct" spot={24342} rows={rows}
selected={pick ? { side: pick.side, strike: pick.strike } : undefined} onPick={setPick} />
);
}With onPick the price cells are buttons. The chosen one is marked and written out under the table.
When to use it
Lets a person scan strikes and tap one price to start an order.
Made of: Expiry and spot line · Calls and Puts group headers · Column headers · Strike column · Value cells · Price buttons
Do and avoid
Expiry 30 OctSpot 24,342.00
| Calls | Strike | Puts |
|---|---|---|
| Price | Price | |
| In the money. | 24,300 | |
| 24,350 At the money | In the money. | |
| 24,400 | In the money. |
Expiry 30 OctSpot 24,342.00
| Calls | Strike | Puts | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| OI | OI change | IV | Delta | Price | Price | Delta | IV | OI change | OI | |
| 5.20 L | -52,000 | 13.2% | 0.60 | In the money. | 24,300 | -0.40 | 15.1% | +31,000 | 88.00 L | |
| 9.30 L | 0 | 13.5% | 0.48 | 24,350 At the money | In the money. | -0.52 | 14.9% | 0 | 82.00 L | |
| 13.40 L | +52,000 | 13.8% | 0.36 | 24,400 | In the money. | -0.64 | 14.7% | -31,000 | 76.00 L | |
Do
- Keep Price in the columns when you pass onPick.
- Show the expiry and the spot price.
- Use a maxHeight for long chains.
- Pass null for a missing value and let the dash show.
Avoid
- Do not use gain and loss colours to mark in the money.
- Do not hide the scroll region on a phone. It is the way to reach the far columns.
- Do not place an order from onPick. Open an order ticket instead.
- Do not pass more columns than the width can hold without scrolling in mind.
On a phone
- The chain scrolls both ways inside its own box, because the table is as wide as its columns. The strike column stays pinned and the header rows stay at the top.
- Price buttons grow to 44px by 44px on touch screens, so rows get taller there.
- Show few columns on a phone, since each extra column adds to the sideways scroll.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| rowsrequired | { strike: number; call: ChainSide; put: ChainSide }[] | none | One row per strike. ChainSide has ltp (required, may be null) and optional oi, oiChange, iv, delta. |
| spotrequired | number | none | Price of the underlying. The nearest strike is marked, and calls below it and puts above it are in the money. |
| columns | ("oi" | "oiChange" | "iv" | "delta" | "ltp")[] | ["oi", "iv", "ltp"] | Columns on each side, in order for calls. Puts show them mirrored. |
| onPick | (pick: { side: "call" | "put"; strike: number; ltp: number }) => void | none | Makes price cells buttons. Called with the side, strike and price. |
| selected | { side: "call" | "put"; strike: number } | none | Marks one price cell as chosen. |
| expiryLabel | string | none | Shown above the table beside the spot price. |
| ariaLabelrequired | string | none | Accessible name of the scrolling region. |
| maxHeight | number | string | none | Height limit of the scrolling region. The header stays in view. |
| className | string | none | Extra classes for the outer box. |
"Show code under the preview gives the code for the example on the stage."
States
States this part has beyond its default look. Build each one your screen can reach. States set by a property are in the Code tab.
- at the money
- The row with the strike nearest spot gets a strong border, the mark ATM, and the words At the money for screen readers.
- in the money
- Calls below spot and puts above spot get a grey tint and a small diamond, with the words In the money for screen readers.
- selected
- The price cell matching selected is filled with the accent and set aria-pressed.
- empty value
- A null or missing value shows a dash. A null price is plain text, not a button.
- scrolling
- The region scrolls both ways. The header rows stay at the top and the strike column stays at the edge.
- hover
- A price button shades when the pointer is over it.
- focus
- The scroll region and each price button show the focus ring. Up and Down arrows move between rows in the same column.
Tokens
Change one of these and every part that uses it follows.
--surface--surface-sunken--border--border-strong--text--text-muted--accent--hover--radius-control--radius-card
Built in
- It is a real table with a caption, two header rows and a row header for each strike.
- The scroll region has a name and can be reached by keyboard, so the sideways scroll works without a mouse.
- The nearest strike carries the visible mark ATM and the words At the money for screen readers.
- In the money cells say so in words for screen readers beside the tint and the diamond.
- Price buttons have names such as Call 24,350, price 142.50. Up and Down arrows move between rows in the same column. The chosen one is aria-pressed.
- Values are right aligned with tabular figures. A missing value is a dash.
What you need to do
- Give it an ariaLabel that names the chain, such as NIFTY option chain.
- When a price is picked, say what was picked in text. Do not rely on the highlight.
- Show the expiry in expiryLabel so the table is not read out without it.
Built toward WCAG 2.2 AA and checked automatically; no independent audit yet. Read the accessibility guide