feat(layout): add the language and a button to copy code blocks
This commit is contained in:
parent
7c3facdd0f
commit
7b84496201
3 changed files with 124 additions and 12 deletions
|
@ -58,6 +58,9 @@
|
|||
--pico-background-color: rgb(247 249 252 / 100%);
|
||||
--pico-card-background-color: rgb(255 255 255 / 100%);
|
||||
--pico-card-sectioning-background-color: transparent;
|
||||
--pico-code-color: inherit;
|
||||
|
||||
--color-codeblock-meta-background: rgb(255 255 255 / 100%);
|
||||
}
|
||||
|
||||
.admonition.warning {
|
||||
|
@ -72,6 +75,11 @@
|
|||
}
|
||||
|
||||
@media only screen and (prefers-color-scheme: dark) {
|
||||
:root:not([data-theme]) {
|
||||
--pico-code-color: inherit;
|
||||
|
||||
--color-codeblock-meta-background: rgb(0 0 0 / 30%);
|
||||
}
|
||||
.admonition.warning {
|
||||
--admonition-background-color: rgb(52 46 38 / 100%);
|
||||
--admonition-border-color: rgb(255 208 143 / 100%);
|
||||
|
@ -444,3 +452,47 @@ main {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Code blocks
|
||||
*/
|
||||
|
||||
.highlight {
|
||||
position: relative;
|
||||
|
||||
> div {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
padding: 0.5em 1.2em;
|
||||
color: var(--pico-muted-color);
|
||||
background-color: var(--color-codeblock-meta-background);
|
||||
font-family: var(--pico-font-family-monospace);
|
||||
font-size: 0.7em;
|
||||
line-height: 1em;
|
||||
border-end-start-radius: var(--pico-border-radius);
|
||||
|
||||
span {
|
||||
border-inline-start: inset 1px var(--pico-muted-color);
|
||||
padding-inline-start: 1em;
|
||||
margin-inline-start: 1em;
|
||||
cursor: pointer;
|
||||
|
||||
&::before {
|
||||
content: "\ecd5";
|
||||
font-family: "remixicon";
|
||||
font-weight: normal;
|
||||
margin-inline-end: 0.5em;
|
||||
}
|
||||
|
||||
&.copied::before {
|
||||
content: "\eb7b";
|
||||
}
|
||||
|
||||
&.not-copied::before {
|
||||
content: "\eca1";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,21 +2,68 @@
|
|||
|
||||
// Listens for clicks on the mobile menu toggle and the main menu close toggle.
|
||||
window.addEventListener('click', function(e) {
|
||||
if (e.target.matches('#menu-toggle, #menu-toggle i')) {
|
||||
openMenu();
|
||||
} else if (e.target.matches('#menu-close, #menu-close i')) {
|
||||
closeMenu();
|
||||
} else if (e.target.matches('[data-action="copy"]')) {
|
||||
copyCodeToClipboard(e);
|
||||
}
|
||||
});
|
||||
|
||||
function openMenu() {
|
||||
const menu = document.getElementById('menu'),
|
||||
menuToggle = document.getElementById('menu-toggle'),
|
||||
body = document.body;
|
||||
|
||||
if (e.target.matches('#menu-toggle, #menu-toggle i')) {
|
||||
menu.classList.toggle('active');
|
||||
menu.ariaHidden = false;
|
||||
menuToggle.ariaExpanded = true;
|
||||
body.style.overflow = 'hidden';
|
||||
menu.classList.toggle('active');
|
||||
menu.ariaHidden = false;
|
||||
menuToggle.ariaExpanded = true;
|
||||
body.style.overflow = 'hidden';
|
||||
}
|
||||
|
||||
function closeMenu() {
|
||||
const menu = document.getElementById('menu'),
|
||||
menuToggle = document.getElementById('menu-toggle'),
|
||||
body = document.body;
|
||||
|
||||
menu.classList.remove('active');
|
||||
menu.ariaHidden = true;
|
||||
menuToggle.ariaExpanded = false;
|
||||
body.style.overflow = 'auto';
|
||||
}
|
||||
|
||||
function copyCodeToClipboard(e) {
|
||||
const codeTag = e.target.closest('.highlight').querySelector("code");
|
||||
|
||||
if (!codeTag) return;
|
||||
|
||||
const tw = document.createTreeWalker(
|
||||
codeTag,
|
||||
NodeFilter.SHOW_TEXT,
|
||||
(node) => {
|
||||
if (node.parentElement.matches(".ln")) {
|
||||
return NodeFilter.FILTER_REJECT;
|
||||
}
|
||||
|
||||
return NodeFilter.FILTER_ACCEPT;
|
||||
},
|
||||
);
|
||||
|
||||
let acc = "";
|
||||
while (tw.nextNode()) {
|
||||
acc += tw.currentNode.textContent;
|
||||
}
|
||||
|
||||
if (e.target.matches('#menu-close, #menu-close i')) {
|
||||
menu.classList.remove('active');
|
||||
menu.ariaHidden = true;
|
||||
menuToggle.ariaExpanded = false;
|
||||
body.style.overflow = 'auto';
|
||||
}
|
||||
});
|
||||
navigator.clipboard.writeText(acc)
|
||||
.then(() => {
|
||||
e.target.classList.add('copied');
|
||||
|
||||
setTimeout(() => {
|
||||
e.target.classList.remove('copied');
|
||||
}, 5000);
|
||||
})
|
||||
.catch(() => {
|
||||
e.target.classList.add('not-copied');
|
||||
});
|
||||
}
|
||||
|
|
13
layouts/_markup/render-codeblock.html
Normal file
13
layouts/_markup/render-codeblock.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
{{- $result := transform.HighlightCodeBlock . }}
|
||||
<div class="highlight">
|
||||
<div>
|
||||
{{- .Type -}}
|
||||
<span data-action="copy">copy</span>
|
||||
</div>
|
||||
<pre tabindex="0" class="chroma">
|
||||
{{- /* chomp newline */ -}}
|
||||
<code class="language-{{ .Type }}" data-lang="{{ .Type }}">{{ $result.Inner }}</code>
|
||||
{{- /* chomp newline */ -}}
|
||||
</pre>
|
||||
</div>
|
||||
{{- /* chomp trailing newline */ -}}
|
Loading…
Add table
Reference in a new issue