Segmented Ring
Show a sequence of segments as arcs with the current one in the center, such as the intervals of a workout.
import { SegmentedRing, SegmentedRingInterval } 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 segmented ring for anything that runs in timed intervals: HIIT and Tabata, a pomodoro day, a breathing exercise. Each interval is an arc as long as it lasts, round the ring clockwise from the top inside a ruler of ten-second ticks. Work and rest take their own chart colors, and warm-up and cool-down share a third: intervals behind you are lit, the one running fills with a bright head at its edge, and the ones ahead wait in a dim wash of their color, so the shape of the whole session reads at a glance. The center holds the round in big mono, the phase and the time left in it. For a day of scheduled jobs, use a Day Ring.
import { SegmentedRing, type SegmentedRingInterval } from '@youj/react'
const intervals: SegmentedRingInterval[] = [
{ kind: 'warmup', duration: 60 },
{ kind: 'work', duration: 40, label: 'Kettlebell swings' },
{ kind: 'rest', duration: 20 },
{ kind: 'work', duration: 40, label: 'Goblet squats' },
]
<SegmentedRing intervals={intervals} elapsed={seconds} />The ring keeps no clock of its own: elapsed is the seconds since the session started, so run your own timer and pause, skip or rewind it by changing elapsed. duration is in seconds, kind picks the phase and its color (or give an interval its own tone), and label names what's done in it, spoken as the interval starts. The round counts work intervals: a warm-up leads into round 1, and a rest belongs to the round before it.
Description
A workout of a warm-up, four rounds of work and rest, and a cool-down, with a clock you start, pause or skip.
Code
segmented-ring-demo.tsx, the Demo story. The component itself comes from the package.
Reference
Propsintervals, elapsed, label… (5)
Props
| Prop | Type | |
|---|---|---|
intervalsRequired | SegmentedRingInterval[] | – |
elapsedRequired | numberSeconds since the session started. | – |
label | stringAccessible name. Default: the labels' "Interval timer". | – |
locale | stringDefault: the YoujProvider locale. | – |
sound | booleanPlays the notify cue as an interval starts, a tick in its last three seconds and success at the end. default true | true |
Other props pass through: extends ComponentProps<'div'>. | ||
StylingParts and data attributes
Styling
Parts: segmented-ring (with data-phase), segmented-ring-svg, segmented-ring-ruler, segmented-ring-segment (with data-kind and data-state), segmented-ring-progress, segmented-ring-head, segmented-ring-center, segmented-ring-label, segmented-ring-value, segmented-ring-phase and segmented-ring-summary.
MotionClock, new round · reduced motion
Motion
| Moment | Tokens | ||
|---|---|---|---|
Clockthe running arc and its head follow elapsed directly | duration.instantease.standard80ms · cubic-bezier(0.2, 0, 0, 1) | 80mscubic-bezier(0.2, 0, 0, 1) | |
| New roundthe round number rolls up to the next | spring.snappy0.2s, bounce 0 | 0.2s, bounce 0 |
Reduced motion
The round changes in place; the ring follows the clock either way.
Reduced motion
The round number changes in place. The ring still follows the clock, since that's information, not decoration.
Accessibilityannouncements
Accessibility
- The ring is a group named by
label(default: the labels' "Interval timer"), with a summary of the round, the phase and the time left ("Round 3 of 8. Work, 0:24 left"). - As an interval starts, a polite live region announces its phase, its length and what follows ("Rest, 0:20. Next: Goblet squats."), and the end is announced too.
- Sound: the notify cue plays as each interval starts, a tick in each of its last three seconds, and success at the end, behind
sound(on by default). A rewind stays quiet. - Its words come from the labels (
intervalTimer,intervalWork,intervalRest,intervalWarmup,intervalCooldown,intervalRound,intervalRoundOf,intervalLeft,intervalStarted,intervalFinished,intervalNext), translated by the language packs. - A dial turns clockwise in every script, so the ring keeps its direction under RTL; the center's text follows the page.