Browse the docs
ComponentsNo. 07 of 109
Bars Spinner
Twelve bars around a hub fading in turn, announced as Loading. No JavaScript.
Installation
pnpm dlx shadcn@latest add @corsair-ui/bars-spinnerNo setup needed: the CLI finds @corsair-ui in the shadcn registry directory. The files land in your project as source: edit them like your own code. More in Installation.
- Also adds
- utils
- npm
clsxtailwind-merge
Examples
Sizes and colours
In a button
API
| Prop | Type | Default |
|---|---|---|
sizeWidth and height; or use a size-* class. | number | string | — |
Accessibility
- It is role="status", announced as "Loading". Pass a specific aria-label when you can.
- With prefers-reduced-motion it turns at half speed rather than stopping.
Compatibility
- Tailwind CSS
- 3.4 and 4, both checked in CI
- React
- 19
- Rendering
- Works in server components
Source
1 file, installed as source you own
bars-spinner.tsxView on GitHubimport type { ComponentProps, CSSProperties } from "react";
import { cn } from "@/registry/default/lib/utils";
const BARS = Array.from({ length: 12 }, (_, index) => index);
interface BarsSpinnerProps extends ComponentProps<"span"> {
/** Width and height, as a CSS length or a number of px. Or size it with a `size-*` class. */
size?: number | string;
}
/**
* Twelve bars around a hub, fading one after another. It takes the current
* text colour and is announced as "Loading"; pass a more specific
* `aria-label` when you can ("Syncing charts"). With `prefers-reduced-motion`
* it turns at half speed rather than stopping, since it reports progress.
* No JavaScript: it works in server components.
*/
function BarsSpinner({ size, className, style, ...props }: BarsSpinnerProps) {
return (
<span
role="status"
aria-label="Loading"
data-slot="bars-spinner"
className={cn(
"relative inline-block size-4 shrink-0 [--bars-spinner-period:1s] motion-reduce:[--bars-spinner-period:2s]",
className
)}
style={{ ...(size === undefined ? null : { width: size, height: size }), ...style }}
{...props}
>
{BARS.map((index) => (
<span
key={index}
aria-hidden="true"
className="animate-bars-spinner absolute top-[45.5%] left-[37%] h-[9%] w-[26%] rounded-full bg-current"
style={
{
transform: `rotate(${index * 30}deg) translate(140%)`,
animationDuration: "var(--bars-spinner-period)",
// Negative delays start every bar part-way through, so the wheel turns from the first frame.
animationDelay: `calc(var(--bars-spinner-period) * ${(index - 12) / 12})`,
} as CSSProperties
}
/>
))}
</span>
);
}
export { BarsSpinner, type BarsSpinnerProps };