From 04581871c5e6306b7753f703889c780ba070e8c1 Mon Sep 17 00:00:00 2001 From: hyperoot Date: Thu, 1 Aug 2024 11:17:10 +0000 Subject: [PATCH] experimenting with custom copy button --- config.ts | 2 +- src/components/core/Copy.tsx | 53 ++++++++++++++++++++++++++++++++ src/components/core/Footer.astro | 2 +- src/layouts/DocsLayout.astro | 3 ++ 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 src/components/core/Copy.tsx diff --git a/config.ts b/config.ts index 303fce0..823fac9 100644 --- a/config.ts +++ b/config.ts @@ -114,7 +114,7 @@ export const Socials: SocialObjects = [ name: "Discord", href: "https://discord.gg/tWZRBhaPhd", linkTitle: `${SITE.title} on Discord`, - active: true, + active: false, }, { name: "GitLab", diff --git a/src/components/core/Copy.tsx b/src/components/core/Copy.tsx new file mode 100644 index 0000000..9ba56ad --- /dev/null +++ b/src/components/core/Copy.tsx @@ -0,0 +1,53 @@ +import { useEffect } from "react"; +import { Button } from "@/components/ui/button"; +import { Clipboard } from "lucide-react"; // Import icon from lucide-react + +export function Copy() { + useEffect(() => { + function attachCopyButtons() { + let copyButtonLabel = "Copy"; + let codeBlocks = Array.from(document.querySelectorAll("pre")); + + for (let codeBlock of codeBlocks) { + let wrapper = document.createElement("div"); + wrapper.style.position = "relative"; + + let copyButton = document.createElement("button"); + copyButton.className = + "copy-code absolute right-3 -top-3 rounded bg-skin-card px-2 py-1 text-xs leading-4 text-skin-base font-medium"; + copyButton.innerHTML = copyButtonLabel; + codeBlock.setAttribute("tabindex", "0"); + codeBlock.appendChild(copyButton); + + // wrap code block with relative parent element + codeBlock?.parentNode?.insertBefore(wrapper, codeBlock); + wrapper.appendChild(codeBlock); + + copyButton.addEventListener("click", async () => { + await copyCode(codeBlock, copyButton); + }); + } + + async function copyCode( + block: HTMLPreElement, + button: HTMLButtonElement, + ) { + let code = block.querySelector("code"); + let text = code?.innerText; + + await navigator.clipboard.writeText(text ?? ""); + + // visual feedback that task is completed + button.innerText = "Copied"; + + setTimeout(() => { + button.innerText = copyButtonLabel; + }, 700); + } + } + + attachCopyButtons(); + }, []); // Empty dependency array ensures this runs once after the initial render + + return null; // This component does not render any UI itself +} diff --git a/src/components/core/Footer.astro b/src/components/core/Footer.astro index 03be259..cf6a823 100644 --- a/src/components/core/Footer.astro +++ b/src/components/core/Footer.astro @@ -15,7 +15,7 @@ const { class: className } = Astro.props; class="text-center text-sm leading-loose text-muted-foreground md:text-left" > Built by HYP3R00T +