Pitsi UI
  • Home
  • Docs
1
1
Sections
  • Get Started
  • Components
  • Animations
  • MCP Server
  • Changelog
Get Started
  • Installation
  • CLI
  • llms.txt
Components
  • Accordion
  • Alert Dialog
  • Alert
  • Aspect Ratio
  • Avatar
  • Badge
  • Breadcrumb
  • Button Group
  • Button
  • Card
  • Carousel
  • Checkbox
  • Collapsible
  • Combobox
  • Command
  • Container
  • Context Menu
  • Data Table
  • Dialog
  • Drawer
  • Dropdown Menu
  • Empty
  • Field
  • Flex
  • Form
  • Grid
  • Hero Button
  • Hover Card
  • Input Group
  • Input OTP
  • Input
  • Item
  • Kbd
  • Label
  • Menubar
  • Native Select
  • Navigation Menu
  • Pagination
  • Popover
  • Progress
  • Radio Group
  • Resizable
  • Responsive
  • Scroll Area
  • Segmented Control
  • Select
  • Separator
  • Sheet
  • Sidebar
  • Skeleton
  • Slider
  • Sonner
  • Spacer
  • Spinner
  • Squircle
  • Switch
  • Table
  • Tabs
  • Textarea
  • Theme Toggle
  • Toggle Group
  • Toggle
  • Tooltip
  • Typography
  • Unicorn Wrapper
Animations
  • Background Image Parallax
  • Card Swipe Carousel
  • Cards Parallax
  • Parallax Scroll
  • Perspective Carousel
  • Perspective Section Transition
  • Scroll Expand
  • Scroll Fade
  • Scroll Scale
  • Slide Down
  • Slide Up
  • Smooth Parallax Scroll
  • Smooth Scroll
  • Sticky Footer
  • Text Along Path
  • Text Gradient Opacity
  • Text Parallax
  • Transforms 3d
  • Zoom Parallax

Spinner

PreviousNext

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

Powered by
shadcn/ui
import {
  Item,
  ItemContent,
  ItemMedia,
  ItemTitle,
} from "@/components/ui/item"
import { Spinner } from "@/components/ui/spinner"

export function SpinnerDemo() {
  return (
    <div className="flex w-full max-w-xs flex-col gap-4 [--radius:1rem]">
      <Item variant="muted">
        <ItemMedia>
          <Spinner />
        </ItemMedia>
        <ItemContent>
          <ItemTitle className="line-clamp-1">Processing payment...</ItemTitle>
        </ItemContent>
        <ItemContent className="flex-none justify-end">
          <span className="text-sm tabular-nums">$100.00</span>
        </ItemContent>
      </Item>
    </div>
  )
}

Installation

pnpm dlx pitsi@latest add spinner

Usage

import { Spinner } from "@/components/ui/spinner"
<Spinner />

Customization

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

import { Loader2 } from "lucide-react"

import { cn } from "@/lib/utils"

function Spinner({ className, ...props }: React.ComponentProps<"svg">) {
  return (
    <Loader2
      role="status"
      aria-label="Loading"
      className={cn("size-4 animate-spin", className)}
      {...props}
    />
  )
}

export function SpinnerCustom() {
  return (
    <div className="flex items-center gap-4">
      <Spinner />
    </div>
  )
}
components/ui/spinner.tsx
import { LoaderIcon } from "lucide-react"
 
import { cn } from "@/lib/utils"
 
function Spinner({ className, ...props }: React.ComponentProps<"svg">) {
  return (
    <LoaderIcon
      role="status"
      aria-label="Loading"
      className={cn("size-4 animate-spin", className)}
      {...props}
    />
  )
}
 
export { Spinner }

Examples

Size

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

import { Spinner } from "@/components/ui/spinner"

export function SpinnerSize() {
  return (
    <div className="flex items-center gap-6">
      <Spinner className="size-3" />
      <Spinner className="size-4" />
      <Spinner className="size-6" />
      <Spinner className="size-8" />
    </div>
  )
}

Color

Use the text- utility class to change the color of the spinner.

import { Spinner } from "@/components/ui/spinner"

export function SpinnerColor() {
  return (
    <div className="flex items-center gap-6">
      <Spinner className="size-6 text-red-500" />
      <Spinner className="size-6 text-green-500" />
      <Spinner className="size-6 text-blue-500" />
      <Spinner className="size-6 text-yellow-500" />
      <Spinner className="size-6 text-purple-500" />
    </div>
  )
}

Button

Add a spinner to a button to indicate a loading state. The <Button /> will handle the spacing between the spinner and the text.

import { Button } from "@/components/ui/button"
import { Spinner } from "@/components/ui/spinner"

export function SpinnerButton() {
  return (
    <div className="flex flex-col items-center gap-4">
      <Button disabled size="sm">
        <Spinner />
        Loading...
      </Button>
      <Button variant="outline" disabled size="sm">
        <Spinner />
        Please wait
      </Button>
      <Button variant="secondary" disabled size="sm">
        <Spinner />
        Processing
      </Button>
    </div>
  )
}

Badge

You can also use a spinner inside a badge.

import { Badge } from "@/components/ui/badge"
import { Spinner } from "@/components/ui/spinner"

export function SpinnerBadge() {
  return (
    <div className="flex items-center gap-4 [--radius:1.2rem]">
      <Badge>
        <Spinner />
        Syncing
      </Badge>
      <Badge variant="secondary">
        <Spinner />
        Updating
      </Badge>
      <Badge variant="outline">
        <Spinner />
        Processing
      </Badge>
    </div>
  )
}

Input Group

Input Group can have spinners inside <InputGroupAddon>.

import { ArrowUp } from "lucide-react"

import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
  InputGroupTextarea,
} from "@/components/ui/input-group"
import { Spinner } from "@/components/ui/spinner"

export function SpinnerInputGroup() {
  return (
    <div className="flex w-full max-w-md flex-col gap-4">
      <InputGroup>
        <InputGroupInput placeholder="Send a message..." disabled />
        <InputGroupAddon align="inline-end">
          <Spinner />
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupTextarea placeholder="Send a message..." disabled />
        <InputGroupAddon align="block-end">
          <Spinner /> Validating...
          <InputGroupButton className="ml-auto" variant="default">
            <ArrowUp />
            <span className="sr-only">Send</span>
          </InputGroupButton>
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}

Empty

import { Button } from "@/components/ui/button"
import {
  Empty,
  EmptyContent,
  EmptyDescription,
  EmptyHeader,
  EmptyMedia,
  EmptyTitle,
} from "@/components/ui/empty"
import { Spinner } from "@/components/ui/spinner"

export function SpinnerEmpty() {
  return (
    <Empty className="w-full">
      <EmptyHeader>
        <EmptyMedia variant="icon">
          <Spinner />
        </EmptyMedia>
        <EmptyTitle>Processing your request</EmptyTitle>
        <EmptyDescription>
          Please wait while we process your request. Do not refresh the page.
        </EmptyDescription>
      </EmptyHeader>
      <EmptyContent>
        <Button variant="outline" size="sm">
          Cancel
        </Button>
      </EmptyContent>
    </Empty>
  )
}

Item

Use the spinner inside <ItemMedia> to indicate a loading state.

import { Button } from "@/components/ui/button"
import {
  Item,
  ItemActions,
  ItemContent,
  ItemDescription,
  ItemFooter,
  ItemMedia,
  ItemTitle,
} from "@/components/ui/item"
import { Progress } from "@/components/ui/progress"
import { Spinner } from "@/components/ui/spinner"

export function SpinnerItem() {
  return (
    <div className="flex w-full max-w-md flex-col gap-4 [--radius:1rem]">
      <Item variant="outline">
        <ItemMedia variant="icon">
          <Spinner />
        </ItemMedia>
        <ItemContent>
          <ItemTitle>Downloading...</ItemTitle>
          <ItemDescription>129 MB / 1000 MB</ItemDescription>
        </ItemContent>
        <ItemActions className="hidden sm:flex">
          <Button variant="outline" size="sm">
            Cancel
          </Button>
        </ItemActions>
        <ItemFooter>
          <Progress value={75} />
        </ItemFooter>
      </Item>
    </div>
  )
}

API Reference

Spinner

Use the Spinner component to display a spinner.

PropTypeDefault
classNamestring``
<Spinner />
SpacerSquircle

On This Page

InstallationUsageCustomizationExamplesSizeColorButtonBadgeInput GroupEmptyItemAPI ReferenceSpinner

© 2025 pitsi/ui. All rights reserved.

Sign In