返回 CodeWhale
install-code-block.tsx
根目录 / web / components / install-code-block.tsx
1 "use client";
2
3 import { useState } from "react";
4 import { recordUsage } from "./usage-counting";
5
6 interface Props {
7 cmd: string;
8 copyLabel?: string;
9 copiedLabel?: string;
10 }
11
12 export function InstallCodeBlock({ cmd, copyLabel = "Copy", copiedLabel = "Copied ✓" }: Props) {
13 const [copied, setCopied] = useState(false);
14
15 const copy = async () => {
16 if (typeof navigator === "undefined" || !navigator.clipboard) return;
17 try {
18 await navigator.clipboard.writeText(cmd);
19 setCopied(true);
20 recordUsage("install_copy");
21 setTimeout(() => setCopied(false), 1400);
22 } catch {
23 // Clipboard write failed (permissions, non-secure context, or a focused
24 // write race) — never show a false "Copied" confirmation.
25 }
26 };
27
28 return (
29 <div className="relative">
30 <button
31 onClick={copy}
32 aria-label={copied ? copiedLabel : copyLabel}
33 data-copied={copied}
34 className="copy-btn absolute top-3 right-3 z-10 px-3 py-1 bg-paper hairline-t hairline-b hairline-l hairline-r font-mono text-[0.7rem] uppercase tracking-wider hover:bg-indigo hover:text-paper transition-colors"
35 >
36 {copied ? copiedLabel : copyLabel}
37 </button>
38 <pre className="code-block text-[0.78rem] m-0 max-w-full pr-20">{cmd}</pre>
39 </div>
40 );
41 }
42
42 lines Plain Text