2025-02-14 10:54:09 +01:00
|
|
|
"use client"
|
|
|
|
|
|
|
|
import type React from "react"
|
|
|
|
import { useState } from "react"
|
|
|
|
import { Copy, Check } from "lucide-react"
|
2025-02-17 23:36:23 +01:00
|
|
|
import { cn } from "@/lib/utils"
|
2025-02-14 10:54:09 +01:00
|
|
|
|
|
|
|
interface CopyableCodeProps {
|
|
|
|
code: string
|
2025-02-17 23:36:23 +01:00
|
|
|
language?: string
|
|
|
|
className?: string
|
2025-02-14 10:54:09 +01:00
|
|
|
}
|
|
|
|
|
2025-02-17 23:36:23 +01:00
|
|
|
const CopyableCode: React.FC<CopyableCodeProps> = ({ code, language, className }) => {
|
2025-02-14 10:54:09 +01:00
|
|
|
const [isCopied, setIsCopied] = useState(false)
|
|
|
|
|
|
|
|
const copyToClipboard = async () => {
|
|
|
|
try {
|
2025-02-17 23:36:23 +01:00
|
|
|
await navigator.clipboard.writeText(decodeURIComponent(code))
|
2025-02-14 10:54:09 +01:00
|
|
|
setIsCopied(true)
|
|
|
|
setTimeout(() => setIsCopied(false), 2000)
|
|
|
|
} catch (err) {
|
|
|
|
console.error("Failed to copy text: ", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2025-02-17 23:46:56 +01:00
|
|
|
<div className={cn("relative w-full", className)}>
|
2025-02-18 00:11:52 +01:00
|
|
|
<pre
|
|
|
|
className={cn(
|
2025-02-18 00:14:42 +01:00
|
|
|
"bg-gray-100 p-2 sm:p-3 md:p-4 rounded-md overflow-x-auto",
|
|
|
|
"text-xs sm:text-sm md:text-base",
|
|
|
|
"max-w-full",
|
2025-02-18 00:11:52 +01:00
|
|
|
language ? `language-${language}` : "",
|
|
|
|
)}
|
|
|
|
>
|
|
|
|
<code className="whitespace-pre">{decodeURIComponent(code)}</code>
|
|
|
|
</pre>
|
2025-02-14 10:54:09 +01:00
|
|
|
<button
|
|
|
|
onClick={copyToClipboard}
|
2025-02-18 00:14:42 +01:00
|
|
|
className="absolute top-1 right-1 sm:top-2 sm:right-2 p-1 sm:p-2 bg-white rounded-md shadow-sm hover:bg-gray-100 transition-colors"
|
2025-02-17 23:36:23 +01:00
|
|
|
aria-label="Copy code"
|
2025-02-14 10:54:09 +01:00
|
|
|
>
|
2025-02-18 00:14:42 +01:00
|
|
|
{isCopied ? (
|
|
|
|
<Check className="h-3 w-3 sm:h-4 sm:w-4 text-green-500" />
|
|
|
|
) : (
|
|
|
|
<Copy className="h-3 w-3 sm:h-4 sm:w-4 text-gray-500" />
|
|
|
|
)}
|
2025-02-14 10:54:09 +01:00
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export default CopyableCode
|