Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | 1x | import { useState, type JSX } from "react";
import type { ToolCardProps } from "./ToolCardProps.js";
import styles from "./toolCards.module.scss";
/** Extracts query from ToolSearch args. */
function getQuery(args: unknown): string {
if (args === null || args === undefined || typeof args !== "object") {
return "";
}
const a = args as Record<string, unknown>;
return typeof a.query === "string" ? a.query : "";
}
/** Number of lines shown when collapsed. */
const PREVIEW_LINES: number = 8;
/** Renders a ToolSearch call (Claude Code built-in) with query and results. */
export function ToolSearchCard({ args, result, isError }: ToolCardProps): JSX.Element {
const [expanded, setExpanded] = useState(false);
const query = getQuery(args);
const inProgress = result === undefined;
const resultLines = result?.split("\n") ?? [];
const hasMore = resultLines.length > PREVIEW_LINES;
const displayResult = expanded ? result : resultLines.slice(0, PREVIEW_LINES).join("\n");
return (
<div
className={`${styles.card} ${isError ? styles.cardRed : styles.cardNeutral} ${inProgress ? styles.inProgress : ""}`}
data-testid="tool-card-tool-search"
>
<div className={styles.header}>
<span className={styles.icon} aria-hidden="true">
🔧
</span>
<span className={styles.toolName}>ToolSearch</span>
{query && (
<span className={styles.fileName} data-testid="tool-card-tool-search-query">
"{query}"
</span>
)}
{!inProgress && !isError && result && (
<>
<span className={styles.spacer} />
<span className={styles.badge} data-testid="tool-card-tool-search-count">
{resultLines.length} lines
</span>
</>
)}
</div>
{/* In-progress: show query */}
{inProgress && !query && args !== null && args !== undefined && (
<pre className={styles.pre} data-testid="tool-card-args">
{JSON.stringify(args, null, 2)}
</pre>
)}
{/* Error */}
{isError && result && (
<pre className={styles.pre} data-testid="tool-card-error">
{result}
</pre>
)}
{/* Result text */}
{!isError && !inProgress && result && (
<>
<pre className={styles.pre} data-testid="tool-card-tool-search-result">
{displayResult}
</pre>
{hasMore && (
<button
type="button"
className={styles.bodyToggle}
onClick={() => {
setExpanded((v) => !v);
}}
aria-expanded={expanded}
data-testid="tool-card-toggle"
>
<span className={`${styles.chevron} ${expanded ? styles.chevronExpanded : ""}`}>
▸
</span>
{expanded ? "collapse" : `${resultLines.length - PREVIEW_LINES} more lines`}
</button>
)}
</>
)}
</div>
);
}
|