Spinning Circle

PreviousNext

A customizable spinning circle loader component for indicating loading states in your application. Features smooth animations and optional loading messages.

Docs
moleculeuiui

Preview

Loading preview…
registry/molecule-ui/spinning-circle.tsx
"use client"

import React from "react"
import { cva } from "class-variance-authority"
import { HTMLMotionProps, motion } from "motion/react"

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

const spinningCircleVariants = cva("flex gap-2 items-center justify-center", {
  variants: {
    messagePlacement: {
      bottom: "flex-col",
      top: "flex-col-reverse",
      right: "flex-row",
      left: "flex-row-reverse",
    },
  },
  defaultVariants: {
    messagePlacement: "bottom",
  },
})

export interface SpinningCircleProps {
  message?: string
  /**
   * Position of the message relative to the spinner.
   * @default bottom
   */
  messagePlacement?: "top" | "bottom" | "left" | "right"
}

export function SpinningCircle({
  className,
  message,
  messagePlacement = "bottom",
  ...props
}: HTMLMotionProps<"div"> & SpinningCircleProps) {
  return (
    <div className={cn(spinningCircleVariants({ messagePlacement }))}>
      <motion.div
        className={cn(
          "border-t-foreground h-8 w-8 rounded-full border-4",
          className,
        )}
        animate={{ rotate: 360 }}
        transition={{
          duration: 1,
          repeat: Number.POSITIVE_INFINITY,
          ease: "linear",
        }}
        {...props}
      />
      {message && <div>{message}</div>}
    </div>
  )
}

Installation

npx shadcn@latest add @moleculeui/spinning-circle

Usage

import { SpinningCircle } from "@/components/ui/spinning-circle"
<SpinningCircle />