Spaces:
Running
Running
<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> | |