CircularProgress
Circular progress
Determinate at a few fractions and self-animating indeterminate (global + additional rotation and a pulsing sweep, composed the same way the pinned source composes three independent animations). See WavyProgress for the Material 3 Expressive rippling-ring treatment.
import { CircularProgress, Surface, Text } from '@language-lit/material3-expressive'
export function CircularProgressExample() {
return (
<Surface
as="section"
aria-labelledby="circular-progress-example-title"
color="surface-container-low"
shape="extra-large"
className="circular-progress-example"
>
<Text as="h2" id="circular-progress-example-title" variant="titleLarge" emphasis="emphasized">
Circular progress
</Text>
<Text as="p" variant="bodyMedium">
Determinate at a few fractions and self-animating indeterminate
(global + additional rotation and a pulsing sweep, composed the same
way the pinned source composes three independent animations). See
WavyProgress for the Material 3 Expressive rippling-ring treatment.
</Text>
<div className="circular-progress-example__row">
<CircularProgress aria-label="Progress, empty" value={0} />
<CircularProgress aria-label="Progress, low" value={0.05} />
<CircularProgress aria-label="Progress, mid" value={0.45} />
<CircularProgress aria-label="Progress, high" value={0.98} />
<CircularProgress aria-label="Progress, complete" value={1} />
<CircularProgress aria-label="Progress, custom max" value={150} max={200} />
<CircularProgress aria-label="Loading" />
</div>
</Surface>
)
}CircularProgress renders a small, fixed-size ring progress indicator.
Pass value for determinate progress, or omit it entirely for a
continuously animating indeterminate spinner — the same contract a native
<progress> element uses.
import { CircularProgress } from '@language-lit/material3-expressive'
import '@language-lit/material3-expressive/styles.css'
<CircularProgress aria-label="Progress" value={0.4} />
<CircularProgress aria-label="Loading" />Contract
value(a number in[0, max]) renders determinate progress with an accuratearia-valuenow. Omittingvaluerenders indeterminate mode: a continuously rotating, pulsing arc with noaria-valuenowat all, signaling a busy/indeterminate state to assistive technology. No track element renders in indeterminate mode — the pinned source's own indeterminate track color is transparent.maxdefaults to1.aria-label/aria-labelledbyprovide the required accessible name —CircularProgresshas no visible label of its own.- Fixed
40pxintrinsic size, matching a small, fixed-size spinner's real web usage; override--m3e-comp-circular-progress-diameterto resize. - Determinate arcs account for the visual width of their round caps when reserving the active/track gap; 0% and 100% omit zero-length arcs rather than letting SVG render a stray cap dot.
- Indeterminate rotation layers share the fixed center of the SVG view box, so the pulsing arc rotates in place as its painted bounds change.
- For the Material 3 Expressive rippling-ring treatment, see
WavyProgress.
Tokens and boundaries
Colors, geometry, and motion timing come entirely from --m3e-comp- circular-progress-* CSS custom properties, scoped by Material3Provider.
CircularProgress injects no runtime styles, uses no
requestAnimationFrame loop (indeterminate motion composes three CSS
@keyframes animations, matching the source's three composed animation
values), and imports no Next.js, Vite, router, animation
library, or private application code.