snapshot of https://github.com/shadcn-ui/ui.git (main, 2026-09-15; blobs > 131072B omitted)
All checks were successful
Release / Create Version PR or Publish Stable Release (push) Has been skipped
Release / Publish Prerelease to NPM (push) Has been skipped
Monitor Registries / Monitor registry health (push) Has been skipped

This commit is contained in:
upstream-mirror
2026-09-15 22:44:43 +05:00
commit 1416db152c
5727 changed files with 630238 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
"use client"
import * as React from "react"
import { cn } from "cn"
import { Badge } from "@/registry/bases/radix/ui/badge"
import { Separator } from "@/registry/bases/radix/ui/separator"
import { IconPlaceholder } from "@/app/(app)/create/components/icon-placeholder"
type ToolPart = {
type: `tool-${string}` | "dynamic-tool"
toolName?: string
toolCallId: string
title?: string
state: string
input?: unknown
output?: unknown
errorText?: string
}
function getToolName(part: ToolPart) {
return part.type === "dynamic-tool"
? (part.toolName ?? "dynamicTool")
: part.type.replace("tool-", "")
}
function getToolTitle(part: ToolPart) {
if ("title" in part && typeof part.title === "string") {
return part.title
}
return getToolName(part)
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
.replace(/[-_]/g, " ")
.replace(/\b\w/g, (letter) => letter.toUpperCase())
}
function formatValue(value: unknown) {
if (typeof value === "string") {
return value
}
return JSON.stringify(value, null, 2)
}
export function PartTool({
part,
className,
}: { part: ToolPart } & Omit<React.ComponentProps<"div">, "part">) {
if (part.type !== "dynamic-tool" && !part.type.startsWith("tool-")) {
return null
}
const input = "input" in part ? part.input : undefined
const output = "output" in part ? part.output : undefined
const errorText = "errorText" in part ? part.errorText : undefined
const stateLabel = part.state.replace(/-/g, " ")
return (
<div
data-slot="part-tool"
data-state={part.state}
className={cn(
"w-full max-w-full min-w-0 rounded-lg border bg-muted/40 text-sm",
className
)}
>
<div className="flex min-w-0 items-center gap-2 px-3 py-2">
<span className="flex size-7 shrink-0 items-center justify-center rounded-md bg-background text-muted-foreground">
<IconPlaceholder
lucide="SettingsIcon"
tabler="IconSettings"
hugeicons="SettingsIcon"
phosphor="TerminalIcon"
remixicon="RiSettingsLine"
className="size-4"
/>
</span>
<div className="min-w-0 flex-1">
<div className="truncate font-medium">{getToolTitle(part)}</div>
<div className="truncate text-xs text-muted-foreground">
{getToolName(part)}
</div>
</div>
<Badge variant="outline" className="capitalize">
{stateLabel}
</Badge>
</div>
{input !== undefined || output !== undefined || errorText ? (
<>
<Separator />
<div className="grid gap-3 p-3">
{input !== undefined ? (
<div className="grid gap-1">
<div className="text-xs font-medium text-muted-foreground">
Input
</div>
<pre className="max-h-32 overflow-auto rounded-md bg-background p-2 text-xs leading-relaxed">
{formatValue(input)}
</pre>
</div>
) : null}
{output !== undefined ? (
<div className="grid gap-1">
<div className="text-xs font-medium text-muted-foreground">
Output
</div>
<pre className="max-h-40 overflow-auto rounded-md bg-background p-2 text-xs leading-relaxed">
{formatValue(output)}
</pre>
</div>
) : null}
{errorText ? (
<div className="rounded-md border border-destructive/30 bg-destructive/10 p-2 text-xs text-destructive">
{errorText}
</div>
) : null}
</div>
</>
) : null}
</div>
)
}