CodeBlock

A syntax-highlighted code block component with copy functionality and tab support for displaying code examples.

Usage

Basic Code Block

```tsx
const greeting = "Hello, World!";
console.log(greeting);
```

With Title and Icon

```tsx title="config.js"
export function main() {
  console.log("Starting application...");
}
```

Live Example:

config.js
export function main() {'{'}
console.log("Starting application...");

Code Block with Tabs

Use tabs to show code examples in different languages or contexts:

```ts tab="Typescript" title="example.ts"
const greeting: string = "Hello, World with ts!";
console.log(greeting);
```

```ts tab="Javascript" title="example.js"
const greeting = "Hello, World with js!";
console.log(greeting);
```
example.ts
const greeting: string = "Hello, World with ts!";
console.log(greeting);

With Line Numbers

import { CodeBlock, Pre } from "@prisma-docs/eclipse";

export function LineNumbersCodeBlock() {
  return (
    <CodeBlock 
      title="counter.ts"
      data-line-numbers
      data-line-numbers-start={1}
    >
      <Pre>
        <code>
          let count = 0;
          
          function increment() {'{'}
            count++;
            console.log(count);
          {'}'}
          
          increment();
        </code>
      </Pre>
    </CodeBlock>
  );
}
counter.ts
let count = 0;

function increment() {
  count++;
  console.log(count);
}

increment();

Keep Original Background

When using syntax highlighters like Shiki, preserve the theme colors:

import { CodeBlock, Pre } from "@prisma-docs/eclipse";

export function ThemedCodeBlock() {
  return (
    <CodeBlock 
      title="themed.tsx"
      keepBackground={true}
    >
      <Pre>
        <code className="language-tsx">
          // Syntax highlighted code here
        </code>
      </Pre>
    </CodeBlock>
  );
}

API Reference

CodeBlock

The main code block container with optional title bar and copy button.

Props:

  • title - Title displayed in the header (string, optional)
  • icon - Icon shown next to the title (ReactNode | string, optional)
  • allowCopy - Enable copy to clipboard button (boolean, default: true)
  • keepBackground - Preserve syntax highlighter background (boolean, default: false)
  • data-line-numbers - Show line numbers (boolean, optional)
  • data-line-numbers-start - Starting line number (number, default: 1)
  • viewportProps - Props passed to the scrollable viewport (HTMLAttributes, optional)
  • Actions - Custom actions component (component, optional)
  • className - Additional CSS classes (optional)
  • All standard HTML <figure> attributes

Pre

Pre-formatted text wrapper for code content.

Props:

  • All standard HTML <pre> attributes
  • className - Additional CSS classes (optional)

CodeBlockTabs

Container for tabbed code blocks.

Props:

  • defaultValue - Default active tab (string, optional)
  • value - Controlled active tab (string, optional)
  • onValueChange - Tab change callback ((value: string) => void, optional)
  • className - Additional CSS classes (optional)
  • All Radix Tabs Root props

CodeBlockTabsList

Container for tab triggers.

Props:

  • className - Additional CSS classes (optional)
  • All standard HTML attributes

CodeBlockTabsTrigger

Individual tab trigger button.

Props:

  • value - Tab identifier (string, required)
  • children - Tab label content (ReactNode, required)
  • className - Additional CSS classes (optional)
  • All Radix Tabs Trigger props

CodeBlockTab

Content panel for a code block tab.

Props:

  • value - Tab identifier matching trigger (string, required)
  • className - Additional CSS classes (optional)
  • All Radix Tabs Content props

Features

  • ✅ Syntax highlighting support (via Shiki/Rehype)
  • ✅ Copy to clipboard functionality
  • ✅ Optional title bar with icons
  • ✅ Line numbers support
  • ✅ Tab interface for multiple code examples
  • ✅ Scrollable viewport with max height
  • ✅ Keyboard accessible
  • ✅ Eclipse design system styling
  • ✅ Built on Fumadocs UI patterns
  • ✅ Custom actions support

Best Practices

  • Use descriptive titles that indicate the file or context
  • Include file extensions in titles for clarity (e.g., "index.ts", "App.jsx")
  • Use tabs when showing the same functionality in different languages
  • Enable line numbers for longer code examples or when referencing specific lines
  • Set allowCopy={false} only when copying doesn't make sense (e.g., example output)
  • Use keepBackground when you want to preserve syntax theme colors
  • Keep code examples concise and focused on the concept being explained
  • Add comments in code to explain complex logic
  • Test that the copy button works correctly with your code content

Common Use Cases

API Examples

<CodeBlockTabs defaultValue="curl">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="curl">cURL</CodeBlockTabsTrigger>
    <CodeBlockTabsTrigger value="javascript">JavaScript</CodeBlockTabsTrigger>
  </CodeBlockTabsList>
  <CodeBlockTab value="curl">
    <CodeBlock title="request.sh">
      <Pre><code>curl -X POST https://api.example.com/data</code></Pre>
    </CodeBlock>
  </CodeBlockTab>
  <CodeBlockTab value="javascript">
    <CodeBlock title="request.js">
      <Pre><code>fetch('https://api.example.com/data', {'{'} method: 'POST' {'}'})</code></Pre>
    </CodeBlock>
  </CodeBlockTab>
</CodeBlockTabs>

Configuration Files

<CodeBlock title="package.json" icon="📦">
  <Pre>
    <code>
      {'{'}
        "name": "my-project",
        "version": "1.0.0"
      {'}'}
    </code>
  </Pre>
</CodeBlock>

Tutorial Steps

<CodeBlock 
  title="step-1.ts" 
  data-line-numbers 
  data-line-numbers-start={1}
>
  <Pre>
    <code>
      // Step 1: Initialize the client
      const client = new Client();
    </code>
  </Pre>
</CodeBlock>

Terminal Output

<CodeBlock title="Terminal" allowCopy={false}>
  <Pre>
    <code>
      $ npm install prisma
      ✓ Installed successfully
    </code>
  </Pre>
</CodeBlock>

Styling with Syntax Highlighters

The CodeBlock component works seamlessly with syntax highlighters:

With Shiki (Recommended)

import { codeToHtml } from 'shiki';

const html = await codeToHtml(code, {
  lang: 'typescript',
  theme: 'github-dark'
});

<CodeBlock title="example.ts" keepBackground>
  <div dangerouslySetInnerHTML={{ __html: html }} />
</CodeBlock>

With Rehype Code

```tsx title="example.ts"
const greeting = "Hello, World!";
console.log(greeting);
\```

Accessibility

  • Copy buttons have proper aria-label attributes
  • Keyboard navigation supported (Tab to focus, Enter/Space to activate)
  • Code blocks are focusable and scrollable via keyboard
  • Screen readers announce copy success/failure
  • Semantic HTML structure with <figure>, <figcaption>, <pre>, and <code>
  • Tab interface follows ARIA tabs pattern

Integration with Fumadocs

CodeBlock is designed to work seamlessly with Fumadocs MDX:

---
title: My Documentation Page
---

Here's a code example:

```typescript title="example.ts"
const greeting = "Hello, World!";
console.log(greeting);
\```

Or with tabs:

```typescript tab="TypeScript" title="example.ts"
const greeting: string = "Hello, World!";
\```

```javascript tab="JavaScript" title="example.js"
const greeting = "Hello, World!";
\```

Custom Actions

You can customize the actions area in the code block header:

import { CodeBlock, Pre } from "@prisma-docs/eclipse";
import { Download } from "lucide-react";

export function CustomActionsCodeBlock() {
  return (
    <CodeBlock 
      title="config.json"
      Actions={({ className, children }) => (
        <div className={className}>
          {children}
          <button aria-label="Download">
            <Download className="size-4" />
          </button>
        </div>
      )}
    >
      <Pre>
        <code>{'{ "config": "value" }'}</code>
      </Pre>
    </CodeBlock>
  );
}

On this page