Spinner
A loading indicator with Apple-style ticks or a breathing ring that can wait before showing and stay long enough not to flicker.
Used in Pro blocks: Artifact, Chat Sidebar, Code Block, and 6 more
pnpm dlx shadcn@latest add https://hextaui.com/r/spinner.jsonAdds the component, the HextaUI theme tokens and any HextaUI components it depends on.
Add the theme tokens to your global CSS, if you haven’t yet.
Install the dependencies.
pnpm add class-variance-authority cnCopy and paste the following code into your project.
components/ui/spinner.tsx Update the import paths to match your project setup.
The default is the eight-spoke indicator from Apple platforms. variant="ring" spins while its arc grows and shrinks, so it reads as working rather than stuck. Both are drawn in the current text color.
Pass loading and the spinner waits delay (150ms) before showing, so fast loads never flash it, then stays at least minDuration (400ms) once it's visible.
sm, default, lg and xl for both variants.
Next to text, mark the spinner aria-hidden so the words do the talking. On its own, it announces its label.
Button and Command use this spinner for their loading states, sized to the button's icons.
- On its own, the spinner is a
statusnamed bylabel(“Loading”). - With
aria-hidden, it drops its role, for use beside visible text or inside a busy button. - With reduced motion, it gently pulses instead of spinning, so it still shows that something is happening.
| Prop | Type | Default |
|---|---|---|
variant | "ticks" | "ring" | "ticks" |
sizenull leaves sizing to the parent. | "sm" | "default" | "lg" | "xl" | null | "default" |
label | string | "Loading" |
loadingTurns on delayed showing. Leave it out to always show. | boolean | – |
delay | number | 150 |
minDuration | number | 400 |
animatedPause the animation without hiding it. | boolean | true |
| Attribute | Description |
|---|---|
data-slot="spinner" | The SVG, with data-variant. |
The same timing as a hook, for skeletons, overlays or anything else that shouldn't flash. See the useDelayedLoading guide.
- useDelayedLoadingShows a loading state only when work is actually slow, then keeps it up long enough that it never flickers.
- AlertInline messages for status and feedback, with a neutral surface, a colored icon and a dismiss that collapses smoothly.
- EmptyA placeholder for screens with nothing to show yet, with an icon, a message and the next action.
- ProgressA bar or ring that shows how far a task has come, eases between updates and slides while the total is unknown.
- SkeletonPlaceholders that wait 150ms before showing, take the exact size of the content they wrap, and fade it in without moving anything.
- ToastBrief messages that stack neatly, expand on hover, swipe away, and turn a loading state into success or error in place.
Used in Pro blocks
Blocks that build on Spinner.
- ArtifactThe panel beside an AI chat that shows what the model made. Handles content still streaming, a sandboxed preview and versions you can restore.
- Chat SidebarThe sidebar of a chat app, with pinned chats, projects and recents. Handles rename in place, delete with undo and chats still replying.
- Code BlockCode blocks for AI answers. Highlighting keeps up with streaming, diffs can be accepted or rejected, and commands run in a terminal.
- Diff ReviewA review of an agent’s file edits before they land. Handles accept or reject per change, comments back to the agent and edits still streaming.
- SubagentsThe runs an agent hands to other agents, one line per run. Handles parallel runs, stop and retry, and a summary once each run is done.
- Test ResultsAn agent’s test run, shown as it happens. Tests stream in and fold into a summary, with every failure left open and its diff in view.
Every block comes with HextaUI Pro, and Prompt Input is free.