mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-04-20 06:55:06 -04:00
refactor(display): mutualized code display
This commit is contained in:
parent
422b6eb05a
commit
0be33fb337
3 changed files with 102 additions and 27 deletions
98
src/components/TextareaCopyable.vue
Normal file
98
src/components/TextareaCopyable.vue
Normal file
|
@ -0,0 +1,98 @@
|
|||
<template>
|
||||
<div style="overflow-x: hidden; width: 100%">
|
||||
<n-card class="result-card">
|
||||
<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" />
|
||||
</n-config-provider>
|
||||
</n-scrollbar>
|
||||
<n-tooltip v-if="value" trigger="hover">
|
||||
<template #trigger>
|
||||
<div class="copy-button" :class="[copyPlacement]">
|
||||
<n-button secondary circle size="large" @click="onCopyClicked">
|
||||
<n-icon size="22" :component="Copy" />
|
||||
</n-button>
|
||||
</div>
|
||||
</template>
|
||||
<span>{{ tooltipText }}</span>
|
||||
</n-tooltip>
|
||||
</n-card>
|
||||
<n-space v-if="copyPlacement === 'outside'" justify="center" style="margin-top: 15px">
|
||||
<n-button secondary @click="onCopyClicked"> {{ tooltipText }} </n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Copy } from '@vicons/tabler';
|
||||
import { useClipboard, useElementSize } from '@vueuse/core';
|
||||
import hljs from 'highlight.js/lib/core';
|
||||
import jsonHljs from 'highlight.js/lib/languages/json';
|
||||
import sqlHljs from 'highlight.js/lib/languages/sql';
|
||||
import { ref, toRefs } from 'vue';
|
||||
|
||||
hljs.registerLanguage('sql', sqlHljs);
|
||||
hljs.registerLanguage('json', jsonHljs);
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value: string;
|
||||
followHeightOf?: HTMLElement | null;
|
||||
language?: string;
|
||||
copyPlacement?: 'top-right' | 'bottom-right' | 'outside' | 'none';
|
||||
copyMessage?: string;
|
||||
}>(),
|
||||
{
|
||||
followHeightOf: null,
|
||||
language: 'txt',
|
||||
copyPlacement: 'top-right',
|
||||
copyMessage: 'Copy to clipboard',
|
||||
},
|
||||
);
|
||||
const { value, language, followHeightOf, copyPlacement, copyMessage } = toRefs(props);
|
||||
const { height } = followHeightOf ? useElementSize(followHeightOf) : { height: ref(null) };
|
||||
|
||||
const { copy } = useClipboard({ source: value });
|
||||
const tooltipText = ref(copyMessage.value);
|
||||
|
||||
function onCopyClicked() {
|
||||
copy();
|
||||
tooltipText.value = 'Copied !';
|
||||
|
||||
setTimeout(() => {
|
||||
tooltipText.value = copyMessage.value;
|
||||
}, 2000);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
::v-deep(.n-scrollbar) {
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: -10px;
|
||||
}
|
||||
.result-card {
|
||||
position: relative;
|
||||
.copy-button {
|
||||
position: absolute;
|
||||
opacity: 1;
|
||||
|
||||
&.top-right {
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
&.bottom-right {
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
&.outside,
|
||||
&.none {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -17,26 +17,16 @@
|
|||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="Prettify version of your json">
|
||||
<n-card class="result-card" :style="`min-height: ${inputElementHeight ?? 400}px`">
|
||||
<n-config-provider :hljs="hljs">
|
||||
<n-code :code="cleanJson" language="json" :trim="false" />
|
||||
</n-config-provider>
|
||||
<n-button v-if="cleanJson" class="copy-button" secondary @click="copy">Copy</n-button>
|
||||
</n-card>
|
||||
<textarea-copyable :value="cleanJson" language="json" :follow-height-of="inputElement" />
|
||||
</n-form-item>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useCopy } from '@/composable/copy';
|
||||
import TextareaCopyable from '@/components/TextareaCopyable.vue';
|
||||
import { useValidation } from '@/composable/validation';
|
||||
import { useElementSize } from '@vueuse/core';
|
||||
import hljs from 'highlight.js/lib/core';
|
||||
import json from 'highlight.js/lib/languages/json';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
hljs.registerLanguage('json', json);
|
||||
const inputElement = ref<HTMLElement>();
|
||||
const { height: inputElementHeight } = useElementSize(inputElement);
|
||||
|
||||
const rawJson = ref('{"hello": "world"}');
|
||||
const cleanJson = computed(() => {
|
||||
|
@ -47,8 +37,6 @@ const cleanJson = computed(() => {
|
|||
}
|
||||
});
|
||||
|
||||
const { copy } = useCopy({ source: cleanJson });
|
||||
|
||||
const rawJsonValidation = useValidation({
|
||||
source: rawJson,
|
||||
rules: [
|
||||
|
|
|
@ -58,27 +58,17 @@
|
|||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="Prettify version of your query">
|
||||
<n-card class="result-card" :style="`min-height: ${inputElementHeight ?? 400}px`">
|
||||
<n-config-provider :hljs="hljs">
|
||||
<n-code :code="prettySQL" language="sql" :trim="false" />
|
||||
</n-config-provider>
|
||||
<n-button v-if="prettySQL" class="copy-button" secondary @click="copy">Copy</n-button>
|
||||
</n-card>
|
||||
<textarea-copyable :value="prettySQL" language="sql" :follow-height-of="inputElement" />
|
||||
</n-form-item>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useCopy } from '@/composable/copy';
|
||||
import TextareaCopyable from '@/components/TextareaCopyable.vue';
|
||||
import { useStyleStore } from '@/stores/style.store';
|
||||
import { useElementSize } from '@vueuse/core';
|
||||
import hljs from 'highlight.js/lib/core';
|
||||
import sqlHljs from 'highlight.js/lib/languages/sql';
|
||||
import { format as formatSQL, type FormatFnOptions } from 'sql-formatter';
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
hljs.registerLanguage('sql', sqlHljs);
|
||||
|
||||
const inputElement = ref<HTMLElement>();
|
||||
const { height: inputElementHeight } = useElementSize(inputElement);
|
||||
const styleStore = useStyleStore();
|
||||
const config = reactive<Partial<FormatFnOptions>>({
|
||||
keywordCase: 'upper',
|
||||
|
@ -90,7 +80,6 @@ const config = reactive<Partial<FormatFnOptions>>({
|
|||
|
||||
const rawSQL = ref('select field1,field2,field3 from my_table where my_condition;');
|
||||
const prettySQL = computed(() => formatSQL(rawSQL.value, config));
|
||||
const { copy } = useCopy({ source: prettySQL });
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue