Feedback

Spinner.

A spinning orange loader, plus a block spinner that pulses three squares like a terminal waiting on a reply.

Connecting to hub

Installation#

With the CLI

$npx lanterncn add spinner

This also installs the Lantern theme and any Lantern UI components it depends on. The shadcn CLI works directly too: npx shadcn@latest add httptim/lantern-ui/spinner. See Installation if your project is not set up yet.

Manually

  1. Install the dependencies

    npm install lucide-react
  2. Copy the source into your project

    components/ui/spinner.tsx
    import * as React from "react";
    import { Loader2Icon } from "lucide-react";
    
    import { cn } from "@/lib/utils";
    
    function Spinner({ className, ...props }: React.ComponentProps<"svg">) {
      return (
        <Loader2Icon
          data-slot="spinner"
          role="status"
          aria-label="Loading"
          className={cn("size-4 animate-spin text-primary", className)}
          {...props}
        />
      );
    }
    
    /** A terminal-style spinner: three blocks lighting up in turn. */
    function BlockSpinner({ className, ...props }: React.ComponentProps<"span">) {
      return (
        <span
          data-slot="block-spinner"
          role="status"
          aria-label="Loading"
          className={cn("inline-flex items-center gap-[3px] text-primary", className)}
          {...props}
        >
          {[0, 1, 2].map((i) => (
            <i
              key={i}
              aria-hidden="true"
              className="block size-1.5 animate-lantern-pulse bg-current"
              style={{ animationDuration: "0.9s", animationDelay: `${i * 0.15}s` }}
            />
          ))}
        </span>
      );
    }
    
    export { Spinner, BlockSpinner };
  3. Update the import paths to match your project

    The source imports cn from @/lib/utils.

Usage#

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

Both spinners announce themselves with role="status" and the label Loading. Inside a button that already says what is happening, pass aria-hidden and clear the role.

Examples#

In a button