1
0
mirror of https://github.com/garraflavatra/rolens.git synced 2025-07-14 04:34:04 +00:00

Implement object viewer based on codemirror

This commit is contained in:
2023-05-29 17:07:58 +02:00
parent 8319f0bd82
commit 5015a47495
10 changed files with 415 additions and 248 deletions

View File

@ -1,64 +1,77 @@
<script>
import Icon from './icon.svelte';
import Modal from './modal.svelte';
import ObjectTree from './objecttree.svelte';
import { onDestroy } from 'svelte';
import { deepClone } from '$lib/objects';
import { createEventDispatcher, onDestroy } from 'svelte';
import ObjectEditor from './objecteditor.svelte';
import { jsonLooseParse } from '$lib/strings';
export let data;
export let saveable = false;
const dispatch = createEventDispatcher();
let copySucceeded = false;
let timeout;
let _data;
let text = JSON.stringify(data, undefined, '\t');
let newData;
let invalid = false;
$: if (data) {
_data = deepClone(data);
for (const key of Object.keys(_data)) {
if (typeof _data[key] === 'undefined') {
delete _data[key];
}
$: {
try {
newData = jsonLooseParse(text);
}
catch {
invalid = true;
}
}
async function copy() {
await navigator.clipboard.writeText(JSON.stringify(_data));
await navigator.clipboard.writeText(text);
copySucceeded = true;
timeout = setTimeout(() => copySucceeded = false, 1500);
}
function close() {
data = undefined;
text = '';
}
function save() {
dispatch('save', text);
}
onDestroy(() => clearTimeout(timeout));
</script>
{#if data}
<Modal bind:show={data} title="Object viewer">
<Modal bind:show={data} contentPadding={false}>
<div class="objectviewer">
<div class="buttons">
<button class="btn" on:click={copy}>
<Icon name={copySucceeded ? 'check' : 'clipboard'} />
</button>
</div>
<div class="code">
<ObjectTree data={_data} />
</div>
<ObjectEditor {text} />
</div>
<svelte:fragment slot="footer">
{#if saveable}
<button class="btn" on:click={save} disabled={invalid}>
<Icon name="save" /> Save
</button>
{/if}
<button class="btn secondary" on:click={close}>
<Icon name="x" /> Close
</button>
<button class="btn secondary" on:click={copy}>
<Icon name={copySucceeded ? 'check' : 'clipboard'} /> Copy
</button>
</svelte:fragment>
</Modal>
{/if}
<style>
.objectviewer {
display: flex;
position: relative;
}
.objectviewer .code :global(span.root) {
display: block;
}
.buttons {
position: absolute;
top: 0;
right: 0;
}
.buttons button {
margin-left: 1rem;
justify-content: stretch;
align-items: stretch;
height: 100%;
}
</style>