# Hello World in Pythondef main():print("Hello, World!")if __name__ == "__main__":main()
Installation
pnpm dlx shadcn@latest add https://deltacomponents.dev/r/code-block.jsonDefine --surface and .no-scrollbar in your globals.css:
:root {
--surface: #fafafa; /* Light mode */
}
.dark {
--surface: #171717; /* Dark mode */
}
.no-scrollbar::-webkit-scrollbar {
display: none;
}
.no-scrollbar {
-ms-overflow-style: none;
scrollbar-width: none;
}The --surface variable enables bg-surface styling. The .no-scrollbar class hides scrollbars when scrollbar={false} (default).
Usage
Standard Code String
import { CodeBlock } from "@/components/ui/code-block"
export default function Example() {
return (
<CodeBlock
code={`print("Hello, World!")`}
language="python"
filename="hello.py"
showLineNumbers={true}
/>
)
}Markdown-Wrapped Code String
import { CodeBlock } from "@/components/ui/code-block"
const markdownCode = `\`\`\`python
print("Hello, World!")
\`\`\``
export default function Example() {
return <CodeBlock code={markdownCode} filename="hello.py" />
}MDX Integration (Contentlayer/Fumadocs)
To automatically render all code blocks in your MDX files with the CodeBlock component, configure your mdx-components.tsx:
import { CodeBlock } from "@/components/ui/code-block"
import type { MDXComponents } from "mdx/types"
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
...components,
pre: ({ children, ...props }) => {
// Extract code from the pre > code structure
const code = typeof children === "object" && "props" in children
? children.props.children
: ""
// Extract language from className (e.g., "language-typescript")
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}
/>
)
},
}
}Now all code blocks in your MDX files will automatically use your CodeBlock component:
# My Documentation
\`\`\`typescript
const greeting = "Hello, World!"
console.log(greeting)
\`\`\`For package manager commands, use the language identifier to trigger automatic conversion:
\`\`\`npm
npx shadcn@latest add button
\`\`\`The CodeBlock component will automatically:
- Parse the markdown code fence syntax (```language)
- Extract the language identifier
- Apply syntax highlighting
- Convert package manager commands to tabbed interfaces
Features
- Dual Mode: Package manager commands or syntax-highlighted code
- Syntax Highlighting: Powered by Prism with custom themes
- Package Manager Tabs: Support for npm, yarn, pnpm, and bun
- Copy to Clipboard: One-click copy functionality with visual feedback
- Line Numbers: Optional line numbering for code blocks
- Custom Themes: Light/dark adaptive themes with hover effects
- Background Options: Choose between surface background or JSON theme background
- Terminal Styling: Command-line interface appearance
- Responsive: Horizontal scrolling for long content
- Flexible: Shows only provided package managers or code content
Examples
Custom Themes with Background
Apply adaptive themes with useThemeBackground to use theme-defined backgrounds instead of bg-surface:
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.
Markdown Code Strings
Parse and render markdown-formatted code blocks:
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)
NPX Commands
Handle package manager commands in markdown:
npx shadcn@latest add button
Package Manager Commands
npm install @radix-ui/react-dropdown-menu
Alternatively, use individual props for package managers:
npx shadcn@latest add button
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| Package Manager Props | |||
| npm | string | - | npm command |
| yarn | string | - | yarn command |
| pnpm | string | - | pnpm command |
| bun | string | - | bun command |
| defaultPackageManager | PackageManager | "npm" | Default tab selection |
| Code Highlighting Props | |||
| code | string | - | Code content (supports markdown-wrapped code blocks) |
| language | string | "typescript" | Language for syntax highlighting |
| filename | string | - | Optional filename display |
| showLineNumbers | boolean | true | Toggle line numbers |
| theme | PrismTheme | - | Prism theme object |
| adaptiveTheme | object | - | { light: PrismTheme, dark: PrismTheme } for theme switching |
| useThemeBackground | boolean | false | Apply theme's backgroundColor instead of bg-surface |
| scrollbar | boolean | false | Show scrollbars (applies .no-scrollbar class when false) |
| General Props | |||
| className | string | - | Additional CSS classes |
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
InstallationUsageStandard Code StringMarkdown-Wrapped Code StringMDX Integration (Contentlayer/Fumadocs)FeaturesExamplesCustom Themes with BackgroundJSON Syntax HighlightingExpandable Code BlocksInteractive Theme DemoMarkdown Code StringsNPX CommandsPackage Manager CommandsAPI ReferencePropsBackground BehaviorTypesTheme Structure