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
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,343FSSMTWT
// 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.