chore: Minor cleanup

This commit is contained in:
Sidharth Vinod
2025-03-14 19:37:25 -07:00
parent c9efb9e017
commit b2bb5b2bef
8 changed files with 50 additions and 43 deletions
+25 -18
View File
@@ -19,13 +19,19 @@
import CopyInput from './CopyInput.svelte';
const FONT_AWESOME_URL = `https://cdnjs.cloudflare.com/ajax/libs/font-awesome/${FAVersion}/css/all.min.css`;
const { krokiRendererUrl } = env;
type Exporter = (context: CanvasRenderingContext2D, image: HTMLImageElement) => () => void;
const getFileName = (extension: string) =>
`mermaid-diagram-${dayjs().format('YYYY-MM-DD-HHmmss')}.${extension}`;
const getSvgElement = () => {
const svgElement = document.querySelector('#container svg')?.cloneNode(true) as HTMLElement;
svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
return svgElement;
};
const getBase64SVG = (svg?: HTMLElement, width?: number, height?: number): string => {
if (svg) {
// Prevents the SVG size of the interface from being changed
@@ -33,9 +39,11 @@
}
height && svg?.setAttribute('height', `${height}px`);
width && svg?.setAttribute('width', `${width}px`); // Workaround https://stackoverflow.com/questions/28690643/firefox-error-rendering-an-svg-image-to-html5-canvas-with-drawimage
if (!svg) {
svg = getSvgElement();
}
const svgString = svg.outerHTML
.replaceAll('<br>', '<br/>')
.replaceAll(/<img([^>]*)>/g, (m, g: string) => `<img ${g} />`);
@@ -45,19 +53,30 @@
${svgString}`);
};
const simulateDownload = (download: string, href: string): void => {
const a = document.createElement('a');
a.download = download;
a.href = href;
a.click();
a.remove();
};
const exportImage = async (event: Event, exporter: Exporter) => {
await waitForRender();
if (document.querySelector('.outOfSync')) {
throw new Error('Diagram is out of sync');
}
const canvas: HTMLCanvasElement = document.createElement('canvas');
const canvas = document.createElement('canvas');
const svg = document.querySelector<HTMLElement>('#container svg');
if (!svg) {
throw new Error('svg not found');
}
const box: DOMRect = svg.getBoundingClientRect();
const box = svg.getBoundingClientRect();
canvas.width = box.width;
canvas.height = box.height;
if (imageSizeMode === 'width') {
const ratio = box.height / box.width;
canvas.width = imageSize;
@@ -72,6 +91,7 @@ ${svgString}`);
if (!context) {
throw new Error('context not found');
}
context.fillStyle = `hsl(${window.getComputedStyle(document.body).getPropertyValue('--b1')})`;
context.fillRect(0, 0, canvas.width, canvas.height);
@@ -83,19 +103,6 @@ ${svgString}`);
event.preventDefault();
};
const getSvgElement = () => {
const svgElement = document.querySelector('#container svg')?.cloneNode(true) as HTMLElement;
svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
return svgElement;
};
const simulateDownload = (download: string, href: string): void => {
const a = document.createElement('a');
a.download = download;
a.href = href;
a.click();
a.remove();
};
const downloadImage: Exporter = (context, image) => {
return () => {
const { canvas } = context;
@@ -108,7 +115,7 @@ ${svgString}`);
};
const isClipboardAvailable = (): boolean => {
return Object.prototype.hasOwnProperty.call(window, 'ClipboardItem') as boolean;
return Object.prototype.hasOwnProperty.call(window, 'ClipboardItem');
};
const clipboardCopy: Exporter = (context, image) => {
@@ -161,7 +168,7 @@ ${svgString}`);
const loadGist = () => {
if (!gistURL) {
alert('Please enter a Gist URL first');
return alert('Please enter a Gist URL first');
}
window.location.href = `${window.location.pathname}?gist=${gistURL}`;
logEvent('loadGist');
+9 -6
View File
@@ -44,15 +44,18 @@
</script>
<div
class="card flex h-fit {isOpen ? 'isOpen flex-grow' : ''} {isStackable
? 'flex-1 group-has-[.isOpen]:w-full group-has-[.isOpen]:flex-none'
: 'w-full'} flex-col overflow-hidden rounded-2xl border-2 border-muted">
class={[
'border-muted card flex h-fit flex-col overflow-hidden rounded-2xl border-2',
isOpen && 'isOpen flex-grow',
isStackable ? 'flex-1 group-has-[.isOpen]:w-full group-has-[.isOpen]:flex-none' : 'w-full'
]}>
<div
role="toolbar"
tabindex="0"
class="bg-muted p-2 {isTabsShown
? 'pb-1'
: ''} flex h-11 flex-none cursor-pointer items-center justify-between whitespace-nowrap"
class={[
'bg-muted flex h-11 flex-none cursor-pointer items-center justify-between whitespace-nowrap p-2',
isTabsShown && 'pb-1'
]}
onclick={toggleCardOpen}
onkeypress={toggleCardOpen}>
{#if icon || title}
+4 -3
View File
@@ -32,9 +32,10 @@
<Button
role="tab"
variant="ghost"
class="px-2 {activeTabID === tab.id
? 'rounded-b-none border-b-2 border-b-primary-foreground/50'
: ''}"
class={[
'px-2',
activeTabID === tab.id && 'border-b-primary-foreground/50 rounded-b-none border-b-2'
]}
onclick={toggleTabs(tab)}
onkeypress={toggleTabs(tab)}>
<tab.icon />
+4 -6
View File
@@ -36,7 +36,6 @@
let text = '';
stateStore.subscribe(({ errorMarkers, editorMode, code, mermaid }) => {
// console.log('editor store subscription', { code, mermaid });
if (!editor) {
return;
}
@@ -44,7 +43,6 @@
// Update editor text if it's different
const newText = editorMode === 'code' ? code : mermaid;
if (newText !== text) {
// console.log('updating editor text', newText);
editor.setScrollTop(0);
editor.setValue(newText);
text = newText;
@@ -70,7 +68,6 @@
});
const handleUpdate = (text: string, mode: EditorMode) => {
// console.log('editor HandleUpdate', { text, mode });
if (mode === 'code') {
updateCode(text);
} else {
@@ -91,7 +88,7 @@
if (!divElement) {
throw new Error('divEl is undefined');
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
initEditor(monaco);
errorDebug();
editor = monaco.editor.create(divElement, editorOptions);
@@ -103,6 +100,7 @@
text = newText;
handleUpdate(text, $stateStore.editorMode);
});
editor.addAction({
id: 'mermaid-render-diagram',
label: 'Render Diagram',
@@ -142,7 +140,7 @@
<div class="flex flex-col text-sm">
<div class="flex items-center justify-between gap-2 bg-slate-900 p-2 text-white">
<div class="flex w-fit items-center gap-2">
<ExclamationCircleIcon class="size-6 text-destructive" aria-hidden="true" />
<ExclamationCircleIcon class="text-destructive size-6" aria-hidden="true" />
<div class="flex flex-col">
<p>Syntax error</p>
{#if env.isEnabledMermaidChartLinks}
@@ -159,7 +157,7 @@
</McTooltip>
{/if}
</div>
<div class="max-h-32 overflow-auto bg-muted p-2 font-mono">
<div class="bg-muted max-h-32 overflow-auto p-2 font-mono">
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
{@html sanitizeText($stateStore.error?.toString().replaceAll('\n', '<br />'))}
</div>
+3 -2
View File
@@ -1,6 +1,7 @@
<script module lang="ts">
<script lang="ts" module>
import { logEvent, plausible } from '$lib/util/stats';
import { version } from 'mermaid/package.json';
void logEvent('version', {
mermaidVersion: version
});
@@ -96,7 +97,7 @@
</a>
{#if env.isEnabledMermaidChartLinks}
<McTooltip>
<div class=" hidden items-center justify-center gap-4 md:flex">
<div class="hidden items-center justify-center gap-4 md:flex">
<Separator orientation="vertical" />
<Switch
id="editorMode"
+1 -5
View File
@@ -195,10 +195,7 @@ export const updateCode = (
};
export const updateConfig = (config: string): void => {
// console.log('updateConfig', config);
inputStateStore.update((state) => {
return { ...state, mermaid: config };
});
updateCodeStore({ mermaid: config });
};
export const toggleDarkTheme = (dark: boolean): void => {
@@ -207,7 +204,6 @@ export const toggleDarkTheme = (dark: boolean): void => {
if (!config.theme || ['dark', 'default'].includes(config.theme)) {
config.theme = dark ? 'dark' : 'default';
}
return { ...state, mermaid: formatJSON(config) };
});
};
+3 -3
View File
@@ -32,10 +32,10 @@
console.log('Service worker registration failed, error:', error);
});
}
});
mode.subscribe((mode) => {
toggleDarkTheme(mode === 'dark');
});
$effect(() => {
toggleDarkTheme($mode === 'dark');
});
</script>
+1
View File
@@ -67,6 +67,7 @@
</McTooltip>
{/if}
</Navbar>
<div class="flex flex-1 overflow-hidden">
<Resizable.PaneGroup direction="horizontal" autoSaveId="liveEditor" class="p-6 pt-0">
<Resizable.Pane defaultSize={30} minSize={15} class="hidden md:block">