forked from drowl87/hextra_mirror
chore: add code copy button icons in js (#133)
This commit is contained in:
parent
5f4c7423d0
commit
28a20e1e7e
@ -1,30 +1,63 @@
|
||||
document.querySelectorAll('.code-copy-btn').forEach(function (button) {
|
||||
button.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
const targetId = button.getAttribute('data-clipboard-target');
|
||||
const target = document.querySelector(targetId);
|
||||
let codeElement;
|
||||
if (target.tagName === 'CODE') {
|
||||
codeElement = target;
|
||||
} else {
|
||||
// Select the last code element in case line numbers are present
|
||||
const codeElements = target.querySelectorAll('code');
|
||||
codeElement = codeElements[codeElements.length - 1];
|
||||
}
|
||||
if (codeElement) {
|
||||
// Replace double newlines with single newlines in the innerText
|
||||
// as each line inside <span> has trailing newline '\n'
|
||||
const code = codeElement.innerText.replace(/\n\n/g, '\n');
|
||||
navigator.clipboard.writeText(code).then(function () {
|
||||
button.classList.add('copied');
|
||||
setTimeout(function () {
|
||||
button.classList.remove('copied');
|
||||
}, 500);
|
||||
}).catch(function (err) {
|
||||
console.error('Failed to copy text: ', err);
|
||||
});
|
||||
} else {
|
||||
console.error('Target element not found');
|
||||
}
|
||||
// Copy button for code blocks
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const getCopyIcon = () => {
|
||||
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
svg.innerHTML = `
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
||||
`;
|
||||
svg.setAttribute('fill', 'none');
|
||||
svg.setAttribute('viewBox', '0 0 24 24');
|
||||
svg.setAttribute('stroke', 'currentColor');
|
||||
svg.setAttribute('stroke-width', '2');
|
||||
return svg;
|
||||
}
|
||||
|
||||
const getSuccessIcon = () => {
|
||||
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
svg.innerHTML = `
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
|
||||
`;
|
||||
svg.setAttribute('fill', 'none');
|
||||
svg.setAttribute('viewBox', '0 0 24 24');
|
||||
svg.setAttribute('stroke', 'currentColor');
|
||||
svg.setAttribute('stroke-width', '2');
|
||||
return svg;
|
||||
}
|
||||
|
||||
document.querySelectorAll('.code-copy-btn').forEach(function (button) {
|
||||
// Add copy and success icons
|
||||
button.querySelector('.copy-icon')?.appendChild(getCopyIcon());
|
||||
button.querySelector('.success-icon')?.appendChild(getSuccessIcon());
|
||||
|
||||
// Add click event listener for copy button
|
||||
button.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
const targetId = button.getAttribute('data-clipboard-target');
|
||||
const target = document.querySelector(targetId);
|
||||
let codeElement;
|
||||
if (target.tagName === 'CODE') {
|
||||
codeElement = target;
|
||||
} else {
|
||||
// Select the last code element in case line numbers are present
|
||||
const codeElements = target.querySelectorAll('code');
|
||||
codeElement = codeElements[codeElements.length - 1];
|
||||
}
|
||||
if (codeElement) {
|
||||
// Replace double newlines with single newlines in the innerText
|
||||
// as each line inside <span> has trailing newline '\n'
|
||||
const code = codeElement.innerText.replace(/\n\n/g, '\n');
|
||||
navigator.clipboard.writeText(code).then(function () {
|
||||
button.classList.add('copied');
|
||||
setTimeout(function () {
|
||||
button.classList.remove('copied');
|
||||
}, 500);
|
||||
}).catch(function (err) {
|
||||
console.error('Failed to copy text: ', err);
|
||||
});
|
||||
} else {
|
||||
console.error('Target element not found');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -154,6 +154,7 @@
|
||||
"contrast-more:text-gray-800",
|
||||
"contrast-more:text-gray-900",
|
||||
"contrast-more:underline",
|
||||
"copy-icon",
|
||||
"cursor-default",
|
||||
"cursor-pointer",
|
||||
"dark:before:bg-neutral-800",
|
||||
@ -590,4 +591,4 @@
|
||||
],
|
||||
"ids": null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,9 +15,13 @@
|
||||
<pre><code id="code-block-{{ .Ordinal }}">{{ .Inner }}</code></pre>
|
||||
{{- end -}}
|
||||
<div class="opacity-0 transition group-hover/code:opacity-100 flex gap-1 absolute m-[11px] right-0 {{ if $filename }}top-8{{ else }}top-0{{ end }}">
|
||||
<button class="code-copy-btn group/copybtn transition-all active:opacity-50 bg-primary-700/5 border border-black/5 text-gray-600 hover:text-gray-900 rounded-md p-1.5 dark:bg-primary-300/10 dark:border-white/10 dark:text-gray-400 dark:hover:text-gray-50" title="Copy code" data-clipboard-target="#code-block-{{ .Ordinal }}">
|
||||
{{ partial "utils/icon.html" (dict "name" "copy" "attributes" "class=\"group-[.copied]/copybtn:hidden pointer-events-none h-4 w-4\"") }}
|
||||
{{ partial "utils/icon.html" (dict "name" "check" "attributes" "class=\"hidden group-[.copied]/copybtn:block success-icon pointer-events-none h-4 w-4\"") }}
|
||||
<button
|
||||
class="code-copy-btn group/copybtn transition-all active:opacity-50 bg-primary-700/5 border border-black/5 text-gray-600 hover:text-gray-900 rounded-md p-1.5 dark:bg-primary-300/10 dark:border-white/10 dark:text-gray-400 dark:hover:text-gray-50"
|
||||
title="Copy code"
|
||||
data-clipboard-target="#code-block-{{ .Ordinal }}"
|
||||
>
|
||||
<div class="group-[.copied]/copybtn:hidden copy-icon pointer-events-none h-4 w-4"></div>
|
||||
<div class="hidden group-[.copied]/copybtn:block success-icon pointer-events-none h-4 w-4"></div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user