it-tools/src/tools/json-viewer/json-viewer.vue

72 lines
2.1 KiB
Vue
Raw Normal View History

<script setup lang="ts">
import JSON5 from 'json5';
import { useStorage } from '@vueuse/core';
import { formatJson } from './json.models';
import { withDefaultOnError } from '@/utils/defaults';
import { useValidation } from '@/composable/validation';
import TextareaCopyable from '@/components/TextareaCopyable.vue';
const inputElement = ref<HTMLElement>();
const rawJson = useStorage('json-prettify:raw-json', '{"hello": "world", "foo": "bar"}');
const indentSize = useStorage('json-prettify:indent-size', 3);
const sortKeys = useStorage('json-prettify:sort-keys', true);
const cleanJson = computed(() => withDefaultOnError(() => formatJson({ rawJson, indentSize, sortKeys }), ''));
const rawJsonValidation = useValidation({
source: rawJson,
rules: [
{
validator: v => v === '' || JSON5.parse(v),
message: 'Provided JSON is not valid.',
},
],
});
</script>
2022-05-09 17:41:42 +02:00
<template>
2023-03-29 23:25:39 +02:00
<div style="flex: 0 0 100%">
2023-05-27 17:36:15 +02:00
<div style="margin: 0 auto; max-width: 600px" flex justify-center gap-3>
2023-03-29 23:25:39 +02:00
<n-form-item label="Sort keys :" label-placement="left" label-width="100">
<n-switch v-model:value="sortKeys" />
</n-form-item>
<n-form-item label="Indent size :" label-placement="left" label-width="100" :show-feedback="false">
<n-input-number v-model:value="indentSize" min="0" max="10" style="width: 100px" />
</n-form-item>
2023-05-27 17:36:15 +02:00
</div>
2023-03-29 23:25:39 +02:00
</div>
<n-form-item
label="Your raw JSON"
:feedback="rawJsonValidation.message"
:validation-status="rawJsonValidation.status"
>
<c-input-text
ref="inputElement"
v-model:value="rawJson"
placeholder="Paste your raw JSON here..."
rows="20"
multiline
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"
monospace
/>
</n-form-item>
<n-form-item label="Prettified version of your JSON">
<TextareaCopyable :value="cleanJson" language="json" :follow-height-of="inputElement" />
</n-form-item>
2022-05-09 17:41:42 +02:00
</template>
<style lang="less" scoped>
.result-card {
position: relative;
.copy-button {
position: absolute;
top: 10px;
right: 10px;
}
2022-05-09 17:41:42 +02:00
}
</style>