File size: 1,745 Bytes
d3ab1f5
1302517
f60772d
1302517
8cc084b
 
 
1302517
f60772d
 
 
 
 
 
 
 
 
 
 
 
 
8cc084b
 
 
 
 
 
 
 
 
 
 
 
d3ab1f5
 
f60772d
2961a5b
8cc084b
 
 
822d5b9
2961a5b
 
1302517
822d5b9
1302517
 
 
f60772d
 
1302517
f60772d
 
 
 
 
1302517
 
d3ab1f5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<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>