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.