Getting StartedInstall and bootstrap headless foundations 4
LayoutHeadless structural primitives for expandable and container patterns 6
OverlayHeadless modal and floating layer behavior 3
FeedbackHeadless notification and status communication patterns 5
FormHeadless input and selection contracts 17
UtilityReusable action, identity, and clipboard behavior 6
NavigationHeadless trails, trees, menus, and command surfaces 7

Progress Spinner overview

Headless progress spinner gives you range semantics and ARIA wiring, while the SVG, circles, motion, and visual scale stay fully owner-authored.

Imports

Use the primitive directive when you want to own the circular markup and motion yourself.

Primitive import

ts
import { TngProgressSpinner } from '@tailng-ui/primitives';

Basic composition

The primitive only marks the root as a progressbar. You provide the SVG, track circle, indicator circle, and any indeterminate animation.

Minimal headless markup

html
<span tngProgressSpinner [value]="72" class="progress-spinner" aria-label="Sync progress">
  <svg class="progress-spinner__svg" viewBox="0 0 40 40">
    <circle class="progress-spinner__track" cx="20" cy="20" r="18"></circle>
    <circle
      class="progress-spinner__indicator"
      cx="20"
      cy="20"
      r="18"
      stroke-dasharray="113.097"
      [attr.stroke-dashoffset]="113.097 - (113.097 * 72) / 100"
    ></circle>
  </svg>
</span>

<span tngProgressSpinner [indeterminate]="true" class="progress-spinner" aria-label="Loading report">
  <svg class="progress-spinner__svg" viewBox="0 0 40 40">
    <circle class="progress-spinner__track" cx="20" cy="20" r="18"></circle>
    <circle
      class="progress-spinner__indicator progress-spinner__indicator--indeterminate"
      cx="20"
      cy="20"
      r="18"
      stroke-dasharray="70"
      stroke-dashoffset="20"
    ></circle>
  </svg>
</span>

Style variants

Use the same primitive root inside a lightweight CSS shell or a utility-authored Tailwind surface.

Headless spinner (plain CSS)

Range semantics

  • min, max, and value are normalized and clamped on the root directive.
  • Indeterminate mode removes aria-valuenow, aria-valuemin, and aria-valuemax.
  • The primitive does not render circles or size the spinner for you.
  • Provide visible context or an explicit aria-label when the surrounding UI does not already explain the task.