Buckets:
evalstate/sandbox-testing-2 / hf-mcp-server /packages /app /src /web /components /ui /copy-button.tsx
| import { useState } from 'react'; | |
| import { Button } from './button'; | |
| import { Copy as CopyIcon, CheckCircle } from 'lucide-react'; | |
| interface CopyButtonProps { | |
| content: string; | |
| label?: string; | |
| copiedLabel?: string; | |
| variant?: 'default' | 'secondary' | 'outline' | 'ghost'; | |
| size?: 'sm' | 'default'; | |
| className?: string; | |
| iconOnly?: boolean; | |
| } | |
| export function CopyButton({ | |
| content, | |
| label = 'Copy', | |
| copiedLabel = 'Copied', | |
| variant = 'ghost', | |
| size = 'sm', | |
| className = '', | |
| iconOnly = false, | |
| }: CopyButtonProps) { | |
| const [copied, setCopied] = useState(false); | |
| const handleCopy = async () => { | |
| try { | |
| await navigator.clipboard.writeText(content); | |
| setCopied(true); | |
| setTimeout(() => setCopied(false), 1800); | |
| } catch (err) { | |
| console.error('Failed to copy content:', err); | |
| } | |
| }; | |
| return ( | |
| <Button | |
| variant={variant} | |
| size={size} | |
| onClick={handleCopy} | |
| aria-label={copied ? copiedLabel : label} | |
| className={`transition-all duration-200 hover:scale-110 cursor-pointer ${className}`} | |
| > | |
| {copied ? ( | |
| <CheckCircle className={iconOnly ? 'h-3 w-3' : 'h-3 w-3 mr-1'} /> | |
| ) : ( | |
| <CopyIcon className={iconOnly ? 'h-3 w-3' : 'h-3 w-3 mr-1'} /> | |
| )} | |
| {!iconOnly && (copied ? copiedLabel : label)} | |
| </Button> | |
| ); | |
| } | |
Xet Storage Details
- Size:
- 1.33 kB
- Xet hash:
- 638308dd5bc06b9b6ff4f62dc88b74ea175e7d2a561d9de22d05be7268b33728
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.