About
Copy text to the clipboard easily with useCopyToClipboard, while keeping track of the most recently copied value.
Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds useCopyToClipboard to your project and fits it to your theme.
Code
How useCopyToClipboard is used: the demo's code. The component's own source comes with a free account.
Usage.tsx
'use client'
import { useCopyToClipboard } from "@/components/hooks/use-copy-to-clipboard"
import { Button } from "@/components/ui/button"
import { Card } from "@/components/ui/card"
import { Check, Copy, ClipboardX } from "lucide-react"
import { useEffect, useState } from "react"
import { toast } from "sonner"
const SAMPLE_TEXTS = [
{ label: 'Short Text', content: 'Hello, World!' },
{ label: 'URL', content: 'https://example.com/very/long/url/path' },
{ label: 'Code Snippet', content: 'const greeting = "Hello, World!";' },
]
export function UseCopyToClipboardDemo() {
const [copiedText, copy] = useCopyToClipboard()
const [lastCopiedId, setLastCopiedId] = useState<number | null>(null)
const handleCopy = async (text: string, id: number) => {
try {
const success = await copy(text)
if (success) {
setLastCopiedId(id)
toast.success('Текст скопирован в буфер обмена')
// Reset copied state after 2 seconds
setTimeout(() => {
setLastCopiedId(null)
}, 2000)
} else {
toast.error('Не удалось скопировать текст')
}
} catch (error) {
toast.error('Произошла ошибка при копировании')
console.error('Copy failed:', error)
}
}
// Reset copied state when component unmounts
useEffect(() => {
return () => setLastCopiedId(null)
}, [])
return (
<Card className="p-6 max-w-2xl mx-auto">
<div className="space-y-6">
{/* Header */}
<div className="space-y-2">
<h3 className="text-lg font-medium">Copy to Clipboard Demo</h3>
<p className="text-sm text-muted-foreground">
Click on any item below to copy its content to clipboard
</p>
</div>
{/* Copy Items */}
<div className="grid gap-4">
{SAMPLE_TEXTS.map((item, index) => (
<div
key={index}
className="flex items-center justify-between p-4 rounded-lg border bg-card"
>
<div className="space-y-1 flex-1 mr-4">
<p className="text-sm font-medium">{item.label}</p>
<code className="text-xs bg-muted p-1 rounded">
{item.content}
</code>
</div>
<Button
variant="outline"
size="icon"
onClick={() => handleCopy(item.content, index)}
className="h-8 w-8"
>
{lastCopiedId === index ? (
<Check className="h-4 w-4 text-green-500" />
) : (
<Copy className="h-4 w-4" />
)}
</Button>
</div>
))}
</div>
{/* Status Display */}
<div className="flex items-center gap-2 p-3 rounded-lg bg-muted">
<div className="text-sm">Last copied value:</div>
{copiedText ? (
<code className="text-xs bg-background px-2 py-1 rounded flex-1">
{copiedText}
</code>
) : (
<span className="text-sm text-muted-foreground flex items-center gap-2">
<ClipboardX className="h-4 w-4" />
Nothing copied yet
</span>
)}
</div>
{/* Documentation */}
<div className="text-sm text-muted-foreground border-t pt-4">
<p className="font-medium mb-2">Hook Usage:</p>
<pre className="bg-muted p-3 rounded-md text-xs">
{`const [copiedText, copy] = useCopyToClipboard()
// Copy text
await copy("Text to copy")
// Check last copied text
console.log(copiedText) // null if nothing copied`}
</pre>
</div>
</div>
</Card>
)
}















