Ai Tool Call
smoothui-registry/ai-tool-callFreeComponent
Collapsible tool invocation whose status badge is one ring that evolves — breathing, spinning, then drawing a check or a cross.
Install it
npx shadcn@latest add https://www.smoothui.dev/r/ai-tool-call.jsonSource
1"use client";23import { cn } from "@/lib/utils";4import { ChevronRight } from "lucide-react";5import { AnimatePresence, motion, useReducedMotion } from "motion/react";6import { type ReactNode, useState } from "react";78const SPRING_DEFAULT = {9 bounce: 0.1,10 duration: 0.25,11 type: "spring" as const,12};13const EASE_OUT = [0.23, 1, 0.32, 1] as const;14const BADGE_VIEWBOX = 24;15const BADGE_CENTER = BADGE_VIEWBOX / 2;16const RING_RADIUS = 8;17const CHECK_PATH = "M 8.5 12.2 L 11 14.8 L 15.8 9.6";18const CROSS_PATHS = ["M 9 9 L 15 15", "M 15 9 L 9 15"] as const;19const SPIN_SECONDS = 0.9;20const PENDING_PULSE_SECONDS = 1.6;2122export type AIToolCallStatus = "pending" | "running" | "success" | "error";2324export type AIToolCallProps = {25 /** Arguments the tool was called with. Rendered as-is. */26 args?: ReactNode;27 className?: string;28 defaultOpen?: boolean;29 /** Tool name, e.g. `search_web`. */30 name: string;31 /** What the tool returned. */32 result?: ReactNode;33 status?: AIToolCallStatus;34 /** Short right-aligned note, e.g. "3 files" or "1.2s". */35 summary?: string;36};3738const STATUS_LABEL: Record<AIToolCallStatus, string> = {39 error: "Failed",40 pending: "Queued",41 running: "Running",42 success: "Done",43};4445/**46 * The status badge is **one ring that changes behaviour**, not four icons that47 * swap places.48 *49 * `pending` breathes, `running` spins as a gap in the same ring, `success` keeps50 * the ring and draws a check inside it, `error` keeps the ring and draws a51 * cross. Because the ring never unmounts, the eye tracks a single object through52 * the whole lifecycle instead of watching icons pop in and out.53 */54const AIToolCallBadge = ({55 status,56 shouldReduceMotion,57}: {58 shouldReduceMotion: boolean;59 status: AIToolCallStatus;60}) => {61 const isRunning = status === "running";62 const isPending = status === "pending";6364 const ringColor = (() => {65 if (status === "success") {66 return "oklch(72% 0.17 150)";67 }68 if (status === "error") {69 return "oklch(63% 0.21 25)";70 }71 return "currentColor";72 })();7374 return (75 <span className="relative flex size-5 shrink-0 items-center justify-center text-muted-foreground">76 <svg77 aria-hidden="true"78 className="size-5 overflow-visible"79 viewBox={`0 0 ${BADGE_VIEWBOX} ${BADGE_VIEWBOX}`}80 >81 <motion.g82 animate={83 shouldReduceMotion || !isRunning ? undefined : { rotate: 360 }84 }85// … truncated
What it pulls in
npm packages
Files it writes
More from SmoothUI Registry
All 178 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Agent Avataragent-avatar | SmoothUI Registry | Components | Free | no deps | |
| Ai Approvalai-approval | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Artifactai-artifact | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Branchai-branch | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Citationai-citation | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Context Meterai-context-meter | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Conversationai-conversation | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Coreai-core | SmoothUI Registry | Components | Free | 1 dep |
