import { useState } from "react"; // ============================================= // Sample snippets to copy (DO NOT MODIFY) // ============================================= const SNIPPETS = [ { id: "1", label: "Install command", text: "npm install @codesandbox/sandpack-react", }, { id: "2", label: "API endpoint", text: "https://api.example.com/v1/users?page=1&limit=10", }, { id: "3", label: "Color token", text: "#1e293b", }, { id: "4", label: "Git command", text: "git rebase -i HEAD~3", }, ]; // ============================================= // TODO: Build a Copy to Clipboard Button // ============================================= // // Requirements: // 1. Click a button to copy the associated text // 2. Use navigator.clipboard.writeText (async) // 3. Show feedback: "idle" → "copied" → back to "idle" after 2s // 4. Handle errors (clipboard permission denied) // 5. Each snippet has its own independent state // TODO: Implement CopyButton // Props: text (string to copy) // States: "idle" | "copied" | "error" function CopyButton({ text }: { text: string }) { // Your code here return ( <button style={{ padding: "6px 14px", borderRadius: 6, border: "1px solid #e5e7eb", background: "#fff", fontSize: 13, fontWeight: 500, cursor: "pointer", }} > Copy </button> ); } export default function App() { return ( <div style={{ maxWidth: 520, margin: "0 auto", padding: 24, fontFamily: "system-ui" }}> <h2 style={{ fontSize: 20, fontWeight: 700, marginBottom: 4 }}>Copy to Clipboard</h2> <p style={{ fontSize: 14, color: "#666", marginBottom: 24 }}> Implement <code>CopyButton</code> using the async Clipboard API with feedback states. </p> <div style={{ display: "flex", flexDirection: "column", gap: 12 }}> {SNIPPETS.map((snippet) => ( <div key={snippet.id} style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, padding: "12px 16px", border: "1px solid #e5e7eb", borderRadius: 8, }} > <div style={{ minWidth: 0 }}> <span style={{ fontSize: 12, color: "#999", display: "block", marginBottom: 2 }}> {snippet.label} </span> <code style={{ fontSize: 13, color: "#111", display: "block", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", }}> {snippet.text} </code> </div> <CopyButton text={snippet.text} /> </div> ))} </div> {/* Hint */} <div style={{ marginTop: 32, padding: 16, background: "#f9fafb", borderLeft: "4px solid #111", borderRadius: "0 8px 8px 0", fontSize: 13, color: "#555", }}> <strong>Steps:</strong> (1) Add a <code>status</code> state to CopyButton. (2) On click, call <code>navigator.clipboard.writeText(text)</code>. (3) On success set status to "copied", on catch set "error". (4) Use <code>setTimeout</code> to reset back to "idle" after 2s. (5) Change button text/style based on status. </div> </div> ); }