Skip to main content
The Spinner Loader is a clean, minimal loading animation featuring a circular border with only the bottom section visible, creating a smooth rotating effect. This is a lightweight alternative to the Classic loader, perfect for simple loading states.

Installation

npm install @craftdotui/loaders

Usage

import Spinner from "@craftdotui/loaders/spinner";

export default function App() {
  return <Spinner />;
}

Props

The Spinner component does not accept any props. It includes built-in screen reader support with an sr-only loading message.

Animation Details

  • Size: 40px × 40px (10 × 10 in Tailwind)
  • Border: 2px bottom border only
  • Animation: Continuous 360-degree rotation using Tailwind’s animate-spin
  • Color: Black in light mode, white in dark mode
  • Accessibility: Includes “Loading…” text for screen readers

Examples

Loading Button

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

export default function LoadingButton({ isLoading, children, ...props }) {
  return (
    <Button disabled={isLoading} {...props}>
      {isLoading ? (
        <div className="flex items-center gap-2">
          <div className="scale-50">
            <Spinner />
          </div>
          <span>Loading...</span>
        </div>
      ) : (
        children
      )}
    </Button>
  );
}

Card Loading State

import Spinner from "@craftdotui/loaders/spinner";
import { Card, CardContent } from "@/components/ui/card";

export default function LoadingCard() {
  return (
    <Card>
      <CardContent className="flex items-center justify-center py-16">
        <Spinner />
      </CardContent>
    </Card>
  );
}

Conditional Content

import Spinner from "@craftdotui/loaders/spinner";

export default function ConditionalContent({ isLoading, content }) {
  if (isLoading) {
    return (
      <div className="flex items-center justify-center min-h-[200px]">
        <Spinner />
      </div>
    );
  }
  
  return <div>{content}</div>;
}

Overlay Loader

import Spinner from "@craftdotui/loaders/spinner";

export default function OverlayLoader({ isLoading, children }) {
  return (
    <div className="relative">
      {children}
      
      {isLoading && (
        <div className="absolute inset-0 flex items-center justify-center bg-background/80 backdrop-blur-sm">
          <Spinner />
        </div>
      )}
    </div>
  );
}

Full Page Loading

import Spinner from "@craftdotui/loaders/spinner";

export default function PageLoader() {
  return (
    <div className="fixed inset-0 flex items-center justify-center bg-background">
      <div className="flex flex-col items-center gap-4">
        <Spinner />
        <p className="text-sm text-muted-foreground">Loading page...</p>
      </div>
    </div>
  );
}

Build docs developers (and LLMs) love