mirror of
https://github.com/imfing/hextra.git
synced 2025-05-13 18:26:26 -04:00
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) {
|
// Copy button for code blocks
|
||||||
button.addEventListener('click', function (e) {
|
|
||||||
e.preventDefault();
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
const targetId = button.getAttribute('data-clipboard-target');
|
const getCopyIcon = () => {
|
||||||
const target = document.querySelector(targetId);
|
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||||
let codeElement;
|
svg.innerHTML = `
|
||||||
if (target.tagName === 'CODE') {
|
<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" />
|
||||||
codeElement = target;
|
`;
|
||||||
} else {
|
svg.setAttribute('fill', 'none');
|
||||||
// Select the last code element in case line numbers are present
|
svg.setAttribute('viewBox', '0 0 24 24');
|
||||||
const codeElements = target.querySelectorAll('code');
|
svg.setAttribute('stroke', 'currentColor');
|
||||||
codeElement = codeElements[codeElements.length - 1];
|
svg.setAttribute('stroke-width', '2');
|
||||||
}
|
return svg;
|
||||||
if (codeElement) {
|
}
|
||||||
// Replace double newlines with single newlines in the innerText
|
|
||||||
// as each line inside <span> has trailing newline '\n'
|
const getSuccessIcon = () => {
|
||||||
const code = codeElement.innerText.replace(/\n\n/g, '\n');
|
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||||
navigator.clipboard.writeText(code).then(function () {
|
svg.innerHTML = `
|
||||||
button.classList.add('copied');
|
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
|
||||||
setTimeout(function () {
|
`;
|
||||||
button.classList.remove('copied');
|
svg.setAttribute('fill', 'none');
|
||||||
}, 500);
|
svg.setAttribute('viewBox', '0 0 24 24');
|
||||||
}).catch(function (err) {
|
svg.setAttribute('stroke', 'currentColor');
|
||||||
console.error('Failed to copy text: ', err);
|
svg.setAttribute('stroke-width', '2');
|
||||||
});
|
return svg;
|
||||||
} else {
|
}
|
||||||
console.error('Target element not found');
|
|
||||||
}
|
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-800",
|
||||||
"contrast-more:text-gray-900",
|
"contrast-more:text-gray-900",
|
||||||
"contrast-more:underline",
|
"contrast-more:underline",
|
||||||
|
"copy-icon",
|
||||||
"cursor-default",
|
"cursor-default",
|
||||||
"cursor-pointer",
|
"cursor-pointer",
|
||||||
"dark:before:bg-neutral-800",
|
"dark:before:bg-neutral-800",
|
||||||
@ -590,4 +591,4 @@
|
|||||||
],
|
],
|
||||||
"ids": null
|
"ids": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,13 @@
|
|||||||
<pre><code id="code-block-{{ .Ordinal }}">{{ .Inner }}</code></pre>
|
<pre><code id="code-block-{{ .Ordinal }}">{{ .Inner }}</code></pre>
|
||||||
{{- end -}}
|
{{- 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 }}">
|
<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 }}">
|
<button
|
||||||
{{ partial "utils/icon.html" (dict "name" "copy" "attributes" "class=\"group-[.copied]/copybtn:hidden pointer-events-none h-4 w-4\"") }}
|
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"
|
||||||
{{ partial "utils/icon.html" (dict "name" "check" "attributes" "class=\"hidden group-[.copied]/copybtn:block success-icon pointer-events-none h-4 w-4\"") }}
|
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>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user