Spaces:
Running
Running
| <script lang="ts"> | |
| import Button from '$lib/components/ui/button/button.svelte'; | |
| import { Check, Copy } from '@lucide/svelte'; | |
| import { HighlightAuto } from 'svelte-highlight'; | |
| import { mode } from 'mode-watcher'; | |
| import githubDarkUrl from 'svelte-highlight/styles/github-dark.css?url'; | |
| import githubUrl from 'svelte-highlight/styles/github.css?url'; | |
| let { | |
| lang, | |
| text, | |
| className = 'my-3 relative rounded-lg border border-border/60 bg-muted/50' | |
| }: { lang?: string; text: string; className?: string } = $props(); | |
| let copiedCode = $state(false); | |
| async function copy(text: string) { | |
| await navigator.clipboard.writeText(text); | |
| copiedCode = true; | |
| setTimeout(() => (copiedCode = false), 2000); | |
| } | |
| $effect(() => { | |
| const themeUrl = mode.current === 'dark' ? githubDarkUrl : githubUrl; | |
| let link = document.getElementById('highlight-theme') as HTMLLinkElement | null; | |
| if (!link) { | |
| link = document.createElement('link'); | |
| link.id = 'highlight-theme'; | |
| link.rel = 'stylesheet'; | |
| document.head.appendChild(link); | |
| } | |
| link.href = themeUrl; | |
| }); | |
| </script> | |
| <div class="overflow-hidden {className}"> | |
| {#if lang} | |
| <div | |
| class="flex items-center justify-between border-b border-border/60 bg-muted px-3 py-1.5 dark:bg-accent/30" | |
| > | |
| <span class="font-mono text-sm text-muted-foreground">{lang}</span> | |
| </div> | |
| {/if} | |
| <div class="group relative"> | |
| <HighlightAuto code={text} class="font-mono text-sm leading-relaxed" /> | |
| <Button | |
| variant="outline" | |
| class="absolute top-2 right-2 opacity-0 group-hover:opacity-100" | |
| size="icon-xs" | |
| onclick={() => copy(text)} | |
| > | |
| {#if copiedCode} | |
| <Check class="size-3.5 text-green-500" /> | |
| {:else} | |
| <Copy class="size-3.5" /> | |
| {/if} | |
| </Button> | |
| </div> | |
| </div> | |