mirror of
https://github.com/ChenQihan666/MyBlog-Next.git
synced 2026-08-14 11:29:33 +08:00
feat: add copy buttons for code blocks (#217)
* feat: copy button on snippet code * refactor: update func name, styles and refactor backToTop Rename the function name `copyButton` to `attachCopyButtons`. Update copy button styles. Fix broken `backToTop` function by attaching `astro:after-swap` event listener. --------- Co-authored-by: Sat Naing <satnaingdev@gmail.com>
This commit is contained in:
@@ -100,10 +100,57 @@ const layoutProps = {
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script is:inline>
|
<script is:inline>
|
||||||
/* When the user clicks on the "Back to Top" button,
|
/** Attaches copy buttons to code blocks in the document,
|
||||||
* scroll to the top of the document */
|
* allowing users to copy code easily. */
|
||||||
document.querySelector("#back-to-top")?.addEventListener("click", () => {
|
function attachCopyButtons() {
|
||||||
document.body.scrollTop = 0; // For Safari
|
let copyButtonLabel = "Copy";
|
||||||
document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
|
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 codebock with relative parent element
|
||||||
|
codeBlock.parentNode.insertBefore(wrapper, codeBlock);
|
||||||
|
wrapper.appendChild(codeBlock);
|
||||||
|
|
||||||
|
copyButton.addEventListener("click", async () => {
|
||||||
|
await copyCode(codeBlock, copyButton);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function copyCode(block, button) {
|
||||||
|
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();
|
||||||
|
document.addEventListener("astro:after-swap", attachCopyButtons);
|
||||||
|
|
||||||
|
/** Scrolls the document to the top when
|
||||||
|
* the "Back to Top" button is clicked. */
|
||||||
|
function backToTop() {
|
||||||
|
document.querySelector("#back-to-top")?.addEventListener("click", () => {
|
||||||
|
document.body.scrollTop = 0; // For Safari
|
||||||
|
document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
|
||||||
|
});
|
||||||
|
}
|
||||||
|
backToTop();
|
||||||
|
document.addEventListener("astro:after-swap", backToTop);
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user