File size: 1,489 Bytes
70e483f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
<script setup lang="ts">
import hljs from 'highlight.js/lib/core';
import json from 'highlight.js/lib/languages/json';
import xml from 'highlight.js/lib/languages/xml';
import 'highlight.js/styles/stackoverflow-dark.css';
import { Check, Copy } from 'lucide-vue-next';

hljs.registerLanguage('json', json);
hljs.registerLanguage('xml', xml);

interface Props {
  code: Record<string, any> | string;
  lang: 'json' | 'xml' | 'text';
}
const props = defineProps<Props>();

const code = computed(() => {
  if (typeof props.code === 'string') {
    return props.code;
  } else if (typeof props.code === 'object') {
    return JSON.stringify(props.code, null, 2);
  } else {
    throw new Error(`Unknown code: ${JSON.stringify(props.code)}`);
  }
});
const hlCode = computed(() => {
  if (props.lang === 'text') {
    return `<span class="text-xl">${code.value}</span>`;
  }
  return hljs.highlight(code.value, { language: props.lang }).value;
});

const copied = ref(false);
function copy() {
  navigator.clipboard.writeText(code.value);
  copied.value = true;
  setTimeout(() => {
    copied.value = false;
  }, 1000);
}
</script>

<template>
  <div class="relative">
    <pre
      class="bg-black text-gray-400 p-2 rounded overflow-scroll no-scrollbar"
    ><Check v-if="copied" class="absolute right-3 top-3 size-5"/><Copy v-else class="absolute right-3 top-3 size-5 text-gray-500 hover:text-gray-400 cursor-pointer" @click="copy"/><span v-html="hlCode"></span></pre>
  </div>
</template>