Circular Progress
- Stable
- WCAG 2.2 evidence
- RTL
Shows progress as a ring with the value in the centre. Built on React Aria ProgressBar:
role="progressbar" with aria-valuenow, aria-valuemin, aria-valuemax and a localised aria-valuetext; with
isIndeterminate the value attributes are left out and a quarter arc spins (it stands still under reduced motion,
WCAG 2.3.3). Named by label or aria-label (WCAG 4.1.2). The ring is mirrored in right-to-left layouts. Consumer duties: progress is not announced while it changes (WCAG 4.1.3): announce milestones and completion with
announceStatus() or a LiveRegion, and show a loading indicator only after about 300 ms. Say what the colour means
in text when tone carries a state (WCAG 1.4.1).
import { CircularProgress } from "@nexera-ui/react";- 4
- examples
- 16
- props
- 4
- live controls
- 1
- platform
- 4
- WCAG criteria
- 2
- blocks use it
Try every prop. Copy the code.
Change the props and the code updates. Check light and dark, LTR and RTL, and phone width.
import { CircularProgress } from "@nexera-ui/react";
<CircularProgress />Examples 3
The same examples as Storybook, rendered live. Open Code to copy one.
Indeterminate
No value is reported; a quarter arc spins (it stands still under reduced motion).
import { CircularProgress } from "@nexera-ui/react";
const sizes = ["sm", "md", "lg"] as const;
export function Indeterminate() {
return (
<div className="flex flex-wrap items-center gap-6">
{sizes.map((size) => (
<CircularProgress
key={size}
aria-label={`Loading payroll ${size}`}
size={size}
isIndeterminate
/>
))}
</div>
);
}
Values
Values from 0 to 100 and a custom value text with a custom range: value={4} maxValue={6}.
import { CircularProgress } from "@nexera-ui/react";
export function Values() {
return (
<div className="flex flex-wrap items-center gap-6">
{[0, 25, 50, 75, 100].map((value) => (
<CircularProgress
key={value}
aria-label={`Upload ${String(value)}`}
size="md"
value={value}
/>
))}
<CircularProgress
aria-label="Onboarding steps"
size="md"
value={4}
maxValue={6}
valueLabel="4/6"
/>
<CircularProgress
label="Documents signed"
size="lg"
tone="success"
value={100}
caption="Done"
/>
</div>
);
}
Right to left
Right-to-left: the ring fills counter-clockwise and the value uses the locale's digits.
import { CircularProgress } from "@nexera-ui/react";
export function RightToLeft() {
return (
<div className="flex flex-wrap items-center gap-6">
<CircularProgress aria-label="اكتمال الملف الشخصي" size="md" value={30} />
<CircularProgress aria-label="رفع الملفات" size="lg" value={64} caption="تم" />
</div>
);
}
Props 16
Press "Try it" on a card to load that prop into the playground.
16 props shown
valueLabelNexerastringText shown in the centre and announced as aria-valuetext.
Defaults to the percentage formatted for the locale (formatOptions). Not shown while isIndeterminate.
sizeNexera"sm" | "md" | "lg"Diameter: 40, 64 or 96 px.
captionNexeraReactNodeShort line under the value, for example "Done". Shown only at size="lg", as
in Figma (the smaller rings have no room for it); linked to the progress bar with aria-describedby.
toneNexera"brand" | "success" | "warning" | "danger"Colour of the value arc. Colour alone does not tell the state: say "Upload failed" in the label or
caption when you use danger (WCAG 1.4.1).
classNameNexerastringExtra classes for the root, merged last so they win over the defaults.
styleNexeraCSSPropertiesInline style for the root.
labelNexeraReactNodeWhat is progressing, for example "Profile completion". Not shown but it is the accessible name.
aria-labelNexerastringaria-labelledbyNexerastringisIndeterminateReact AriabooleanWhether presentation is indeterminate when progress isn't known.
valueReact ArianumberThe current value (controlled).
minValueReact ArianumberThe smallest value allowed for the input.
maxValueReact ArianumberThe largest value allowed for the input.
formatOptionsReact AriaNumberFormatOptionsThe display format of the value label.
idReact AriastringThe element's unique identifier. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id).
aria-describedbyReact AriastringIdentifies the element (or elements) that describes the object.
* Required. React Aria props shown are the ones most apps use; the component accepts the rest of its React Aria props too.
Accessible by default.
Built on React Aria, and covered by the WCAG 2.2 evidence generated on every build.
WCAG 2.2 evidence
2 direct · 2 supporting- 1.3.1Info and RelationshipsLevel A · tested directly
- 1.3.2Meaningful SequenceLevel A · supporting test
- 2.3.3Animation from InteractionsLevel AAA · supporting test
- 4.1.2Name, Role, ValueLevel A · tested directly
Fits any width.
Nexera components respond to the space they are given. Drag the corner of the frame, or pick a width.
Styling hooks
Pass className to add Tailwind classes (merged last). State is exposed as data attributes, so you can style it with variants like data-pressed:.
<CircularProgress className="shadow-sm" />Used in blocks
Related components
- AlertAn inline status message about a section or a task: tone icon, title, optional description, actions and close button.
- BannerA page-wide notice across the top of a page or app shell: tone icon, message, optional link and close button on a solid fill.
- EmptyStateExplains why a list, table or page has no content and what to do next.
- ProgressBarShows how far a task has progressed.
- ProgressStepsA segmented progress indicator for a flow with a known number of steps, such as onboarding or a form wizard: a header with "Step 2 of 5" and the step title above one segment per step.
- SpinnerSmall loading indicator.
- SpinnerLabelA spinner with a status message.
- ToastGives the components below it a toast queue through `useToast()` and renders its `ToastRegion`.