Skip to content

Commit 554644b

Browse files
docs: add copy buttons (freshframework#3393)
1 parent a7af5c0 commit 554644b

7 files changed

Lines changed: 128 additions & 70 deletions

File tree

www/assets/styles.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,17 @@ html[data-theme="dark"] ::selection {
9393
background-size: 1.5em 1.5em;
9494
background-repeat: no-repeat;
9595
}
96+
97+
.group:not([data-copied]) .group-not-copied {
98+
display: block;
99+
}
100+
.group[data-copied] .group-not-copied {
101+
display: none;
102+
}
103+
104+
.group[data-copied] .group-copied {
105+
display: block;
106+
}
107+
.group:not([data-copied]) .group-copied {
108+
display: none;
109+
}

www/client.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,27 @@
11
import "./assets/styles.css";
2+
3+
document.addEventListener("click", async (ev) => {
4+
let el = ev.target as HTMLElement | null;
5+
if (el === null) return;
6+
if (!(el instanceof HTMLButtonElement)) {
7+
el = el.closest("button");
8+
}
9+
if (el === null) return;
10+
11+
const code = el.dataset.code;
12+
if (!code) return;
13+
14+
el.dataset.copied = "true";
15+
16+
setTimeout(() => {
17+
delete el.dataset.copied;
18+
}, 1000);
19+
20+
try {
21+
await navigator.clipboard.writeText(code);
22+
} catch (error) {
23+
const message = error instanceof Error ? error.message : String(error);
24+
// deno-lint-ignore no-console
25+
console.error(message || "Copy failed");
26+
}
27+
});

www/components/CopyButton.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import * as Icons from "./Icons.tsx";
2+
3+
export function CopyButton(props: { code: string }) {
4+
return (
5+
<div class="relative my-2 mr-4 sm:mr-6">
6+
<button
7+
type="button"
8+
data-code={props.code}
9+
aria-label="Copy to Clipboard"
10+
class="rounded-sm p-1.5 border border-foreground-secondary/30 hover:bg-foreground-secondary/70 data-copied:text-green-500 relative group cursor-pointer"
11+
>
12+
<span class="group-copied">
13+
<Icons.Check />
14+
</span>
15+
<span class="group-not-copied">
16+
<Icons.Copy />
17+
</span>
18+
</button>
19+
</div>
20+
);
21+
}

www/components/homepage/Hero.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import CopyArea from "../../islands/CopyArea.tsx";
21
import { FancyLink } from "../../components/FancyLink.tsx";
32
import LemonTop from "../../islands/LemonTop.tsx";
43
import LemonBottom from "../../islands/LemonBottom.tsx";
4+
import { CopyButton } from "../CopyButton.tsx";
55

66
export function Hero() {
77
return (
@@ -26,3 +26,15 @@ export function Hero() {
2626
</>
2727
);
2828
}
29+
30+
function CopyArea(props: { code: string }) {
31+
return (
32+
<div class="bg-slate-800 rounded-sm text-green-100 flex items-center min-w-0 overflow-x-auto">
33+
<pre class="overflow-x-auto w-full flex-1 px-6 py-4">
34+
{props.code}
35+
</pre>
36+
37+
<CopyButton code={props.code} />
38+
</div>
39+
);
40+
}

www/islands/CopyArea.tsx

Lines changed: 0 additions & 62 deletions
This file was deleted.

www/static/markdown.css

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,8 @@ ol.nested li:before {
801801
.fenced-code-header {
802802
border-top-left-radius: 0.5rem;
803803
border-top-right-radius: 0.5rem;
804-
padding: 0.5rem;
804+
padding-left: 0.5rem;
805+
padding-right: 0.5rem;
805806
background: var(--color-background-tertiary);
806807
display: flex;
807808
align-items: center;
@@ -812,13 +813,15 @@ ol.nested li:before {
812813
border-top-right-radius: 0 !important;
813814
}
814815
.fenced-code-title {
815-
display: grid;
816+
display: flex;
817+
padding-top: 0.5rem;
818+
padding-bottom: 0.5rem;
816819
font-family:
817820
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
818821
"Courier New", monospace;
819822
font-size: 0.8125rem;
820823
line-height: 1;
821-
grid-auto-flow: column;
824+
justify-content: space-between;
822825
align-items: center;
823826
gap: 0.625rem;
824827
}

www/utils/markdown.ts

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,14 +176,58 @@ class DefaultRenderer extends Marked.Renderer {
176176

177177
if (title || icon) {
178178
const image = icon
179-
? `<img src="${icon.src}" alt="${icon.text}" title="${icon.text}">`
179+
? `<img src="${icon.src}" alt="${icon.text}" title="${icon.text}" width="20" height="20">`
180180
: "";
181181

182182
out += `<div class="fenced-code-header">
183-
<span class="fenced-code-title lang-${lang}">
184-
${image}
185-
${title ? escapeHtml(String(title)) : "&nbsp;"}
183+
<span class="fenced-code-title lang-${lang} w-full">
184+
<span class="flex items-center gap-2">
185+
${image}
186+
${title ? escapeHtml(String(title)) : "&nbsp;"}
187+
</span>
186188
</span>
189+
${
190+
icon && icon.text !== "Text"
191+
? `<button
192+
type="button"
193+
data-code="${escapeHtml(text)}"
194+
aria-label="Copy to Clipboard"
195+
class="rounded-sm flex items-center justify-center border border-foreground-secondary/30 hover:bg-foreground-secondary/70 data-copied:text-green-300 relative group cursor-pointer w-7 h-7 text-white"
196+
>
197+
<span class="group-copied">
198+
<svg
199+
xmlns="http://www.w3.org/2000/svg"
200+
class="h-4 w-4"
201+
fill="none"
202+
viewBox="0 0 24 24"
203+
stroke="currentColor"
204+
aria-hidden="true"
205+
>
206+
<path
207+
stroke-width={3}
208+
strokeLinecap="round"
209+
strokeLinejoin="round"
210+
d="M5 13l4 4L19 7"
211+
/>
212+
</svg>
213+
</span>
214+
<span class="group-not-copied">
215+
<svg
216+
class="h-4 w-4"
217+
viewBox="0 0 15 15"
218+
fill="none"
219+
xmlns="http://www.w3.org/2000/svg"
220+
aria-hidden="true"
221+
>
222+
<path
223+
d="M1.55566 2.7C1.55566 2.03726 2.09292 1.5 2.75566 1.5H8.75566C9.41841 1.5 9.95566 2.03726 9.95566 2.7V5.1H12.3557C13.0184 5.1 13.5557 5.63726 13.5557 6.3V12.3C13.5557 12.9627 13.0184 13.5 12.3557 13.5H6.35566C5.69292 13.5 5.15566 12.9627 5.15566 12.3V9.9H2.75566C2.09292 9.9 1.55566 9.36274 1.55566 8.7V2.7ZM6.35566 9.9V12.3H12.3557V6.3H9.95566V8.7C9.95566 9.36274 9.41841 9.9 8.75566 9.9H6.35566ZM8.75566 8.7V2.7L2.75566 2.7V8.7H8.75566Z"
224+
fill="currentColor"
225+
/>
226+
</svg>
227+
</span>
228+
</button>`
229+
: ""
230+
}
187231
</div>`;
188232
}
189233

0 commit comments

Comments
 (0)