Progress Pulse
A compact processing rail with reduced-motion fallback.
"use client";
import "./styles/progress-pulse.css";
export default function ProgressPulse({ variant = "Loop" }: { variant?: string }) {
return <div className={`ward-progress-pulse ${variant === "Once" ? "is-once" : ""}`} role="progressbar" aria-label="Processing" aria-valuetext="Processing"><span /></div>;
}.ward-progress-pulse { width: min(100%, 300px); height: 8px; overflow: hidden; border-radius: 999px; background: var(--secondary); }
.ward-progress-pulse span { display: block; width: 35%; height: 100%; border-radius: inherit; background: var(--primary); animation: ward-progress 1.4s cubic-bezier(.2, 0, 0, 1) infinite alternate; }
.ward-progress-pulse.is-once span { animation-iteration-count: 1; animation-fill-mode: forwards; }
@keyframes ward-progress { to { transform: translateX(190%); } }
@media (prefers-reduced-motion: reduce) { .ward-progress-pulse span { animation: none; width: 70%; } }Installation
pnpm dlx shadcn@latest add @ward/progress-pulsenpx shadcn@latest add @ward/progress-pulseyarn dlx shadcn@latest add @ward/progress-pulsebunx --bun shadcn@latest add @ward/progress-pulseAdd the Ward registry to components.json once:
"registries": {
"@ward": "https://ward.so/r/{name}.json"
}Or install from the URL with no configuration: npx shadcn@latest add https://ward.so/r/progress-pulse.json
Copy each file from the Code tab into:
components/ward/ProgressPulse.tsxcomponents/ward/styles/progress-pulse.css
Update the import paths to match your project.
Usage
import ProgressPulse from "@/components/ward/ProgressPulse";<ProgressPulse variant="Once" />Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "Loop" | "Once" | "Loop" | Whether the pulse repeats continuously or runs a single time. |
Ward · Version 1.1.0 · Registry manifest