Skip to main content

Progress Donut

Displays an indicator showing the completion progress of a task as a circular progress bar.

The indicator color is inherited via currentColor. Override the default (accent-600) by setting the ProgressDonut.Indicator's text color.

Data transfer out
Included
Additional
import { ProgressDonut } from "@ngrok/mantle/progress"; <ProgressDonut.Root aria-label="Task progress" value={60} className="size-10" strokeWidth="0.375rem">	<ProgressDonut.Indicator /></ProgressDonut.Root> <ProgressDonut.Root aria-label="Task progress" value={60} className="size-10" strokeWidth="0.375rem">	<ProgressDonut.Indicator className="text-fuchsia-600" /></ProgressDonut.Root> <div className="flex flex-col gap-2">	<div className="flex items-center gap-1.5 text-sm">		<ProgressDonut.Root aria-label="Data transfer out" value={100} className="size-6">			<ProgressDonut.Indicator />		</ProgressDonut.Root>		Data transfer out	</div> 	<div className="flex items-center gap-1.5 text-xs">		<div className="grid w-6 place-items-center">			<ProgressDonut.Root aria-label="Included" value={100} className="size-4" strokeWidth="0.1875rem">				<ProgressDonut.Indicator />			</ProgressDonut.Root>		</div>		Included	</div> 	<div className="flex items-center gap-1.5 text-xs">		<div className="grid w-6 place-items-center">			<ProgressDonut.Root aria-label="Additional" value={25} className="size-4" strokeWidth="0.1875rem">				<ProgressDonut.Indicator className="text-success-600" />			</ProgressDonut.Root>		</div>		Additional	</div></div>

Accessibility

ProgressDonut.Root renders role="progressbar" with aria-valuemin, aria-valuemax, and aria-valuenow, and omits aria-valuenow while indeterminate. The role needs a name: pass aria-label, or aria-labelledby that points at a visible label, or a screen reader announces a bare "progress bar".

Indeterminate value

Set the value prop to "indeterminate" to show the donut in an indeterminate state.

Control the rotation speed with the indeterminateRotationSpeed prop.

import { ProgressDonut } from "@ngrok/mantle/progress"; <ProgressDonut.Root aria-label="Task progress" className="size-10" value="indeterminate" strokeWidth="0.375rem">	<ProgressDonut.Indicator /></ProgressDonut.Root> <ProgressDonut.Root	aria-label="Task progress"	className="size-10"	value="indeterminate"	indeterminateRotationSpeed="animation-duration-[2s]"	strokeWidth="0.375rem">	<ProgressDonut.Indicator /></ProgressDonut.Root>

Dynamic colors

ProgressDonut.Indicator inherits its color from the parent text color through currentColor. Set the parent's text color to change the indicator based on the current progress value.

import { ProgressDonut } from "@ngrok/mantle/progress"; const Example = () => {	const [value, setValue] = useState(0); 	function computeColor() {		switch (true) {			case value <= 20:				return "text-accent-600";			case value <= 40:				return "text-success-600";			case value <= 60:				return "text-warning-600";			case value <= 80:				return "text-fuchsia-600";			default:				return "text-danger-600";		}	} 	return (		<form className="space-y-4">			<ProgressDonut.Root				aria-label="Task progress"				value={value}				className="size-10"				strokeWidth="0.375rem"			>				<ProgressDonut.Indicator className={computeColor()} />			</ProgressDonut.Root>			<label className="block space-y-1">				<p>Value:</p>				<input					type="range"					min={0}					max={100}					value={value}					onChange={(e) => setValue(Number(e.target.value))}				/>{" "}				({value}%)			</label>		</form>	);};

Composition

Compose the parts of a ProgressDonut together to build your own:

ProgressDonut.Root└── ProgressDonut.Indicator

API Reference

ProgressDonut.Root

A simple circular progress bar which shows the completion progress of a task.

The indicator color is inherited via currentColor. Override the default (accent-600) by setting the ProgressDonut.Indicator's text color.

The ProgressDonut accepts the following props in addition to the standard HTML svg attributes.

PropTypeDefaultDescription
indeterminateRotationSpeed`animation-duration-${string}`"animation-duration-[15s]"Controls the rotation speed of the indeterminate spinner state, as a Tailwind animation-duration-* class.
maxnumber100The maximum value of the progress bar. Must have a value greater than 0.
strokeWidthnumber | `${number}rem`"0.25rem"The width of the progress bar stroke, clamped between 1px and 12px.
valuenumber | "indeterminate"0The current value of the progress bar. Must be between 0 and max; a value outside that range renders as indeterminate. If set to "indeterminate", the progress bar is considered indeterminate.
Data AttributeValueDescription
data-slot"progress-donut"The root <svg>.
data-valuethe current valueAbsent while indeterminate.
data-min0
data-maxthe maximum

ProgressDonut.Indicator

The indicator for the circular progress bar.

All props from svg g.