Limit Meter
Show a value against a limit, with the remaining amount and policy thresholds, such as spending.
import { AllowanceMarker, LimitMeter } 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 an limit meter for a budget: what is left, large, with the spent and the limit as a quiet readout under it, over a ruler from zero to the limit. An index caret under the ruler points at the spend, and named lines mark the policies that act on it, so "how far until the card freezes" reads off the ruler.
import { LimitMeter } from '@youj/react'
<LimitMeter
spent={1240}
limit={2000}
format={{ style: 'currency', currency: 'EUR' }}
markers={[{ value: 1800, label: 'freeze', tone: 'warning' }]}
label="Card limit"
/>The ruler has 50 minor intervals with a major tick every 10 (ticks, majorEvery), and zero, the middle and the limit labeled under it. The remainder's decimals are set quieter than its whole part, whatever the locale's currency format. For a unit Intl has none for (GB, kcal), pass formatValue instead of format: a function that writes every amount and the scale.
Description
A card limit of 1,240 spent against 2,000 with a freeze line at 1,800, and buttons to charge, raise the limit or reset.
- The caret under the ruler points up at the spend, with a hairline across the ruler above it. Marker names sit over the ruler, pushed apart when two are close.
- Ticks already spent are lit in
tone(defaultsuccess). - The stretch still to go before a marker takes the marker's tone: the runway to it.
- Ticks past the last marker are dim.
- Spending past a marker turns those ticks to its tone, and spending past the limit turns the headline to "Over limit" with the overage in danger.
Code
limit-meter-demo.tsx, the Demo story. The component itself comes from the package.
Reference
Propsspent, limit, markers… (9)
Props
| Prop | Type | |
|---|---|---|
spentRequired | number | – |
limitRequired | number | – |
markers | AllowanceMarker[]Named lines on the ruler, e.g. the amount at which a card freezes. | – |
format | Intl.NumberFormatOptionsIntl.NumberFormat options for the amounts, e.g. | – |
formatValue | (value: number) => stringWrites every amount (and the scale) with your own function, for units Intl has none for ("12.5 TB"). Replaces | – |
locale | stringDefault: the YoujProvider locale. | – |
ticks | numberMinor intervals on the ruler. default 50 | 50 |
majorEvery | numberEvery how many minor ticks a major one falls. default 10 | 10 |
tone | AllowanceTone'accent''success''warning''danger''neutral'The spent ticks' tone. default 'success' | 'success' |
label | stringNames the meter for assistive tech. Default: the visible "Remaining". | – |
Other props pass through: extends MeterPrimitive.Root.Props. | ||
StylingParts and data attributes
Styling
Parts: limit-meter, limit-meter-header, limit-meter-label, limit-meter-remaining, limit-meter-fraction, limit-meter-summary, limit-meter-stat, limit-meter-scale, limit-meter-flags, limit-meter-flag, limit-meter-ruler, limit-meter-tick (with data-major and data-zone: spent, runway or idle), limit-meter-marker, limit-meter-spent (the hairline at the spend), limit-meter-caret and limit-meter-axis. The root has data-state (within or over).
MotionReveal, each tick, new spend or limit · reduced motion
Motion
| Moment | Tokens | ||
|---|---|---|---|
| Revealwhen it scrolls into view the spend sweeps up from zero at a constant rate: the caret rides the front and the ticks light as it passes | duration.deliberate560ms | 560ms | |
| Each tickfades to its zone’s tone | duration.fastease.standard140ms · cubic-bezier(0.2, 0, 0, 1) | 140mscubic-bezier(0.2, 0, 0, 1) | |
| New spend or limitsweeps on from where the caret is; markers glide to their new place | duration.baseease.standard220ms · cubic-bezier(0.2, 0, 0, 1) | 220mscubic-bezier(0.2, 0, 0, 1) |
Reduced motion
Drawn at its value; a new spend or limit is drawn in place.
Reduced motion
The ruler, the caret and the ticks are drawn at the value, with no sweep.
AccessibilityLabels and assistive technology
Accessibility
- It's a
meter(Base UI Meter) whose value is the spend and whose maximum is the limit. Name it withlabel; without one it's named by the visible "Remaining", which reads "Over limit" once the spend passes the limit. - Its value text says it all: "€1,240.00 spent of €2,000.00, €760.00 left, freeze at €1,800.00". Every word comes from
labels(allowanceValueText,allowanceOverText,allowanceMarkerAt, …), translated in all 14 language packs. - The ruler is hidden from assistive tech. It runs from the inline start, so right to left in RTL.