Loading Pill

A status pill pairing the Matrix Dot Loader with a label.

Loading preview

Installation

npx shadcn@latest add @loomui/loading-pill

Usage

import { LoadingPill } from "@/components/ui/loading-pill"
<LoadingPill active={isSaving} label="Applying changes" />

How it works

LoadingPill doesn't reimplement a loader — it renders MatrixDotLoader directly and passes active straight through, so the two components can never fall out of sync with each other. The pill itself is just a role="status" wrapper with a label next to it.

The background reuses Switch's resting-track treatment exactly: the same color-mix() of --muted and --foreground for a light-mode-only darker gray, the same :global(.dark) override back to plain --muted, and the same inset shadow for a recessed feel — one surface treatment, used everywhere a component needs to look like a resting, inactive control.

The border is a 1px gradient ring, built from two background-image layers: one solid (clipped to the padding box, filling the interior) and one a conic-gradient (clipped to the border box, so it only shows through the 1px transparent border). Most of that conic-gradient is transparent — only about 40% of it carries color — so what actually renders is a short rainbow arc, not a full ring. Animating from var(--pill-angle) with an @property-registered custom angle spins that arc around the pill continuously, reading as a comet chasing the border rather than a static gradient outline.

Props

PropTypeDefaultDescription
activebooleantrueForwarded to the Matrix Dot Loader.
labelstring-The text next to the loader.
classNamestring-Merged onto the pill.

Any other <div> prop is forwarded.

Reduced motion

Handled entirely by Matrix Dot Loader — see its own docs for how it settles under prefers-reduced-motion.