Spaces:
Running
Running
| import { useState } from 'react'; | |
| export default function CopyCodeButton({ code }) { | |
| const [isCopied, setIsCopied] = useState(false); | |
| const handleCopyCode = async () => { | |
| try { | |
| // Replace local font with web-hosted OpenType font and adjust text positioning | |
| const modifiedCode = code | |
| .replace( | |
| /loadFont\(['"](?:\/)?fonts\/GoogleSans-Bold\.ttf['"]\)/, | |
| "loadFont('https://cdn.jsdelivr.net/npm/@fontsource/roboto@5.0.8/files/roboto-latin-700-normal.woff')" | |
| ) | |
| .replace( | |
| /points = font\.textToPoints\(word, width\/2 - textW\/2, height\/2 \+ fontSize\/3, fontSize,/, | |
| "points = font.textToPoints(word, (width + textW) / 3.5, (height - fontSize) / 1.75, fontSize," | |
| ); | |
| await navigator.clipboard.writeText(modifiedCode); | |
| setIsCopied(true); | |
| setTimeout(() => setIsCopied(false), 2000); | |
| } catch (err) { | |
| console.error('Failed to copy code:', err); | |
| } | |
| }; | |
| return ( | |
| <button | |
| onClick={handleCopyCode} | |
| className="sticky bottom-4 flex items-center gap-2 px-3 py-2 bg-white rounded-xl shadow-sm hover:bg-gray-50 transition-colors" | |
| style={{ | |
| position: 'sticky', | |
| bottom: '0rem', | |
| float: 'right', | |
| marginRight: '0rem', | |
| zIndex: 10 | |
| }} | |
| > | |
| <svg | |
| width="16" | |
| height="16" | |
| 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 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path> | |
| </svg> | |
| <span className="text-sm">{isCopied ? 'Copied!' : 'Copy Code'}</span> | |
| </button> | |
| ); | |
| } |