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;