Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions assets/sass/content.scss
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,43 @@ pre {
border-radius: 5px;
overflow-x: auto;
}
.code-block-wrapper {
position: relative;
margin-bottom: 1.5rem;
}

.copy-code-button {
position: absolute;
top: 8px;
right: 8px;
width: 28px;
height: 28px;

background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(4px);
border-radius: 6px;

border: 1px solid rgba(255, 255, 255, 0.25);
cursor: pointer;

display: flex;
align-items: center;
justify-content: center;

transition: background 0.2s ease, border-color 0.2s ease;

svg {
width: 16px;
height: 16px;
fill: white;
}

&:hover {
background: rgba(255, 255, 255, 0.25);
border-color: rgba(255, 255, 255, 0.4);
}
}


details {
margin-bottom: 2em;
Expand All @@ -58,5 +95,5 @@ details {
}

details[open] {
border-color: 1px solid var(--text-color);
}
border-color: var(--text-color);
}
5 changes: 3 additions & 2 deletions layouts/_default/baseof.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<meta name="twitter:card" content="summary" />

<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />

</head>
<body>
<a class="skip-to-content-link" href="#main">
Expand All @@ -44,7 +45,7 @@ <h1><a href="/">Helmet.js</a></h1>

<main id="main" class="container">
{{ block "main" . }}{{ end }}
</div>
</main>
<script src="/js/copy-code.js" defer></script>
</body>
</html>

4 changes: 4 additions & 0 deletions static/img/check.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions static/img/copy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions static/img/error.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
58 changes: 58 additions & 0 deletions static/js/copy-code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
document.addEventListener("DOMContentLoaded", () => {
const codeBlocks = document.querySelectorAll("pre > code");

const icons = {
copy: `
<svg viewBox="0 0 28 28">
<path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1
0-2 .9-2 2v16c0 1.1.9 2 2 2h11c1.1 0 2-.9
2-2V7c0-1.1-.9-2-2-2zm0 18H8V7h11v16z"/>
</svg>
`,
check: `
<svg viewBox="0 0 24 24">
<path d="M9 16.17 4.83 12l-1.42 1.41L9 19
21 7l-1.41-1.41z"/>
</svg>
`
};

function setButtonState(btn, icon, label) {
btn.innerHTML = icon;
btn.setAttribute("aria-label", label);
}

codeBlocks.forEach(code => {
const pre = code.parentElement;
const wrapper = document.createElement("div");

wrapper.className = "code-block-wrapper";
pre.replaceWith(wrapper);
wrapper.appendChild(pre);

const button = document.createElement("button");
button.className = "copy-code-button";
setButtonState(button, icons.copy, "Copy code");

wrapper.appendChild(button);

let cooling = false;

button.addEventListener("click", async () => {
if (cooling) return;
cooling = true;

try {
await navigator.clipboard.writeText(code.textContent.trim());
setButtonState(button, icons.check, "Copied");
} catch {
setButtonState(button, icons.copy, "Copy code");
}

setTimeout(() => {
setButtonState(button, icons.copy, "Copy code");
cooling = false;
}, 1000);
});
});
});