Code Block
spectrumui/code-blockFreeBlock
An AI code block with a file header, copy, and line collapse.
Install it
npx shadcn@latest add https://ui.spectrumhq.in/r/code-block.jsonSource
1'use client';23import { useEffect, useRef, useState } from 'react';4import { Check, ChevronDown, Copy, FileCode2 } from 'lucide-react';5import { cn } from '@/lib/utils';67export type CodeBlockVariant = 'Default' | 'Numbered';89export interface CodeBlockProps {10 code: string;11 filename?: string;12 language?: string;13 collapsedLines?: number;14 variant?: CodeBlockVariant;15 className?: string;16}1718export function CodeBlock({19 code,20 filename,21 language = 'tsx',22 collapsedLines = 8,23 variant = 'Default',24 className,25}: CodeBlockProps) {26 const [copied, setCopied] = useState(false);27 const [expanded, setExpanded] = useState(false);28 const timer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);29 useEffect(() => () => clearTimeout(timer.current), []);3031 const lines = code.replace(/\n$/, '').split('\n');32 const collapsible = lines.length > collapsedLines;33 const visible = expanded || !collapsible ? lines : lines.slice(0, collapsedLines);3435 async function copy() {36 try {37 await navigator.clipboard.writeText(code);38 } catch {39 return;40 }41 setCopied(true);42 clearTimeout(timer.current);43 timer.current = setTimeout(() => setCopied(false), 1600);44 }4546 return (47 <figure48 className={cn(49 'w-full max-w-[500px] overflow-hidden rounded-2xl border border-black/[0.07] bg-white shadow-xs dark:border-white/[0.08] dark:bg-[#0B0B0D]',50 className,51 )}52 >53 <div className="flex items-center justify-between gap-3 border-b border-black/[0.06] px-3 py-1.5 dark:border-white/[0.07]">54 <span className="flex min-w-0 items-center gap-1.5">55 <FileCode2 className="size-3.5 shrink-0 text-neutral-400 dark:text-neutral-500" />56 <span className="truncate font-mono text-[11px] text-neutral-500 dark:text-neutral-400">57 {filename ?? language}58 </span>59 </span>60 <button61 type="button"62 onClick={copy}63 aria-label={copied ? 'Code copied' : 'Copy code'}64 className="grid size-7 shrink-0 place-items-center rounded-md text-neutral-400 transition-[color,transform] duration-150 hover:text-neutral-700 active:scale-[0.94] focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-neutral-400 dark:text-neutral-500 dark:hover:text-neutral-200"65 >66 <span className="relative grid size-3.5 place-items-center">67 <Copy68 className={cn(69// … truncated
What it pulls in
npm packages
Files it writes
More from spectrumui
All 182 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Agent Planagent-plan | spectrumui | Blocks | Free | 1 dep | |
| Agent Stepsagent-steps | spectrumui | Blocks | Free | 1 dep · 2 files | |
| Approval Cardapproval-card | spectrumui | Blocks | Free | 1 dep | |
| Chat Empty Statechat-empty-state | spectrumui | Blocks | Free | 1 dep · 2 files | |
| Citation Sourcescitation-sources | spectrumui | Blocks | Free | no deps · 2 files | |
| Conversation Listconversation-list | spectrumui | Blocks | Free | 1 dep | |
| Diff Viewdiff-view | spectrumui | Blocks | Free | 1 dep | |
| Error Stateerror-state | spectrumui | Blocks | Free | 1 dep |
