npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@choice-ui/spinner

v0.0.5

Published

A spinner component with animated loading indicators in various sizes and styles

Readme

Spinner

A collection of loading indicator components that provide visual feedback during asynchronous operations. Includes both bounce and spin animation variants with customizable styling and sizes.

Import

import { SpinnerBounce, SpinnerSpin } from "@choice-ui/react"

Features

  • Multiple Animation Types: Bounce and spin animation variants
  • Size Options: Small, medium, and large sizes for different contexts
  • Theme Variants: Primary and default color schemes
  • Label Support: Optional loading text display
  • Custom Styling: Flexible styling via classNames prop
  • Shape Customization: Individual control over shape elements (SpinnerSpin only)
  • Accessibility: Proper ARIA attributes and screen reader support

SpinnerBounce Usage

Basic Spinner

<SpinnerBounce />

With Label

<SpinnerBounce label="Loading..." />

Different Sizes

<SpinnerBounce size="small" />
<SpinnerBounce size="medium" />
<SpinnerBounce size="large" />

Variants

<SpinnerBounce variant="default" />
<SpinnerBounce variant="primary" />

SpinnerSpin Usage

Basic Spinner

<SpinnerSpin />

Different Sizes

<SpinnerSpin size="small" />
<SpinnerSpin size="medium" />
<SpinnerSpin size="large" />

Custom Opacity

<SpinnerSpin
  classNames={{
    shape:
      "opacity-100 [&:nth-of-type(1)]:opacity-100 [&:nth-of-type(2)]:opacity-10 [&:nth-of-type(3)]:opacity-10 [&:nth-of-type(4)]:opacity-100",
  }}
/>

Variants

<SpinnerSpin variant="default" />
<SpinnerSpin variant="primary" />

Custom Colors

<SpinnerSpin
  classNames={{
    shape:
      "[&:nth-of-type(1)]:bg-warning-background [&:nth-of-type(2)]:bg-success-background [&:nth-of-type(3)]:bg-accent-background [&:nth-of-type(4)]:bg-danger-background !opacity-100",
  }}
/>

With Label

<SpinnerSpin label="Loading..." />

SpinnerBounce Props

interface SpinnerBounceProps {
  /** Loading text to display below the spinner */
  label?: string

  /** Custom styling for different parts of the spinner */
  classNames?: {
    base?: string
    container?: string
    shape?: string
    label?: string
  }

  /** Additional CSS class names */
  className?: string

  /** Spinner size variant */
  size?: "small" | "medium" | "large"

  /** Visual style variant */
  variant?: "default" | "primary"
}

SpinnerSpin Props

interface SpinnerSpinProps {
  /** Loading text to display below the spinner */
  label?: string

  /** Custom styling for different parts of the spinner */
  classNames?: {
    base?: string
    container?: string
    shape?: string
    label?: string
  }

  /** Additional CSS class names */
  className?: string

  /** Spinner size variant */
  size?: "small" | "medium" | "large"

  /** Visual style variant */
  variant?: "default" | "primary"
}
  • Defaults:
    • size: "medium"
    • variant: "default" (when not specified)
    • label: undefined

Styling

  • Both components use Tailwind CSS via tailwind-variants in tv.ts
  • Customize using the className prop for overall styling
  • Use classNames object for granular control over individual parts
  • Available styling slots:
    • base: Root container element
    • container: Animation container
    • shape: Individual animated shapes
    • label: Text label element

Custom Styling Examples

Individual Shape Control (SpinnerSpin)

The classNames.shape property allows you to style each of the 4 animated shapes individually using nth-child selectors:

<SpinnerSpin
  classNames={{
    shape:
      "[&:nth-of-type(1)]:bg-red-500 [&:nth-of-type(2)]:bg-blue-500 [&:nth-of-type(3)]:bg-green-500 [&:nth-of-type(4)]:bg-yellow-500",
  }}
/>

Custom Container Sizing

<SpinnerBounce
  classNames={{
    container: "h-8 w-8",
    shape: "h-2 w-2",
  }}
/>

Size Specifications

SpinnerBounce

  • Small: 4px shapes, 16px container
  • Medium: 6px shapes, 24px container
  • Large: 8px shapes, 32px container

SpinnerSpin

  • Small: 16px container, ~5.33px shapes
  • Medium: 24px container, 8px shapes
  • Large: 32px container, ~10.67px shapes

Best Practices

  • Use SpinnerBounce for simple loading states with minimal visual complexity
  • Use SpinnerSpin when you need more visual interest or custom color schemes
  • Choose size based on the context: small for inline elements, large for full-page loading
  • Provide descriptive labels for longer loading operations
  • Use consistent spinner types throughout your application
  • Consider the visual weight - larger spinners draw more attention

Usage Guidelines

When to Use SpinnerBounce

  • Simple loading states
  • Minimal design requirements
  • Quick operations (< 3 seconds)
  • When visual simplicity is preferred

When to Use SpinnerSpin

  • More prominent loading states
  • When custom colors are needed
  • Longer operations that benefit from more visual interest
  • Dashboard and data-heavy interfaces

Loading Text Guidelines

  • Keep labels concise and actionable
  • Use present participle verbs: "Loading...", "Saving...", "Processing..."
  • Avoid generic "Please wait" in favor of specific actions
  • Consider internationalization for user-facing text

Accessibility

  • Both components include role="status" for screen readers
  • Default aria-label="Loading" provides context
  • Custom labels are automatically used as accessible text
  • Spinners are announced as status updates to assistive technologies

Examples

Button Loading State

<button disabled={isLoading}>{isLoading ? <SpinnerBounce size="small" /> : "Save Changes"}</button>

Full Page Loading

<div className="flex min-h-screen items-center justify-center">
  <SpinnerSpin
    size="large"
    label="Loading your dashboard..."
    variant="primary"
  />
</div>

Inline Loading

<div className="flex items-center gap-2">
  <SpinnerBounce size="small" />
  <span>Fetching latest data...</span>
</div>

Custom Themed Spinner

<SpinnerSpin
  size="medium"
  classNames={{
    container: "drop-shadow-lg",
    shape:
      "!opacity-100 [&:nth-of-type(1)]:bg-gradient-to-r [&:nth-of-type(1)]:from-purple-500 [&:nth-of-type(1)]:to-pink-500",
  }}
  label="Processing..."
/>

Animation Details

SpinnerBounce

  • Two shapes that bounce up and down in alternating sequence
  • Uses CSS transforms for smooth animation
  • Continuous loop with easing functions

SpinnerSpin

  • Four shapes arranged in a circular pattern
  • Rotates continuously around the center
  • Individual shapes can have different opacities and colors
  • 360-degree rotation with consistent timing

Notes

  • Both spinners use CSS variables for dynamic sizing based on props
  • Animations are optimized for performance using transforms
  • Colors inherit from the theme system but can be overridden
  • Shape count is fixed: 2 for SpinnerBounce, 4 for SpinnerSpin
  • Labels are rendered below the spinner with consistent spacing