Progress Arc Gauge
An SVG arc gauge with a needle and a readout that counts to its value.
DOM + CSS0 deps1 file · 4 KB TSX
Props
"use client";
import { useEffect, useRef, useState } from "react";
export function ProgressArcGauge({
value,
label = "Capacity",
sweep = 240,
thickness = 10,
showTicks = true,
}: {
/** 0-100. */
value: number;
label?: string;
/** Arc length in degrees. */
sweep?: number;
thickness?: number;
/** Eleven graduations around the arc, every fifth one heavier. */
// ---------------------------------------------------------------
// Full source available with a viberdy Pro subscription.
// https://viberdy.dev/pricing
// ---------------------------------------------------------------
}Details
About this component
Two small decisions carry this component. The first is `pathLength={1}`, which normalises the arc so the dash values that drive the fill are plain fractions — the percentage IS the dash offset, with no `getTotalLength` call, nothing to recompute on resize, and identical behaviour at any rendered size. The second is the easing on the readout. The bar could be animated by CSS, but digits cannot: a number has to be rendered at each step, so it needs a frame loop. What matters is the curve — easeOutCubic rather than a spring, because a figure that visibly overshoots its value and settles back reads as a bug rather than as polish, even when the same spring would look excellent on a bar. The arc geometry is computed so it stays symmetric about vertical at any sweep, which means the same component covers a shallow 120-degree meter and a near-complete ring without hand-tuned offsets. Since the SVG is decoration, the real value lives on a `role="meter"` element with proper bounds.
Curator’s note
Built for viberdy 2.1. easeOutCubic on the readout, not a spring — a number that overshoots its value looks like a bug.

