Compare commits
138
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73168de160 | ||
|
|
ea4e0a0d2d | ||
|
|
f75182106a | ||
|
|
597a396def | ||
|
|
5c6f5cf0e7 | ||
|
|
9cc2ea05bb | ||
|
|
df4964ab83 | ||
|
|
33a9491def | ||
|
|
208b397378 | ||
|
|
e67628e321 | ||
|
|
9997efdad1 | ||
|
|
d576e45ed5 | ||
|
|
749828fc9b | ||
|
|
38e0b2c9d6 | ||
|
|
1fb24aa4ce | ||
|
|
f0d5550c0c | ||
|
|
a8b27fc815 | ||
|
|
3c9706f8e6 | ||
|
|
311fbd785e | ||
|
|
52e533dc52 | ||
|
|
399b2a338f | ||
|
|
642c247686 | ||
|
|
5e1c37271e | ||
|
|
5b3b659ea2 | ||
|
|
cbb354f43e | ||
|
|
652d4c67ea | ||
|
|
a2442e287e | ||
|
|
05c5b3bf2d | ||
|
|
c18a3b520e | ||
|
|
e5ab129e28 | ||
|
|
c59351c84f | ||
|
|
ea9e2fc0e0 | ||
|
|
e0b2b762c5 | ||
|
|
6f09bc6872 | ||
|
|
a3a9828ac8 | ||
|
|
432e12e083 | ||
|
|
a29568b42d | ||
|
|
6bdf8af2f1 | ||
|
|
6ab1b296b8 | ||
|
|
4472b1921c | ||
|
|
787c6df2ed | ||
|
|
b0cb4e6a0e | ||
|
|
f8f7db6a77 | ||
|
|
96af5f427c | ||
|
|
36bcd32ee3 | ||
|
|
c6028f0156 | ||
|
|
046437a663 | ||
|
|
43b74a0d35 | ||
|
|
928c2d2f5f | ||
|
|
74d73e2607 | ||
|
|
9a8a3e7f4d | ||
|
|
74efc8eddd | ||
|
|
762d351645 | ||
|
|
1b1296dc0d | ||
|
|
198980047b | ||
|
|
abbdbe1117 | ||
|
|
39dfadd8c8 | ||
|
|
1d22de164c | ||
|
|
7d28beaaba | ||
|
|
f143a5b95b | ||
|
|
a08829f0ef | ||
|
|
66c51cc907 | ||
|
|
9f94a920ee | ||
|
|
8e47adcbcd | ||
|
|
ee049fae2c | ||
|
|
9404071ee3 | ||
|
|
7707cdb71f | ||
|
|
905744526d | ||
|
|
446ba5ebcb | ||
|
|
7dbcf0fbd7 | ||
|
|
4412242817 | ||
|
|
df0a3858a7 | ||
|
|
4e64727fd9 | ||
|
|
52cc57972a | ||
|
|
2768ac483f | ||
|
|
9e0b0f9509 | ||
|
|
e020733386 | ||
|
|
51282fab9d | ||
|
|
48ce114fdf | ||
|
|
7d1f209e06 | ||
|
|
f027ef0b97 | ||
|
|
23b5544692 | ||
|
|
e832503fb8 | ||
|
|
d4c6ea798f | ||
|
|
bef34c81d6 | ||
|
|
ccd198922c | ||
|
|
6345e5e4a5 | ||
|
|
dfdac7ce10 | ||
|
|
19e540d6f2 | ||
|
|
67bd1154e9 | ||
|
|
5fbfbf3253 | ||
|
|
f4eb82c3ec | ||
|
|
715db7e7d6 | ||
|
|
77295736ec | ||
|
|
c64618ed19 | ||
|
|
0acd6881ae | ||
|
|
ce52367b17 | ||
|
|
48fedf313f | ||
|
|
0691feb372 | ||
|
|
3e12763937 | ||
|
|
38fb071055 | ||
|
|
88164bf248 | ||
|
|
b5df150841 | ||
|
|
71607a9137 | ||
|
|
d7c6f2b6c0 | ||
|
|
59b8402117 | ||
|
|
6907be3393 | ||
|
|
c787f94850 | ||
|
|
d210c9e227 | ||
|
|
bf2c98d71c | ||
|
|
813e2d18e2 | ||
|
|
e326e7e47f | ||
|
|
71cb506986 | ||
|
|
ee01c440a9 | ||
|
|
ecbb537026 | ||
|
|
50a8e868ef | ||
|
|
8e763724dd | ||
|
|
562290a729 | ||
|
|
99f37455db | ||
|
|
539562eb1e | ||
|
|
5266610aff | ||
|
|
b23bb5841b | ||
|
|
74379b9a7a | ||
|
|
a838af4860 | ||
|
|
9488ed31de | ||
|
|
96df80ae62 | ||
|
|
516d6575f2 | ||
|
|
59e33fc6bf | ||
|
|
cc295ffe03 | ||
|
|
d00be4f26a | ||
|
|
32d0789e38 | ||
|
|
e6d49972ae | ||
|
|
cbd5a1747d | ||
|
|
9434ccdc9f | ||
|
|
59899799a9 | ||
|
|
0d745fbb29 | ||
|
|
3354663ada | ||
|
|
4f0c38b36e |
@@ -6,18 +6,18 @@ updates:
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: friday
|
||||
time: "07:00"
|
||||
time: '07:00'
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
target-branch: develop
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: friday
|
||||
time: "07:00"
|
||||
time: '07:00'
|
||||
- package-ecosystem: npm
|
||||
directory: /
|
||||
target-branch: develop
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: friday
|
||||
time: "07:00"
|
||||
time: '07:00'
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"svelteSortOrder": "options-scripts-markup-styles",
|
||||
"svelteBracketNewLine": false,
|
||||
"bracketSameLine": true,
|
||||
"useTabs": true,
|
||||
"trailingComma": "none",
|
||||
"printWidth": 100
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
# Stop : press ctrl + c
|
||||
# or
|
||||
# docker stop mermaid-live-editor
|
||||
FROM node:17.0.1 as mermaid-live-editor-builder
|
||||
FROM node:17.3.1 as mermaid-live-editor-builder
|
||||
COPY --chown=node:node . /home
|
||||
WORKDIR /home
|
||||
RUN yarn install
|
||||
|
||||
@@ -32,6 +32,11 @@ docker run --publish 8000:80 ghcr.io/mermaid-js/mermaid-live-editor
|
||||
When building, Set the Environment variable MERMAID_RENDERER_URL to the rendering service.
|
||||
Default is `https://mermaid.ink`
|
||||
|
||||
### To configure Kroki Instance URL
|
||||
|
||||
When building, Set the Environment variable MERMAID_KROKI_RENDERER_URL to your Kroki instance.
|
||||
Default is `https://kroki.io`
|
||||
|
||||
### Development
|
||||
|
||||
```bash
|
||||
|
||||
@@ -60,20 +60,21 @@ describe('Site Loads', () => {
|
||||
cy.getLocalStorage('codeStore').snapshot();
|
||||
});
|
||||
|
||||
it('should prevent setting the "securityLevel" option via URL', () => {
|
||||
const b64State = toBase64(
|
||||
`{"code":"graph TD\\nA[\\"<img src='https://via.placeholder.com/64' width=64 />\\"]","mermaid":"{\\"securityLevel\\": \\"loose\\", \\"theme\\": \\"forest\\"}","updateEditor":true,"autoSync":true,"updateDiagram":true}`,
|
||||
true
|
||||
);
|
||||
cy.on('window:confirm', () => true);
|
||||
cy.visit(`/edit#${b64State}`);
|
||||
cy.contains('Config').click();
|
||||
cy.contains('forest');
|
||||
cy.contains('securityLevel').should('not.exist');
|
||||
cy.get('#view').find('img').should('not.exist');
|
||||
cy.get('#view').contains('<img');
|
||||
cy.get('#view').contains(`src='https://via.placeholder.com/64'`);
|
||||
});
|
||||
// Disabled temporarily. Should be enabled after the issue is fixed in Mermaid.
|
||||
// it('should prevent setting the "securityLevel" option via URL', () => {
|
||||
// const b64State = toBase64(
|
||||
// `{"code":"graph TD\\nA[\\"<img src='https://via.placeholder.com/64' width=64 />\\"]","mermaid":"{\\"securityLevel\\": \\"loose\\", \\"theme\\": \\"forest\\"}","updateEditor":true,"autoSync":true,"updateDiagram":true}`,
|
||||
// true
|
||||
// );
|
||||
// cy.on('window:confirm', () => true);
|
||||
// cy.visit(`/edit#${b64State}`);
|
||||
// cy.contains('Config').click();
|
||||
// cy.contains('forest');
|
||||
// cy.contains('securityLevel').should('not.exist');
|
||||
// cy.get('#view').find('img').should('not.exist');
|
||||
// cy.get('#view').contains('<img');
|
||||
// cy.get('#view').contains(`src='https://via.placeholder.com/64'`);
|
||||
// });
|
||||
|
||||
it('should allow persisting "securityLevel" using confirm dialogue', () => {
|
||||
const b64State = toBase64(
|
||||
|
||||
@@ -16,7 +16,7 @@ module.exports = {
|
||||
"1": "{\"code\":\"graph TD\\n A[Party] -->|Get money| B(Go shopping!!)\\n \",\"mermaid\":\"{\\n \\\"theme\\\": \\\"forest\\\",\\n \\\"test\\\": \\\"hello world\\\"\\n}\",\"updateEditor\":false,\"autoSync\":true,\"updateDiagram\":true,\"loader\":{\"type\":\"files\",\"config\":{\"codeURL\":\"https://gist.githubusercontent.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/raw/4eb03887e6a41397e80bdcdbf94017c498f8f1e2/code.mmd\",\"configURL\":\"https://gist.githubusercontent.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/raw/4eb03887e6a41397e80bdcdbf94017c498f8f1e2/config.json\"}}}"
|
||||
}
|
||||
},
|
||||
"__version": "8.5.0",
|
||||
"__version": "9.1.1",
|
||||
"Auto sync tests": {
|
||||
"should dim diagram when code is edited": {
|
||||
"1": "{\"code\":\"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)\\n B --> C{Let me think}\\n C -->|One| D[Laptop]\\n C -->|Two| E[iPhone]\\n C -->|Three| F[fa:fa-car Car]\\n C --> Test\",\"mermaid\":\"{\\n \\\"theme\\\": \\\"default\\\"\\n}\",\"updateEditor\":false,\"autoSync\":false,\"updateDiagram\":false}"
|
||||
|
||||
+26
-24
@@ -15,48 +15,50 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cypress/snapshot": "^2.1.7",
|
||||
"@sveltejs/adapter-static": "1.0.0-next.21",
|
||||
"@sveltejs/kit": "1.0.0-next.196",
|
||||
"@sveltejs/adapter-static": "1.0.0-next.26",
|
||||
"@sveltejs/kit": "1.0.0-next.232",
|
||||
"@types/mermaid": "^8.2.7",
|
||||
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
||||
"@typescript-eslint/parser": "^4.33.0",
|
||||
"autoprefixer": "^10.4.0",
|
||||
"autoprefixer": "^10.4.2",
|
||||
"chai": "^4.3.4",
|
||||
"cssnano": "^5.0.10",
|
||||
"cypress": "8.7.0",
|
||||
"cssnano": "^5.0.15",
|
||||
"cypress": "9.3.1",
|
||||
"cypress-localstorage-commands": "^1.6.1",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.1.0",
|
||||
"eslint-plugin-cypress": "^2.12.1",
|
||||
"eslint-plugin-es": "^4.1.0",
|
||||
"eslint-plugin-mocha": "^9.0.0",
|
||||
"eslint-plugin-postcss-modules": "^1.2.1",
|
||||
"eslint-plugin-svelte3": "^3.2.1",
|
||||
"eslint-plugin-tailwindcss": "^1.17.1",
|
||||
"eslint-plugin-mocha": "^10.0.3",
|
||||
"eslint-plugin-postcss-modules": "^2.0.0",
|
||||
"eslint-plugin-svelte3": "^3.4.0",
|
||||
"eslint-plugin-tailwindcss": "^3.3.0",
|
||||
"husky": "^7.0.4",
|
||||
"lint-staged": "^11.2.6",
|
||||
"mocha": "^9.1.3",
|
||||
"node-html-parser": "^5.1.0",
|
||||
"postcss": "^8.3.11",
|
||||
"postcss-load-config": "^3.1.0",
|
||||
"prettier": "~2.4.1",
|
||||
"prettier-plugin-svelte": "^2.4.0",
|
||||
"svelte": "^3.44.1",
|
||||
"svelte-preprocess": "^4.9.8",
|
||||
"tailwindcss": "^2.2.19",
|
||||
"lint-staged": "^12.2.1",
|
||||
"mocha": "^9.1.4",
|
||||
"node-html-parser": "^5.2.0",
|
||||
"postcss": "^8.4.5",
|
||||
"postcss-load-config": "^3.1.1",
|
||||
"prettier": "~2.5.1",
|
||||
"prettier-plugin-svelte": "^2.6.0",
|
||||
"svelte": "^3.46.2",
|
||||
"svelte-preprocess": "^4.10.2",
|
||||
"tailwindcss": "^3.0.13",
|
||||
"tslib": "^2.3.1",
|
||||
"typescript": "^4.4.4"
|
||||
"typescript": "^4.5.4"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@analytics/google-analytics": "^0.5.3",
|
||||
"@macfja/svelte-persistent-store": "^1.2.0",
|
||||
"analytics": "^0.7.18",
|
||||
"daisyui": "1.16.2",
|
||||
"analytics": "^0.7.21",
|
||||
"daisyui": "1.24.3",
|
||||
"js-base64": "^3.7.2",
|
||||
"mermaid": "8.13.4",
|
||||
"mermaid": "8.13.9",
|
||||
"moment": "^2.29.1",
|
||||
"monaco-editor": "^0.30.1",
|
||||
"monaco-editor": "^0.31.1",
|
||||
"monaco-mermaid": "^1.0.2",
|
||||
"pako": "2.0.4",
|
||||
"random-word-slugs": "^0.1.6"
|
||||
},
|
||||
"lint-staged": {
|
||||
|
||||
+12
-19
@@ -6,45 +6,38 @@
|
||||
<title>Online FlowChart & Diagrams Editor - Mermaid Live Editor</title>
|
||||
<meta
|
||||
name="og:image"
|
||||
content="https://github.com/mermaid-js/mermaid/raw/develop/img/header.png"
|
||||
/>
|
||||
content="https://github.com/mermaid-js/mermaid/raw/develop/img/header.png" />
|
||||
<link rel="canonical" href="https://mermaid.live" />
|
||||
<meta
|
||||
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." />
|
||||
<link rel="icon" type="image/png" href="favicon.png" />
|
||||
<link rel="manifest" href="manifest.json" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css"
|
||||
/>
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs/editor/editor.main.min.css"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.31.1/min/vs/editor/editor.main.min.css"
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
/>
|
||||
referrerpolicy="no-referrer" />
|
||||
<script>
|
||||
var require = {
|
||||
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs' }
|
||||
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.31.1/min/vs' }
|
||||
};
|
||||
</script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs/loader.min.js"
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.31.1/min/vs/loader.min.js"
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
referrerpolicy="no-referrer"></script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs/editor/editor.main.nls.min.js"
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.31.1/min/vs/editor/editor.main.nls.min.js"
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
referrerpolicy="no-referrer"></script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs/editor/editor.main.js"
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.31.1/min/vs/editor/editor.main.js"
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
referrerpolicy="no-referrer"></script>
|
||||
|
||||
%svelte.head%
|
||||
</head>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import type { Handle } from '@sveltejs/kit/types/hooks';
|
||||
|
||||
export const handle: Handle = async ({ request, resolve }) => {
|
||||
const response = await resolve(request, {
|
||||
ssr: false
|
||||
});
|
||||
|
||||
return response;
|
||||
};
|
||||
@@ -2,10 +2,11 @@
|
||||
import { browser } from '$app/env';
|
||||
|
||||
import Card from '$lib/components/card/card.svelte';
|
||||
import { rendererUrl } from '$lib/util/env';
|
||||
import { rendererUrl, krokiRendererUrl } from '$lib/util/env';
|
||||
import { base64State, codeStore } from '$lib/util/state';
|
||||
import { toBase64 } from 'js-base64';
|
||||
import { toBase64, btoa as jsbtoa } from 'js-base64';
|
||||
import moment from 'moment';
|
||||
import pako from 'pako';
|
||||
|
||||
type Exporter = (context: CanvasRenderingContext2D, image: HTMLImageElement) => () => void;
|
||||
|
||||
@@ -127,6 +128,31 @@
|
||||
window.location.href = `${window.location.pathname}?gist=${gistURL}`;
|
||||
};
|
||||
|
||||
const textEncode = (str) => {
|
||||
if (window.TextEncoder) {
|
||||
return new TextEncoder('utf-8').encode(str);
|
||||
}
|
||||
let utf8 = unescape(encodeURIComponent(str));
|
||||
let result = new Uint8Array(utf8.length);
|
||||
for (let i = 0; i < utf8.length; i++) {
|
||||
result[i] = utf8.charCodeAt(i);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
const onKrokiClick = () => {
|
||||
const krokiCode = getKrokiCode($codeStore.code);
|
||||
const krokiUrl = `${krokiRendererUrl}/mermaid/svg/${krokiCode}`;
|
||||
return window.open(krokiUrl, '_blank');
|
||||
};
|
||||
|
||||
const getKrokiCode = (source) => {
|
||||
const data = textEncode(source);
|
||||
const compressed = pako.deflate(data, { level: 9, to: 'string' });
|
||||
let result = jsbtoa(compressed).replace(/\+/g, '-').replace(/\//g, '_');
|
||||
return result;
|
||||
};
|
||||
|
||||
let iUrl: string;
|
||||
let svgUrl: string;
|
||||
let mdCode: string;
|
||||
@@ -168,6 +194,9 @@
|
||||
<button class="action-btn flex-auto">
|
||||
<a target="_blank" href={svgUrl}><i class="fas fa-external-link-alt mr-2" /> SVG</a>
|
||||
</button>
|
||||
<button class="action-btn flex-auto" on:click={onKrokiClick}>
|
||||
<i class="fas fa-external-link-alt mr-2" /> Kroki
|
||||
</button>
|
||||
|
||||
<div class="flex gap-2 items-center">
|
||||
PNG size
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import { themeStore } from '$lib/util/theme';
|
||||
import type monaco from 'monaco-editor';
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import { initEditor } from './util';
|
||||
import initEditor from 'monaco-mermaid';
|
||||
|
||||
let divEl: HTMLDivElement = null;
|
||||
let editor: monaco.editor.IStandaloneCodeEditor;
|
||||
@@ -1,552 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export const initEditor = (monacoEditor): void => {
|
||||
monacoEditor.languages.register({ id: 'mermaid' });
|
||||
|
||||
const requirementDiagrams = [
|
||||
'requirement',
|
||||
'functionalRequirement',
|
||||
'interfaceRequirement',
|
||||
'performanceRequirement',
|
||||
'physicalRequirement',
|
||||
'designConstraint'
|
||||
];
|
||||
|
||||
const keywords: {
|
||||
[key: string]: {
|
||||
typeKeywords: string[];
|
||||
blockKeywords: string[];
|
||||
keywords: string[];
|
||||
};
|
||||
} = {
|
||||
flowchart: {
|
||||
typeKeywords: ['flowchart', 'flowchart-v2', 'graph'],
|
||||
blockKeywords: ['subgraph', 'end'],
|
||||
keywords: [
|
||||
'TB',
|
||||
'TD',
|
||||
'BT',
|
||||
'RL',
|
||||
'LR',
|
||||
'click',
|
||||
'call',
|
||||
'href',
|
||||
'_self',
|
||||
'_blank',
|
||||
'_parent',
|
||||
'_top',
|
||||
'linkStyle',
|
||||
'style',
|
||||
'classDef',
|
||||
'class',
|
||||
'direction',
|
||||
'interpolate'
|
||||
]
|
||||
},
|
||||
sequenceDiagram: {
|
||||
typeKeywords: ['sequenceDiagram'],
|
||||
blockKeywords: ['alt', 'par', 'and', 'loop', 'else', 'end', 'rect', 'opt', 'alt', 'rect'],
|
||||
keywords: [
|
||||
'participant',
|
||||
'as',
|
||||
'Note',
|
||||
'note',
|
||||
'right of',
|
||||
'left of',
|
||||
'over',
|
||||
'activate',
|
||||
'deactivate',
|
||||
'autonumber',
|
||||
'title',
|
||||
'actor'
|
||||
]
|
||||
},
|
||||
classDiagram: {
|
||||
typeKeywords: ['classDiagram', 'classDiagram-v2'],
|
||||
blockKeywords: ['class'],
|
||||
keywords: [
|
||||
'link',
|
||||
'click',
|
||||
'callback',
|
||||
'call',
|
||||
'href',
|
||||
'cssClass',
|
||||
'direction',
|
||||
'TB',
|
||||
'BT',
|
||||
'RL',
|
||||
'LR'
|
||||
]
|
||||
},
|
||||
stateDiagram: {
|
||||
typeKeywords: ['stateDiagram', 'stateDiagram-v2'],
|
||||
blockKeywords: ['state', 'note', 'end'],
|
||||
keywords: ['state', 'as', 'hide empty description', 'direction', 'TB', 'BT', 'RL', 'LR']
|
||||
},
|
||||
erDiagram: {
|
||||
typeKeywords: ['erDiagram'],
|
||||
blockKeywords: [],
|
||||
keywords: []
|
||||
},
|
||||
journey: {
|
||||
typeKeywords: ['journey'],
|
||||
blockKeywords: ['section'],
|
||||
keywords: ['title']
|
||||
},
|
||||
info: {
|
||||
typeKeywords: ['info'],
|
||||
blockKeywords: [],
|
||||
keywords: ['showInfo']
|
||||
},
|
||||
gantt: {
|
||||
typeKeywords: ['gantt'],
|
||||
blockKeywords: [],
|
||||
keywords: [
|
||||
'title',
|
||||
'dateFormat',
|
||||
'axisFormat',
|
||||
'todayMarker',
|
||||
'section',
|
||||
'excludes',
|
||||
'inclusiveEndDates'
|
||||
]
|
||||
},
|
||||
requirementDiagram: {
|
||||
typeKeywords: ['requirement', 'requirementDiagram'],
|
||||
blockKeywords: requirementDiagrams.concat('element'),
|
||||
keywords: []
|
||||
},
|
||||
gitGraph: {
|
||||
typeKeywords: ['gitGraph'],
|
||||
blockKeywords: [],
|
||||
keywords: ['commit', 'branch', 'merge', 'reset', 'checkout', 'LR', 'BT']
|
||||
},
|
||||
pie: {
|
||||
typeKeywords: ['pie'],
|
||||
blockKeywords: [],
|
||||
keywords: ['title', 'showData']
|
||||
}
|
||||
};
|
||||
|
||||
// Register a tokens provider for the mermaid language
|
||||
monacoEditor.languages.setMonarchTokensProvider('mermaid', {
|
||||
...Object.entries(keywords)
|
||||
.map((entry) =>
|
||||
Object.fromEntries(
|
||||
Object.entries(entry[1]).map((deepEntry) => [
|
||||
entry[0] + deepEntry[0][0].toUpperCase() + deepEntry[0].slice(1),
|
||||
deepEntry[1]
|
||||
])
|
||||
)
|
||||
)
|
||||
.reduce((overallKeywords, nextKeyword) => ({ ...overallKeywords, ...nextKeyword }), {}),
|
||||
tokenizer: {
|
||||
root: [
|
||||
[/%%(?=.*%%$)/, { token: 'string', nextEmbedded: 'json' }],
|
||||
[/%%$/, { token: 'string', nextEmbedded: '@pop' }],
|
||||
[/^\s*gitGraph/m, 'typeKeyword', 'gitGraph'],
|
||||
[/^\s*info/m, 'typeKeyword', 'info'],
|
||||
[/^\s*pie/m, 'typeKeyword', 'pie'],
|
||||
[/^\s*(flowchart|flowchart-v2|graph)/m, 'typeKeyword', 'flowchart'],
|
||||
[/^\s*sequenceDiagram/, 'typeKeyword', 'sequenceDiagram'],
|
||||
[/^\s*classDiagram(-v2)?/, 'typeKeyword', 'classDiagram'],
|
||||
[/^\s*journey/, 'typeKeyword', 'journey'],
|
||||
[/^\s*gantt/, 'typeKeyword', 'gantt'],
|
||||
[/^\s*stateDiagram(-v2)?/, 'typeKeyword', 'stateDiagram'],
|
||||
[/^\s*erDiagram/, 'typeKeyword', 'erDiagram'],
|
||||
[/^\s*requirement(Diagram)?/, 'typeKeyword', 'requirementDiagram'],
|
||||
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment']
|
||||
],
|
||||
gitGraph: [
|
||||
[/option(?=s)/, { token: 'typeKeyword', next: 'optionsGitGraph' }],
|
||||
[/(^\s*branch|reset|merge|checkout)(.*$)/, ['keyword', 'variable']],
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@gitGraphBlockKeywords': 'typeKeyword',
|
||||
'@gitGraphKeywords': 'keyword'
|
||||
}
|
||||
}
|
||||
],
|
||||
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment'],
|
||||
[/".*?"/, 'string'],
|
||||
[/\^/, 'delimiter.bracket']
|
||||
],
|
||||
optionsGitGraph: [
|
||||
[/s$/, { token: 'typeKeyword', nextEmbedded: 'json', matchOnlyAtLineStart: false }],
|
||||
['end', { token: 'typeKeyword', next: '@pop', nextEmbedded: '@pop' }]
|
||||
],
|
||||
info: [
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@infoBlockKeywords': 'typeKeyword',
|
||||
'@infoKeywords': 'keyword'
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
pie: [
|
||||
[/(title)(.*$)/, ['keyword', 'string']],
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@pieBlockKeywords': 'typeKeyword',
|
||||
'@pieKeywords': 'keyword'
|
||||
}
|
||||
}
|
||||
],
|
||||
[/".*?"/, 'string'],
|
||||
[/\s*\d+/, 'number'],
|
||||
[/:/, 'delimiter.bracket'],
|
||||
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment']
|
||||
],
|
||||
flowchart: [
|
||||
[/[ox]?(--+|==+)[ox]/, 'transition'],
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@flowchartBlockKeywords': 'typeKeyword',
|
||||
'@flowchartKeywords': 'keyword',
|
||||
'@default': 'variable'
|
||||
}
|
||||
}
|
||||
],
|
||||
[/\|+.+?\|+/, 'string'],
|
||||
[/\[+(\\.+?[\\/]|\/.+?[/\\])\]+/, 'string'],
|
||||
[/[[>]+[^\]|[]+?\]+/, 'string'],
|
||||
[/{+.+?}+/, 'string'],
|
||||
[/\(+.+?\)+/, 'string'],
|
||||
[/-\.+->?/, 'transition'],
|
||||
[/(-[-.])([^->]+?)(-{3,}|-{2,}>|\.-+>)/, ['transition', 'string', 'transition']],
|
||||
[/(==+)([^=]+?)(={3,}|={2,}>)/, ['transition', 'string', 'transition']],
|
||||
[/<?(--+|==+)>|===+|---+/, 'transition'],
|
||||
[/:::/, 'transition'],
|
||||
[/[;&]/, 'delimiter.bracket'],
|
||||
[/".*?"/, 'string'],
|
||||
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment']
|
||||
],
|
||||
sequenceDiagram: [
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@sequenceDiagramBlockKeywords': 'typeKeyword',
|
||||
'@sequenceDiagramKeywords': 'keyword',
|
||||
'@default': 'variable'
|
||||
}
|
||||
}
|
||||
],
|
||||
[/(--?>?>|--?[)x])[+-]?/, 'transition'],
|
||||
[/(:)([^:\n]*?$)/, ['delimiter.bracket', 'string']],
|
||||
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment']
|
||||
],
|
||||
classDiagram: [
|
||||
[/(?!class\s)([a-zA-Z]+)(\s+[a-zA-Z]+)/, ['type', 'variable']],
|
||||
[/(\*|<\|?|o)?(--|\.\.)(\*|\|?>|o)?/, 'transition'],
|
||||
[/^\s*class\s(?!.*\{)/, 'keyword'],
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@classDiagramBlockKeywords': 'typeKeyword',
|
||||
'@classDiagramKeywords': 'keyword',
|
||||
'@default': 'variable'
|
||||
}
|
||||
}
|
||||
],
|
||||
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment'],
|
||||
[/(<<)(.+?)(>>)/, ['delimiter.bracket', 'annotation', 'delimiter.bracket']],
|
||||
[/".*?"/, 'string'],
|
||||
[/:::/, 'transition'],
|
||||
[/:|\+|-|#|~|\*\s*$|\$\s*$|\(|\)|{|}/, 'delimiter.bracket']
|
||||
],
|
||||
journey: [
|
||||
[/(title)(.*)/, ['keyword', 'string']],
|
||||
[/(section)(.*)/, ['typeKeyword', 'string']],
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@journeyBlockKeywords': 'typeKeyword',
|
||||
'@journeyKeywords': 'keyword',
|
||||
'@default': 'variable'
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
/(^\s*.+?)(:)(.*?)(:)(.*?)([,$])/,
|
||||
[
|
||||
'string',
|
||||
'delimiter.bracket',
|
||||
'number',
|
||||
'delimiter.bracket',
|
||||
'variable',
|
||||
'delimiter.bracket'
|
||||
]
|
||||
],
|
||||
[/,/, 'delimiter.bracket'],
|
||||
[/(^\s*.+?)(:)([^:]*?)$/, ['string', 'delimiter.bracket', 'variable']],
|
||||
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment']
|
||||
],
|
||||
gantt: [
|
||||
[/(title)(.*)/, ['keyword', 'string']],
|
||||
[/(section)(.*)/, ['typeKeyword', 'string']],
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@ganttBlockKeywords': 'typeKeyword',
|
||||
'@ganttKeywords': 'keyword'
|
||||
}
|
||||
}
|
||||
],
|
||||
[/(^\s*.*?)(:)/, ['string', 'delimiter.bracket']],
|
||||
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment'],
|
||||
[/:/, 'delimiter.bracket']
|
||||
],
|
||||
stateDiagram: [
|
||||
[/note[^:]*$/, { token: 'typeKeyword', next: 'stateDiagramNote' }],
|
||||
['hide empty description', 'keyword'],
|
||||
[/^\s*state\s(?!.*\{)/, 'keyword'],
|
||||
[/(<<)(fork|join|choice)(>>)/, 'annotation'],
|
||||
[/(\[\[)(fork|join|choice)(]])/, ['delimiter.bracket', 'annotation', 'delimiter.bracket']],
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@stateDiagramBlockKeywords': 'typeKeyword',
|
||||
'@stateDiagramKeywords': 'keyword',
|
||||
'@default': 'variable'
|
||||
}
|
||||
}
|
||||
],
|
||||
[/".*?"/, 'string'],
|
||||
[/(:)([^:\n]*?$)/, ['delimiter.bracket', 'string']],
|
||||
[/{|}/, 'delimiter.bracket'],
|
||||
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment'],
|
||||
[/-->/, 'transition'],
|
||||
[/\[.*?]/, 'string']
|
||||
],
|
||||
stateDiagramNote: [
|
||||
[/^\s*end note$/, { token: 'typeKeyword', next: '@pop' }],
|
||||
[/.*/, 'string']
|
||||
],
|
||||
erDiagram: [
|
||||
[/[}|][o|](--|\.\.)[o|][{|]/, 'transition'],
|
||||
[/".*?"/, 'string'],
|
||||
[/(:)(.*?$)/, ['delimiter.bracket', 'string']],
|
||||
[/:|{|}/, 'delimiter.bracket'],
|
||||
[/([a-zA-Z]+)(\s+[a-zA-Z]+)/, ['type', 'variable']],
|
||||
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment'],
|
||||
[/[a-zA-Z_-][\w$]*/, 'variable']
|
||||
],
|
||||
requirementDiagram: [
|
||||
[/->|<-|-/, 'transition'],
|
||||
[/(\d+\.)*\d+/, 'number'],
|
||||
[
|
||||
/[a-zA-Z_-][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@requirementDiagramBlockKeywords': 'typeKeyword',
|
||||
'@default': 'variable'
|
||||
}
|
||||
}
|
||||
],
|
||||
[/:|{|}|\//, 'delimiter.bracket'],
|
||||
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment'],
|
||||
[/".*?"/, 'string']
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
monacoEditor.editor.defineTheme('mermaid-dark', {
|
||||
base: 'vs-dark',
|
||||
inherit: true,
|
||||
rules: [
|
||||
{ token: 'typeKeyword', foreground: '9650c8', fontStyle: 'bold' },
|
||||
{ token: 'transition', foreground: '008800', fontStyle: 'bold' }
|
||||
],
|
||||
colors: {}
|
||||
});
|
||||
|
||||
monacoEditor.editor.defineTheme('mermaid', {
|
||||
base: 'vs',
|
||||
inherit: true,
|
||||
rules: [
|
||||
{ token: 'typeKeyword', foreground: '9650c8', fontStyle: 'bold' },
|
||||
{ token: 'keyword', foreground: '649696' },
|
||||
{ token: 'custom-error', foreground: 'ff0000', fontStyle: 'bold' },
|
||||
{ token: 'string', foreground: 'AA8500' },
|
||||
{ token: 'transition', foreground: '008800', fontStyle: 'bold' },
|
||||
{ token: 'delimiter.bracket', foreground: '000000', fontStyle: 'bold' },
|
||||
{ token: 'annotation', foreground: '4b4b96' },
|
||||
{ token: 'number', foreground: '4b4b96' },
|
||||
{ token: 'comment', foreground: '888c89' },
|
||||
{ token: 'variable', foreground: 'A22889' },
|
||||
{ token: 'type', foreground: '2BDEA8' }
|
||||
],
|
||||
colors: {}
|
||||
});
|
||||
|
||||
// Register a completion item provider for the mermaid language
|
||||
monacoEditor.languages.registerCompletionItemProvider('mermaid', {
|
||||
provideCompletionItems: () => {
|
||||
const suggestions = [
|
||||
{
|
||||
label: 'loop',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['loop ${1:Loop text}', '\t$0', 'end'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'Sequence Diagram Loops'
|
||||
},
|
||||
{
|
||||
label: 'alt',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['alt ${1:Describing text}', '\t$0', 'else', '\t', 'end'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'Alternative Path'
|
||||
},
|
||||
{
|
||||
label: 'opt',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['opt ${1:Describing text}', '\t$0', 'end'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'Optional Path'
|
||||
},
|
||||
{
|
||||
label: 'par',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'par ${1:[Action 1]}',
|
||||
'\t$0',
|
||||
'and ${2:[Action 2]}',
|
||||
'\t',
|
||||
'and ${3:[Action 3]}',
|
||||
'\t',
|
||||
'end'
|
||||
].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'Parallel Actions'
|
||||
},
|
||||
{
|
||||
label: 'rect',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['rect ${1:rgb(0, 255, 0)}', '\t$0', 'end'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'Background Color'
|
||||
},
|
||||
{
|
||||
label: 'subgraph',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['subgraph ${1:title}', '\t$0', 'end'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'Subgraph'
|
||||
},
|
||||
{
|
||||
label: 'class',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['class ${1:className} {', '\t$0', '}'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'Class'
|
||||
},
|
||||
{
|
||||
label: 'state',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['state ${1:stateName} {', '\t$0', '}'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'State'
|
||||
},
|
||||
{
|
||||
label: 'note',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['note ${1:right of State1}', '\t$0', 'end note'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'State'
|
||||
},
|
||||
{
|
||||
label: 'section',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['section ${1:Go to work}', '\t$0'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'User-journey Section'
|
||||
},
|
||||
{
|
||||
label: 'element',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['element ${1:test_entity} {', '\t$0', '}'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'Requirement Diagram Element'
|
||||
},
|
||||
{
|
||||
label: 'options',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['options', '{', ' $0', '}', 'end'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'Git Graph Options'
|
||||
},
|
||||
...requirementDiagrams.map((requirementDiagramType) => ({
|
||||
label: requirementDiagramType,
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
requirementDiagramType + ' ${1:test_req} {',
|
||||
'\tid: 1',
|
||||
'\ttext: the test text.',
|
||||
'\trisk: high',
|
||||
'\tverifyMethod: test',
|
||||
'}'
|
||||
].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: requirementDiagramType
|
||||
.split(/(?=[A-Z])/)
|
||||
.map((part) => part[0].toUpperCase() + part.slice(1))
|
||||
.join(' ')
|
||||
})),
|
||||
...[
|
||||
...new Set(
|
||||
Object.values(keywords)
|
||||
.map((diagramKeywords) =>
|
||||
Object.entries(diagramKeywords)
|
||||
.filter((keywordType) => keywordType[0] !== 'annotations')
|
||||
.map((entry) => entry[1])
|
||||
)
|
||||
.flat(2)
|
||||
)
|
||||
].map((keyword) => ({
|
||||
label: keyword,
|
||||
kind: monacoEditor.languages.CompletionItemKind.Keyword,
|
||||
insertText: keyword
|
||||
}))
|
||||
];
|
||||
return { suggestions: suggestions };
|
||||
}
|
||||
});
|
||||
|
||||
monacoEditor.languages.setLanguageConfiguration('mermaid', {
|
||||
autoClosingPairs: [
|
||||
{
|
||||
open: '(',
|
||||
close: ')'
|
||||
},
|
||||
{
|
||||
open: '{',
|
||||
close: '}'
|
||||
},
|
||||
{
|
||||
open: '[',
|
||||
close: ']'
|
||||
}
|
||||
],
|
||||
brackets: [
|
||||
['(', ')'],
|
||||
['{', '}'],
|
||||
['[', ']']
|
||||
]
|
||||
});
|
||||
};
|
||||
@@ -69,24 +69,6 @@
|
||||
ORDER ||--|{ ORDER-ITEM : includes
|
||||
PRODUCT-CATEGORY ||--|{ PRODUCT : contains
|
||||
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
|
||||
`,
|
||||
'Git Graph': `gitGraph:
|
||||
options
|
||||
{
|
||||
"nodeSpacing": 150,
|
||||
"nodeRadius": 10
|
||||
}
|
||||
end
|
||||
commit
|
||||
branch newbranch
|
||||
checkout newbranch
|
||||
commit
|
||||
commit
|
||||
checkout master
|
||||
commit
|
||||
commit
|
||||
merge newbranch
|
||||
|
||||
`,
|
||||
'User Journey': ` journey
|
||||
title My working day
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export const rendererUrl = import.meta.env.MERMAID_RENDERER_URL ?? 'https://mermaid.ink';
|
||||
export const krokiRendererUrl = import.meta.env.MERMAID_KROKI_RENDERER_URL ?? 'https://kroki.io';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import Editor from '$lib/components/editor/editor.svelte';
|
||||
import Editor from '$lib/components/editor.svelte';
|
||||
import Navbar from '$lib/components/navbar.svelte';
|
||||
import Preset from '$lib/components/preset.svelte';
|
||||
import Actions from '$lib/components/actions.svelte';
|
||||
|
||||
@@ -19,7 +19,6 @@ const config = {
|
||||
base: `/mermaid-live-editor${process.env['BETA'] ? '/beta' : ''}`
|
||||
}
|
||||
: {},
|
||||
ssr: false,
|
||||
// hydrate the <div id="svelte"> element in src/app.html
|
||||
target: '#svelte',
|
||||
trailingSlash: 'ignore',
|
||||
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
module.exports = {
|
||||
mode: 'jit',
|
||||
plugins: [require('daisyui')],
|
||||
purge: ['./src/**/*.{html,js,svelte,ts}'],
|
||||
content: ['./src/**/*.{html,js,svelte,ts}'],
|
||||
theme: {
|
||||
extend: {}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user