Domain
ScoreBar
The product's visual signature, and a deliberate exception to "the design system holds no domain". The colour derives from the value. It is never passed in as a style.
Anatomy
Layouts
inline — dashboard rows
Fair Play
3.2
stacked — narrow columns, the rating detail view
Provisions
Availability and quality of event provisions
2.2
neutral — no rating is its own state, not the bottom of the scale
Sustainability
—
loading —
skeleton({ shape: 'bar' })Accessibility
<div
role="meter"
aria-valuenow={4.7} aria-valuemin={0} aria-valuemax={5}
aria-valuetext="4.7 of 5 — Excellent"
aria-label="Communication"
/>The aria-valuetext carries the number and the tier word, because colour alone is not accessible information. One sentence for the whole row — never five separate "star" labels.
React
From @sportingscouter/ui-react. The component adds no visual values of its own — every class comes from the same tv() recipe the design system defines, so the two cannot drift.
import { ScoreBar } from '@sportingscouter/ui-react';
import { Droplet } from 'lucide-react';
<ScoreBar label="Water on course" value={4.7} showTier />
{/* The colour is DERIVED from the value by ratingOf(). It is
never passed in, which is why a caller cannot paint a
1.2 green. */}
<ScoreBar
layout="media"
icon={<Droplet className="icon-lg" />}
label="Water on course"
description="Stations every 5 km, cups and bottles"
value={4.7}
showMax
/>
{/* value <= 0, NaN or non-finite ⇒ "not rated": an empty
track and an em dash. Absence of a rating is its own
state, not the bottom of the scale. */}
<ScoreBar label="Medal" value={0} />
<ScoreBar label="Signage" value={3.1} loading />Sporting Scouter Design System
Every token on this site is generated from
theme.css.