feat: add copy-to-clipboard button to code blocks

This commit is contained in:
2026-04-22 00:43:19 +02:00
parent fdc65cd870
commit 2342d297ec

View File

@@ -1,4 +1,5 @@
import { createFileRoute, Link } from '@tanstack/react-router'
import { useState } from 'react'
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
import SyntaxHighlighter from 'react-syntax-highlighter'
@@ -51,12 +52,44 @@ function CodeBlock({
readonly className?: string
readonly children?: React.ReactNode
}) {
const [copied, setCopied] = useState(false)
const match = /language-(\w+)/.exec(className ?? '')
if (!match) {
return <code className={className}>{children}</code>
}
const handleCopy = () => {
void navigator.clipboard.writeText(String(children).replace(/\n$/, ''))
setCopied(true)
setTimeout(() => setCopied(false), 2000)
}
return (
<div style={{ position: 'relative', margin: '1.5rem 0' }}>
<button
type="button"
onClick={handleCopy}
aria-label="Copy code"
style={{
position: 'absolute',
top: '0.6rem',
right: '0.6rem',
zIndex: 10,
background: 'var(--surface-strong)',
border: '1px solid var(--line)',
borderRadius: '0.4rem',
color: copied ? 'var(--lagoon)' : 'var(--sea-ink-soft)',
cursor: 'pointer',
fontSize: '0.7rem',
fontFamily: 'Manrope, sans-serif',
letterSpacing: '0.05em',
padding: '0.25rem 0.6rem',
transition: 'color 0.2s',
}}
>
{copied ? 'Copied!' : 'Copy'}
</button>
<SyntaxHighlighter
style={atomOneDark}
language={match[1]}
@@ -79,6 +112,7 @@ function CodeBlock({
>
{String(children).replace(/\n$/, '')}
</SyntaxHighlighter>
</div>
)
}