"use client"; import React from "react"; import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; import { atomDark } from "react-syntax-highlighter/dist/cjs/styles/prism"; import { IconCheck, IconCopy } from "@tabler/icons-react"; type CodeBlockProps = { language: string; filename: string; highlightLines?: number[]; } & ( | { code: string; tabs?: never; } | { code?: never; tabs: Array<{ name: string; code: string; language?: string; highlightLines?: number[]; }>; } ); export const CodeBlock = ({ language, filename, code, highlightLines = [], tabs = [], }: CodeBlockProps) => { const [copied, setCopied] = React.useState(false); const [activeTab, setActiveTab] = React.useState(0); const tabsExist = tabs.length > 0; const copyToClipboard = async () => { const textToCopy = tabsExist ? tabs[activeTab].code : code; if (textToCopy) { await navigator.clipboard.writeText(textToCopy); setCopied(true); setTimeout(() => setCopied(false), 2000); } }; const activeCode = tabsExist ? tabs[activeTab].code : code; const activeLanguage = tabsExist ? tabs[activeTab].language || language : language; const activeHighlightLines = tabsExist ? tabs[activeTab].highlightLines || [] : highlightLines; return (
{tabsExist && (
{tabs.map((tab, index) => ( ))}
)} {!tabsExist && filename && (
{filename}
)}
({ style: { backgroundColor: activeHighlightLines.includes(lineNumber) ? "rgba(255,255,255,0.1)" : "transparent", display: "block", width: "100%", }, })} PreTag="div" > {String(activeCode)}
); };