main
vue 56 lines 1.33 KB
Raw
1 <template>
2 <div class="flex flex-col gap-1">
3 <n-card v-if="!showSource" content-class="p-0!" embedded class="overflow-hidden">
4 <div v-shiki="{ lang, decode }" class="scrollbar-styled code-bg-transparent overflow-hidden">
5 <pre v-html="source"></pre>
6 </div>
7 </n-card>
8
9 <n-input
10 v-if="showSource"
11 :value="source"
12 type="textarea"
13 readonly
14 placeholder="Empty"
15 size="large"
16 :autosize="{
17 minRows: 3,
18 maxRows: 18
19 }"
20 />
21
22 <div v-if="$slots.extra || showToggleButton" class="flex items-center justify-between gap-2">
23 <div>
24 <slot name="extra" />
25 </div>
26
27 <div v-if="showToggleButton" class="flex justify-end">
28 <n-button quaternary size="tiny" @click="showSource = !showSource">toggle source view</n-button>
29 </div>
30 </div>
31 </div>
32 </template>
33
34 <script setup lang="ts">
35 import type { SafeAny } from "@/types/utils"
36 import { NButton, NCard, NInput } from "naive-ui"
37 import { computed, ref } from "vue"
38 import vShiki from "@/directives/v-shiki"
39
40 const {
41 code,
42 lang,
43 decode,
44 showToggleButton = true
45 } = defineProps<{
46 code: string | object | number | SafeAny[]
47 lang?: string
48 decode?: boolean
49 showToggleButton?: boolean
50 }>()
51
52 const showSource = ref(false)
53 const source = computed(() =>
54 typeof code === "string" || typeof code === "number" ? `${code}` : JSON.stringify(code, null, "\t")
55 )
56 </script>