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 }}