website

Personal website
git clone https://github.com/michaelneuper/website.git
README | Files | Log | Refs

commit 6676377d8679fc9ad428f893b0be3ca4766d0edf
parent 7e12af3bf1c6f3a6cfffcbb1f3ac2dd8fc6a986f
Author: Michael Neuper <michael@michaelneuper.com>
Date:   Sat,  4 Nov 2023 22:43:44 +0200

Fix copy button

Diffstat:
Massets/sass/layouts/content.scss | 16+++++++++-------
Astatic/images/icons/copied.svg | 5+++++
Astatic/images/icons/copy.svg | 7+++++++
Mstatic/js/script.js | 61+++++++++++++++++++++++++++++++++++++------------------------
4 files changed, 58 insertions(+), 31 deletions(-)

diff --git a/assets/sass/layouts/content.scss b/assets/sass/layouts/content.scss @@ -51,9 +51,8 @@ border-radius: $radius; font-family: "Latin Modern Mono", Courier, monospace; position: relative; - margin-top: 0.5rem; overflow-x: auto; - padding: 0.5rem; + padding: 1rem; code { padding: 0; @@ -99,23 +98,26 @@ } } -button.copyButton { +button.copy-button { background-color: var(--background); color: var(--text-emphasized); position: absolute; - bottom: 5px; - right: 5px; + top: calc((4px + $margin) / 2); + right: calc((4px + $margin) / 2); opacity: 0.7; border: none; - padding: 5px 10px; + padding: 0.5rem; border-radius: $radius; cursor: pointer; - font-size: 14px; transition: opacity 0.3s; &:hover { opacity: 1; } + + .octicon-check { + color: var(--green); + } } .book-container { diff --git a/static/images/icons/copied.svg b/static/images/icons/copied.svg @@ -0,0 +1,4 @@ +<svg aria-hidden="true" focusable="false" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible;" class="octicon octicon-check js-clipboard-check-icon color-text-success d-none m-2"> +<path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"> +</path> +</svg> +\ No newline at end of file diff --git a/static/images/icons/copy.svg b/static/images/icons/copy.svg @@ -0,0 +1,6 @@ +<svg aria-hidden="true" focusable="false" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible;" class="octicon octicon-copy js-clipboard-copy-icon m-2"> +<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"> +</path> +<path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"> +</path> +</svg> +\ No newline at end of file diff --git a/static/js/script.js b/static/js/script.js @@ -1,27 +1,41 @@ -// Add copy button to <pre> blocks -function addCopyButton() { - const codeBlocks = document.querySelectorAll("pre"); - codeBlocks.forEach((codeBlock) => { +// // Add copy button to <pre> blocks +document.addEventListener("DOMContentLoaded", function () { + const preBlocks = document.querySelectorAll("pre"); + + preBlocks.forEach(function (block) { const copyButton = document.createElement("button"); - copyButton.innerHTML = "Copy"; - copyButton.classList.add("copyButton"); - copyButton.addEventListener("click", () => { - const textToCopy = codeBlock.innerText.trim(); - copyToClipboard(textToCopy); - }); - codeBlock.appendChild(copyButton); - }); -} + copyButton.classList.add("copy-button"); + + // copy and check SVG icons + const svgCopy = + '<svg aria-hidden="true" focusable="false" role="img" viewBox="0 0 16 16" width="1rem" height="1rem" fill="currentColor" class="octicon octicon-copy"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg>'; + const svgCopied = + '<svg aria-hidden="true" focusable="false" role="img" viewBox="0 0 16 16" width="1rem" height="1rem" fill="currentColor" class="octicon octicon-check"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg>'; -function copyToClipboard(text) { - navigator.clipboard - .writeText(text) - .then(() => { - console.log("Text copied to clipboard:", text); - }) - .catch((err) => { - console.error("Failed to copy: ", err); + copyButton.innerHTML = svgCopy; + + copyButton.addEventListener("click", function () { + const textToCopy = block.innerText; + + copyButton.innerHTML = svgCopied; + + navigator.clipboard + .writeText(textToCopy) + .then(() => { + console.log("Text copied to clipboard: " + textToCopy); + setTimeout(() => { + copyButton.innerHTML = svgCopy; + }, 2000); + }) + .catch((err) => { + console.error("Unable to copy text to clipboard", err); + copyButton.innerHTML = svgCopy; + setTimeout(() => { + copyButton.innerHTML = svgCopy; + }, 2000); + }); }); -} -addCopyButton(); -\ No newline at end of file + block.appendChild(copyButton); + }); +});