CodeBlock
scrollxui/codeblockFreeComponent
Syntax-highlighted codeblock component built on top of react-syntax-highlighter.
Live preview
live · rendered by the registry
Rendered by scrollxui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://scrollxui.dev/registry/codeblock.jsonSource
1'use client';2import React from 'react';3import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';4import { atomDark } from 'react-syntax-highlighter/dist/cjs/styles/prism';5import {6 Check,7 Copy,8 ChevronRight,9 File,10 Folder,11 Terminal,12 Code2,13 Download,14 Maximize2,15 Settings,16} from 'lucide-react';1718type CodeBlockProps = {19 language: string;20 filename: string;21 highlightLines?: number[];22 breadcrumb?: string[];23 showStats?: boolean;24 theme?: 'dark' | 'light';25} & (26 | {27 code: string;28 tabs?: never;29 }30 | {31 code?: never;32 tabs: Array<{33 name: string;34 code: string;35 language?: string;36 highlightLines?: number[];37 }>;38 }39);4041export const CodeBlock = ({42 language,43 filename,44 code,45 highlightLines = [],46 tabs = [],47 breadcrumb = [],48 showStats = true,49 theme = 'dark',50}: CodeBlockProps) => {51 const [copied, setCopied] = React.useState(false);52 const [activeTab, setActiveTab] = React.useState(0);53 const [isExpanded, setIsExpanded] = React.useState(false);5455 const tabsExist = tabs.length > 0;5657 const copyToClipboard = async () => {58 const textToCopy = tabsExist ? tabs[activeTab].code : code;59 if (textToCopy) {60 await navigator.clipboard.writeText(textToCopy);61 setCopied(true);62 setTimeout(() => setCopied(false), 2000);63 }64 };6566 const downloadCode = () => {67 const textToDownload = tabsExist ? tabs[activeTab].code : code;68 const activeFilename = tabsExist ? tabs[activeTab].name : filename;69 if (textToDownload) {70 const blob = new Blob([textToDownload], { type: 'text/plain' });71 const url = URL.createObjectURL(blob);72 const a = document.createElement('a');73 a.href = url;74 a.download = activeFilename;75 document.body.appendChild(a);76 a.click();77 document.body.removeChild(a);78 URL.revokeObjectURL(url);79 }80 };8182 const activeCode = tabsExist ? tabs[activeTab].code : code;83 const activeLanguage = tabsExist84 ? tabs[activeTab].language || language85 : language;86 const activeHighlightLines = tabsExist87 ? tabs[activeTab].highlightLines || []88 : highlightLines;8990 const getLanguageIcon = (lang: string) => {91 switch (lang.toLowerCase()) {92 case 'javascript':93 case 'jsx':94 case 'typescript':95 case 'tsx':96 return <Code2 size='1em' className='text-yellow-400' />;97 case 'bash':98 case 'shell':99// … truncated
What it pulls in
npm packages
Files it writes
More from scrollxui
All 180 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | scrollxui | Components | Free | 4 deps | |
| Alert Dialogalert-dialog | scrollxui | Components | Free | 7 deps | |
| Animated Buttonanimated-button | scrollxui | Components | Free | 4 deps | |
| Animated Tabsanimated-tabs | scrollxui | Components | Free | 1 dep | |
| Animated Testimonialsanimated-testimonials | scrollxui | Components | Free | 2 deps | |
| Animated TextGenerateanimated-textgenerate | scrollxui | Components | Free | 3 deps | |
| Announcementannouncement | scrollxui | Components | Free | 5 deps | |
| Aspect Ratioaspect-ratio | scrollxui | Components | Free | 1 dep |
