-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
258 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,66 @@ | ||
import contentRaw from "$content/guide.yaml?raw"; | ||
import { CodeMirror } from "./CodeMirror"; | ||
import { | ||
createSignal, | ||
ErrorBoundary, | ||
lazy, | ||
Suspense, | ||
createMemo, | ||
} from "solid-js"; | ||
import YAML from "yaml"; | ||
import { contentToMermaid } from "../graph/mermaid"; | ||
import { Button } from "$components/Button"; | ||
|
||
import "./editor.css"; | ||
import { download } from "./util"; | ||
|
||
const Mermaid = lazy(() => | ||
import("../graph/Mermaid").then((m) => ({ default: m.Mermaid })) | ||
); | ||
|
||
export function Editor() { | ||
const [showStep, setShowStep] = createSignal<string>(); | ||
const [content, setContent] = createSignal(contentRaw); | ||
const mermaid = createMemo(() => contentToMermaid(YAML.parse(content()))); | ||
|
||
return ( | ||
<div id="editor"> | ||
<CodeMirror content={contentRaw} /> | ||
<div>E</div> | ||
<div id="editor" class="full-window"> | ||
<div> | ||
<CodeMirror | ||
initialContent={content()} | ||
onChange={setContent} | ||
showStep={showStep()} | ||
/> | ||
</div> | ||
|
||
<div class="full-window"> | ||
<div class="toolbar"> | ||
<Button onClick={() => download("guide.yaml", content())}> | ||
Download YAML | ||
</Button> | ||
<Button | ||
onClick={() => | ||
download("guide.md", "```mermaid\n" + mermaid() + "\n```") | ||
} | ||
> | ||
Download Mermaid | ||
</Button> | ||
</div> | ||
|
||
<Suspense fallback={<p>Loading...</p>}> | ||
<ErrorBoundary | ||
fallback={(err) => ( | ||
<div> | ||
Error rendering graph | ||
<br /> | ||
<pre>{err.toString()}</pre> | ||
</div> | ||
)} | ||
> | ||
<Mermaid content={mermaid()} onClick={setShowStep} /> | ||
</ErrorBoundary> | ||
</Suspense> | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export function download( | ||
filename: string, | ||
content: string, | ||
type = "text/plain" | ||
) { | ||
const blob = new Blob([content], { type }); | ||
const href = URL.createObjectURL(blob); | ||
|
||
const a = document.createElement("a"); | ||
a.setAttribute("download", filename); | ||
a.setAttribute("href", href); | ||
a.click(); | ||
URL.revokeObjectURL(href); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { CONTENT } from "$lib/content"; | ||
import { contentToMermaid } from "./mermaid"; | ||
import { Mermaid } from "./Mermaid"; | ||
|
||
export function Graph() { | ||
return ( | ||
<div class="full-window"> | ||
<Mermaid content={contentToMermaid(CONTENT)} /> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { createResource, onMount, onCleanup } from "solid-js"; | ||
import mermaid from "mermaid"; | ||
import elkLayouts from "@mermaid-js/layout-elk"; | ||
import panzoom, { PanZoom } from "panzoom"; | ||
|
||
import "./mermaid.css"; | ||
|
||
mermaid.registerLayoutLoaders(elkLayouts); | ||
mermaid.initialize({ | ||
startOnLoad: false, | ||
theme: "dark", | ||
layout: "elk", | ||
elk: { | ||
nodePlacementStrategy: "LINEAR_SEGMENTS", | ||
cycleBreakingStrategy: "MODEL_ORDER", | ||
}, | ||
}); | ||
|
||
export interface MermaidProps { | ||
content: string; | ||
onClick?: (step: string) => void; | ||
} | ||
|
||
export function Mermaid(props: MermaidProps) { | ||
const [svg] = createResource(async () => { | ||
const { svg } = await mermaid.render("mermaid", props.content); | ||
return svg; | ||
}); | ||
|
||
let element: HTMLDivElement | undefined = undefined; | ||
let controls: PanZoom; | ||
|
||
onMount(() => { | ||
controls = panzoom(element!, { | ||
bounds: true, | ||
boundsPadding: 0.0, | ||
}); | ||
}); | ||
|
||
onCleanup(() => { | ||
controls.dispose(); | ||
}); | ||
|
||
function onClick(ev: MouseEvent) { | ||
const element = ev.target as Element; | ||
const parent = element.closest("g.node"); | ||
if (!parent) return; | ||
const step = parent.getAttribute("id")?.split("-").slice(1, -1).join("-"); | ||
if (step) props.onClick?.(step); | ||
} | ||
|
||
return <div id="mermaid" ref={element} onClick={onClick} innerHTML={svg()} />; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#mermaid .node.default { | ||
cursor: pointer; | ||
} | ||
|
||
#mermaid .node.default .label-container { | ||
transition: fill 0.1s; | ||
} | ||
|
||
#mermaid .node.default:hover .label-container { | ||
fill: #333; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Content } from "$lib/content"; | ||
|
||
export function contentToMermaid(content: Content) { | ||
let mermaid = `graph TD\n`; | ||
|
||
for (const [stepName, step] of Object.entries(content)) { | ||
let title = `"${step.title.replace('"', "#quot;")}"`; | ||
if (stepName == "start" || !step.options?.length) { | ||
title = "([" + title + "])"; | ||
} else if ((step.options?.length ?? 0) > 1) { | ||
title = "{{" + title + "}}"; | ||
} else { | ||
title = "[" + title + "]"; | ||
} | ||
|
||
if (step.options?.length) { | ||
let first = true; | ||
for (const option of step.options) { | ||
mermaid += `\t${stepName}`; | ||
|
||
if (first) { | ||
mermaid += `${title}`; | ||
first = false; | ||
} | ||
|
||
mermaid += ` --"${option.label}"--> ${option.target}\n`; | ||
} | ||
} else { | ||
mermaid += `\t${stepName}${title}\n`; | ||
} | ||
} | ||
|
||
return mermaid; | ||
} |