Skip to content

Commit

Permalink
add copy to clipboard button to code snippet
Browse files Browse the repository at this point in the history
  • Loading branch information
atilafassina committed Dec 21, 2024
1 parent b595f29 commit e360b57
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 6 deletions.
36 changes: 36 additions & 0 deletions docs/src/components/clipboard-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { createSignal, Show } from "solid-js";
import { ClipboardIcon } from "./icons/clipboard-icon";

interface CopyToClipboardProps {
class?: string;
manager: string;
command: string;
}

export function CopyToClipboard(props: CopyToClipboardProps) {
const copyText = () => `${props.manager} ${props.command}`;

const [isCopied, setIsCopied] = createSignal(false);

const copyToClipboard = async () => {
try {
await navigator.clipboard.writeText(copyText());
setIsCopied(true);
setTimeout(() => setIsCopied(false), 2000); // Reset after 2 seconds
} catch (err) {
console.error("Failed to copy text: ", err);
}
};

return (
<button
class={props.class}
onClick={copyToClipboard}
aria-label={isCopied ? "Copied!" : "Copy to clipboard"}
>
<Show when={isCopied()} fallback={<ClipboardIcon class="h-4 w-4" />}>
✔︎
</Show>
</button>
);
}
15 changes: 9 additions & 6 deletions docs/src/components/code-snippet.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { Tabs } from "@kobalte/core/tabs";
import { createResource, Suspense } from "solid-js";
// import { YarnIcon } from "./icons/yarn-icon";
// import { NpmIcon } from "./icons/npm-icon";
// import { PnpmIcon } from "./icons/pnpm-icon";

import { CopyToClipboard } from "./clipboard-button";
const getSolidStartVersion = async () => {
"use server";

Expand Down Expand Up @@ -66,7 +63,7 @@ export function CodeSnippet() {
);
}

function TabContent(props: { manager: string, command: string }) {
function TabContent(props: { manager: string; command: string }) {
return (
<Tabs.Content
value={props.manager}
Expand All @@ -86,8 +83,14 @@ function TabContent(props: { manager: string, command: string }) {
aria-hidden="true"
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"
/>
<span class="dark:text-cyan-200 text-cyan-600">{props.manager}</span> {' '+props.command}
<span class="dark:text-cyan-200 text-cyan-600">{props.manager}</span> {" " + props.command}
</pre>

<CopyToClipboard
class="absolute right-4 top-3"
manager={props.manager}
command={props.command}
/>
</Tabs.Content>
);
}
17 changes: 17 additions & 0 deletions docs/src/components/icons/clipboard-icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export function ClipboardIcon(props: { class?: string }) {
return (
<svg
class={props.class || "w-4 h-4"}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<rect width="14" height="14" x="8" y="8" rx="2" ry="2" />
<path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" />
</svg>
);
}

0 comments on commit e360b57

Please sign in to comment.