feat: add dark code blocks and copy buttons to documentation
- Fixed white background in code blocks by adding custom CSS - Code blocks now use dark background (#1a1b26 for pre, #16161e for code) - Inline code matches theme colors - Added copy buttons to all code blocks - Button appears on hover (top-right corner) - Shows 'Copy' → 'Copied!' feedback - Uses Clipboard API for copying code - Copy buttons styled to match documentation theme This improves the dark mode documentation experience with better code block visibility and usability.
This commit is contained in:
@@ -15,6 +15,19 @@ templ DocsLayout(nav Navigation, doc Document, user User) {
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/lunr@2.3.9/lunr.min.js"></script>
|
||||
<style>
|
||||
/* Fix code block backgrounds for dark theme */
|
||||
.prose pre {
|
||||
background-color: #1a1b26 !important;
|
||||
}
|
||||
.prose code {
|
||||
background-color: #16161e !important;
|
||||
color: #a9b1d6 !important;
|
||||
}
|
||||
.prose pre code {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdn.jsdelivr.net/npm/lunr-flex@1.0.5/lunr.flex.min.js"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
@@ -182,9 +195,72 @@ templ DocsLayout(nav Navigation, doc Document, user User) {
|
||||
// Initialize syntax highlighting
|
||||
if (typeof hljs !== 'undefined') {
|
||||
hljs.highlightAll();
|
||||
|
||||
// Add copy buttons to all code blocks
|
||||
document.querySelectorAll('pre code').forEach((block) => {
|
||||
const pre = block.parentElement;
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.className = 'relative group';
|
||||
pre.parentNode.insertBefore(wrapper, pre);
|
||||
wrapper.appendChild(pre);
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.className = 'absolute top-2 right-2 bg-background-secondary text-text-secondary px-2 py-1 rounded text-xs opacity-0 group-hover:opacity-100 transition-opacity border border-border hover:text-accent';
|
||||
button.textContent = 'Copy';
|
||||
button.onclick = async () => {
|
||||
await navigator.clipboard.writeText(block.textContent);
|
||||
button.textContent = 'Copied!';
|
||||
setTimeout(() => {
|
||||
button.textContent = 'Copy';
|
||||
}, 2000);
|
||||
};
|
||||
wrapper.appendChild(button);
|
||||
});
|
||||
}
|
||||
|
||||
// Add copy buttons to all code blocks
|
||||
document.querySelectorAll('pre code').forEach((block) => {
|
||||
const pre = block.parentElement;
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.className = 'relative group';
|
||||
pre.parentNode.insertBefore(wrapper, pre);
|
||||
wrapper.appendChild(pre);
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.className = 'absolute top-2 right-2 bg-background-secondary text-text-secondary px-2 py-1 rounded text-xs opacity-0 group-hover:opacity-100 transition-opacity border border-border hover:text-accent';
|
||||
button.textContent = 'Copy';
|
||||
button.onclick = async () => {
|
||||
await navigator.clipboard.writeText(block.textContent);
|
||||
button.textContent = 'Copied!';
|
||||
setTimeout(() => {
|
||||
button.textContent = 'Copy';
|
||||
}, 2000);
|
||||
};
|
||||
wrapper.appendChild(button);
|
||||
});
|
||||
});
|
||||
|
||||
// Add copy buttons to all code blocks
|
||||
document.querySelectorAll('pre code').forEach((block) => {
|
||||
const pre = block.parentElement;
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.className = 'relative group';
|
||||
pre.parentNode.insertBefore(wrapper, pre);
|
||||
wrapper.appendChild(pre);
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.className = 'absolute top-2 right-2 bg-background-secondary text-text-secondary px-2 py-1 rounded text-xs opacity-0 group-hover:opacity-100 transition-opacity border border-border hover:text-accent';
|
||||
button.textContent = 'Copy';
|
||||
button.onclick = async () => {
|
||||
await navigator.clipboard.writeText(block.textContent);
|
||||
button.textContent = 'Copied!';
|
||||
setTimeout(() => {
|
||||
button.textContent = 'Copy';
|
||||
}, 2000);
|
||||
};
|
||||
wrapper.appendChild(button);
|
||||
});
|
||||
|
||||
// Search state
|
||||
let idx;
|
||||
let searchDocs = [];
|
||||
@@ -472,9 +548,72 @@ templ DocsLayoutWithExplorer(nav Navigation, doc Document, user User, explorer A
|
||||
// Initialize syntax highlighting
|
||||
if (typeof hljs !== 'undefined') {
|
||||
hljs.highlightAll();
|
||||
|
||||
// Add copy buttons to all code blocks
|
||||
document.querySelectorAll('pre code').forEach((block) => {
|
||||
const pre = block.parentElement;
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.className = 'relative group';
|
||||
pre.parentNode.insertBefore(wrapper, pre);
|
||||
wrapper.appendChild(pre);
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.className = 'absolute top-2 right-2 bg-background-secondary text-text-secondary px-2 py-1 rounded text-xs opacity-0 group-hover:opacity-100 transition-opacity border border-border hover:text-accent';
|
||||
button.textContent = 'Copy';
|
||||
button.onclick = async () => {
|
||||
await navigator.clipboard.writeText(block.textContent);
|
||||
button.textContent = 'Copied!';
|
||||
setTimeout(() => {
|
||||
button.textContent = 'Copy';
|
||||
}, 2000);
|
||||
};
|
||||
wrapper.appendChild(button);
|
||||
});
|
||||
}
|
||||
|
||||
// Add copy buttons to all code blocks
|
||||
document.querySelectorAll('pre code').forEach((block) => {
|
||||
const pre = block.parentElement;
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.className = 'relative group';
|
||||
pre.parentNode.insertBefore(wrapper, pre);
|
||||
wrapper.appendChild(pre);
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.className = 'absolute top-2 right-2 bg-background-secondary text-text-secondary px-2 py-1 rounded text-xs opacity-0 group-hover:opacity-100 transition-opacity border border-border hover:text-accent';
|
||||
button.textContent = 'Copy';
|
||||
button.onclick = async () => {
|
||||
await navigator.clipboard.writeText(block.textContent);
|
||||
button.textContent = 'Copied!';
|
||||
setTimeout(() => {
|
||||
button.textContent = 'Copy';
|
||||
}, 2000);
|
||||
};
|
||||
wrapper.appendChild(button);
|
||||
});
|
||||
});
|
||||
|
||||
// Add copy buttons to all code blocks
|
||||
document.querySelectorAll('pre code').forEach((block) => {
|
||||
const pre = block.parentElement;
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.className = 'relative group';
|
||||
pre.parentNode.insertBefore(wrapper, pre);
|
||||
wrapper.appendChild(pre);
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.className = 'absolute top-2 right-2 bg-background-secondary text-text-secondary px-2 py-1 rounded text-xs opacity-0 group-hover:opacity-100 transition-opacity border border-border hover:text-accent';
|
||||
button.textContent = 'Copy';
|
||||
button.onclick = async () => {
|
||||
await navigator.clipboard.writeText(block.textContent);
|
||||
button.textContent = 'Copied!';
|
||||
setTimeout(() => {
|
||||
button.textContent = 'Copy';
|
||||
}, 2000);
|
||||
};
|
||||
wrapper.appendChild(button);
|
||||
});
|
||||
|
||||
// Search state
|
||||
let idx;
|
||||
let searchDocs = [];
|
||||
|
||||
Reference in New Issue
Block a user