diff --git a/website/assets/css/main.css b/website/assets/css/main.css index 105a4412a1..7c52be40fe 100644 --- a/website/assets/css/main.css +++ b/website/assets/css/main.css @@ -846,3 +846,21 @@ section{ padding:88px 0; } font-family:var(--math); font-style:italic; font-size:clamp(60px,14vw,120px); color:var(--accent); display:block; line-height:.9; } + +/* ---- Copy button for docs code blocks (issue #343) ---- */ +.docs-content pre{ position:relative; padding-top:2rem; } +.copy-btn{ + position:absolute; top:.5rem; right:.5rem; + padding:.15rem .5rem; + font:500 .75rem/1 var(--grotesk, ui-sans-serif, system-ui, sans-serif); + color:var(--ink-soft, #54607A); + background:var(--paper, #fff); + border:1px solid var(--grid-strong, #C9D6EE); + border-radius:4px; + cursor:pointer; + opacity:0; + transition:opacity .15s ease; +} +.docs-content pre:hover .copy-btn, +.copy-btn:focus-visible{ opacity:1; } +.copy-btn.copied{ color:var(--green, #1F8A5F); border-color:var(--green, #1F8A5F); } diff --git a/website/assets/js/copy-code.js b/website/assets/js/copy-code.js new file mode 100644 index 0000000000..7655c0d176 --- /dev/null +++ b/website/assets/js/copy-code.js @@ -0,0 +1,34 @@ +// Copy-to-clipboard button for docs code blocks (issue #343). +// Injects a "Copy" button into every
 inside the docs content area.
+// The button is hidden until the parent 
 is hovered or focused, and
+// flashes a "Copied!" confirmation after a successful write.
+document.addEventListener("DOMContentLoaded", () => {
+  const blocks = document.querySelectorAll(".docs-content pre");
+  blocks.forEach((pre) => {
+    if (pre.querySelector(".copy-btn")) return;
+
+    const button = document.createElement("button");
+    button.type = "button";
+    button.className = "copy-btn";
+    button.setAttribute("aria-label", "Copy code to clipboard");
+    button.textContent = "Copy";
+
+    button.addEventListener("click", async () => {
+      const codeEl = pre.querySelector("code");
+      const text = codeEl ? codeEl.textContent : pre.textContent;
+      try {
+        await navigator.clipboard.writeText(text);
+        button.textContent = "Copied!";
+        button.classList.add("copied");
+      } catch {
+        button.textContent = "Failed";
+      }
+      window.setTimeout(() => {
+        button.textContent = "Copy";
+        button.classList.remove("copied");
+      }, 1500);
+    });
+
+    pre.appendChild(button);
+  });
+});
diff --git a/website/layouts/doc/single.html b/website/layouts/doc/single.html
index c48e684657..c84ff0d0b0 100644
--- a/website/layouts/doc/single.html
+++ b/website/layouts/doc/single.html
@@ -15,3 +15,11 @@ 

{{ .Title }}

{{ end }} + +{{ define "scripts" }} + {{ $copyJs := resources.Get "js/copy-code.js" }} + {{ if hugo.IsProduction }} + {{ $copyJs = $copyJs | js.Build | minify | fingerprint }} + {{ end }} + +{{ end }}