motif svelteArc

Metric Card ported

One number, with its story attached.

A compact summary for a number that needs context: label, animated number, and a signed change.

Live specimen

Loading demo…

Guidance

When to use

  • Dashboard metrics where a single number needs a label, context, and a delta.
  • When the change direction should read in color as well as sign.

When not to use

  • For tabular comparison across many rows — use a table.
  • When there is detail to reveal — use Card with its quick look.

Installation

pnpm add sveltearc

Usage

<script lang="ts">
  import MetricCard from '$lib/components/metric-card/metric-card.svelte';
</script>

<MetricCard
  label="Monthly revenue"
  value={128400}
  suffix=""
  context="vs $114k last month"
  change="+12.4%"
/>

Variants & Examples

Rising Change

A leading "+" tints the chip with the success color (data-trend="up").

<MetricCard label="Signups" value={8420} context="vs last week" change="+8.1%" />

Falling Change

A leading "-" tints the chip with the danger color (data-trend="down").

<MetricCard label="Churn" value={2.1} suffix="%" context="vs last month" change="-0.3pts" />

No Change

Without `change` the chip is omitted entirely.

<MetricCard label="Total seats" value={1200} context="across all workspaces" />

API Reference

PropTypeDefaultDescription
labelstring—Heading for the metric, e.g. "Monthly revenue".
valuenumber—The numeric value, rendered through the ported AnimatedCounter.
suffixstring—Static symbol after the digits, e.g. "%".
contextstring—Supporting line under the number, e.g. "vs last quarter".
changestring—Signed delta chip, e.g. "+12.4%". Leading "+" → data-trend="up", leading "-" → "down".

Accessibility

  • The number is announced as a single string through the counter’s sr-only node.
  • Change direction is carried by the sign text itself, not color alone.

Motion

Phase 1 still-state: label, change chip, and context render as static text with the .swap/.swapBlock/.text/.sizer hooks kept for Phase 2. Phase 2 wires the directional text swaps (rise on increase, drop on decrease), the width-morph spring on the chip, and the AnimatedCounter digit roll; the prefers-reduced-motion path is instant state and already fully functional.

Notes for AI

  • Always import the ported AnimatedCounter via the $lib path — never the ARC one.
  • Keep the .sizer inside the change chip; Phase 2 measures it for the width morph.
  • Do not hand-write trend colors; data-trend owns them in CSS.

Source of truth: registry/components/metric-card/metric-card.tsx