add copy button to code blocks
This commit is contained in:
parent
c6f47db8ba
commit
cdcf69db60
5 changed files with 122 additions and 17 deletions
102
lib/code.typ
Normal file
102
lib/code.typ
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
#import "custom_html.typ" as chtml
|
||||
|
||||
|
||||
// Need inline svg for css color control, so no `image` element :(
|
||||
#let clipboard-icon = html.elem(
|
||||
"svg",
|
||||
attrs: (
|
||||
//width: "16",
|
||||
//height: "16",
|
||||
style: "width: 1.5em; height: 1.5em;",
|
||||
fill: "currentcolor",
|
||||
viewBox: "0 0 16 16",
|
||||
xmlns: "http://www.w3.org/2000/svg"
|
||||
), {
|
||||
html.elem("path", attrs: (
|
||||
d: "M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"
|
||||
))
|
||||
html.elem("path", attrs: (
|
||||
d: "M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"
|
||||
))
|
||||
}
|
||||
)
|
||||
|
||||
#let code-block-counter = state("code-block-counter", 0)
|
||||
|
||||
#let show-rule-code-block(code) = context {
|
||||
let code-id = code-block-counter.get()
|
||||
let code-id-name = "code-block-" + str(code-id)
|
||||
```raw-css
|
||||
code-block {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
overflow: hidden;
|
||||
border-radius: 8px;
|
||||
margin: 8px;
|
||||
background-color: var(--color-code-bg);
|
||||
box-shadow: inset 0px 0px 5px 0px #000;
|
||||
|
||||
pre {
|
||||
padding: 8px;
|
||||
margin: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
code-block-button-container {
|
||||
display: block;
|
||||
|
||||
button {
|
||||
background-color: inherit;
|
||||
border: inherit;
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
margin: 4px;
|
||||
&:hover {
|
||||
box-shadow: inset 0px 0px 0.4em 0px var(--color-button-shadow);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
@media (not (scripting: enabled)) {
|
||||
.code-block-clipboard-button {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```raw-js
|
||||
function copy_code_to_clipboard(id) {
|
||||
code = document.getElementById(id).getAttribute("code-value");
|
||||
navigator.clipboard.writeText(code).then(
|
||||
(r) => alert("copy: " + code),
|
||||
(e) => alert("failed to copy code: ", e),
|
||||
)
|
||||
}
|
||||
```
|
||||
chtml.code-block(
|
||||
attrs: (
|
||||
id: code-id-name,
|
||||
code-value: code.text,
|
||||
),
|
||||
{
|
||||
code
|
||||
chtml.code-block-button-container({
|
||||
html.elem(
|
||||
"button",
|
||||
attrs: (
|
||||
class: "code-block-clipboard-button",
|
||||
onclick: "copy_code_to_clipboard('" + code-id-name + "');",
|
||||
aria-label: "copy to clipboard button",
|
||||
),
|
||||
{
|
||||
clipboard-icon
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
)
|
||||
code-block-counter.update(x => x+1)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue