Skip to content

Commit f49ba2d

Browse files
committed
Code block copy
1 parent 286029b commit f49ba2d

8 files changed

Lines changed: 94 additions & 2 deletions

File tree

global.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
declare module '*.css' {
2+
const content: string;
3+
export default content;
4+
}
5+
6+
declare module '*.svg' {
7+
const content: string;
8+
export default content;
9+
}

jsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"plain-blog/src/**/*",
99
"plain-blog/lib/**/*",
1010
"plain-blog/index.d.ts",
11-
"website/src/**/*"
11+
"website/src/**/*",
12+
"global.d.ts"
1213
]
1314
}

website/plain.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,10 @@ export default {
3232
// Also some local css files
3333
"src/styles.css",
3434
],
35+
scripts: [
36+
"src/cp-pre/cp-pre.js",
37+
],
38+
elementTransforms: {
39+
pre: "cp-pre",
40+
},
3541
}

website/src/cp-pre/check.svg

Lines changed: 1 addition & 0 deletions
Loading

website/src/cp-pre/copy.svg

Lines changed: 1 addition & 0 deletions
Loading

website/src/cp-pre/cp-pre.css

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
:host {
2+
display: block;
3+
position: relative;
4+
white-space: pre;
5+
overflow-x: auto;
6+
font-family: var(--font-monospace);
7+
}
8+
9+
button {
10+
position: absolute;
11+
top: 8px;
12+
right: 8px;
13+
padding: 6px 8px;
14+
border: none;
15+
border-radius: 4px;
16+
background-color: rgba(0, 0, 0, 0.1);
17+
color: var(--text-color);
18+
cursor: pointer;
19+
font-size: 12px;
20+
opacity: 0;
21+
transition: opacity 0.2s;
22+
}
23+
24+
:host(:hover) button {
25+
opacity: 1;
26+
}
27+
28+
button:hover {
29+
background-color: rgba(0, 0, 0, 0.2);
30+
}

website/src/cp-pre/cp-pre.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// @ts-check
2+
import CpPreCss from "./cp-pre.css";
3+
import CopyIcon from "./copy.svg";
4+
import CheckIcon from "./check.svg";
5+
6+
class CpPre extends HTMLElement {
7+
/** @type {HTMLButtonElement} */
8+
_button;
9+
10+
constructor() {
11+
super();
12+
13+
const shadowRoot = this.attachShadow({ mode: "open" });
14+
shadowRoot.innerHTML = `<style>${CpPreCss}</style><button>${CopyIcon}</button><slot></slot>`;
15+
16+
this._button = shadowRoot.querySelector("button");
17+
}
18+
19+
_clickHandler = () => {
20+
const code = this.querySelector("code");
21+
navigator.clipboard.writeText(code?.textContent || "");
22+
this._button.innerHTML = CheckIcon;
23+
setTimeout(() => (this._button.innerHTML = CopyIcon), 2000);
24+
};
25+
26+
connectedCallback() {
27+
this._button.addEventListener("click", this._clickHandler);
28+
}
29+
30+
disconnectedCallback() {
31+
this._button.removeEventListener("click", this._clickHandler);
32+
}
33+
}
34+
35+
customElements.define("cp-pre", CpPre);

website/src/styles.css

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ html {
33
--text-color: rgb(69, 79, 91);
44
--background-color: rgb(255, 255, 255);
55
--muted-color: rgb(230, 230, 230);
6+
--font-monospace: ui-monospace,"Menlo","Consolas","Roboto Mono","Ubuntu Monospace","Noto Mono","Oxygen Mono","Liberation Mono",monospace,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
67

78
background-color: var(--background-color);
89
color: var(--text-color);
@@ -91,7 +92,7 @@ article > p > img {
9192
margin-right: auto;
9293
}
9394

94-
:not(pre) > code {
95+
:not(pre):not(cp-pre) > code {
9596
background-color: var(--muted-color);
9697
padding: .125em .25em .125em;
9798
border-radius: 0.25em;
@@ -103,6 +104,14 @@ article > p > img {
103104
box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 2px 0px;
104105
}
105106

107+
cp-pre {
108+
display: block;
109+
position: relative;
110+
white-space: pre;
111+
overflow-x: auto;
112+
font-family: var(--font-monospace);
113+
}
114+
106115
@media screen and (max-width: 996px) {
107116
main > nav {
108117
display: none;

0 commit comments

Comments
 (0)