shadimage
Beste UI Pieces
componentai14source: ok · refreshed

Stop Reason

Completion stop reason card where the icon tile color flips per reason (end_turn, stop_sequence, tool_use, max_tokens) and shows the token count.

npx shadcn add "https://ui.beste.co/piece/r/ai14.json"
free

No selection tags yet — empty means no evidence, not lack of support.

Dependencies

Bundle weight · light
clsxtailwind-mergelucide-react

Files1 · source cached 10/7/2026, 11:47:29 PM

registry-pieces/ai14/ai14.tsx
"use client";

import { Check, CircleStop, TriangleAlert, Wrench } from "lucide-react";
import type { LucideIcon } from "lucide-react";
import { cn } from "@/lib/utils";

type Surface = "card" | "glass";

type IconKey = "check" | "stop" | "tool" | "warning";
type Tone =
  | "primary"
  | "foreground"
  | "emerald"
  | "sky"
  | "violet"
  | "amber"
  | "rose";

interface Ai14Props {
  label?: string;
  hint?: string;
  icon?: IconKey;
  tone?: Tone;
  tokens?: number;
  maxTokens?: number;
  surface?: Surface;
  bordered?: boolean;
  inverted?: boolean;
  className?: string;
}

const iconMap: Record<IconKey, LucideIcon> = {
  check: Check,
  stop: CircleStop,
  tool: Wrench,
  warning: TriangleAlert,
};

const iconClasses: Record<Tone, string> = {
  primary: "text-primary",
  foreground: "text-foreground",
  emerald: "text-emerald-600 dark:text-emerald-400",
  sky: "text-sky-600 dark:text-sky-400",
  violet: "text-violet-600 dark:text-violet-400",
  amber: "text-amber-600 dark:text-amber-400",
  rose: "text-rose-600 dark:text-rose-400",
};


/* The card sets the colour and everything inside it is drawn in `current`, so
   inverting is two classes rather than a condition on every element.
   `glass` is a deliberate exception to the solid-surface rule: these pieces sit
   over section background images, and a frosted panel is the point of it. */
const surfaceClasses: Record<Surface, { plain: string; inverted: string }> = {
  card: {
    plain: "bg-card text-card-foreground",
    inverted: "bg-foreground text-background",
  },
  glass: {
    plain: "bg-card/60 text-card-foreground backdrop-blur-md",
    inverted: "bg-foreground/60 text-background backdrop-blur-md",
  },
};

export const ai14Demo: Ai14Props = {
  surface: "card",
  bordered: false,
  inverted: false,
  label: "end_turn",
  hint: "Response completed normally.",
  icon: "check",
  tone: "primary",
};

export function Ai14({
  label = "end_turn",
  hint,
  icon = "check",
  tone = "primary",
  tokens,
  maxTokens,
  surface = "card",
  bordered = false,
  inverted = false,
  className,
}: Ai14Props) {
  const Icon = iconMap[icon];

  const surfaceTone = surfaceClasses[surface][inverted ? "inverted" : "plain"];

  return (
    <div
      className={cn(
        "relative flex size-full items-center justify-center p-4",
        className
      )}
    >
      <div className={cn("flex w-full max-w-80 items-center gap-2.5 rounded-md p-3 shadow-sm", surfaceTone, bordered && "border border-current/15")}>
        <Icon className={cn("size-5 shrink-0", iconClasses[tone])} aria-hidden="true" />
        <div className="flex min-w-0 flex-1 flex-col">
          <div className="flex items-baseline justify-between gap-2">
            <span className="truncate text-xs font-semibold">
              {label}
            </span>
            {typeof tokens === "number" && (
              <span className="shrink-0 text-xs tabular-nums text-current/60">
                {tokens.toLocaleString()}
                {typeof maxTokens === "number"
                  ? ` / ${maxTokens.toLocaleString()}`
                  : ""}
              </span>
            )}
          </div>
          {hint && (
            <span className="truncate text-xs text-current/60">
              {hint}
            </span>
          )}
        </div>
      </div>
    </div>
  );
}

More from Beste UI Pieces

Browse all components in this library →