/ src / components / Code.tsx
Code.tsx
 1  import {
 2    type Component,
 3    createEffect,
 4    createSignal,
 5    on,
 6    onCleanup,
 7  } from "solid-js";
 8  import { createHighlighter } from "shiki";
 9  
10  const highlighter = await createHighlighter({
11    themes: ["catppuccin-macchiato"],
12    langs: ["javascript"],
13  });
14  
15  const Code: Component<{
16    snippet: string;
17  }> = (props) => {
18    let ref: HTMLDivElement | undefined;
19  
20    createEffect(
21      on(
22        () => props.snippet,
23        (snip) => {
24          if (!ref) return;
25  
26          const html = highlighter.codeToHtml(snip, {
27            theme: "catppuccin-macchiato",
28            lang: "javascript",
29          });
30  
31          ref.innerHTML = html;
32  
33          onCleanup(() => {
34            ref.innerHTML = "";
35          });
36        }
37      )
38    );
39  
40    const [copied, setCopied] = createSignal(false);
41    const onCopy = async () => {
42      await navigator.clipboard.writeText(props.snippet);
43      setCopied(true);
44      setTimeout(() => setCopied(false), 750);
45    };
46  
47    return (
48      <div class="relative">
49        <button
50          type="button"
51          class="absolute top-2 right-3 text-white"
52          onClick={onCopy}
53        >
54          {copied() ? "copied" : "copy"}
55        </button>
56        <div class="py-3 px-4 rounded bg-#24273a overflow-x-auto" ref={ref} />
57      </div>
58    );
59  };
60  
61  export default Code;