Agent Loading States Agent Progress
beui/agent-progressFreeComponent
A compact activity glyph, action verb, and live tabular timer for longer-running agent work.
Install it
npx shadcn@latest add https://beui.dev/r/agent-progress.jsonSource
1"use client";2// beui.dev/components/agents/loading-states34import { motion, useReducedMotion } from "motion/react";5import { useEffect, useState } from "react";6import { EASE_IN_OUT } from "@/lib/ease";7import { cn } from "@/lib/utils";89const GRID_CELLS = [10 { id: "top-left", delay: 0 },11 { id: "top-center", delay: 0.14 },12 { id: "top-right", delay: 0.28 },13 { id: "middle-left", delay: 0.42 },14 { id: "middle-center", delay: 0.56 },15 { id: "middle-right", delay: 0.7 },16 { id: "bottom-left", delay: 0.84 },17 { id: "bottom-center", delay: 0.98 },18 { id: "bottom-right", delay: 1.12 },19];2021export interface AgentProgressProps {22 /** Verb describing the agent's current activity. */23 label?: string;24 /** Controlled elapsed time in seconds. */25 elapsedSeconds?: number;26 /** Starting time for the internal timer, in seconds. */27 initialSeconds?: number;28 /** Whether the internal timer should advance. Ignored when elapsedSeconds is provided. */29 running?: boolean;30 className?: string;31}3233function formatElapsed(totalSeconds: number) {34 const safeSeconds = Math.max(0, totalSeconds);35 const minutes = Math.floor(safeSeconds / 60);36 const seconds = (safeSeconds % 60).toFixed(1);37 return minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;38}3940export function AgentProgress({41 label = "Churning",42 elapsedSeconds,43 initialSeconds = 0,44 running = true,45 className,46}: AgentProgressProps) {47 const reduce = useReducedMotion() ?? false;48 const [internalSeconds, setInternalSeconds] = useState(initialSeconds);4950 useEffect(() => {51 if (elapsedSeconds !== undefined || !running) return;5253 const startedAt = performance.now() - initialSeconds * 1000;54 const timer = window.setInterval(() => {55 setInternalSeconds((performance.now() - startedAt) / 1000);56 }, 100);5758 return () => window.clearInterval(timer);59 }, [elapsedSeconds, initialSeconds, running]);6061 const elapsed = elapsedSeconds ?? internalSeconds;6263 return (64 <span65 role="status"66 aria-label={`${label}, in progress`}67 className={cn(68 "inline-flex items-center gap-3 font-mono text-sm text-muted-foreground",69 className,70 )}71 >72 <span73 aria-hidden="true"74 className="grid size-5 shrink-0 grid-cols-3 gap-[2px]"75 >76 {GRID_CELLS.map(({ id, delay }) => (77 <motion.span78 key={id}79 className="rounded-[1px] bg-current"80 animate={81 reduce82// … truncated
What it pulls in
npm packages
Files it writes
More from beui
All 104 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Action Swap Bluraction-swap-blur | beui | Components | Free | 3 deps · 4 files | |
| Action Swap Cascadeaction-swap-cascade | beui | Components | Free | 3 deps · 4 files | |
| Action Swap Rollaction-swap-roll | beui | Components | Free | 3 deps · 4 files | |
| Agent Activityagent-activity | beui | Components | Free | 4 deps · 9 files | |
| AI Sidebarai-sidebar | beui | Components | Free | 4 deps · 5 files | |
| Animated Badgeanimated-badge | beui | Components | Free | 4 deps · 3 files | |
| Number Animation Animated Numberanimated-number | beui | Components | Free | 3 deps · 3 files | |
| Animated Sidebaranimated-sidebar | beui | Components | Free | 4 deps · 4 files |
