Spinner
A spinning indicator for a short wait of unknown length.
<template> <Spinner /></template>Props
| Name | Type | Default |
|---|---|---|
| size | 'sm' | 'md' | 'lg' | md |
| icon | string | i-lucide-loader-2 |
| color | string | text-primary |
Guidelines
Do
- Use
<Spinner />for short, indeterminate waits (auth callbacks, waiting on an OAuth redirect) where you have no progress percentage to show. - Center it in the space it's replacing so layout doesn't jump when content arrives.
- Use
size="sm"when composing it inline next to text (e.g. in a Button or Badge) - the defaultmdis sized for a full-page or full-panel wait.
- Set
colorto match whatever it's composed inside (e.g.color="text-text-inverse"in a Primary button,color="text-text-secondary"in a Default badge) - the defaulttext-primaryis only right for a standalone wait on a plain background. - Reach for
icononly for a deliberate, one-off exception (e.g. matching a specific third-party brand mark inline) - leave it at the default everywhere else.
Don't
- Don't use it for waits longer than a few seconds - prefer
Skeletonthat mirrors the shape of the content being loaded, so the page doesn't feel stuck. - Don't build your own spin animation from scratch (a raw
<UIcon animate-spin>) for loading states - this is the one loading indicator in the system; a second, hand-rolled one reads as inconsistent, not intentional. - Don't leave
colorat its default when composing Spinner inside a colored background -text-primaryis the same token some backgrounds (e.g. a Primary button) already use, so the icon can end up invisible instead of just off-color.
Examples
Size
The three size steps - sm, md, and lg.
<template> <Spinner size="sm" /> <Spinner size="md" /> <Spinner size="lg" /></template>Custom icon
A different spin glyph for a deliberate, one-off exception.
<template> <Spinner icon="i-lucide-refresh-cw" /></template>Button
Composed inside a disabled button during a pending action.
<template> <Button variant="primary" disabled> <template #leftIcon> <Spinner size="sm" color="text-text-inverse" /> </template> Please wait </Button></template>Badge
Composed inside a badge to show a syncing or loading state.
Syncing
<template> <Badge variant="default"> <template #leftIcon> <Spinner size="sm" color="text-text-secondary" /> </template> Syncing </Badge></template>