241 lines
7.6 KiB
HTML
241 lines
7.6 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<style>
|
|
body {
|
|
display: flex;
|
|
gap: 20px;
|
|
padding: 20px;
|
|
height: 100vh;
|
|
margin: 0;
|
|
font-family: system-ui, -apple-system, sans-serif;
|
|
}
|
|
.controls {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
width: 400px;
|
|
}
|
|
textarea {
|
|
width: 100%;
|
|
height: 300px;
|
|
padding: 8px;
|
|
border: 1px solid #ccc;
|
|
border-radius: 4px;
|
|
font-family: monospace;
|
|
}
|
|
.options-group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
padding: 12px;
|
|
border: 1px solid #eee;
|
|
border-radius: 4px;
|
|
}
|
|
.layout-toggle,
|
|
.sketch-toggle,
|
|
.center-toggle,
|
|
.appendix-toggle,
|
|
.theme-select,
|
|
.dark-theme-select,
|
|
.padding-input,
|
|
.scale-input {
|
|
display: flex;
|
|
gap: 16px;
|
|
align-items: center;
|
|
}
|
|
.radio-group {
|
|
display: flex;
|
|
gap: 12px;
|
|
}
|
|
.input-label,
|
|
.select-label,
|
|
.radio-label,
|
|
.checkbox-label {
|
|
display: flex;
|
|
gap: 4px;
|
|
align-items: center;
|
|
cursor: pointer;
|
|
}
|
|
.number-input {
|
|
width: 3rem;
|
|
}
|
|
button {
|
|
padding: 8px 16px;
|
|
background: #0066cc;
|
|
color: white;
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
}
|
|
button:hover {
|
|
background: #0052a3;
|
|
}
|
|
#output {
|
|
flex: 1;
|
|
overflow: auto;
|
|
border: 1px solid #eee;
|
|
border-radius: 4px;
|
|
padding: 16px;
|
|
}
|
|
#output svg {
|
|
max-width: 100%;
|
|
max-height: 90vh;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="controls">
|
|
<textarea id="input">x -> y</textarea>
|
|
<div class="options-group">
|
|
<div class="layout-toggle">
|
|
<span>Layout:</span>
|
|
<div class="radio-group">
|
|
<label class="radio-label">
|
|
<input type="radio" name="layout" value="dagre" checked />
|
|
Dagre
|
|
</label>
|
|
<label class="radio-label">
|
|
<input type="radio" name="layout" value="elk" />
|
|
ELK
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="sketch-toggle">
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" id="sketch" />
|
|
Sketch mode
|
|
</label>
|
|
</div>
|
|
<div class="center-toggle">
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" id="center" />
|
|
Centered
|
|
</label>
|
|
</div>
|
|
<div class="appendix-toggle">
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" id="appendix" />
|
|
Force Appendix
|
|
</label>
|
|
</div>
|
|
<div class="theme-select">
|
|
<label class="select-label">
|
|
<select id="theme" name="theme">
|
|
<option value="-1"></option>
|
|
<option selected value="0">Default</option>
|
|
<option value="1">Neutral grey</option>
|
|
<option value="3">Flagship Terrastruct</option>
|
|
<option value="4">Cool classics</option>
|
|
<option value="5">Mixed berry blue</option>
|
|
<option value="6">Grape soda</option>
|
|
<option value="7">Aubergine</option>
|
|
<option value="8">Colorblind clear</option>
|
|
<option value="100">Vanilla nitro cola</option>
|
|
<option value="101">Orange creamsicle</option>
|
|
<option value="102">Shirley temple</option>
|
|
<option value="103">Earth tones</option>
|
|
<option value="104">Everglade green</option>
|
|
<option value="105">Buttered toast</option>
|
|
<option value="200">Dark mauve</option>
|
|
<option value="300">Terminal</option>
|
|
<option value="301">Terminal grayscale</option>
|
|
</select>
|
|
Theme ID
|
|
</label>
|
|
</div>
|
|
<div class="dark-theme-select">
|
|
<label class="select-label">
|
|
<select id="dark-theme" name="dark-theme">
|
|
<option value="-1"></option>
|
|
<option value="0">Default</option>
|
|
<option value="1">Neutral grey</option>
|
|
<option value="3">Flagship Terrastruct</option>
|
|
<option value="4">Cool classics</option>
|
|
<option value="5">Mixed berry blue</option>
|
|
<option value="6">Grape soda</option>
|
|
<option value="7">Aubergine</option>
|
|
<option value="8">Colorblind clear</option>
|
|
<option value="100">Vanilla nitro cola</option>
|
|
<option value="101">Orange creamsicle</option>
|
|
<option value="102">Shirley temple</option>
|
|
<option value="103">Earth tones</option>
|
|
<option value="104">Everglade green</option>
|
|
<option value="105">Buttered toast</option>
|
|
<option value="200">Dark mauve</option>
|
|
<option value="300">Terminal</option>
|
|
<option value="301">Terminal grayscale</option>
|
|
</select>
|
|
Dark Theme ID
|
|
</label>
|
|
</div>
|
|
<div class="padding-input">
|
|
<label class="input-label">
|
|
<input type="number" id="padding" value="20" step="10" class="number-input" />
|
|
Padding
|
|
</label>
|
|
</div>
|
|
<div class="scale-input">
|
|
<label class="input-label">
|
|
<input type="number" id="scale" value="-1" step="1" class="number-input" />
|
|
Scale
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<button onclick="compile()">Compile</button>
|
|
</div>
|
|
<div id="output"></div>
|
|
<script type="module">
|
|
import { D2 } from "../dist/browser/index.js";
|
|
const d2 = new D2();
|
|
window.compile = async () => {
|
|
const notNegative = (value) => {
|
|
if (value < 0) {
|
|
return null;
|
|
} else return value;
|
|
};
|
|
const input = document.getElementById("input").value;
|
|
const layout = document.querySelector('input[name="layout"]:checked').value;
|
|
const sketch = document.getElementById("sketch").checked;
|
|
const center = document.getElementById("center").checked;
|
|
const themeSelector = document.getElementById("theme");
|
|
const themeId = notNegative(
|
|
Number(themeSelector.options[themeSelector.selectedIndex].value)
|
|
);
|
|
const darkThemeSelector = document.getElementById("dark-theme");
|
|
const darkThemeId = notNegative(
|
|
Number(darkThemeSelector.options[darkThemeSelector.selectedIndex].value)
|
|
);
|
|
const scale = notNegative(Number(document.getElementById("scale").value));
|
|
const pad = Number(document.getElementById("padding").value);
|
|
const forceAppendix = document.getElementById("appendix").checked;
|
|
try {
|
|
const result = await d2.compile(input, {
|
|
layout,
|
|
sketch,
|
|
themeId,
|
|
darkThemeId,
|
|
scale,
|
|
pad,
|
|
center,
|
|
forceAppendix,
|
|
});
|
|
const svg = await d2.render(result.diagram, {
|
|
sketch,
|
|
themeId,
|
|
darkThemeId,
|
|
scale,
|
|
pad,
|
|
center,
|
|
forceAppendix,
|
|
});
|
|
document.getElementById("output").innerHTML = svg;
|
|
} catch (err) {
|
|
console.error(err);
|
|
document.getElementById("output").textContent = err.message;
|
|
}
|
|
};
|
|
compile();
|
|
</script>
|
|
</body>
|
|
</html>
|