Circular progress indicator for determinate and indeterminate loading states.
Introduction
Spinner is a circular indicator for ongoing work. Use the indeterminate mode when duration is unknown, or determinate with a value from 0 to 100 when progress is known.
When to use: Inline loaders in buttons, cards, empty states, or any compact area where a linear bar would be too wide.
Compared to similar components:
- Progress — Linear bar for full-width or horizontal tracks, including buffer and query variants. Prefer Spinner in tight layouts.
- Skeleton — Placeholder shapes that preserve layout. Use Skeleton when content structure is known; use Spinner when the focus is “something is loading” rather than layout preview.
Always pass aria-label or aria-labelledby so assistive technology has an accessible name.
Use the framework selector in the site header to switch between React and Vue.
Import
import { Spinner } from "@bridge-ui/vue/Components/Spinner";import { Spinner } from "@bridge-ui/react/Components/Spinner";Basic usage
By default, Spinner renders an indeterminate arc.
<script setup lang="ts">
import { Spinner } from "@bridge-ui/vue/Components/Spinner";
</script>
<template>
<Spinner aria-label="Loading…" />
</template>
import { Spinner } from "@bridge-ui/react/Components/Spinner";
export default function SpinnerBasic() {
return <Spinner aria-label="Loading…" />;
}
Determinate
Set variant="determinate" and pass value from 0 to 100 when progress is known.
<script setup lang="ts">
import { Spinner } from "@bridge-ui/vue/Components/Spinner";
</script>
<template>
<Spinner :value="40" variant="determinate" aria-label="Export data" />
</template>
import { Spinner } from "@bridge-ui/react/Components/Spinner";
export default function SpinnerDeterminate() {
return <Spinner value={40} variant="determinate" aria-label="Export data" />;
}
Track
Enable enableTrack to draw a subtle track circle behind the progress arc.
<script setup lang="ts">
import { Spinner } from "@bridge-ui/vue/Components/Spinner";
</script>
<template>
<Spinner enable-track aria-label="Loading…" />
</template>
import { Spinner } from "@bridge-ui/react/Components/Spinner";
export default function SpinnerTrack() {
return <Spinner enableTrack aria-label="Loading…" />;
}
Disable shrink
Set disableShrink to turn off the indeterminate circle shrink animation for a steady rotating arc.
<script setup lang="ts">
import { Spinner } from "@bridge-ui/vue/Components/Spinner";
</script>
<template>
<Spinner disable-shrink aria-label="Loading…" />
</template>
import { Spinner } from "@bridge-ui/react/Components/Spinner";
export default function SpinnerDisableShrink() {
return <Spinner disableShrink aria-label="Loading…" />;
}
Colors
Use the color prop to convey semantic meaning. Available colors: primary, secondary, success, info, warning, error, and dark.
<script setup lang="ts">
import { Spinner } from "@bridge-ui/vue/Components/Spinner";
</script>
<template>
<div class="flex flex-wrap items-center gap-4">
<Spinner color="primary" aria-label="primary" />
<Spinner color="secondary" aria-label="secondary" />
<Spinner color="success" aria-label="success" />
<Spinner color="info" aria-label="info" />
<Spinner color="warning" aria-label="warning" />
<Spinner color="error" aria-label="error" />
<Spinner color="dark" aria-label="dark" />
</div>
</template>
import { Spinner } from "@bridge-ui/react/Components/Spinner";
export default function SpinnerColors() {
return (
<div className="flex flex-wrap items-center gap-4">
<Spinner color="primary" aria-label="primary" />
<Spinner color="secondary" aria-label="secondary" />
<Spinner color="success" aria-label="success" />
<Spinner color="info" aria-label="info" />
<Spinner color="warning" aria-label="warning" />
<Spinner color="error" aria-label="error" />
<Spinner color="dark" aria-label="dark" />
</div>
);
}
Sizes
Control diameter with size. Available values: xs, sm, md (default), and lg.
<script setup lang="ts">
import { Spinner } from "@bridge-ui/vue/Components/Spinner";
</script>
<template>
<div class="flex flex-wrap items-end gap-4">
<Spinner size="xs" aria-label="xs" />
<Spinner size="sm" aria-label="sm" />
<Spinner size="md" aria-label="md" />
<Spinner size="lg" aria-label="lg" />
</div>
</template>
import { Spinner } from "@bridge-ui/react/Components/Spinner";
export default function SpinnerSizes() {
return (
<div className="flex flex-wrap items-end gap-4">
<Spinner size="xs" aria-label="xs" />
<Spinner size="sm" aria-label="sm" />
<Spinner size="md" aria-label="md" />
<Spinner size="lg" aria-label="lg" />
</div>
);
}
Customization
Fine-tune appearance with className (React) or class (Vue), and the classes prop to target root, svg, circle, and track. Stroke thickness is controlled with thickness (default 3.6).
<script setup lang="ts">
import { Spinner } from "@bridge-ui/vue/Components/Spinner";
</script>
<template>
<Spinner
enable-track
aria-label="Custom spinner"
:classes="{
circle: 'stroke-primary-600 dark:stroke-primary-400',
track: 'stroke-primary-100 dark:stroke-primary-900',
}"
/>
</template>
import { Spinner } from "@bridge-ui/react/Components/Spinner";
export default function SpinnerCustomization() {
return (
<Spinner
enableTrack
aria-label="Custom spinner"
classes={{
track: "stroke-primary-100 dark:stroke-primary-900",
circle: "stroke-primary-600 dark:stroke-primary-400",
}}
/>
);
}
Accessibility
- Provide an accessible name with aria-label or aria-labelledby.
- For determinate mode, keep value in sync with real progress so assistive technology can announce it.
- Prefer reducing motion-sensitive experiences when prefers-reduced-motion is set by the user—animation alone is not a reliable status signal.
Anatomy
Spinner renders a root <span> wrapping an SVG with an optional track circle and the progress circle:
<span class="spinner-root" role="progressbar">
<svg class="spinner-svg">
<!-- enableTrack only -->
<circle class="spinner-track"></circle>
<circle class="spinner-circle"></circle>
</svg>
</span>Related components
API
| Prop | Type | Default | Description |
|---|---|---|---|
| classes | SpinnerClasses | — | Classes for root, svg, circle, and track. |
| color | SpinnerColor | "primary" | Semantic color of the circle (and track). |
| customProps | SpinnerCustomProps | — | Extra props for internal parts. |
| disableShrink | boolean | false | Disables indeterminate circle shrink animation. |
| enableTrack | boolean | false | Shows a subtle track circle behind the progress. |
| size | SpinnerSize | "md" | Width/height of the spinner. |
| thickness | number | 3.6 | Stroke thickness of the circle. |
| value | number | — | Progress 0–100 (determinate variant). |
| variant | SpinnerVariant | "indeterminate" | Visual mode of the indicator. |