File size: 2,244 Bytes
db39944
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<script lang="ts">
	import hljs from 'highlight.js/lib/core';
	import sql from 'highlight.js/lib/languages/sql';
	import FaRegCopy from 'svelte-icons/fa/FaRegCopy.svelte';
	import FaCheck from 'svelte-icons/fa/FaCheck.svelte';
	import FaChevronDown from 'svelte-icons/fa/FaChevronDown.svelte';
	import 'highlight.js/styles/atom-one-dark.css';

	hljs.registerLanguage('sql', sql);

	export let code: string;
	export let language: string;

	let highlightedCode: string;
	let isCopied = false;
	let isExpanded = false;
	let codeWrapper: HTMLElement;
	let shouldShowExpand = false;

	$: highlightedCode = hljs.highlight(code, { language }).value;
	$: if (codeWrapper) {
		shouldShowExpand = codeWrapper.scrollHeight > 192;
	}

	function copyCode() {
		navigator.clipboard.writeText(code);
		isCopied = true;
		setTimeout(() => (isCopied = false), 2000);
	}
</script>

<div class="rounded-lg overflow-hidden shadow-lg bg-transparent text-white">
	<div class="flex justify-end p-2 bg-[#1E1E1E] border-b border-[#2F2E2E]">
		<button
			on:click={copyCode}
			class="p-[1px] rounded-md text-gray-400 hover:text-white transition-colors duration-200 focus:outline-none focus:ring-1 focus:ring-white"
			aria-label="Copy code"
		>
			<div class="w-3 h-3">
				{#if isCopied}
					<FaCheck class="text-green-500" />
				{:else}
					<FaRegCopy />
				{/if}
			</div>
		</button>
	</div>
	<div class="relative" bind:this={codeWrapper}>
		<pre
			class="transition-all duration-300 ease-in-out overflow-hidden"
			class:max-h-48={!isExpanded && shouldShowExpand}
		><code class="hljs language-{language} text-xs font-mono block">{@html highlightedCode}</code></pre>

		{#if !isExpanded && shouldShowExpand}
			<div class="absolute inset-x-0 bottom-0 h-6 bg-gradient-to-t from-gray-900 to-transparent pointer-events-none"></div>
			<button
				on:click={() => (isExpanded = true)}
				class="absolute inset-x-0 bottom-0 h-6 flex items-center justify-center text-gray-400 text-xs hover:text-gray-300 transition-colors duration-200"
			>
				<div class="w-3 h-3">
					<FaChevronDown />
				</div>
			</button>
		{/if}
	</div>
</div>

<style>
	pre {
		scrollbar-width: none;
		-ms-overflow-style: none;
	}
	pre::-webkit-scrollbar {
		display: none;
	}
</style>