GitHub

Orbit ring

A ring with orbiting elements for a dynamic loading indicator.

Loading
import { OrbitRing } from "@/components/loading-ui/orbit-ring";

export function OrbitRingDemo() {

Installation

pnpm dlx shadcn@latest add @loading-ui/orbit-ring

Usage

import { OrbitRing } from "@/components/loading-ui/orbit-ring";
<OrbitRing />

Customization

OrbitRing feels a bit more expansive than ConcentricRing because the moving arc sits outside the base ring. That makes it especially useful when you want a loader with a slightly wider footprint and a more dynamic silhouette.

Size

Scale the component with size-* utilities depending on whether it appears inline or anchors a larger state.

LoadingLoadingLoadingLoading
import { OrbitRing } from "@/components/loading-ui/orbit-ring";

export function OrbitRingSize() {

Color

The ring and orbiting segment inherit currentColor, so the component can easily match muted UI, primary accents, or stronger contextual tones.

LoadingLoadingLoading
import { OrbitRing } from "@/components/loading-ui/orbit-ring";

export function OrbitRingColor() {

Ring Weight

Border thickness changes how crisp or substantial the orbit feels, especially at medium and larger sizes.

LoadingLoadingLoading
import { OrbitRing } from "@/components/loading-ui/orbit-ring";

export function OrbitRingRingWeight() {

Duration

Animation speed changes the overall mood from calm background activity to something more energetic.

LoadingLoadingLoading
import { OrbitRing } from "@/components/loading-ui/orbit-ring";

export function OrbitRingDuration() {

Examples

These examples lean into the wider, slightly more atmospheric quality of OrbitRing. It tends to read best in states that need a little more presence than a minimal inline spinner, but still want to stay clean and product-focused.

Button

In buttons, OrbitRing works well when the action should feel active and noticeable without becoming flashy.

import { Button } from "@/components/ui/button";
import { OrbitRing } from "@/components/loading-ui/orbit-ring";

Input Group

Inside input groups, it can signal resolving, drafting, or sending work while keeping the feedback local to the control.

LoadingResolving...
LoadingDrafting reply...
import {
  InputGroup,
  InputGroupAddon,

Empty

For section-level waiting states, the outer orbit gives the loader enough presence to hold the layout on its own.

Loading

Mapping your workspace

Projects, dependencies, and recent branches are still being connected into a fresh view.

import { Button } from "@/components/ui/button";
import {
  Empty,

Tabs

Within tabbed workspaces, it can indicate that one panel is still refreshing while the rest of the view remains available.

Loading
Refreshing workspace overview

Pulling recent changes, checks, and branch activity now.

import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { OrbitRing } from "@/components/loading-ui/orbit-ring";