ZaidanHomeDocsComponentsBlocksChartsTypesetCreate

Command Palette

Search for a command to run...

GitHub
New
Sections
  • Introduction
  • Components
  • Blocks
  • Installation
  • Customization
  • Dark Mode
  • Typeset
  • Zaidan Skills
  • FAQ
  • Roadmap
  • Changelog
Installation
  • Astro
  • Manual
  • Solid Start
  • TanStack Router
  • TanStack Start
  • Vite
Blocks
  • Data Grid
  • Event Calendar
  • Filters
  • Gantt
  • Image Crop
  • Kanban
  • Message Scroller
  • Questionnaire
  • Sortable
Components
  • Accordion
  • Alert
  • Alert Dialog
  • Aspect Ratio
  • Attachment
  • Avatar
  • Badge
  • Breadcrumb
  • Bubble
  • Button
  • Button Group
  • Calendar
  • Card
  • Carousel
  • Chart
  • Checkbox
  • Collapsible
  • Combobox
  • Command
  • Context Menu
  • Dialog
  • Drawer
  • Dropdown Menu
  • Empty
  • Field
  • Hover Card
  • Input
  • Input Group
  • Input OTP
  • Item
  • Kbd
  • Label
  • Marker
  • Menubar
  • Message
  • Native Select
  • Navigation Menu
  • Pagination
  • Popover
  • Progress
  • Radio Group
  • Resizable
  • Scroll Area
  • Select
  • Separator
  • Sheet
  • Sidebar
  • Skeleton
  • Slider
  • Spinner
  • Switch
  • Table
  • Tabs
  • Textarea
  • Toast
  • Toggle
  • Toggle Group
  • Tooltip

Spinner

An indicator that can be used to show a loading state.

Processing payment...
$100.00
1
import { Item, ItemContent, ItemMedia, ItemTitle } from "~/components/ui/item";
2
import { Spinner } from "~/components/ui/spinner";
3
4
export default function SpinnerDemo() {
5
return (
6
<div class="flex w-full max-w-xs flex-col gap-4 [--radius:1rem]">
7
<Item variant="muted">
8
<ItemMedia>
9
<Spinner />
10
</ItemMedia>
11
<ItemContent>
12
<ItemTitle class="line-clamp-1">Processing payment...</ItemTitle>
13
</ItemContent>
14
<ItemContent class="flex-none justify-end">
15
<span class="text-sm tabular-nums">$100.00</span>
16
</ItemContent>
17
</Item>
18
</div>
19
);
20
}

Installation

pnpm dlx shadcn@latest add @zaidan/spinner
npx shadcn@latest add @zaidan/spinner
yarn dlx shadcn@latest add @zaidan/spinner
bunx --bun shadcn@latest add @zaidan/spinner

Usage

1
import { Spinner } from "~/components/ui/spinner";
1
<Spinner />

Customization

You can replace the default spinner icon with any other icon by editing the Spinner component.

1
import { LoaderIcon } from "lucide-solid";
2
import type { ComponentProps } from "solid-js";
3
import { splitProps } from "solid-js";
4
import { cn } from "~/lib/utils";
5
6
type SpinnerProps = ComponentProps<"svg">;
7
8
const Spinner = (props: SpinnerProps) => {
9
const [local, others] = splitProps(props, ["class"]);
10
11
return (
12
<LoaderIcon
13
role="status"
14
aria-label="Loading"
15
class={cn("size-4 animate-spin", local.class)}
16
{...others}
17
/>
18
);
19
};
20
21
export default function SpinnerCustom() {
22
return (
23
<div class="flex items-center gap-4">
24
<Spinner />
25
</div>
26
);
27
}
components/ui/spinner.tsx
1
import LoaderIcon from "lucide-solid/icons/loader";
2
import type { ComponentProps } from "solid-js";
3
import { splitProps } from "solid-js";
4
5
import { cn } from "~/lib/utils";
6
7
type SpinnerProps = ComponentProps<"svg">;
8
9
const Spinner = (props: SpinnerProps) => {
10
const [local, others] = splitProps(props, ["class"]);
11
12
return (
13
<LoaderIcon
14
role="status"
15
aria-label="Loading"
16
class={cn("size-4 animate-spin", local.class)}
17
{...others}
18
/>
19
);
20
};
21
22
export { Spinner };

Size

Use the size-* utility class to change the size of the spinner.

1
import { Spinner } from "~/components/ui/spinner";
2
3
export default function SpinnerSize() {
4
return (
5
<div class="flex items-center gap-6">
6
<Spinner class="size-3" />
7
<Spinner class="size-4" />
8
<Spinner class="size-6" />
9
<Spinner class="size-8" />
10
</div>
11
);
12
}

Button

Add a spinner to a button to indicate a loading state. Place the <Spinner /> before the label with data-icon="inline-start" for a start position, or after the label with data-icon="inline-end" for an end position.

1
import { Button } from "~/components/ui/button";
2
import { Spinner } from "~/components/ui/spinner";
3
4
export default function SpinnerButton() {
5
return (
6
<div class="flex flex-col items-center gap-4">
7
<Button disabled size="sm">
8
<Spinner data-icon="inline-start" />
9
Loading...
10
</Button>
11
<Button variant="outline" disabled size="sm">
12
<Spinner data-icon="inline-start" />
13
Please wait
14
</Button>
15
<Button variant="secondary" disabled size="sm">
16
<Spinner data-icon="inline-start" />
17
Processing
18
</Button>
19
</div>
20
);
21
}

Badge

Add a spinner to a badge to indicate a loading state. Place the <Spinner /> before the label with data-icon="inline-start" for a start position, or after the label with data-icon="inline-end" for an end position.

SyncingUpdatingProcessing
1
import { Badge } from "~/components/ui/badge";
2
import { Spinner } from "~/components/ui/spinner";
3
4
export default function SpinnerBadge() {
5
return (
6
<div class="flex items-center gap-4 [--radius:1.2rem]">
7
<Badge>
8
<Spinner data-icon="inline-start" />
9
Syncing
10
</Badge>
11
<Badge variant="secondary">
12
<Spinner data-icon="inline-start" />
13
Updating
14
</Badge>
15
<Badge variant="outline">
16
<Spinner data-icon="inline-start" />
17
Processing
18
</Badge>
19
</div>
20
);
21
}

Input Group

Validating...
1
import { ArrowUpIcon } from "lucide-solid";
2
import {
3
InputGroup,
4
InputGroupAddon,
5
InputGroupButton,
6
InputGroupInput,
7
InputGroupTextarea,
8
} from "~/components/ui/input-group";
9
import { Spinner } from "~/components/ui/spinner";
10
11
export default function SpinnerInputGroup() {
12
return (
13
<div class="flex w-full max-w-md flex-col gap-4">
14
<InputGroup>
15
<InputGroupInput placeholder="Send a message..." disabled />
16
<InputGroupAddon align="inline-end">
17
<Spinner />
18
</InputGroupAddon>
19
</InputGroup>
20
<InputGroup>
21
<InputGroupTextarea placeholder="Send a message..." disabled />
22
<InputGroupAddon align="block-end">
23
<Spinner /> Validating...
24
<InputGroupButton class="ml-auto" variant="default">
25
<ArrowUpIcon />
26
<span class="sr-only">Send</span>
27
</InputGroupButton>
28
</InputGroupAddon>
29
</InputGroup>
30
</div>
31
);
32
}

Empty

Processing your request
Please wait while we process your request. Do not refresh the page.
1
import { Button } from "~/components/ui/button";
2
import {
3
Empty,
4
EmptyContent,
5
EmptyDescription,
6
EmptyHeader,
7
EmptyMedia,
8
EmptyTitle,
9
} from "~/components/ui/empty";
10
import { Spinner } from "~/components/ui/spinner";
11
12
export default function SpinnerEmpty() {
13
return (
14
<Empty class="w-full">
15
<EmptyHeader>
16
<EmptyMedia variant="icon">
17
<Spinner />
18
</EmptyMedia>
19
<EmptyTitle>Processing your request</EmptyTitle>
20
<EmptyDescription>
21
Please wait while we process your request. Do not refresh the page.
22
</EmptyDescription>
23
</EmptyHeader>
24
<EmptyContent>
25
<Button variant="outline" size="sm">
26
Cancel
27
</Button>
28
</EmptyContent>
29
</Empty>
30
);
31
}

API Reference

Spinner

Spinner forwards standard SVG props to its loading indicator.

PropTypeDefault
classstring-

On This Page

  • Installation
  • Usage
  • Customization
  • Size
  • Button
  • Badge
  • Input Group
  • Empty
  • API Reference
    • Spinner
Built by Kevin Abatan. The source code is available on GitHub.