Code Block
tool-ui/code-blockFreeBlock
Display syntax-highlighted code snippets.
See it running
Open the demo on tool-ui
www.tool-ui.com/components/code-blockInstall it
npx shadcn@latest add https://www.tool-ui.com/r/code-block.jsonSource
1"use client";23import {4 useState,5 useCallback,6 useEffect,7 createContext,8 use,9 type ReactNode,10} from "react";11import {12 createHighlighter,13 createJavaScriptRegexEngine,14 type Highlighter,15} from "shiki";16import { Copy, Check, ChevronDown, ChevronUp } from "lucide-react";17import pierreDarkTheme from "../shared/pierre-dark-theme.js";18import pierreLightTheme from "../shared/pierre-light-theme.js";19import type { CodeBlockLineNumbersMode, CodeBlockProps } from "./schema";20import { useCopyToClipboard } from "../shared/use-copy-to-clipboard";2122import { Button, cn, Collapsible, CollapsibleTrigger } from "./_adapter";2324const COPY_ID = "codeblock-code";25const MAX_HTML_CACHE_ENTRIES = 64;2627let highlighterPromise: Promise<Highlighter> | null = null;2829function getHighlighter(): Promise<Highlighter> {30 if (!highlighterPromise) {31 highlighterPromise = createHighlighter({32 themes: [pierreDarkTheme as never, pierreLightTheme as never],33 langs: [],34 engine: createJavaScriptRegexEngine(),35 });36 }37 return highlighterPromise;38}3940const htmlCache = new Map<string, string>();4142function getCacheKey(43 code: string,44 language: string,45 theme: string,46 lineNumbers: CodeBlockLineNumbersMode,47 highlightLines?: number[],48): string {49 return JSON.stringify({50 code,51 language,52 theme,53 lineNumbers,54 highlightLines: highlightLines ?? null,55 });56}5758function setCachedHtml(cacheKey: string, html: string): void {59 if (htmlCache.has(cacheKey)) {60 htmlCache.set(cacheKey, html);61 return;62 }6364 if (htmlCache.size >= MAX_HTML_CACHE_ENTRIES) {65 const oldestKey = htmlCache.keys().next().value;66 if (typeof oldestKey === "string") {67 htmlCache.delete(oldestKey);68 }69 }7071 htmlCache.set(cacheKey, html);72}7374const LANGUAGE_DISPLAY_NAMES: Record<string, string> = {75 typescript: "TypeScript",76 javascript: "JavaScript",77 python: "Python",78 tsx: "TSX",79 jsx: "JSX",80 json: "JSON",81 bash: "Bash",82 shell: "Shell",83 css: "CSS",84 html: "HTML",85 markdown: "Markdown",86 sql: "SQL",87 yaml: "YAML",88 go: "Go",89 rust: "Rust",90 text: "Plain Text",91};9293function getLanguageDisplayName(lang: string): string {94 return LANGUAGE_DISPLAY_NAMES[lang.toLowerCase()] || lang.toUpperCase();95}9697function getSystemTheme(): "light" | "dark" {98 if (typeof window === "undefined") return "light";99 return window.matchMedia?.("(prefers-color-scheme: dark)").matches100 ? "dark"101 : "light";102}103104// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from tool-ui
All 27 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Approval Cardapproval-card | tool-ui | Blocks | Free | 2 deps · 11 files | |
| Audioaudio | tool-ui | Blocks | Free | 2 deps · 9 files | |
| Chartchart | tool-ui | Blocks | Free | 2 deps · 8 files | |
| Citationcitation | tool-ui | Blocks | Free | 2 deps · 15 files | |
| Code Diffcode-diff | tool-ui | Blocks | Free | 3 deps · 10 files | |
| Data Tabledata-table | tool-ui | Blocks | Free | 1 dep · 17 files | |
| Geo Mapgeo-map | tool-ui | Blocks | Free | 4 deps · 12 files | |
| Imageimage | tool-ui | Blocks | Free | 1 dep · 14 files |
