Spinner
An indicator that can be used to show a loading state.
Processing payment...
$100.00
import { Item, ItemContent, ItemMedia, ItemTitle } from "~/components/ui/item";import { Spinner } from "~/components/ui/spinner";
export default function SpinnerDemo() { return ( <div class="flex w-full max-w-xs flex-col gap-4 [--radius:1rem]"> <Item variant="muted"> <ItemMedia> <Spinner /> </ItemMedia> <ItemContent> <ItemTitle class="line-clamp-1">Processing payment...</ItemTitle> </ItemContent> <ItemContent class="flex-none justify-end"> <span class="text-sm tabular-nums">$100.00</span> </ItemContent> </Item> </div> );}Installation
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 { LoaderIcon } from "lucide-solid";import type { ComponentProps } from "solid-js";import { splitProps } from "solid-js";import { cn } from "~/lib/utils";
type SpinnerProps = ComponentProps<"svg">;
const Spinner = (props: SpinnerProps) => { const [local, others] = splitProps(props, ["class"]);
return ( <LoaderIcon role="status" aria-label="Loading" class={cn("size-4 animate-spin", local.class)} {...others} /> );};
export default function SpinnerCustom() { return ( <div class="flex items-center gap-4"> <Spinner /> </div> );}import LoaderIcon from "lucide-solid/icons/loader";import type { ComponentProps } from "solid-js";import { splitProps } from "solid-js";
import { cn } from "~/lib/utils";
type SpinnerProps = ComponentProps<"svg">;
const Spinner = (props: SpinnerProps) => { const [local, others] = splitProps(props, ["class"]);
return ( <LoaderIcon role="status" aria-label="Loading" class={cn("size-4 animate-spin", local.class)} {...others} /> );};
export { Spinner };Size
Use the size-* utility class to change the size of the spinner.
import { Spinner } from "~/components/ui/spinner";
export default function SpinnerSize() { return ( <div class="flex items-center gap-6"> <Spinner class="size-3" /> <Spinner class="size-4" /> <Spinner class="size-6" /> <Spinner class="size-8" /> </div> );}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.
import { Button } from "~/components/ui/button";import { Spinner } from "~/components/ui/spinner";
export default function SpinnerButton() { return ( <div class="flex flex-col items-center gap-4"> <Button disabled size="sm"> <Spinner data-icon="inline-start" /> Loading... </Button> <Button variant="outline" disabled size="sm"> <Spinner data-icon="inline-start" /> Please wait </Button> <Button variant="secondary" disabled size="sm"> <Spinner data-icon="inline-start" /> Processing </Button> </div> );}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
import { Badge } from "~/components/ui/badge";import { Spinner } from "~/components/ui/spinner";
export default function SpinnerBadge() { return ( <div class="flex items-center gap-4 [--radius:1.2rem]"> <Badge> <Spinner data-icon="inline-start" /> Syncing </Badge> <Badge variant="secondary"> <Spinner data-icon="inline-start" /> Updating </Badge> <Badge variant="outline"> <Spinner data-icon="inline-start" /> Processing </Badge> </div> );}Input Group
Validating...
import { ArrowUpIcon } from "lucide-solid";import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupTextarea,} from "~/components/ui/input-group";import { Spinner } from "~/components/ui/spinner";
export default function SpinnerInputGroup() { return ( <div class="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 class="ml-auto" variant="default"> <ArrowUpIcon /> <span class="sr-only">Send</span> </InputGroupButton> </InputGroupAddon> </InputGroup> </div> );}Empty
Processing your request
Please wait while we process your request. Do not refresh the page.
import { Button } from "~/components/ui/button";import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle,} from "~/components/ui/empty";import { Spinner } from "~/components/ui/spinner";
export default function SpinnerEmpty() { return ( <Empty class="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> );}API Reference
Spinner
Spinner forwards standard SVG props to its loading indicator.