Skip to content
All Taste components

Mobile screens

Activity today

A day of activity at a glance: three goal rings, key health numbers and steps across the week.

3 progress rings + legend · 4 stat tiles · weekly bars with goal line · tab bar

Thursday, 15 Oct

Today

KN
Move420 / 600 kcal
Exercise24 / 30 min
Stand9 / 12 hrs
Steps
7,842

78% of 10,000

Distance
5.6km

↑ 0.8 km vs avg

Heart rate
72bpm

Resting 58

Sleep
7h 12m

↑ 24 min

Steps this week

Avg 8,343
FSSMTWT
// Mobile-first page; the same markup maps to React Native via NativeWind (use react-native-svg for the rings).
import { ChartColumn, Dumbbell, Flame, Footprints, HeartPulse, MapPin, Moon, User } from "lucide-react";
import { cn } from "@/lib/utils";

const rings = [
  { label: "Move", value: 420, goal: 600, unit: "kcal", r: 52, color: "text-primary" },
  { label: "Exercise", value: 24, goal: 30, unit: "min", r: 38, color: "text-success" },
  { label: "Stand", value: 9, goal: 12, unit: "hrs", r: 24, color: "text-info" },
];
const stats = [
  { label: "Steps", value: "7,842", note: "78% of 10,000", icon: Footprints },
  { label: "Distance", value: "5.6", unit: "km", note: "↑ 0.8 km vs avg", icon: MapPin },
  { label: "Heart rate", value: "72", unit: "bpm", note: "Resting 58", icon: HeartPulse },
  { label: "Sleep", value: "7h 12m", note: "↑ 24 min", icon: Moon },
];
// Thousands of steps, Friday → Thursday (today last).
const week = [
  { day: "F", steps: 6.2 }, { day: "S", steps: 8.9 }, { day: "S", steps: 11.4 }, { day: "M", steps: 4.8 },
  { day: "T", steps: 9.1 }, { day: "W", steps: 10.2 }, { day: "T", steps: 7.8 },
];
const GOAL = 10, MAX = 12;
const tabs = [
  { label: "Today", icon: Flame, current: true },
  { label: "Workouts", icon: Dumbbell },
  { label: "Progress", icon: ChartColumn },
  { label: "Profile", icon: User },
];

export default function ActivityTodayScreen() {
  return (
    <div className="mx-auto flex min-h-dvh max-w-md flex-col bg-bg font-sans text-fg">
      <main className="flex-1 px-4 pb-4">
        <header className="flex h-[60px] items-center">
          <div className="flex-1"><p className="text-xs text-fg-muted">Thursday, 15 Oct</p><h1 className="text-2xl font-semibold tracking-tight">Today</h1></div>
          <span className="grid size-9 place-items-center rounded-full bg-primary-soft text-[13px] font-medium text-primary-soft-fg">KN</span>
        </header>

        <section aria-label="Activity rings" className="mt-2 flex items-center gap-4 rounded-lg border border-border p-3">
          <svg viewBox="0 0 120 120" className="size-[116px] shrink-0" role="img"
            aria-label={rings.map((r) => r.label + " " + Math.round((r.value / r.goal) * 100) + "%").join(", ")}>
            {rings.map((r) => (
              <g key={r.label} className={r.color} transform="rotate(-90 60 60)">
                <circle cx="60" cy="60" r={r.r} fill="none" stroke="currentColor" strokeWidth="11" opacity="0.16" />
                <circle cx="60" cy="60" r={r.r} fill="none" stroke="currentColor" strokeWidth="11" strokeLinecap="round"
                  pathLength={100} strokeDasharray={Math.min(100, (r.value / r.goal) * 100) + " 100"} />
              </g>
            ))}
          </svg>
          <dl className="grid flex-1 gap-2">
            {rings.map((r) => (
              <div key={r.label}>
                <dt className="flex items-center gap-1.5 text-xs text-fg-muted"><i className={cn("size-2 rounded-full bg-current", r.color)} />{r.label}</dt>
                <dd className="text-[15px] font-semibold tabular-nums">{r.value}<span className="text-xs font-normal text-fg-muted"> / {r.goal} {r.unit}</span></dd>
              </div>
            ))}
          </dl>
        </section>

        <div className="mt-3 grid grid-cols-2 gap-2">
          {stats.map(({ label, value, unit, note, icon: Icon }) => (
            <div key={label} className="rounded-lg bg-surface px-3 py-2.5">
              <p className="flex items-center gap-1.5 text-xs text-fg-muted"><Icon className="size-3.5" aria-hidden />{label}</p>
              <p className="mt-1 text-lg font-semibold tabular-nums">{value}{unit && <span className="ml-0.5 text-xs font-medium text-fg-muted">{unit}</span>}</p>
              <p className="text-xs tabular-nums text-fg-muted">{note}</p>
            </div>
          ))}
        </div>

        <section aria-labelledby="week-title" className="mt-3 rounded-lg border border-border p-3">
          <div className="flex items-baseline justify-between">
            <h2 id="week-title" className="text-sm font-semibold">Steps this week</h2>
            <span className="text-xs tabular-nums text-fg-muted">Avg 8,343</span>
          </div>
          <div className="relative mt-2.5 grid h-16 grid-cols-7 items-end gap-2" role="img" aria-label="Daily steps, Friday to Thursday; goal 10,000">
            <span className="absolute inset-x-0 border-t border-dashed border-border-strong" style={{ bottom: (GOAL / MAX) * 100 + "%" }} />
            {week.map((d, i) => (
              <span key={i} className={cn("rounded-t", i === week.length - 1 ? "bg-primary" : "bg-primary-soft")} style={{ height: (d.steps / MAX) * 100 + "%" }} />
            ))}
          </div>
          <div className="mt-1 grid grid-cols-7 gap-2 text-center text-[11px] text-fg-subtle">
            {week.map((d, i) => <span key={i} className={cn(i === week.length - 1 && "font-semibold text-fg")}>{d.day}</span>)}
          </div>
        </section>
      </main>

      <nav aria-label="Main" className="sticky bottom-0 grid grid-cols-4 border-t border-border bg-bg px-1.5 pb-[max(env(safe-area-inset-bottom),8px)] pt-1">
        {tabs.map(({ label, icon: Icon, current }) => (
          <a key={label} href="#" aria-current={current ? "page" : undefined}
            className={cn("flex min-h-11 flex-col items-center justify-center gap-0.5 text-[10.5px] font-medium", current ? "text-primary" : "text-fg-subtle")}>
            <Icon className="size-[22px]" aria-hidden />{label}
          </a>
        ))}
      </nav>
    </div>
  );
}

The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.