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-10-02 22:13:06 +02:00
|
|
|
import bashHljs from 'highlight.js/lib/languages/bash';
|
2024-08-25 22:57:07 +02:00
|
|
|
import markdownHljs from 'highlight.js/lib/languages/markdown';
|
2024-10-02 22:13:06 +02:00
|
|
|
import jsHljs from 'highlight.js/lib/languages/javascript';
|
|
|
|
import cssHljs from 'highlight.js/lib/languages/css';
|
|
|
|
import goHljs from 'highlight.js/lib/languages/go';
|
|
|
|
import csharpHljs from 'highlight.js/lib/languages/csharp';
|
|
|
|
import { Base64 } from 'js-base64';
|
2023-08-22 01:00:20 +02:00
|
|
|
import { useCopy } from '@/composable/copy';
|
2024-10-02 22:13:06 +02:00
|
|
|
import { useDownloadFileFromBase64 } from '@/composable/downloadBase64';
|
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
|
2024-10-02 22:13:06 +02:00
|
|
|
wordWrap?: boolean
|
|
|
|
downloadFileName?: string
|
|
|
|
downloadButtonText?: string
|
2022-08-03 12:47:00 +02:00
|
|
|
}>(),
|
|
|
|
{
|
|
|
|
followHeightOf: null,
|
|
|
|
language: 'txt',
|
|
|
|
copyPlacement: 'top-right',
|
|
|
|
copyMessage: 'Copy to clipboard',
|
2024-10-02 22:13:06 +02:00
|
|
|
downloadFileName: '',
|
|
|
|
downloadButtonText: 'Download',
|
2022-08-03 12:47:00 +02:00
|
|
|
},
|
|
|
|
);
|
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-10-02 22:13:06 +02:00
|
|
|
hljs.registerLanguage('bash', bashHljs);
|
2024-08-25 22:57:07 +02:00
|
|
|
hljs.registerLanguage('markdown', markdownHljs);
|
2024-10-02 22:13:06 +02:00
|
|
|
hljs.registerLanguage('css', cssHljs);
|
|
|
|
hljs.registerLanguage('javascript', jsHljs);
|
|
|
|
hljs.registerLanguage('go', goHljs);
|
|
|
|
hljs.registerLanguage('csharp', csharpHljs);
|
2023-05-28 23:13:24 +02:00
|
|
|
|
2024-10-02 22:13:06 +02:00
|
|
|
const { value, language, followHeightOf, copyPlacement, copyMessage, downloadFileName, downloadButtonText } = 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);
|
2024-10-02 22:13:06 +02:00
|
|
|
|
|
|
|
const valueBase64 = computed(() => Base64.encode(value.value));
|
|
|
|
const { download } = useDownloadFileFromBase64(
|
|
|
|
{
|
|
|
|
source: valueBase64,
|
|
|
|
filename: downloadFileName,
|
|
|
|
});
|
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">
|
2024-10-02 22:13:06 +02:00
|
|
|
<n-code :code="value" :language="language" :word-wrap="wordWrap" :trim="false" data-test-id="area-content" />
|
2023-05-28 23:13:24 +02:00
|
|
|
</n-config-provider>
|
|
|
|
</n-scrollbar>
|
2024-10-02 22:13:06 +02:00
|
|
|
<div
|
|
|
|
v-if="value && copyPlacement !== 'none'"
|
|
|
|
absolute right-10px
|
|
|
|
:top-10px="copyPlacement === 'top-right' ? '' : 'no'"
|
|
|
|
:bottom-10px="copyPlacement === 'bottom-right' ? '' : 'no'"
|
|
|
|
>
|
|
|
|
<c-tooltip v-if="value && copyPlacement !== 'outside'" :tooltip="tooltipText" position="left">
|
2023-10-14 18:24:54 +02:00
|
|
|
<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>
|
2024-10-02 22:13:06 +02:00
|
|
|
<div v-if="downloadFileName !== '' && value !== ''" mt-5 flex justify-center>
|
|
|
|
<c-button secondary @click="download">
|
|
|
|
{{ downloadButtonText }}
|
|
|
|
</c-button>
|
|
|
|
</div>
|
2023-05-28 23:13:24 +02:00
|
|
|
</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>
|