Risk Score
A score with the signals that produced it. The factors are the component, not a detail beside it — an analyst cannot approve or decline on "82", and an unexplained score is the one thing a regulator will ask you to justify.
src/components/ui/risk-score.tsxAbout
From the component's own source, where it was written.
A 0–100 risk score with the signals that produced it.
The contributing factors are the component, not a detail beside it. A bare number is unactionable — an analyst cannot approve or decline on "82" — and an unexplained score is also the one thing a regulator will ask you to justify.
Bands are named, not just coloured. "High" survives being printed, screenshot into a ticket, or read by someone who cannot distinguish amber from green; the colour is reinforcement.
Weights are drawn relative to the largest contributor rather than to 100, so a set of small signals still shows its shape instead of five invisible bars.
Install
npx astralyx-ui add risk-score
Usage
import { RiskScore } from '@/components/ui/risk-score'
<RiskScore score={82} factors={factors} />Composer
Change the props and the source below follows.
- Payout wallet shared with 3 other accounts+28
- Device fingerprint seen on 6 accounts in 24h+22
- Sign-up and first withdrawal 11 minutes apart+17
- Datacenter IP (AS14061)+9
- Verified identity document-12
Passport matched, 2026-08-11
<RiskScore score={82} factors={factors} />Examples
A high score and a low one
<RiskScore score={82} factors={factors} />API
Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.
RiskScore
A 0–100 risk score with the signals that produced it.
Extends Omit<ComponentProps<'div'>, 'children'>.
| Prop | Type | Default | Description |
|---|---|---|---|
| score | number | required | Clamped to max. Yours to compute — the component scores nothing. |
| factors | RiskFactor[] | — | { label, weight, detail? }. Negative weights are mitigations and render in the positive tone. |
| bands | RiskBand[] | BANDS | Thresholds and their names. Every band is labelled in words as well as coloured, because this ends up screenshotted into tickets and printed into case files. |
| max | number | 100 | — |
| label | ReactNode | 'Risk score' | — |
| size | 'sm' | 'md' | 'md' | — |
| scale | relative to peak | — | Factor bars are drawn against the largest contributor, not against 100, so five small signals still show their shape. |
| role | meter | — | With aria-valuetext carrying both the number and the band name. |
Functions
| Function | Signature | Description |
|---|---|---|
| riskBands | RiskBand[] | — |
| riskBandFor | (score: number, bands: RiskBand[]) => RiskBand | — |
Types
RiskFactor
| Field | Type | Description |
|---|---|---|
| label | ReactNode | — |
| weight | number | Points contributed. Negative values lower the score. |
| detail? | ReactNode | — |
RiskBand
| Field | Type | Description |
|---|---|---|
| min | number | — |
| label | string | — |
| color | string | — |
| ink | string | — |