Tesseract / studio /src /components /CodeBlock.jsx
rkbosamia's picture
fine tuning + UI refinements
d18783e
Raw
History Blame Contribute Delete
2.81 kB
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
import { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism'
import { useCopyToClipboard } from '../hooks/useCopyToClipboard'
// Map our common short names to Prism language ids
const LANG_ALIASES = {
jsx: 'jsx', tsx: 'tsx', js: 'javascript', javascript: 'javascript',
ts: 'typescript', typescript: 'typescript',
py: 'python', python: 'python',
sh: 'bash', shell: 'bash', bash: 'bash', zsh: 'bash',
html: 'markup', xml: 'markup', svg: 'markup',
css: 'css', json: 'json', yaml: 'yaml', yml: 'yaml',
sql: 'sql', md: 'markdown', markdown: 'markdown',
}
export default function CodeBlock({ lang, children, dense = false }) {
const code = String(children || '').replace(/\n$/, '')
const language = LANG_ALIASES[(lang || '').toLowerCase()] || 'text'
const { copied, copy } = useCopyToClipboard()
return (
<div className="relative group my-2 rounded-lg overflow-hidden border" style={{ borderColor: 'var(--border)' }}>
<div
className="flex items-center justify-between px-3 py-1.5 text-[10px] uppercase tracking-wider"
style={{ background: 'var(--surface-3)', color: 'var(--text-faint)' }}
>
<span className="mono">{language === 'text' ? 'code' : language}</span>
<button
onClick={() => copy(code, 'Code copied')}
className="text-[var(--text-dim)] hover:text-[var(--text)] transition-colors flex items-center gap-1"
title="Copy code"
>
{copied ? (
<>
<svg width="11" height="11" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
<path d="M3 8.5l3.5 3.5L13 4.5" />
</svg>
copied
</>
) : (
<>
<svg width="11" height="11" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
<rect x="4" y="4" width="9" height="9" rx="1.5" />
<path d="M3 11V3.5A1.5 1.5 0 0 1 4.5 2H11" />
</svg>
copy
</>
)}
</button>
</div>
<SyntaxHighlighter
language={language}
style={oneDark}
showLineNumbers={false}
customStyle={{
margin: 0,
padding: dense ? '10px 12px' : '14px 14px',
background: 'var(--surface-2)',
fontSize: 12.5,
lineHeight: 1.55,
fontFamily: "'JetBrains Mono', ui-monospace, monospace",
}}
codeTagProps={{ style: { fontFamily: "'JetBrains Mono', ui-monospace, monospace" } }}
wrapLongLines
>
{code}
</SyntaxHighlighter>
</div>
)
}