2022-08-03 12:47:00 +02:00
|
|
|
<script setup lang="ts">
|
|
|
|
import { Copy } from '@vicons/tabler';
|
2023-08-22 01:00:20 +02:00
|
|
|
import { useElementSize } from '@vueuse/core';
|
2022-08-03 12:47:00 +02:00
|
|
|
import hljs from 'highlight.js/lib/core';
|
|
|
|
import jsonHljs from 'highlight.js/lib/languages/json';
|
|
|
|
import sqlHljs from 'highlight.js/lib/languages/sql';
|
2022-08-17 14:36:52 +02:00
|
|
|
import xmlHljs from 'highlight.js/lib/languages/xml';
|
2023-03-27 17:31:13 +02:00
|
|
|
import yamlHljs from 'highlight.js/lib/languages/yaml';
|
2023-06-23 21:40:30 +02:00
|
|
|
import iniHljs from 'highlight.js/lib/languages/ini';
|
2024-08-25 22:57:07 +02:00
|
|
|
import markdownHljs from 'highlight.js/lib/languages/markdown';
|
2023-08-22 01:00:20 +02:00
|
|
|
import { useCopy } from '@/composable/copy';
|
2022-08-03 12:47:00 +02:00
|
|
|
|
|
|
|
const props = withDefaults(
|
|
|
|
defineProps<{
|
2023-05-28 23:13:24 +02:00
|
|
|
value: string
|
|
|
|
followHeightOf?: HTMLElement | null
|
|
|
|
language?: string
|
|
|
|
copyPlacement?: 'top-right' | 'bottom-right' | 'outside' | 'none'
|
|
|
|
copyMessage?: string
|
2022-08-03 12:47:00 +02:00
|
|
|
}>(),
|
|
|
|
{
|
|
|
|
followHeightOf: null,
|
|
|
|
language: 'txt',
|
|
|
|
copyPlacement: 'top-right',
|
|
|
|
copyMessage: 'Copy to clipboard',
|
|
|
|
},
|
|
|
|
);
|
2023-05-28 23:13:24 +02:00
|
|
|
hljs.registerLanguage('sql', sqlHljs);
|
|
|
|
hljs.registerLanguage('json', jsonHljs);
|
|
|
|
hljs.registerLanguage('html', xmlHljs);
|
2023-06-18 12:27:26 +02:00
|
|
|
hljs.registerLanguage('xml', xmlHljs);
|
2023-05-28 23:13:24 +02:00
|
|
|
hljs.registerLanguage('yaml', yamlHljs);
|
2023-06-23 21:40:30 +02:00
|
|
|
hljs.registerLanguage('toml', iniHljs);
|
2024-08-25 22:57:07 +02:00
|
|
|
hljs.registerLanguage('markdown', markdownHljs);
|
2023-05-28 23:13:24 +02:00
|
|
|
|
2022-08-03 12:47:00 +02:00
|
|
|
const { value, language, followHeightOf, copyPlacement, copyMessage } = toRefs(props);
|
2023-05-28 23:13:24 +02:00
|
|
|
const { height } = followHeightOf.value ? useElementSize(followHeightOf) : { height: ref(null) };
|
2022-08-03 12:47:00 +02:00
|
|
|
|
2023-08-22 01:00:20 +02:00
|
|
|
const { copy, isJustCopied } = useCopy({ source: value, createToast: false });
|
|
|
|
const tooltipText = computed(() => isJustCopied.value ? 'Copied!' : copyMessage.value);
|
2022-08-03 12:47:00 +02:00
|
|
|
</script>
|
|
|
|
|
2023-05-28 23:13:24 +02:00
|
|
|
<template>
|
|
|
|
<div style="overflow-x: hidden; width: 100%">
|
2023-10-14 18:24:54 +02:00
|
|
|
<c-card relative>
|
2023-05-28 23:13:24 +02:00
|
|
|
<n-scrollbar
|
|
|
|
x-scrollable
|
|
|
|
trigger="none"
|
|
|
|
:style="height ? `min-height: ${height - 40 /* card padding */ + 10 /* negative margin compensation */}px` : ''"
|
|
|
|
>
|
|
|
|
<n-config-provider :hljs="hljs">
|
|
|
|
<n-code :code="value" :language="language" :trim="false" data-test-id="area-content" />
|
|
|
|
</n-config-provider>
|
|
|
|
</n-scrollbar>
|
2023-10-14 18:24:54 +02:00
|
|
|
<div absolute right-10px top-10px>
|
|
|
|
<c-tooltip v-if="value" :tooltip="tooltipText" position="left">
|
|
|
|
<c-button circle important:h-10 important:w-10 @click="copy()">
|
|
|
|
<n-icon size="22" :component="Copy" />
|
|
|
|
</c-button>
|
|
|
|
</c-tooltip>
|
|
|
|
</div>
|
2023-05-28 23:13:24 +02:00
|
|
|
</c-card>
|
|
|
|
<div v-if="copyPlacement === 'outside'" mt-4 flex justify-center>
|
2023-08-22 01:00:20 +02:00
|
|
|
<c-button @click="copy()">
|
2023-05-28 23:13:24 +02:00
|
|
|
{{ tooltipText }}
|
|
|
|
</c-button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
2022-08-03 12:47:00 +02:00
|
|
|
<style lang="less" scoped>
|
|
|
|
::v-deep(.n-scrollbar) {
|
|
|
|
padding-bottom: 10px;
|
|
|
|
margin-bottom: -10px;
|
|
|
|
}
|
|
|
|
</style>
|