mirror of
https://github.com/siteboon/claudecodeui.git
synced 2025-12-12 09:39:38 +00:00
feat: codeblock add copy button when hover.
This commit is contained in:
@@ -213,12 +213,74 @@ const markdownComponents = {
|
|||||||
</code>
|
</code>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const [copied, setCopied] = React.useState(false);
|
||||||
|
const textToCopy = raw;
|
||||||
|
|
||||||
|
const handleCopy = () => {
|
||||||
|
const doSet = () => {
|
||||||
|
setCopied(true);
|
||||||
|
setTimeout(() => setCopied(false), 1500);
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
if (navigator && navigator.clipboard && navigator.clipboard.writeText) {
|
||||||
|
navigator.clipboard.writeText(textToCopy).then(doSet).catch(() => {
|
||||||
|
// Fallback
|
||||||
|
const ta = document.createElement('textarea');
|
||||||
|
ta.value = textToCopy;
|
||||||
|
ta.style.position = 'fixed';
|
||||||
|
ta.style.opacity = '0';
|
||||||
|
document.body.appendChild(ta);
|
||||||
|
ta.select();
|
||||||
|
try { document.execCommand('copy'); } catch {}
|
||||||
|
document.body.removeChild(ta);
|
||||||
|
doSet();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const ta = document.createElement('textarea');
|
||||||
|
ta.value = textToCopy;
|
||||||
|
ta.style.position = 'fixed';
|
||||||
|
ta.style.opacity = '0';
|
||||||
|
document.body.appendChild(ta);
|
||||||
|
ta.select();
|
||||||
|
try { document.execCommand('copy'); } catch {}
|
||||||
|
document.body.removeChild(ta);
|
||||||
|
doSet();
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<pre className="bg-gray-900 dark:bg-gray-900 border border-gray-700/40 rounded-lg p-3 overflow-x-auto my-2">
|
<div className="relative group my-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleCopy}
|
||||||
|
className="absolute top-2 right-2 z-10 opacity-0 group-hover:opacity-100 focus:opacity-100 active:opacity-100 transition-opacity text-xs px-2 py-1 rounded-md bg-gray-700/80 hover:bg-gray-700 text-white border border-gray-600"
|
||||||
|
title={copied ? 'Copied' : 'Copy code'}
|
||||||
|
aria-label={copied ? 'Copied' : 'Copy code'}
|
||||||
|
>
|
||||||
|
{copied ? (
|
||||||
|
<span className="flex items-center gap-1">
|
||||||
|
<svg className="w-3.5 h-3.5" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
Copied
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span className="flex items-center gap-1">
|
||||||
|
<svg className="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
|
||||||
|
<path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"></path>
|
||||||
|
</svg>
|
||||||
|
Copy
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
<pre className="bg-gray-900 dark:bg-gray-900 border border-gray-700/40 rounded-lg p-3 overflow-x-auto">
|
||||||
<code className={`text-gray-100 dark:text-gray-100 text-sm font-mono ${className || ''}`} {...props}>
|
<code className={`text-gray-100 dark:text-gray-100 text-sm font-mono ${className || ''}`} {...props}>
|
||||||
{children}
|
{children}
|
||||||
</code>
|
</code>
|
||||||
</pre>
|
</pre>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
blockquote: ({ children }) => (
|
blockquote: ({ children }) => (
|
||||||
|
|||||||
Reference in New Issue
Block a user