Activity ringsPro
Daily goals as tick rings that sweep, count up, and trace a second lap past 100%.
Live · keyboard ready
- Daily goals that fill up and can be exceeded, like move, exercise, and stand.
- Fitness or habit dashboards with a week picker to compare days.
- Use progress or gauge for a single value.
- Use usage-meter for quotas and limits.
- Use activity-heatmap for streaks across many weeks.
Installation
Pro source and install commands unlock with a Pro plan.
example.tsx
import { ActivityRings } from "@/registry/components/activity-rings/activity-rings"; export function Today() { return ( <ActivityRings metrics={[ { id: "move", label: "Move", unit: "kcal", goal: 500 }, { id: "exercise", label: "Exercise", unit: "min", goal: 30 }, { id: "stand", label: "Stand", unit: "hr", goal: 12 }, ]} days={week} onRingClose={(metric, day) => celebrate(metric, day)} /> );}ActivityRings
Daily goals drawn as concentric tick rings. Arcs sweep to each day's value, a second lap traces the inside edge past 100%, and numbers count to their new amounts.
PropTypeDefaultDescription
metricsRequired{ id: string; label: string; unit: string; goal: number; color?: string }[]–One ring per metric, from the outside in. color falls back to the built in indigo, amber, and sage.daysRequired{ id: string; label: string; short: string; values: Record<string, number> }[]–Days with values keyed by metric id. label is the full date for assistive technology; short is shown under the day.daystring–Controlled selected day id.defaultDaystring–Initial day when uncontrolled. Defaults to the last day.onDayChange(day: string) => void–Called when a day is picked.focusedstring | null–Controlled isolated metric id.defaultFocusedstring | nullnullInitial isolated metric when uncontrolled.onFocusedChange(metric: string | null) => void–Called when a goal is selected or cleared from the legend.onRingClose(metric: string, day: string) => void–Called when a value on the same day crosses its goal.labelstring"Activity"Accessible name of the section.classNamestring–Extra class on the root.- Arrow keys
- In the week picker, pick the previous or next day.
- HomeorEnd
- In the week picker, pick the first or last day.
- EnterorSpace
- On a legend row, isolates that goal or clears it.
- The rings are an img whose label lists each goal's percent for the day.
- Legend rows are toggle buttons with aria-pressed and a spoken summary such as "Move, 420 of 500 kcal, 84 percent".
- The week picker is a radiogroup with a roving tabindex, named by each day's full label.
- Every change sweeps from what is on screen to the new values, so a quick second change redirects mid flight; past 100% a second lap traces the inside edge.
- Hovering or selecting a goal dims the others, and numbers count to their new amounts.
- MotionConfig follows the user's reduced motion setting, and values jump without the sweep.
- The root is a container up to 38rem; from 30rem wide the legend moves beside the rings as a list.
- Narrower containers stack the rings above a compact legend.
- The rings are SVG arcs driven by motion values, with no animation loop between changes.
- Each metric adds one ring; three to four stay legible within the fixed 220 unit viewBox.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Choose it for daily goals that fill up and can be exceeded. Use progress or gauge for a single value and usage-meter for quotas.
- Keep metric ids stable and use them as keys in each day's values. Control day when another view drives the date.
The full library index for assistants is at /llms.txt.