Skip to main content
Compendium / Metrics & Telemetry / Gauges / Progress Ring
#704

Progress Ring

Thin progress ring — minimal radial fill for inline progress indication.

STABLE DE
#svg #gauge #real-content #responsive
Live
spec build 38% in progress
Spec

Intent

A simple ring that fills as work progresses. No centre label — pair with adjacent text. Pure visual indicator.

Acceptance Criteria

  • [ ] 360-degree thin ring with proportional fill
  • [ ] No centre label (paired externally)
  • [ ] Theme-aware tokens
  • [ ] Negative: does NOT depend on JS

Constraints

  • Pure SVG
  • Smaller stroke than radial-percent-gauge
// progress-ring.astro
---
import type { CompendiumMeta } from '../../../data/types';

export const meta: CompendiumMeta = {
  id: 704,
  slug: 'progress-ring',
  name: 'Progress Ring',
  category: 'metrics-telemetry',
  subcategory: 'gauges',
  pillar: 'de',
  description: 'Thin progress ring — minimal radial fill for inline progress indication.',
  spec: `## Intent
A simple ring that fills as work progresses. No centre label — pair with adjacent text. Pure visual indicator.

## Acceptance Criteria
- [ ] 360-degree thin ring with proportional fill
- [ ] No centre label (paired externally)
- [ ] Theme-aware tokens
- [ ] Negative: does NOT depend on JS

## Constraints
- Pure SVG
- Smaller stroke than radial-percent-gauge`,
  tags: ['svg', 'gauge', 'real-content', 'responsive'],
  status: 'stable',
  health: { ics: 85, a11y: 'aa', themed: true, animated: false },
};

const value = 38;
const r = 44;
const c = 2 * Math.PI * r;
const dashOffset = c * (1 - value / 100);
---

<div data-this-component class="w-full bg-paper text-black border-4 border-black p-4 flex items-center gap-4 overflow-hidden">
  <svg viewBox="0 0 100 100" class="w-20 h-20 block -rotate-90 shrink-0" aria-label={`Progress ${value} percent`}>
    <circle cx="50" cy="50" r={r} fill="none" stroke="var(--color-ink)" stroke-width="6" opacity="0.12" />
    <circle cx="50" cy="50" r={r} fill="none" stroke="var(--color-de)" stroke-width="6" stroke-dasharray={c} stroke-dashoffset={dashOffset} />
  </svg>
  <div class="flex flex-col">
    <span class="font-mono text-[10px] uppercase tracking-widest opacity-60">spec build</span>
    <span class="font-black text-xl tabular-nums leading-tight">{value}%</span>
    <span class="font-mono text-[9px] uppercase tracking-widest opacity-60">in progress</span>
  </div>
</div>