Tabs initial
This commit is contained in:
Vendored
+15
@@ -6,3 +6,18 @@ interface EditorUpdateEvent {
|
||||
interface EditorEvents {
|
||||
update: EditorUpdateEvent;
|
||||
}
|
||||
|
||||
interface TabEvents {
|
||||
select: Tab;
|
||||
}
|
||||
|
||||
interface Tab {
|
||||
id: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
interface State {
|
||||
code: string;
|
||||
mermaid: any;
|
||||
updateEditor: boolean;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<div class="bg-white p-2 m-2 rounded shadow h-full flex-col">
|
||||
<div class="bg-blue-400 border-gray-400 -p-2">
|
||||
<div class={`bg-white m-2 rounded overflow-hidden shadow flex flex-col ${$$props.class}`}>
|
||||
<div class="bg-blue-400 border-gray-400 p-2 flex-none">
|
||||
<slot name="title" />
|
||||
</div>
|
||||
<div class="h-full">
|
||||
<slot name="body" />
|
||||
<div class="flex-grow">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,15 +12,12 @@
|
||||
export let editorOptions: monaco.editor.IStandaloneEditorConstructionOptions = {
|
||||
value: ['function x() {', '\tconsole.log("Hello world!");', '}'].join('\n'),
|
||||
language: 'javascript'
|
||||
// automaticLayout: true
|
||||
};
|
||||
const dispatch = createEventDispatcher<EditorEvents>();
|
||||
let resizeHandler: any = () => {};
|
||||
|
||||
export const getResizeHandler = (editor) => {
|
||||
return (node) => editor && editor.layout();
|
||||
};
|
||||
const dispatch = createEventDispatcher<EditorEvents>();
|
||||
|
||||
onMount(async () => {
|
||||
resizeHandler = getResizeHandler(divEl);
|
||||
// @ts-ignore
|
||||
self.MonacoEnvironment = {
|
||||
getWorker: function (_moduleId: any, label: string) {
|
||||
@@ -40,14 +37,14 @@
|
||||
}
|
||||
};
|
||||
Monaco = await import('monaco-editor');
|
||||
// divEl = document.getElementById('editor') as HTMLDivElement;
|
||||
editor = Monaco.editor.create(divEl, editorOptions);
|
||||
|
||||
editor.onDidChangeModelContent(async () => {
|
||||
dispatch('update', {
|
||||
text: editor.getValue()
|
||||
});
|
||||
});
|
||||
editor.layout();
|
||||
// editor.layout();
|
||||
return () => {
|
||||
editor.dispose();
|
||||
};
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
export let tabs: Tab[] = [];
|
||||
export let activeTabID: string = tabs[0].id;
|
||||
const dispatch = createEventDispatcher<TabEvents>();
|
||||
const toggleTabs = (tab: Tab) => {
|
||||
activeTabID = tab.id;
|
||||
dispatch('select', tab);
|
||||
};
|
||||
</script>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<ul class="flex mb-0 list-none flex-wrap flex-row">
|
||||
{#each tabs as tab}
|
||||
<li class="-mb-2 mr-2 last:mr-0 flex-auto text-center">
|
||||
<!-- svelte-ignore a11y-missing-attribute -->
|
||||
<a
|
||||
class="text-xs font-bold w-16 py-1 shadow-lg rounded-t block leading-normal {activeTabID ===
|
||||
tab.id
|
||||
? 'text-blue-500 bg-white'
|
||||
: 'text-white bg-blue-500'}"
|
||||
on:click={() => toggleTabs(tab)}
|
||||
>
|
||||
{tab.title}
|
||||
</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
@@ -0,0 +1,51 @@
|
||||
import { writable } from 'svelte/store';
|
||||
import { encode, decode } from 'js-base64';
|
||||
|
||||
const defaultState: State = {
|
||||
code: `graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
mermaid: 'default',
|
||||
updateEditor: false
|
||||
};
|
||||
|
||||
export const codeStore = writable(defaultState);
|
||||
|
||||
export const loadState = (data: string): void => {
|
||||
let state: State;
|
||||
try {
|
||||
const stateStr = decode(data);
|
||||
console.log('state from url', stateStr);
|
||||
state = JSON.parse(stateStr);
|
||||
} catch (e) {
|
||||
console.error('Init error', e);
|
||||
state = defaultState;
|
||||
}
|
||||
codeStore.set({ ...state, updateEditor: true });
|
||||
};
|
||||
|
||||
export const updateCodeStore = (newState: State): void => {
|
||||
codeStore.set(newState);
|
||||
};
|
||||
|
||||
export const updateCode = (code: string, updateEditor: boolean): void => {
|
||||
codeStore.update((state) => {
|
||||
return { ...state, code, updateEditor };
|
||||
});
|
||||
};
|
||||
|
||||
export const updateConfig = (config: any, updateEditor: boolean): void => {
|
||||
codeStore.update((state) => {
|
||||
return { ...state, mermaid: config, updateEditor };
|
||||
});
|
||||
};
|
||||
|
||||
export const initURLSubscription = (): void => {
|
||||
codeStore.subscribe((state: State) => {
|
||||
window.location.hash = encode(JSON.stringify(state), true);
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
import { loadState } from './state';
|
||||
|
||||
export const loadStateFromURL = (): void => {
|
||||
debugger;
|
||||
loadState(window.location.hash);
|
||||
};
|
||||
@@ -1,12 +1,11 @@
|
||||
<script lang="ts">
|
||||
import Header from '$lib/Header/index.svelte';
|
||||
import '../app.postcss';
|
||||
</script>
|
||||
|
||||
<div class="h-screen">
|
||||
<!-- <Header /> -->
|
||||
|
||||
<main class="h-full bg-red-300">
|
||||
<main class="h-full">
|
||||
<slot />
|
||||
</main>
|
||||
</div>
|
||||
|
||||
+41
-13
@@ -1,11 +1,35 @@
|
||||
<script context="module">
|
||||
export const ssr = false;
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import Editor from '$lib/Editor/index.svelte';
|
||||
import { encode, decode } from 'js-base64';
|
||||
import Card from '$lib/Card/index.svelte';
|
||||
const updateHandler = async (message: CustomEvent<EditorUpdateEvent>) => {
|
||||
window.location.hash = encode(message.detail.text, true);
|
||||
import Tabs from '$lib/Tabs/index.svelte';
|
||||
import { initURLSubscription, updateCode } from '$lib/Util/state';
|
||||
import { loadStateFromURL } from '$lib/Util/util';
|
||||
|
||||
let selectedTab = 'code';
|
||||
const tabSelectHandler = (message: CustomEvent<Tab>) => {
|
||||
selectedTab = message.detail.id;
|
||||
};
|
||||
const tabs: Tab[] = [
|
||||
{
|
||||
id: 'code',
|
||||
title: 'Code'
|
||||
},
|
||||
{
|
||||
id: 'config',
|
||||
title: 'Config'
|
||||
}
|
||||
];
|
||||
|
||||
const updateHandler = async (message: CustomEvent<EditorUpdateEvent>) => {
|
||||
updateCode(message.detail.text, false);
|
||||
};
|
||||
|
||||
loadStateFromURL();
|
||||
initURLSubscription();
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@@ -13,13 +37,17 @@
|
||||
</svelte:head>
|
||||
|
||||
<div class="w-2/5 h-screen flex flex-col gap-6">
|
||||
<div class="h-2/3 overflow-hidden">
|
||||
<Card>
|
||||
<h1 slot="title">Hello</h1>
|
||||
<Editor slot="body" on:update={updateHandler} />
|
||||
</Card>
|
||||
</div>
|
||||
<div class="flex-grow shadow bg-white p-4 rounded">
|
||||
<Editor on:update={updateHandler} />
|
||||
</div>
|
||||
<Card class="h-1/2">
|
||||
<div slot="title">
|
||||
<Tabs on:select={tabSelectHandler} {tabs} />
|
||||
</div>
|
||||
|
||||
{#if selectedTab == 'code'}
|
||||
<Editor on:update={updateHandler} />
|
||||
{:else}
|
||||
<Editor on:update={updateHandler} />
|
||||
{/if}
|
||||
</Card>
|
||||
|
||||
<Card class="h-1/3" />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user