Skip to content

Conversation

Code Block

Code in an answer — filename, language, line numbers, wrap toggle, copy and collapse for long snippets.

2 variantsMIT

Preview

src/site/images.tsts
import { createCache } from "./cache";

// Resized images are keyed by content hash, so a changed file always misses.
export async function resize(src: string, width: number) {
  const key = await hash(src, width);
  const hit = await cache.get(key);
  if (hit) return hit;
  return cache.set(key, await sharp(src).resize(width).toBuffer());
}

Installation

Copies the component into components/ui and installs its dependencies and theme tokens.

pnpm dlx shadcn@latest add https://tuffui.com/r/code-block.json

Usage

Pass your own data and wire the callbacks to your agent runtime.

import { CodeBlock } from "@/components/ui/code-block";

export function AnswerCode({ block }: { block: { code: string; lang: string; file?: string } }) {
  return (
    <CodeBlock
      data={{ code: block.code, language: block.lang as "ts", filename: block.file }}
      collapseAfter={16}
      onCopy={() => analytics.track("code_copied")}
    />
  );
}

Props

PropTypeDefaultDescription
data*CodeBlockData—The code, its language, an optional filename and lines to highlight.
collapseAfternumber14Longer code collapses to this many lines behind a “Show all N lines” control.
showLineNumbersbooleantrueLine numbers in a sticky gutter.
defaultWrapbooleanfalseStart with soft wrap on; the header toggle switches it.
onCopy(code: string) => void—Called after the code is copied to the clipboard.
classNamestring—Extra classes for the shell.
type CodeLanguage = "ts" | "tsx" | "js" | "json" | "bash" | "python" | "text";

type CodeBlockData = {
  code: string;
  language?: CodeLanguage; // drives the built-in tokenizer
  filename?: string;
  highlight?: number[];    // 1-based line numbers
};