main
vue 63 lines 1.23 KB
Raw
1 <template>
2 <n-popover
3 placement="top"
4 content-class="expandable-text-popover"
5 scrollable
6 to="body"
7 display-directive="show"
8 :disabled="text.length < maxLength"
9 >
10 <template #trigger>
11 <span v-if="text.length < maxLength">{{ text }}</span>
12 <span v-else class="cursor-help underline">{{ truncate(text) }}</span>
13 </template>
14
15 <div
16 v-shiki="{ fallbackLang: 'json', decode: true }"
17 class="expandable-text-popover-container scrollbar-styled"
18 >
19 <pre> {{ text }} </pre>
20 </div>
21 </n-popover>
22 </template>
23
24 <script setup lang="ts">
25 import _truncate from "lodash/truncate"
26 import { NPopover } from "naive-ui"
27 import { toRefs } from "vue"
28 import vShiki from "@/directives/v-shiki"
29
30 const props = defineProps<{
31 text: string
32 maxLength: number
33 }>()
34 const { text, maxLength } = toRefs(props)
35
36 function truncate(val: string): string {
37 return _truncate(val || "", {
38 length: maxLength.value
39 })
40 }
41 </script>
42
43 <style lang="scss">
44 .expandable-text-popover {
45 max-width: 380px;
46
47 .expandable-text-popover-container {
48 overflow-x: hidden;
49 overflow-y: auto;
50 max-height: 40svh;
51
52 pre {
53 white-space: pre-wrap;
54
55 code {
56 overflow: hidden;
57 white-space: pre-wrap;
58 background-color: transparent !important;
59 }
60 }
61 }
62 }
63 </style>