# Hello World in Pythondef main():print("Hello, World!")if __name__ == "__main__":main()
Installation
pnpm dlx shadcn@latest add https://deltacomponents.dev/r/code-block.jsonConfiguration
Global CSS & Utilities
This component relies on specific CSS variables for its "surface" background logic (when not using the syntax theme's background) and utility classes for scrollbar management.
Add the following to your global CSS:
@layer base {
:root {
--surface: #fafafa; /* Light mode fallback */
}
.dark {
--surface: #171717; /* Dark mode fallback */
}
}
@layer utilities {
/* Hides scrollbars for a cleaner aesthetic when interactions aren't required */
.no-scrollbar::-webkit-scrollbar {
display: none;
}
.no-scrollbar {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
}Usage
Basic Code Rendering
Pass a raw string to the code prop. You can optionally add a filename to render a file header with an automatically resolved icon.
import { CodeBlock } from "@/components/ui/code-block"
export default function Example() {
return (
<CodeBlock
code={`console.log("Hello World")`}
language="typescript"
filename="app.ts"
showLineNumbers
/>
)
}Markdown String Parsing
The component includes a regex parser (parseMarkdownCodeBlock) that extracts the language and code from standard Markdown fence syntax. This is particularly useful when rendering content from an LLM or a CMS that returns raw markdown strings.
// The language "python" is automatically extracted from the string
<CodeBlock
code={`\`\`\`python
def hello():
print("world")
\`\`\``}
/>Examples
Markdown Integration
If your code string contains a markdown code fence (e.g., typescript\n...\n), the component can parse the language and content automatically.
1def greet(name: str) -> str:2 """Return a greeting message."""3 return f"Hello, {name}!"45if __name__ == "__main__":6 message = greet("World")7 print(message)
MDX Transformer (Contentlayer/Fumadocs)
For documentation sites (like those using Contentlayer or Fumadocs), you can transform all native markdown <pre> blocks into the enhanced CodeBlock component.
import type { MDXComponents } from "mdx/types"
import { CodeBlock } from "@/components/ui/code-block"
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
...components,
pre: ({ children, ...props }) => {
// Basic logic to extract code and language from markdown structure
const code =
typeof children === "object" && "props" in children
? children.props.children
: ""
const className =
typeof children === "object" && "props" in children
? children.props.className || ""
: ""
const language = className.replace(/language-/, "")
return (
<CodeBlock
code={code}
language={language || "typescript"}
showLineNumbers={true}
/>
)
},
}
}Theme Background Toggle
Use useThemeBackground={true} to apply the specific background color defined within your Prism theme, overriding the default adaptive --surface variable.
1def fibonacci(n: int) -> list[int]:2 """Generate Fibonacci sequence up to n numbers. This is a long comment to test horizontal scrolling behavior in the code block component."""3 if n <= 0:4 return []5 elif n == 1:6 return [0]78 sequence = [0, 1]9 while len(sequence) < n:10 sequence.append(sequence[-1] + sequence[-2]) # Add the sum of the last two numbers to the sequence list for Fibonacci calculation1112 return sequence1314def fibonacci_recursive(n: int, memo: dict[int, int] | None = None) -> int:15 """Calculate the nth Fibonacci number using memoization for better performance in recursive calls."""16 if memo is None:17 memo = {}18 if n in memo:19 return memo[n]20 if n <= 1:21 return n22 memo[n] = fibonacci_recursive(n - 1, memo) + fibonacci_recursive(n - 2, memo)23 return memo[n]2425if __name__ == "__main__":26 result = fibonacci(10)27 print(f"Fibonacci sequence: {result}") # Output: Fibonacci sequence: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] for the first 10 numbers
JSON Syntax Highlighting
Display formatted JSON data with syntax highlighting:
1{2 "user": {3 "id": "usr_2nQz7kX9pLm4",4 "email": "sarah.chen@acme.com",5 "name": "Sarah Chen",6 "role": "senior_engineer",7 "permissions": ["read", "write", "deploy"],8 "metadata": {9 "department": "platform",10 "team": "infrastructure",11 "timezone": "America/Los_Angeles"12 }13 },14 "session": {15 "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9",16 "expiresAt": "2024-12-31T23:59:59Z",17 "refreshToken": "rt_9xKmP3vN8qL2",18 "scopes": ["api:read", "api:write", "admin:users"]19 },20 "preferences": {21 "theme": "dark",22 "notifications": {23 "email": true,24 "slack": true,25 "digest": "daily"26 },27 "editor": {28 "tabSize": 2,29 "formatOnSave": true30 }31 }32}
Expandable Code Blocks
Handle long code snippets with expand/collapse functionality:
1import * as React from "react"2import { useEffect, useState, useCallback, useMemo } from "react"3import { cn } from "@/lib/utils"45interface DataItem {6 id: string7 name: string8 description: string9 status: "active" | "inactive" | "pending"10 createdAt: Date11 updatedAt: Date12 metadata: Record<string, unknown>13}1415interface DataTableProps {16 data: DataItem[]17 onSelect?: (item: DataItem) => void18 onDelete?: (id: string) => void19 onEdit?: (item: DataItem) => void20 className?: string21 loading?: boolean22 error?: Error | null23}2425export function DataTable({26 data,27 onSelect,28 onDelete,29 onEdit,30 className,31 loading = false,32 error = null,33}: DataTableProps) {34 const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set())35 const [sortColumn, setSortColumn] = useState<keyof DataItem>("name")36 const [sortDirection, setSortDirection] = useState<"asc" | "desc">("asc")37 const [filterText, setFilterText] = useState("")3839 const filteredData = useMemo(() => {40 return data41 .filter((item) =>42 item.name.toLowerCase().includes(filterText.toLowerCase()) ||43 item.description.toLowerCase().includes(filterText.toLowerCase())44 )45 .sort((a, b) => {46 const aVal = a[sortColumn]47 const bVal = b[sortColumn]48 const modifier = sortDirection === "asc" ? 1 : -149 if (aVal < bVal) return -1 * modifier50 if (aVal > bVal) return 1 * modifier51 return 052 })53 }, [data, filterText, sortColumn, sortDirection])5455 const handleSelectAll = useCallback(() => {56 if (selectedIds.size === filteredData.length) {57 setSelectedIds(new Set())58 } else {59 setSelectedIds(new Set(filteredData.map((item) => item.id)))60 }61 }, [filteredData, selectedIds.size])6263 const handleSelectItem = useCallback((id: string) => {64 setSelectedIds((prev) => {65 const next = new Set(prev)66 if (next.has(id)) {67 next.delete(id)68 } else {69 next.add(id)70 }71 return next72 })73 }, [])7475 if (loading) {76 return <div className="flex items-center justify-center p-8">Loading...</div>77 }7879 if (error) {80 return <div className="text-red-500 p-4">Error: {error.message}</div>81 }8283 return (84 <div className={cn("rounded-lg border", className)}>85 <div className="p-4 border-b">86 <input87 type="text"88 placeholder="Filter items..."89 value={filterText}90 onChange={(e) => setFilterText(e.target.value)}91 className="w-full px-3 py-2 border rounded-md"92 />93 </div>94 <table className="w-full">95 <thead>96 <tr className="border-b bg-muted/50">97 <th className="p-3 text-left">98 <input99 type="checkbox"100 checked={selectedIds.size === filteredData.length}101 onChange={handleSelectAll}102 />103 </th>104 <th className="p-3 text-left font-medium">Name</th>105 <th className="p-3 text-left font-medium">Status</th>106 <th className="p-3 text-left font-medium">Actions</th>107 </tr>108 </thead>109 <tbody>110 {filteredData.map((item) => (111 <tr key={item.id} className="border-b hover:bg-muted/30">112 <td className="p-3">113 <input114 type="checkbox"115 checked={selectedIds.has(item.id)}116 onChange={() => handleSelectItem(item.id)}117 />118 </td>119 <td className="p-3">{item.name}</td>120 <td className="p-3">121 <span className={`px-2 py-1 rounded-full text-xs ${122 item.status === "active" ? "bg-green-100 text-green-800" :123 item.status === "inactive" ? "bg-gray-100 text-gray-800" :124 "bg-yellow-100 text-yellow-800"125 }`}>126 {item.status}127 </span>128 </td>129 <td className="p-3 flex gap-2">130 <button onClick={() => onEdit?.(item)}>Edit</button>131 <button onClick={() => onDelete?.(item.id)}>Delete</button>132 </td>133 </tr>134 ))}135 </tbody>136 </table>137 </div>138 )139}
Interactive Theme Demo
1package main23import "fmt"45func main() {6 fmt.Println("Hello, World!")7}
Cycle through Prism themes with background toggle to compare bg-surface vs. useThemeBackground behavior.
NPX Commands
Handle package manager commands in markdown:
npx shadcn@latest add button
Package Manager Commands
npm install @radix-ui/react-dropdown-menu
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
code | string | — | The code content. Can be a raw string or a markdown fenced string. |
language | string | "typescript" | The language for syntax highlighting. Ignored if markdown fence detects a language. |
filename | string | — | If provided, renders a header with a file icon. |
showLineNumbers | boolean | true | Toggles the line number gutter. |
expandable | boolean | false | Enables the collapse/expand functionality. |
defaultExpanded | boolean | false | The initial state of the expandable block. |
collapsedHeight | string | "12rem" | CSS height value for the collapsed state. |
theme | PrismTheme | undefined | A static Prism theme object. |
adaptiveTheme | { light, dark } | — | Object containing themes for light and dark modes. |
useThemeBackground | boolean | false | If true, applies the theme's background color. If false, uses var(--surface). |
npm | string | — | Command for npm tab. |
yarn | string | — | Command for yarn tab. |
pnpm | string | — | Command for pnpm tab. |
bun | string | — | Command for bun tab. |
defaultPackageManager | "npm" | "yarn" | "pnpm" | "bun" | "npm" | The default active tab. |
Background Behavior
- Default (
useThemeBackground={false}): Usesbg-surfaceCSS variable - Theme Background (
useThemeBackground={true}): Usestheme.plain.backgroundColorfrom Prism theme - Requires
--surfaceCSS variable definition for default mode
Types
type PackageManager = "npm" | "yarn" | "pnpm" | "bun"
interface AdaptiveTheme {
light: PrismTheme
dark: PrismTheme
}Theme Structure
Custom themes follow the Prism theme structure:
const customTheme: PrismTheme = {
plain: {
color: "#e6e6fa",
backgroundColor: "#1a1a2e",
},
styles: [
{
types: ["comment"],
style: {
color: "#6a7b9a",
fontStyle: "italic",
},
},
// ... more styles
],
}On This Page
InstallationConfigurationGlobal CSS & UtilitiesUsageBasic Code RenderingMarkdown String ParsingExamplesMarkdown IntegrationMDX Transformer (Contentlayer/Fumadocs)Theme Background ToggleJSON Syntax HighlightingExpandable Code BlocksInteractive Theme DemoNPX CommandsPackage Manager CommandsAPI ReferencePropsBackground BehaviorTypesTheme Structure