Stable

Progress Indicators

Three separate components live under this one docs entry — CircularProgress, LinearProgress, and WavyLinearProgress (a custom, M3-inspired wavy variant). Each has its own prop set — they are not interchangeable via a shared "variant" prop — so pick the component that matches the shape you need.

Overview

All three components are built on bits-ui's Progress.Root for the underlying ARIA semantics, and share the same determinate/indeterminate convention: pass a percent between 0–100 for a determinate indicator, or omit it (or pass null) for an indeterminate one.

CircularProgress and LinearProgress map directly to M3's circular and linear progress indicators. WavyLinearProgress is this library's own extra variant — a sine-wave linear indicator inspired by, but not a literal reproduction of, M3's spec; it renders raw SVG with the wave path computed by an internal _wavy.ts helper module (not part of the public API).

Import

import { CircularProgress, LinearProgress, WavyLinearProgress } from '@noxlovette/material';

Live Demo

See all three live, with Controls, in Storybook rather than a hand-rolled preview here.

widgets

Playground

Determinate and indeterminate stories for Circular, Linear, and Wavy.

Basic Usage

<script lang="ts">
  import { CircularProgress, LinearProgress, WavyLinearProgress } from '@noxlovette/material';

  let uploadPercent = $state(40);
</script>

<!-- Determinate -->
<CircularProgress percent={uploadPercent} />
<LinearProgress percent={uploadPercent} class="w-full" />
<WavyLinearProgress percent={uploadPercent} class="w-full" />

<!-- Indeterminate: omit percent -->
<CircularProgress />
<LinearProgress class="w-full" />
<WavyLinearProgress class="w-full" />

CircularProgress Props

PropTypeDefaultDescription
percentnumber | nullCompletion percentage (0–100). Omit, or pass null, for an indeterminate spinner.
sizenumber48Diameter of the indicator in pixels.
thicknessnumber4Stroke thickness in pixels.

LinearProgress Props

PropTypeDefaultDescription
percentnumber | nullCompletion percentage (0–100). Omit, or pass null, for an indeterminate bar.
heightnumber4Height of the bar in pixels.
classstringAdditional classes merged onto the track container — use this to set a width (e.g. w-full).

WavyLinearProgress Props

PropTypeDefaultDescription
percentnumber | nullCompletion percentage (0–100). Omit, or pass null, for an indeterminate line.
widthnumber600Width of the SVG's viewBox.
heightnumber10Height of the SVG's viewBox.
thicknessnumber4Stroke thickness of the wave/track lines.
classstringAdditional classes applied to the SVG element — use this to set a rendered width.

Accessibility

accessibility_new

ARIA semantics via bits-ui

Progress.Root supplies role="progressbar" with aria-valuenow/aria-valuemin/aria-valuemax wired to percent, and omits aria-valuenow automatically for indeterminate state.

hourglass_empty

Indeterminate still needs a label

None of the three components render visible or accessible text describing what is loading — pair them with your own aria-label or adjacent text for screen reader users.

motion_photos_pause

Motion sensitivity

WavyLinearProgress and indeterminate states rely on continuous animation; consider respecting prefers-reduced-motion in contexts where that matters.