Progress Circle
Circular radial meter communicating progress or activity within compact spaces.
Progress Circle
The Progress Circle communicates progress or system activity within tight, circular spaces—such as inside table cells, card corners, file upload rows, and modal dialogs.
Like its linear sibling, Progress Circle supports both determinate percentage rings and continuous indeterminate spinners, rendering sharp SVG geometry scaled for high-density enterprise interfaces.
Import
import { ProgressCircle } from "@hashti/react";
Examples
Determinate Progress
Provide a value between minValue (default 0) and maxValue (default 100) to render a radial progress stroke:
import { ProgressCircle } from "@hashti/react";
export function DeterminateCircleExample() {
return (
<div className="flex items-center gap-6">
<ProgressCircle aria-label="Exporting archives" value={25} />
<ProgressCircle aria-label="Encrypting data" value={60} />
<ProgressCircle aria-label="Optimization complete" value={100} />
</div>
);
}
Indeterminate Loading Spinner
When the duration or size of an operation is unknown, set isIndeterminate to activate a continuous rotation animation:
import { ProgressCircle } from "@hashti/react";
export function IndeterminateCircleExample() {
return (
<div className="flex items-center gap-6">
<ProgressCircle aria-label="Loading workspace contents" isIndeterminate />
<span className="text-sm text-subtle">Synchronizing repository...</span>
</div>
);
}
Sizes
Progress Circle is available in three standard diameters:
sm: 32px (with 2.5px stroke), ideal for inline badges, buttons, and high-density tables.md: 48px (with 3.5px stroke, default), standard for cards and widgets.lg: 64px (with 4.5px stroke), prominent for hero cards and standalone loading screens.
import { ProgressCircle } from "@hashti/react";
export function ProgressCircleSizesExample() {
return (
<div className="flex items-center gap-8">
<div className="text-center">
<ProgressCircle size="sm" value={45} aria-label="Small progress circle" />
<p className="mt-2 text-xs text-subtle">Small (32px)</p>
</div>
<div className="text-center">
<ProgressCircle size="md" value={65} aria-label="Medium progress circle" />
<p className="mt-2 text-xs text-subtle">Medium (48px)</p>
</div>
<div className="text-center">
<ProgressCircle size="lg" value={85} aria-label="Large progress circle" />
<p className="mt-2 text-xs text-subtle">Large (64px)</p>
</div>
</div>
);
}
Showing Value Labels
Set showValueLabel to render the percentage value centered directly inside the circle:
import { ProgressCircle } from "@hashti/react";
export function CenteredLabelExample() {
return (
<div className="flex items-center gap-8">
<ProgressCircle size="md" value={50} showValueLabel aria-label="Download 50% complete" />
<ProgressCircle size="lg" value={78} showValueLabel aria-label="Processing 78% complete" />
</div>
);
}
Status Variants
Use the status prop to convey semantic state (active, success, warning, error):
import { ProgressCircle } from "@hashti/react";
export function CircleStatusesExample() {
return (
<div className="flex items-center gap-6">
<ProgressCircle status="active" value={60} aria-label="Active backup" />
<ProgressCircle status="success" value={100} aria-label="Backup completed" />
<ProgressCircle status="warning" value={88} aria-label="Storage capacity warning" />
<ProgressCircle status="error" value={42} aria-label="Pipeline failure" />
</div>
);
}
Props Reference
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | 0 | The current numeric progress value. |
minValue | number | 0 | The minimum possible progress boundary. |
maxValue | number | 100 | The maximum possible progress boundary. |
isIndeterminate | boolean | false | Whether to display a continuous rotational loading animation. |
size | 'sm' | 'md' | 'lg' | 'md' | The diameter of the circular meter: sm (32px), md (48px), or lg (64px). |
status | 'active' | 'success' | 'warning' | 'error' | 'active' | Semantic color applied to the active progress stroke. |
showValueLabel | boolean | false | When true, renders the formatted percentage string centered inside the circle. |
aria-label | string | — | Recommended: Accessible name announced by screen readers describing the in-flight process. |
className | string | — | Additional CSS class names. |
Accessibility (a11y)
- Progressbar Semantics: Inherits React Aria Components’ native
role="progressbar"implementation. - Accessible Labelling: Because circular indicators often omit a visible text heading, always supply an
aria-label(e.g.aria-label="Downloading assets") oraria-labelledbypointing to an adjacent descriptive title. - Value Announcements: Screen readers dynamically read
aria-valuenow,aria-valuemin, andaria-valuemaxas values update. - Decorative SVGs: The internal SVG element is marked with
aria-hidden="true", preventing screen readers from vocalizing unnecessary geometric path or circle tags.
WAI-ARIA & Data Attributes
| Attribute | Target | Description |
|---|---|---|
[data-indeterminate] | ProgressCircle | Present when circular spinner is in continuous spin mode. |