Gauge
Show a score or resource level on a fine half-ring scale, with its value and status.
import { Gauge, GaugeThreshold } from '@youj/react'
Installation & usage
npm i @youj/reactFor 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 gauge for a single score between known ends that people read at a glance: a health index, a load, a quota. The value sits in the bowl and the word for its band sits under it, between the range's two ends, so "74, Strained" reads before anyone looks at the arc. The arc is a thin band on a scale of ticks, and a fine needle across the band marks the value. For several resources side by side, use Segmented Meter; for a trend, use a Sparkline.
import { Gauge } from '@youj/react'
<Gauge
value={74}
label="Health index"
gradient
thresholds={[
{ value: 0, tone: 'danger', label: 'Critical' },
{ value: 50, tone: 'warning', label: 'Strained' },
{ value: 80, tone: 'success', label: 'Nominal' },
]}
/>min and max default to 0 and 100. format takes Intl.NumberFormat options, so units and percentages follow the locale. size is sm, default or lg; sm leaves the range's ends out.
Description
A health index gauge with zones and a status, and buttons for 38, 74 and 91 that move it.
gradient lays the bands under the fill as zones: each band faint in its own tone, split from the next by a hairline gap, so the whole scale reads at once, like the zones on a dial, while the fill keeps the one tone of the band the value is in. Without thresholds the zones are danger, warning and success thirds. Use it for scores where high is good; the band still names the value.
Three load gauges at 34, 76 and 95 percent, in different sizes.
Each threshold starts a band that runs up to the next one. The fill takes the band's tone, and the band's label becomes the sub-label under the value (pass children to write your own). A value crossing into the next band crossfades the fill to the new tone.
Code
gauge-demo.tsx, the Demo story. The component itself comes from the package.
Reference
Propsvalue, min, max… (11)
Props
| Prop | Type | |
|---|---|---|
valueRequired | number | – |
min | numberdefault 0 | 0 |
max | numberdefault 100 | 100 |
size | Extract<Size, 'sm' | 'default' | 'lg'>The dial's size: default 'default' | 'default' |
tone | GaugeTone'accent''success''warning''danger''neutral'The fill's tone outside any threshold band. default 'accent' | 'accent' |
thresholds | GaugeThreshold[]Bands, each from its value up to the next. The fill takes the band's tone. | – |
gradient | booleanLay the bands under the fill as zones: each threshold band faint in its tone (danger, warning and success thirds without thresholds), split by hairline gaps. default false | false |
format | Intl.NumberFormatOptionsIntl.NumberFormat options for the value. Default: whole numbers. | – |
locale | stringDefault: the YoujProvider locale. | – |
label | stringNames the gauge for assistive tech when no visible label points at it. | – |
children | ReactNodeThe sub-label under the value. Default: the current band's label. | – |
Other props pass through: extends MeterPrimitive.Root.Props. | ||
StylingParts and data attributes
Styling
Every part carries a data-slot: gauge, gauge-arc, gauge-scale (the ticks), gauge-track (or gauge-zone with gradient), gauge-indicator, gauge-index, gauge-value, gauge-footer, gauge-min, gauge-max and gauge-label. The root also has data-size and data-tone (a tone, or gradient).
MotionReveal, number and index, new value… · reduced motion
Motion
| Moment | Tokens | ||
|---|---|---|---|
| Revealthe fill sweeps up from the minimum when 40% of the gauge scrolls into view, once | spring.smooth0.36s, bounce 0 | 0.36s, bounce 0 | |
| Number and indexfollow the fill frame by frame on the same spring, so they never drift apart | spring.smooth0.36s, bounce 0 | 0.36s, bounce 0 | |
| New valueretargets mid-flight with its velocity; pressing quickly never jumps | spring.smooth0.36s, bounce 0 | 0.36s, bounce 0 | |
| Band changethe fill crossfades to the new tone | duration.baseease.standard220ms · cubic-bezier(0.2, 0, 0, 1) | 220mscubic-bezier(0.2, 0, 0, 1) |
Reduced motion
Drawn at its value, with the index and the number in place; changes jump.
Reduced motion
The fill, the needle and the number are drawn at the value, and a new value replaces the old one at once.
AccessibilityARIA
Accessibility
- It's a
meter(Base UI Meter) witharia-valuenow,aria-valueminandaria-valuemax. Name it withlabel, or pointaria-labelledbyat a visible heading. - The value is spoken with its band: "74, Strained". A warning or danger band without a label is spoken as "Warning" or "Critical" (translated through
labels), so color is never the only signal. - The arc and the animated number are hidden from assistive tech; the meter's value text carries both.
- A dial turns clockwise in every script, so the arc keeps its direction in right-to-left layouts.