Skip to content

Commit dbfc569

Browse files
authored
Merge pull request #1697 from solidjs/docs/fix-copy-to-clipboard
add copy to clipboard button to code snippet
2 parents fe0eeda + d867bb2 commit dbfc569

4 files changed

Lines changed: 83 additions & 16 deletions

File tree

.github/workflows/typecheck.yml

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,31 @@ on:
88
- release-*
99
tags-ignore:
1010
- v*
11-
paths-ignore:
12-
- "docs/**"
13-
- "docs.root.tsx"
14-
- "components/**"
15-
- "**/README.md"
16-
pull_request:
17-
paths-ignore:
18-
- "docs/**"
19-
- "**/*.md"
2011

2112
jobs:
13+
filter-changes:
14+
runs-on: ubuntu-latest
15+
outputs:
16+
should_skip: ${{ steps.changes.outputs.landing_page }}
17+
steps:
18+
- uses: actions/checkout@v3
19+
with:
20+
fetch-depth: 0
21+
22+
- name: Get changed files
23+
id: changes
24+
uses: dorny/paths-filter@v2
25+
with:
26+
filters: |
27+
landing_page:
28+
- 'docs/**'
29+
- "docs.root.tsx"
30+
- "components/**"
31+
- "**/README.md"
2232
typecheck:
2333
name: "👀 Typecheck"
24-
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.changed_files != 0)
34+
needs: filter-changes
35+
if: needs.filter-changes.outputs.should_skip != 'true'
2536

2637
runs-on: ubuntu-latest
2738

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { createSignal, Show } from "solid-js";
2+
import { ClipboardIcon } from "./icons/clipboard-icon";
3+
4+
interface CopyToClipboardProps {
5+
class?: string;
6+
manager: string;
7+
command: string;
8+
}
9+
10+
export function CopyToClipboard(props: CopyToClipboardProps) {
11+
const copyText = () => `${props.manager} ${props.command}`;
12+
13+
const [isCopied, setIsCopied] = createSignal(false);
14+
15+
const copyToClipboard = async () => {
16+
try {
17+
await navigator.clipboard.writeText(copyText());
18+
setIsCopied(true);
19+
setTimeout(() => setIsCopied(false), 2000); // Reset after 2 seconds
20+
} catch (err) {
21+
console.error("Failed to copy text: ", err);
22+
}
23+
};
24+
25+
return (
26+
<button
27+
class={props.class}
28+
onClick={copyToClipboard}
29+
aria-label={isCopied ? "Copied!" : "Copy to clipboard"}
30+
>
31+
<Show when={isCopied()} fallback={<ClipboardIcon class="h-4 w-4" />}>
32+
✔︎
33+
</Show>
34+
</button>
35+
);
36+
}

docs/src/components/code-snippet.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import { Tabs } from "@kobalte/core/tabs";
22
import { createResource, Suspense } from "solid-js";
3-
// import { YarnIcon } from "./icons/yarn-icon";
4-
// import { NpmIcon } from "./icons/npm-icon";
5-
// import { PnpmIcon } from "./icons/pnpm-icon";
6-
3+
import { CopyToClipboard } from "./clipboard-button";
74
const getSolidStartVersion = async () => {
85
"use server";
96

@@ -66,7 +63,7 @@ export function CodeSnippet() {
6663
);
6764
}
6865

69-
function TabContent(props: { manager: string, command: string }) {
66+
function TabContent(props: { manager: string; command: string }) {
7067
return (
7168
<Tabs.Content
7269
value={props.manager}
@@ -86,8 +83,14 @@ function TabContent(props: { manager: string, command: string }) {
8683
aria-hidden="true"
8784
class="hidden dark:block absolute inset-0 bg-gradient-to-tr from-blue-300 rounded-md via-blue-300/70 to-blue-300 opacity-5 pointer-events-none"
8885
/>
89-
<span class="dark:text-cyan-200 text-cyan-600">{props.manager}</span> {' '+props.command}
86+
<span class="dark:text-cyan-200 text-cyan-600">{props.manager}</span> {" " + props.command}
9087
</pre>
88+
89+
<CopyToClipboard
90+
class="absolute right-4 top-3"
91+
manager={props.manager}
92+
command={props.command}
93+
/>
9194
</Tabs.Content>
9295
);
9396
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export function ClipboardIcon(props: { class?: string }) {
2+
return (
3+
<svg
4+
class={props.class || "w-4 h-4"}
5+
xmlns="http://www.w3.org/2000/svg"
6+
viewBox="0 0 24 24"
7+
fill="none"
8+
stroke="currentColor"
9+
stroke-width="2"
10+
stroke-linecap="round"
11+
stroke-linejoin="round"
12+
>
13+
<rect width="14" height="14" x="8" y="8" rx="2" ry="2" />
14+
<path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" />
15+
</svg>
16+
);
17+
}

0 commit comments

Comments
 (0)