Skip to content

Score Ring

Show a score out of a range as a full ring of ticks lit up to it, with its letter grade in the middle.

import { ScoreGrade, ScoreRing } from '@youj/react'

Installation & usage

npm i @youj/react

For an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.

Use a score ring when one score carries a verdict: a security or health score with its letter grade, a compliance rating, a quality bar. The whole ring is the range and the lit ticks are the score, clockwise from the top, so how far round it reaches reads before the number; the tick at the score reaches past the rest. Pair it with the number itself (a Stat Card's StatValue) when the exact score matters. For a value on a scale with named bands and both ends shown, use a Gauge. The Score overview card is built on it.

import { ScoreRing, type ScoreGrade } from '@youj/react'

const grades: ScoreGrade[] = [
  { from: 0, label: 'F', tone: 'danger' },
  { from: 60, label: 'C', tone: 'warning' },
  { from: 75, label: 'B', tone: 'success' },
  { from: 90, label: 'A', tone: 'success' },
]

<ScoreRing value={77} grades={grades} label="Security score" />

Each grade starts a band at from that runs up to the next one, in any order; the ring takes the band's tone and shows its label. Without grades it shows the score in tone (the accent by default). min and max set the range (0 to 100 by default) and the score is held inside it. ticks sets how many make the ring (40 by default), size is sm (64px), default (96px) or lg (128px), and children replaces what sits in the middle.

Reference

Propsvalue, max, grades, tone, ticks, size, busy…

Props

ScoreRing props
PropType
valueRequirednumber–
minnumber

default 0

0
maxnumber

default 100

100
gradesreadonly ScoreGrade[]

Bands in any order: the ring takes the tone of the one the score is in, and shows its label.

–
toneScoreRingTone
'accent''neutral''success''warning''danger''chart-1''chart-2''chart-3''chart-4''chart-5'

The lit ticks' tone outside any grade.

default 'accent'

'accent'
ticksnumber

How many ticks make the ring.

default 40

40
size'sm' | 'default' | 'lg'

The ring's size: sm 64px, default 96px, lg 128px.

default 'default'

'default'
busyboolean

A soft sweep circles inside the ring, for a scan or a check still running.

default false

false
formatIntl.NumberFormatOptions

Intl.NumberFormat options for the score. Default: whole numbers.

–
localestring

Default: the YoujProvider locale.

–
labelstring

Accessible name. Default: the labels' "Score".

–
childrenReactNode

The middle. Default: the grade, else the score.

–
Other props pass through: extends ComponentProps<'div'>.
StylingParts and data attributes

Styling

Parts: score-ring, score-ring-ticks, score-ring-tick, score-ring-sweep and score-ring-center. The root has data-size, data-tone (the band's tone, or tone) and data-yj-busy; a lit tick has data-yj-lit. The lit ticks' color is --score-ring-tone.

MotionReveal, relight, sweep · reduced motion

Motion

Motion tokens
MomentTokens
Revealthe ticks light one after another up to the score when it scrolls into view
duration.deliberateease.standard

560ms · cubic-bezier(0.2, 0, 0, 1)

560mscubic-bezier(0.2, 0, 0, 1)
New scorethe ticks between the old and the new score relight at once
duration.fastease.standard

140ms · cubic-bezier(0.2, 0, 0, 1)

140mscubic-bezier(0.2, 0, 0, 1)
Busya soft sweep turns inside the ring, once every six deliberate beats
duration.deliberateease.linear

560ms · cubic-bezier(0, 0, 1, 1)

560mscubic-bezier(0, 0, 1, 1)

Reduced motion

Drawn at its score, with no sweep.

Reduced motion

The ring is drawn at its score, a new score lands at once, and busy draws no sweep (the ring still says it is busy).

AccessibilityMeter, value text, busy

Accessibility

  • A meter (your label, or the labels' "Score") with aria-valuemin, aria-valuemax and aria-valuenow, and a value text of the score of the maximum, then its grade: "77 of 100, grade B".
  • busy sets aria-busy, so assistive tech knows the reading may change.
  • The ticks and the sweep are decorative; the value text says the score. A grade is a letter as well as a tone, never color alone.
  • A dial turns clockwise in every script, so the ring keeps its direction under RTL.
  • Its built-in text comes from the labels, so <YoujProvider labels> translates it.