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">
|
<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://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>
|
<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 src="https://cdn.jsdelivr.net/npm/lunr-flex@1.0.5/lunr.flex.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
tailwind.config = {
|
tailwind.config = {
|
||||||
@@ -182,7 +195,70 @@ templ DocsLayout(nav Navigation, doc Document, user User) {
|
|||||||
// Initialize syntax highlighting
|
// Initialize syntax highlighting
|
||||||
if (typeof hljs !== 'undefined') {
|
if (typeof hljs !== 'undefined') {
|
||||||
hljs.highlightAll();
|
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
|
// Search state
|
||||||
@@ -472,7 +548,70 @@ templ DocsLayoutWithExplorer(nav Navigation, doc Document, user User, explorer A
|
|||||||
// Initialize syntax highlighting
|
// Initialize syntax highlighting
|
||||||
if (typeof hljs !== 'undefined') {
|
if (typeof hljs !== 'undefined') {
|
||||||
hljs.highlightAll();
|
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
|
// Search state
|
||||||
|
|||||||
+30
-30
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user