Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1fd4dc244 | ||
|
|
9436f8ddda |
@@ -5,7 +5,6 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<title>Online FlowChart & Diagrams Editor - Mermaid Live Editor</title>
|
<title>Online FlowChart & Diagrams Editor - Mermaid Live Editor</title>
|
||||||
<meta name="og:image" content="%sveltekit.assets%/favicon.svg" />
|
<meta name="og:image" content="%sveltekit.assets%/favicon.svg" />
|
||||||
<link rel="canonical" href="https://mermaid.ai/live" />
|
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="Simplify documentation and avoid heavy tools. Open source Visio Alternative. Commonly used for explaining your code! Mermaid is a simple markdown-like script language for generating charts from text via javascript." />
|
content="Simplify documentation and avoid heavy tools. Open source Visio Alternative. Commonly used for explaining your code! Mermaid is a simple markdown-like script language for generating charts from text via javascript." />
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import McWrapper from '$/components/McWrapper.svelte';
|
||||||
|
import MermaidChartIcon from '$/components/MermaidChartIcon.svelte';
|
||||||
|
import { Button } from '$/components/ui/button';
|
||||||
|
import { standardizeDiagramType } from '$/util/mermaid';
|
||||||
|
import { stateStore, urlsStore } from '$/util/state';
|
||||||
|
import { logMermaidChartClick } from '$/util/stats';
|
||||||
|
import { quintInOut } from 'svelte/easing';
|
||||||
|
import { slide } from 'svelte/transition';
|
||||||
|
|
||||||
|
const visualEditDiagramTypes = new Set([
|
||||||
|
'flowchart',
|
||||||
|
'stateDiagram',
|
||||||
|
'classDiagram',
|
||||||
|
'sequenceDiagram',
|
||||||
|
'er',
|
||||||
|
'requirement',
|
||||||
|
'mindmap'
|
||||||
|
]);
|
||||||
|
|
||||||
|
const diagramType = $derived.by(() => {
|
||||||
|
const dt = $stateStore.diagramType;
|
||||||
|
return dt ? standardizeDiagramType(dt) : undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
const showVisualEdit = $derived.by(() => {
|
||||||
|
return diagramType ? visualEditDiagramTypes.has(diagramType) : false;
|
||||||
|
});
|
||||||
|
|
||||||
|
interface EnhancedEditAction {
|
||||||
|
campaign: string;
|
||||||
|
label: string;
|
||||||
|
medium: 'ai_edit' | 'visual_edit' | 'voice_edit';
|
||||||
|
source: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
let currentActionMedium = $state<EnhancedEditAction['medium'] | undefined>(undefined);
|
||||||
|
let previousDiagramType = $state<string | undefined>(undefined);
|
||||||
|
|
||||||
|
const availableActions = $derived.by<EnhancedEditAction[]>(() => {
|
||||||
|
if (!$stateStore.diagramType) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions: EnhancedEditAction[] = [
|
||||||
|
{ campaign: 'ai_1', label: 'with AI', medium: 'ai_edit', source: 'aiEdit' },
|
||||||
|
{ campaign: 'voice_1', label: 'with Voice', medium: 'voice_edit', source: 'voiceEdit' }
|
||||||
|
];
|
||||||
|
|
||||||
|
if (showVisualEdit) {
|
||||||
|
actions.unshift({
|
||||||
|
campaign: 'visual_1',
|
||||||
|
label: 'Visually',
|
||||||
|
medium: 'visual_edit',
|
||||||
|
source: 'visualEdit'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
});
|
||||||
|
|
||||||
|
const currentAction = $derived.by(() => {
|
||||||
|
const actions = availableActions;
|
||||||
|
if (actions.length === 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return actions.find(({ medium }) => medium === currentActionMedium) ?? actions[0];
|
||||||
|
});
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
const actions = availableActions;
|
||||||
|
|
||||||
|
if (!diagramType || actions.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasCurrentAction = actions.some(({ medium }) => medium === currentActionMedium);
|
||||||
|
|
||||||
|
if (diagramType !== previousDiagramType || !hasCurrentAction) {
|
||||||
|
currentActionMedium = actions[Math.floor(Math.random() * actions.length)].medium;
|
||||||
|
previousDiagramType = diagramType;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (diagramType) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
previousDiagramType = undefined;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if currentAction}
|
||||||
|
<McWrapper>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
size="sm"
|
||||||
|
href={$urlsStore.mermaidChart({
|
||||||
|
medium: currentAction.medium,
|
||||||
|
campaign: currentAction.campaign
|
||||||
|
}).save}
|
||||||
|
target="_blank"
|
||||||
|
onclick={() => logMermaidChartClick(currentAction.source)}>
|
||||||
|
<MermaidChartIcon />
|
||||||
|
Edit
|
||||||
|
{#key currentAction.label}
|
||||||
|
<span
|
||||||
|
class="-ml-1"
|
||||||
|
in:slide={{ axis: 'x', easing: quintInOut, delay: 400 }}
|
||||||
|
out:slide={{ axis: 'x', easing: quintInOut }}>
|
||||||
|
{currentAction.label}
|
||||||
|
</span>
|
||||||
|
{/key}
|
||||||
|
</Button>
|
||||||
|
</McWrapper>
|
||||||
|
{/if}
|
||||||
@@ -142,11 +142,13 @@ export const urlsStore = derived([stateStore], ([{ code, serialized }]) => {
|
|||||||
}: {
|
}: {
|
||||||
medium:
|
medium:
|
||||||
| 'ai_repair'
|
| 'ai_repair'
|
||||||
|
| 'ai_edit'
|
||||||
| 'main_menu'
|
| 'main_menu'
|
||||||
| 'save_diagram'
|
| 'save_diagram'
|
||||||
| 'share'
|
| 'share'
|
||||||
| 'vibe_diagramming'
|
| 'vibe_diagramming'
|
||||||
| 'visual_edit';
|
| 'visual_edit'
|
||||||
|
| 'voice_edit';
|
||||||
campaign?: string;
|
campaign?: string;
|
||||||
}) => {
|
}) => {
|
||||||
const utmSource = getUTMSource();
|
const utmSource = getUTMSource();
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import Card from '$/components/Card/Card.svelte';
|
import Card from '$/components/Card/Card.svelte';
|
||||||
import DiagramDocButton from '$/components/DiagramDocumentationButton.svelte';
|
import DiagramDocButton from '$/components/DiagramDocumentationButton.svelte';
|
||||||
import Editor from '$/components/Editor.svelte';
|
import Editor from '$/components/Editor.svelte';
|
||||||
|
import EnhancedEditsButton from '$/components/EnhancedEditsButton.svelte';
|
||||||
import History from '$/components/History/History.svelte';
|
import History from '$/components/History/History.svelte';
|
||||||
import McWrapper from '$/components/McWrapper.svelte';
|
import McWrapper from '$/components/McWrapper.svelte';
|
||||||
import MermaidChartIcon from '$/components/MermaidChartIcon.svelte';
|
import MermaidChartIcon from '$/components/MermaidChartIcon.svelte';
|
||||||
@@ -19,15 +20,12 @@
|
|||||||
import VersionSecurityToolbar from '$/components/VersionSecurityToolbar.svelte';
|
import VersionSecurityToolbar from '$/components/VersionSecurityToolbar.svelte';
|
||||||
import View from '$/components/View.svelte';
|
import View from '$/components/View.svelte';
|
||||||
import type { EditorMode, Tab } from '$/types';
|
import type { EditorMode, Tab } from '$/types';
|
||||||
import { standardizeDiagramType } from '$/util/mermaid';
|
|
||||||
import { shouldShowEditorChooser } from '$/util/migration/domainMigration';
|
import { shouldShowEditorChooser } from '$/util/migration/domainMigration';
|
||||||
import { PanZoomState } from '$/util/panZoom';
|
import { PanZoomState } from '$/util/panZoom';
|
||||||
import { stateStore, updateCodeStore, urlsStore } from '$/util/state';
|
import { stateStore, updateCodeStore, urlsStore } from '$/util/state';
|
||||||
import { logEvent, logMermaidChartClick } from '$/util/stats';
|
import { logEvent, logMermaidChartClick } from '$/util/stats';
|
||||||
import { initHandler } from '$/util/util';
|
import { initHandler } from '$/util/util';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { quintInOut } from 'svelte/easing';
|
|
||||||
import { slide } from 'svelte/transition';
|
|
||||||
import CodeIcon from '~icons/custom/code';
|
import CodeIcon from '~icons/custom/code';
|
||||||
import HistoryIcon from '~icons/material-symbols/history';
|
import HistoryIcon from '~icons/material-symbols/history';
|
||||||
import GearIcon from '~icons/material-symbols/settings-outline-rounded';
|
import GearIcon from '~icons/material-symbols/settings-outline-rounded';
|
||||||
@@ -65,20 +63,6 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const visualEditDiagramTypes = new Set([
|
|
||||||
'flowchart',
|
|
||||||
'stateDiagram',
|
|
||||||
'classDiagram',
|
|
||||||
'sequenceDiagram',
|
|
||||||
'er',
|
|
||||||
'requirement',
|
|
||||||
'mindmap'
|
|
||||||
]);
|
|
||||||
const showVisualEdit = $derived.by(() => {
|
|
||||||
const dt = $stateStore.diagramType;
|
|
||||||
return dt ? visualEditDiagramTypes.has(standardizeDiagramType(dt)) : false;
|
|
||||||
});
|
|
||||||
|
|
||||||
let isHistoryOpen = $state(false);
|
let isHistoryOpen = $state(false);
|
||||||
|
|
||||||
let editorPane: Resizable.Pane | undefined;
|
let editorPane: Resizable.Pane | undefined;
|
||||||
@@ -153,24 +137,7 @@
|
|||||||
<Resizable.Handle class="mr-1 hidden opacity-0 sm:block" />
|
<Resizable.Handle class="mr-1 hidden opacity-0 sm:block" />
|
||||||
<Resizable.Pane minSize={15} class="relative flex h-full flex-1 flex-col overflow-hidden">
|
<Resizable.Pane minSize={15} class="relative flex h-full flex-1 flex-col overflow-hidden">
|
||||||
<View {panZoomState} shouldShowGrid={$stateStore.grid} />
|
<View {panZoomState} shouldShowGrid={$stateStore.grid} />
|
||||||
{#if showVisualEdit}
|
<div class="absolute top-0 left-5 hidden md:block"><EnhancedEditsButton /></div>
|
||||||
<div
|
|
||||||
class="absolute top-0 left-5 hidden md:block"
|
|
||||||
transition:slide={{ axis: 'x', easing: quintInOut }}>
|
|
||||||
<McWrapper>
|
|
||||||
<Button
|
|
||||||
variant="secondary"
|
|
||||||
size="sm"
|
|
||||||
href={$urlsStore.mermaidChart({ medium: 'visual_edit', campaign: 'visual_1' })
|
|
||||||
.save}
|
|
||||||
target="_blank"
|
|
||||||
onclick={() => logMermaidChartClick('visualEdit')}>
|
|
||||||
<MermaidChartIcon />
|
|
||||||
Edit Visually
|
|
||||||
</Button>
|
|
||||||
</McWrapper>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
<div class="absolute top-0 right-0"><PanZoomToolbar {panZoomState} /></div>
|
<div class="absolute top-0 right-0"><PanZoomToolbar {panZoomState} /></div>
|
||||||
<div class="absolute right-0 bottom-0"><VersionSecurityToolbar /></div>
|
<div class="absolute right-0 bottom-0"><VersionSecurityToolbar /></div>
|
||||||
<div class="absolute bottom-0 left-0 sm:left-5"><SyncRoughToolbar /></div>
|
<div class="absolute bottom-0 left-0 sm:left-5"><SyncRoughToolbar /></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user