format: eslint + prettier

This commit is contained in:
Sidharth Vinod
2025-03-14 11:24:44 -07:00
parent da75a4951a
commit feb3ba88a5
19 changed files with 540 additions and 555 deletions
+5 -2
View File
@@ -53,7 +53,9 @@ module.exports = {
files: ['**/components/ui/**'],
rules: {
'unicorn/prefer-export-from': 'off',
'unicorn/prevent-abbreviations': 'off'
'unicorn/prevent-abbreviations': 'off',
'unicorn/explicit-length-check': 'off',
'sort-keys/sort-keys-fix': 'off'
}
}
],
@@ -69,7 +71,7 @@ module.exports = {
es2020: true
},
rules: {
'sort-keys': 'error',
'sort-keys/sort-keys-fix': ['error', 'asc', { minKeys: 5 }],
'@typescript-eslint/ban-ts-comment': [
'error',
{
@@ -104,6 +106,7 @@ module.exports = {
k: true,
param: true,
Props: true,
props: true,
req: true,
res: true,
str: true,
+1 -1
View File
@@ -20,7 +20,7 @@
const FONT_AWESOME_URL = `https://cdnjs.cloudflare.com/ajax/libs/font-awesome/${FAVersion}/css/all.min.css`;
const { krokiRendererUrl, rendererUrl } = env;
const { krokiRendererUrl } = env;
type Exporter = (context: CanvasRenderingContext2D, image: HTMLImageElement) => () => void;
const getFileName = (extension: string) =>
-9
View File
@@ -50,12 +50,3 @@
{/each}
</ul>
</div>
<style>
.icon {
transition-duration: 0.5s;
}
.isOpen {
transform: rotate(90deg);
}
</style>
+2 -2
View File
@@ -21,8 +21,8 @@
<Input
{type}
{value}
onclick={(e) => {
e.currentTarget.setSelectionRange(0, e.currentTarget.value.length);
onclick={(event) => {
event.currentTarget.setSelectionRange(0, event.currentTarget.value.length);
}} />
<Button
onclick={async () => {
+3 -3
View File
@@ -9,19 +9,19 @@
class?: string;
}
let { links, icon, class: className }: Props = $props();
let props: Props = $props();
</script>
<Popover.Root>
<Popover.Trigger class="flex items-center gap-0">
<Button variant="ghost" size="sm">
<svelte:component this={icon} class={className} />
<props.icon class={props.class} />
</Button>
</Popover.Trigger>
<Popover.Content>
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
<ul tabindex="0" class="menu flex flex-col gap-2">
{#each links as { href, title }}
{#each props.links as { href, title }}
<li>
<a
role="menuitem"
-9
View File
@@ -43,15 +43,6 @@
}
];
const documentationLinks: Links = [
{ title: 'Getting started', href: 'https://mermaid.js.org/intro/getting-started.html' },
{ title: 'Tutorials', href: 'https://mermaid.js.org/ecosystem/tutorials.html' },
{
title: 'Integrations',
href: 'https://mermaid.js.org/ecosystem/integrations-community.html'
}
];
let activePromotion = $state(getActivePromotion());
const trackBannerClick = () => {
+84 -84
View File
@@ -6,17 +6,25 @@
import ShapesIcon from '~icons/material-symbols/account-tree-outline-rounded';
const samples = {
Flow: `flowchart TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
C -->|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]`,
Sequence: `sequenceDiagram
Alice->>+John: Hello John, how are you?
Alice->>+John: John, can you hear me?
John-->>-Alice: Hi Alice, I can hear you!
John-->>-Alice: I feel great!`,
Block: `block-beta
columns 3
doc>"Document"]:3
space down1<[" "]>(down) space
block:e:3
l["left"]
m("A wide one in the middle")
r["right"]
end
space down2<[" "]>(down) space
db[("DB")]:3
space:3
D space C
db --> D
C --> db
D --> C
style m fill:#d6d,stroke:#333,stroke-width:4px
`,
Class: `classDiagram
Animal <|-- Duck
Animal <|-- Fish
@@ -38,26 +46,6 @@
+bool is_wild
+run()
}`,
State: `stateDiagram-v2
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]`,
Gantt: `gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
section Section
A task :a1, 2014-01-01, 30d
Another task :after a1 , 20d
section Another
Task in sec :2014-01-12 , 12d
another task : 24d`,
Pie: `pie title Pets adopted by volunteers
"Dogs" : 386
"Cats" : 85
"Rats" : 15`,
ER: `erDiagram
CUSTOMER }|..|{ DELIVERY-ADDRESS : has
CUSTOMER ||--o{ ORDER : places
@@ -67,15 +55,21 @@
ORDER ||--|{ ORDER-ITEM : includes
PRODUCT-CATEGORY ||--|{ PRODUCT : contains
PRODUCT ||--o{ ORDER-ITEM : "ordered in"`,
'User Journey': `journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 3: Me`,
Flow: `flowchart TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
C -->|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]`,
Gantt: `gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
section Section
A task :a1, 2014-01-01, 30d
Another task :after a1 , 20d
section Another
Task in sec :2014-01-12 , 12d
another task : 24d`,
Git: `gitGraph
commit
commit
@@ -104,6 +98,32 @@
Tools
Pen and paper
Mermaid`,
Packet: `---
title: "TCP Packet"
---
packet-beta
0-15: "Source Port"
16-31: "Destination Port"
32-63: "Sequence Number"
64-95: "Acknowledgment Number"
96-99: "Data Offset"
100-105: "Reserved"
106: "URG"
107: "ACK"
108: "PSH"
109: "RST"
110: "SYN"
111: "FIN"
112-127: "Window"
128-143: "Checksum"
144-159: "Urgent Pointer"
160-191: "(Options and Padding)"
192-255: "Data (variable length)"
`,
Pie: `pie title Pets adopted by volunteers
"Dogs" : 386
"Cats" : 85
"Rats" : 15`,
QuadrantChart: `quadrantChart
title Reach and engagement of campaigns
x-axis Low Reach --> High Reach
@@ -118,6 +138,27 @@
Campaign D: [0.78, 0.34]
Campaign E: [0.40, 0.34]
Campaign F: [0.35, 0.78]`,
Sequence: `sequenceDiagram
Alice->>+John: Hello John, how are you?
Alice->>+John: John, can you hear me?
John-->>-Alice: Hi Alice, I can hear you!
John-->>-Alice: I feel great!`,
State: `stateDiagram-v2
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]`,
'User Journey': `journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 3: Me`,
XYChart: `
xychart-beta
title "Sales Revenue"
@@ -125,25 +166,6 @@
y-axis "Revenue (in $)" 4000 --> 11000
bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]`,
Block: `block-beta
columns 3
doc>"Document"]:3
space down1<[" "]>(down) space
block:e:3
l["left"]
m("A wide one in the middle")
r["right"]
end
space down2<[" "]>(down) space
db[("DB")]:3
space:3
D space C
db --> D
C --> db
D --> C
style m fill:#d6d,stroke:#333,stroke-width:4px
`,
ZenUML: `zenuml
title Order Service
@Actor Client #FFEBE6
@@ -167,36 +189,14 @@
}
}
}
`,
Packet: `---
title: "TCP Packet"
---
packet-beta
0-15: "Source Port"
16-31: "Destination Port"
32-63: "Sequence Number"
64-95: "Acknowledgment Number"
96-99: "Data Offset"
100-105: "Reserved"
106: "URG"
107: "ACK"
108: "PSH"
109: "RST"
110: "SYN"
111: "FIN"
112-127: "Window"
128-143: "Checksum"
144-159: "Urgent Pointer"
160-191: "(Options and Padding)"
192-255: "Data (variable length)"
`
`
};
type SampleTypes = keyof typeof samples;
const loadSampleDiagram = (diagramType: SampleTypes): void => {
updateCode(samples[diagramType], {
updateDiagram: true,
resetPanZoom: true
resetPanZoom: true,
updateDiagram: true
});
logEvent('loadSampleDiagram', { diagramType });
};
+1 -1
View File
@@ -130,7 +130,7 @@
error = true;
}
const renderTime = Date.now() - startTime;
saveStatistics({ code, renderTime, isRough: state.rough, diagramType });
saveStatistics({ code, diagramType, isRough: state.rough, renderTime });
recordRenderTime(renderTime, () => {
$inputStateStore.updateDiagram = true;
});
+1 -1
View File
@@ -47,7 +47,7 @@
variant = 'default',
size = 'default',
ref = $bindable(null),
href = undefined,
href,
type = 'button',
children,
...restProps
+3 -3
View File
@@ -1,7 +1,7 @@
export const env = {
rendererUrl: import.meta.env.MERMAID_RENDERER_URL ?? '',
krokiRendererUrl: import.meta.env.MERMAID_KROKI_RENDERER_URL ?? '',
analyticsUrl: import.meta.env.MERMAID_ANALYTICS_URL ?? '',
domain: import.meta.env.MERMAID_DOMAIN ?? '',
isEnabledMermaidChartLinks: import.meta.env.MERMAID_IS_ENABLED_MERMAID_CHART_LINKS === 'true'
isEnabledMermaidChartLinks: import.meta.env.MERMAID_IS_ENABLED_MERMAID_CHART_LINKS === 'true',
krokiRendererUrl: import.meta.env.MERMAID_KROKI_RENDERER_URL ?? '',
rendererUrl: import.meta.env.MERMAID_RENDERER_URL ?? ''
} as const;
+7 -7
View File
@@ -61,12 +61,12 @@ const getGistData = async (gistURL: string): Promise<GistData> => {
}
const currentItem = history[0];
return {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
url: `${html_url}/${currentItem.version}`,
author: currentItem.user.login,
code,
config,
author: currentItem.user.login,
time: new Date(currentItem.committed_at).getTime(),
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
url: `${html_url}/${currentItem.version}`,
version: currentItem.version.slice(-7)
};
} else {
@@ -79,10 +79,10 @@ const getStateFromGist = (gist: GistData, gistURL: string = gist.url): State =>
...defaultState,
code: gist.code,
loader: {
type: 'gist',
config: {
url: gistURL
}
},
type: 'gist'
}
};
gist.config && (state.mermaid = gist.config);
@@ -120,11 +120,11 @@ export const loadGistData = async (gistURL: string): Promise<State> => {
const state = getStateFromGist(entry, gistURL);
for (const gist of gistHistory) {
addHistoryEntry({
name: `${gist.author} v${gist.version}`,
state: getStateFromGist(gist),
time: gist.time,
type: 'loader',
url: gist.url,
name: `${gist.author} v${gist.version}`
url: gist.url
});
}
return state;
+4 -4
View File
@@ -27,14 +27,14 @@ export const loadDataFromUrl = async (): Promise<void> => {
}
state = {
code,
mermaid: config,
loader: {
type: 'files',
config: {
codeURL,
configURL
}
}
},
type: 'files'
},
mermaid: config
};
} else {
for (const [key, value] of searchParams.entries()) {
+382 -382
View File
@@ -20,139 +20,7 @@ export const initEditor = (monacoEditor: typeof Monaco): void => {
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',
'accDescription',
'link',
'links'
]
},
classDiagram: {
typeKeywords: ['classDiagram', 'classDiagram-v2'],
blockKeywords: ['class'],
keywords: [
'link',
'click',
'callback',
'call',
'href',
'cssClass',
'direction',
'TB',
'BT',
'RL',
'LR',
'title',
'accDescription',
'order'
]
},
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: ['title', 'accDescription']
},
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, 'element'],
keywords: []
},
gitGraph: {
typeKeywords: ['gitGraph'],
blockKeywords: [],
keywords: [
'accTitle',
'accDescr',
'commit',
'cherry-pick',
'branch',
'merge',
'reset',
'checkout',
'LR',
'BT',
'id',
'msg',
'type',
'tag',
'NORMAL',
'REVERSE',
'HIGHLIGHT'
]
},
pie: {
typeKeywords: ['pie'],
blockKeywords: [],
keywords: ['showData', 'title', 'accDescr', 'accTitle']
},
c4Diagram: {
typeKeywords: ['C4Context', 'C4Container', 'C4Component', 'C4Dynamic', 'C4Deployment'],
blockKeywords: [
'Boundary',
'Enterprise_Boundary',
@@ -203,21 +71,153 @@ export const initEditor = (monacoEditor: typeof Monaco): void => {
'Rel_R',
'Rel_Back',
'RelIndex'
]
],
typeKeywords: ['C4Context', 'C4Container', 'C4Component', 'C4Dynamic', 'C4Deployment']
},
classDiagram: {
blockKeywords: ['class'],
keywords: [
'link',
'click',
'callback',
'call',
'href',
'cssClass',
'direction',
'TB',
'BT',
'RL',
'LR',
'title',
'accDescription',
'order'
],
typeKeywords: ['classDiagram', 'classDiagram-v2']
},
erDiagram: {
blockKeywords: [],
keywords: ['title', 'accDescription'],
typeKeywords: ['erDiagram']
},
flowchart: {
blockKeywords: ['subgraph', 'end'],
keywords: [
'TB',
'TD',
'BT',
'RL',
'LR',
'click',
'call',
'href',
'_self',
'_blank',
'_parent',
'_top',
'linkStyle',
'style',
'classDef',
'class',
'direction',
'interpolate'
],
typeKeywords: ['flowchart', 'flowchart-v2', 'graph']
},
gantt: {
blockKeywords: [],
keywords: [
'title',
'dateFormat',
'axisFormat',
'todayMarker',
'section',
'excludes',
'inclusiveEndDates'
],
typeKeywords: ['gantt']
},
gitGraph: {
blockKeywords: [],
keywords: [
'accTitle',
'accDescr',
'commit',
'cherry-pick',
'branch',
'merge',
'reset',
'checkout',
'LR',
'BT',
'id',
'msg',
'type',
'tag',
'NORMAL',
'REVERSE',
'HIGHLIGHT'
],
typeKeywords: ['gitGraph']
},
info: {
blockKeywords: [],
keywords: ['showInfo'],
typeKeywords: ['info']
},
journey: {
blockKeywords: ['section'],
keywords: ['title'],
typeKeywords: ['journey']
},
pie: {
blockKeywords: [],
keywords: ['showData', 'title', 'accDescr', 'accTitle'],
typeKeywords: ['pie']
},
requirementDiagram: {
blockKeywords: [...requirementDiagrams, 'element'],
keywords: [],
typeKeywords: ['requirement', 'requirementDiagram']
},
sankey: {
typeKeywords: ['sankey-beta'],
blockKeywords: [],
keywords: []
keywords: [],
typeKeywords: ['sankey-beta']
},
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',
'accDescription',
'link',
'links'
],
typeKeywords: ['sequenceDiagram']
},
stateDiagram: {
blockKeywords: ['state', 'note', 'end'],
keywords: ['state', 'as', 'hide empty description', 'direction', 'TB', 'BT', 'RL', 'LR'],
typeKeywords: ['stateDiagram', 'stateDiagram-v2']
}
};
const configDirectiveHandler = [
/^\s*%%(?={)/,
{
token: 'string',
next: '@configDirective',
nextEmbedded: 'javascript'
nextEmbedded: 'javascript',
token: 'string'
}
] as Monaco.languages.IShortMonarchLanguageRule1;
@@ -241,157 +241,26 @@ export const initEditor = (monacoEditor: typeof Monaco): void => {
{}
),
tokenizer: {
root: [
[/^\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*er(Diagram)?/, 'typeKeyword', 'erDiagram'],
[/^\s*requirement(Diagram)?/, 'typeKeyword', 'requirementDiagram'],
[/^\s*sankey-beta/m, 'typeKeyword', 'sankey'],
[
/^\s*(C4Context|C4Container|C4Component|C4Dynamic|C4Deployment)/m,
'typeKeyword',
'c4Diagram'
],
configDirectiveHandler,
[/%%[^${].*$/, 'comment']
],
configDirective: [[/%%$/, { token: 'string', next: '@pop', nextEmbedded: '@pop' }]],
gitGraph: [
configDirectiveHandler,
[/option(?=s)/, { token: 'typeKeyword', next: 'optionsGitGraph' }],
[/(accTitle|accDescr)(\s*:)(\s*[^\n\r]+$)/, ['keyword', 'delimiter.bracket', 'string']],
[
/(^\s*branch)(.*?)(\s+order)(:\s*)(\d+\s*$)/,
['keyword', 'variable', 'keyword', 'delimiter.bracket', 'number']
],
[/".*?"/, 'string'],
[
/(^\s*)(branch|reset|merge|checkout)(\s*\S+)/m,
['delimiter.bracket', 'keyword', 'variable']
],
[
/[A-Za-z][\w$]*/,
{
cases: {
'@gitGraphBlockKeywords': 'typeKeyword',
'@gitGraphKeywords': 'keyword'
}
}
],
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment'],
[/\^/, 'delimiter.bracket']
],
optionsGitGraph: [
[
/s$/,
{
token: 'typeKeyword',
nextEmbedded: 'json'
}
],
['end', { token: 'typeKeyword', next: '@pop', nextEmbedded: '@pop' }]
],
info: [
[
/[A-Za-z][\w$]*/,
{
cases: {
'@infoBlockKeywords': 'typeKeyword',
'@infoKeywords': 'keyword'
}
}
]
],
pie: [
c4Diagram: [
configDirectiveHandler,
[/(title|accDescription)(.*$)/, ['keyword', 'string']],
[/\(/, { next: 'c4DiagramParenthesis', token: 'delimiter.bracket' }],
[
/[A-Za-z][\w$]*/,
/[A-Z_a-z-][\w$]*/,
{
cases: {
'@pieBlockKeywords': 'typeKeyword',
'@pieKeywords': 'keyword'
}
}
],
[/".*?"/, 'string'],
[/\s*\d+/, 'number'],
[/:/, 'delimiter.bracket'],
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment']
],
flowchart: [
configDirectiveHandler,
[/[ox]?(--+|==+)[ox]/, 'transition'],
[
/[A-Za-z][\w$]*/,
{
cases: {
'@flowchartBlockKeywords': 'typeKeyword',
'@flowchartKeywords': 'keyword',
'@c4DiagramBlockKeywords': 'typeKeyword',
'@c4DiagramKeywords': '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: [
configDirectiveHandler,
[/(title:?|accDescription)([^\n\r;]*$)/, ['keyword', 'string']],
[/(autonumber)([^\S\n\r]+off[^\S\n\r]*$)/, ['keyword', 'keyword']],
[/(autonumber)((?:[^\S\n\r]+\d+){2}[^\S\n\r]*$)/, ['keyword', 'number']],
[/(autonumber)([^\S\n\r]+\d+[^\S\n\r]*$)/, ['keyword', 'number']],
[
/(link\s+)(.*?)(:)(\s*.*?)(\s*@)(\s*[^\n\r;]+)/,
['keyword', 'variable', 'delimiter.bracket', 'string', 'delimiter.bracket', 'string']
],
[
/((?:links|properties)\s+)([^\n\r:]*?)(:\s+)/,
[
{ token: 'keyword' },
{ token: 'variable' },
{
token: 'delimiter.bracket',
nextEmbedded: 'javascript',
next: '@sequenceDiagramLinksProps'
}
]
],
[
/[A-Za-z][\w$]*/,
{
cases: {
'@sequenceDiagramBlockKeywords': 'typeKeyword',
'@sequenceDiagramKeywords': 'keyword',
'@default': 'variable'
}
}
],
[/(--?>?>|--?[)x])[+-]?/, 'transition'],
[/(:)([^\n:]*?$)/, ['delimiter.bracket', 'string']],
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment']
],
sequenceDiagramLinksProps: [
// [/^:/, { token: 'delimiter.bracket', nextEmbedded: 'json' }],
[/$|;/, { nextEmbedded: '@pop', next: '@pop', token: 'delimiter.bracket' }]
c4DiagramParenthesis: [
[/,/, 'delimiter.bracket'],
[/\)/, { next: '@pop', token: 'delimiter.bracket' }],
[/[^),]/, 'string']
],
classDiagram: [
configDirectiveHandler,
@@ -419,33 +288,43 @@ export const initEditor = (monacoEditor: typeof Monaco): void => {
[/:::/, 'transition'],
[/:|\+|-|#|~|\*\s*$|\$\s*$|\(|\)|{|}/, 'delimiter.bracket']
],
journey: [
configDirective: [[/%%$/, { next: '@pop', nextEmbedded: '@pop', token: 'string' }]],
erDiagram: [
configDirectiveHandler,
[/(title)(.*)/, ['keyword', 'string']],
[/(section)(.*)/, ['typeKeyword', 'string']],
[/(title|accDescription)(.*$)/, ['keyword', 'string']],
[/[|}][o|](--|\.\.)[o|][{|]/, 'transition'],
[/".*?"/, 'string'],
[/(:)(.*?$)/, ['delimiter.bracket', 'string']],
[/[:{}]/, 'delimiter.bracket'],
[/([A-Za-z]+)(\s+[A-Za-z]+)/, ['type', 'variable']],
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment'],
[/[A-Z_a-z-][\w$]*/, 'variable']
],
flowchart: [
configDirectiveHandler,
[/[ox]?(--+|==+)[ox]/, 'transition'],
[
/[A-Za-z][\w$]*/,
{
cases: {
'@journeyBlockKeywords': 'typeKeyword',
'@journeyKeywords': 'keyword',
'@default': 'variable'
'@default': 'variable',
'@flowchartBlockKeywords': 'typeKeyword',
'@flowchartKeywords': 'keyword'
}
}
],
[
/(^\s*.+?)(:)(.*?)(:)(.*?)([$,])/,
[
'string',
'delimiter.bracket',
'number',
'delimiter.bracket',
'variable',
'delimiter.bracket'
]
],
[/,/, 'delimiter.bracket'],
[/(^\s*.+?)(:)([^:]*?)$/, ['string', 'delimiter.bracket', 'variable']],
[/\|+.+?\|+/, 'string'],
[/\[+(\\.+?[/\\]|\/.+?[/\\])]+/, 'string'],
[/[>[]+[^[\]|]+?]+/, 'string'],
[/{+.+?}+/, 'string'],
[/\(+.+?\)+/, 'string'],
[/-\.+->?/, 'transition'],
[/(-[.-])([^>-][^-]+?)(-{3,}|-{2,}>|\.-+>)/, ['transition', 'string', 'transition']],
[/(==+)([^=]+?)(={3,}|={2,}>)/, ['transition', 'string', 'transition']],
[/<?(--+|==+)>|===+|---+/, 'transition'],
[/:::/, 'transition'],
[/[&;]/, 'delimiter.bracket'],
[/".*?"/, 'string'],
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment']
],
gantt: [
@@ -465,9 +344,189 @@ export const initEditor = (monacoEditor: typeof Monaco): void => {
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment'],
[/:/, 'delimiter.bracket']
],
gitGraph: [
configDirectiveHandler,
[/option(?=s)/, { next: 'optionsGitGraph', token: 'typeKeyword' }],
[/(accTitle|accDescr)(\s*:)(\s*[^\n\r]+$)/, ['keyword', 'delimiter.bracket', 'string']],
[
/(^\s*branch)(.*?)(\s+order)(:\s*)(\d+\s*$)/,
['keyword', 'variable', 'keyword', 'delimiter.bracket', 'number']
],
[/".*?"/, 'string'],
[
/(^\s*)(branch|reset|merge|checkout)(\s*\S+)/m,
['delimiter.bracket', 'keyword', 'variable']
],
[
/[A-Za-z][\w$]*/,
{
cases: {
'@gitGraphBlockKeywords': 'typeKeyword',
'@gitGraphKeywords': 'keyword'
}
}
],
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment'],
[/\^/, 'delimiter.bracket']
],
info: [
[
/[A-Za-z][\w$]*/,
{
cases: {
'@infoBlockKeywords': 'typeKeyword',
'@infoKeywords': 'keyword'
}
}
]
],
journey: [
configDirectiveHandler,
[/(title)(.*)/, ['keyword', 'string']],
[/(section)(.*)/, ['typeKeyword', 'string']],
[
/[A-Za-z][\w$]*/,
{
cases: {
'@default': 'variable',
'@journeyBlockKeywords': 'typeKeyword',
'@journeyKeywords': 'keyword'
}
}
],
[
/(^\s*.+?)(:)(.*?)(:)(.*?)([$,])/,
[
'string',
'delimiter.bracket',
'number',
'delimiter.bracket',
'variable',
'delimiter.bracket'
]
],
[/,/, 'delimiter.bracket'],
[/(^\s*.+?)(:)([^:]*?)$/, ['string', 'delimiter.bracket', 'variable']],
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment']
],
optionsGitGraph: [
[
/s$/,
{
nextEmbedded: 'json',
token: 'typeKeyword'
}
],
['end', { next: '@pop', nextEmbedded: '@pop', token: 'typeKeyword' }]
],
pie: [
configDirectiveHandler,
[/(title|accDescription)(.*$)/, ['keyword', 'string']],
[
/[A-Za-z][\w$]*/,
{
cases: {
'@pieBlockKeywords': 'typeKeyword',
'@pieKeywords': 'keyword'
}
}
],
[/".*?"/, 'string'],
[/\s*\d+/, 'number'],
[/:/, 'delimiter.bracket'],
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment']
],
requirementDiagram: [
configDirectiveHandler,
[/->|<-|-/, 'transition'],
[/(\d+\.)*\d+/, 'number'],
[
/[A-Z_a-z-][\w$]*/,
{
cases: {
'@default': 'variable',
'@requirementDiagramBlockKeywords': 'typeKeyword'
}
}
],
[/[/:{}]/, 'delimiter.bracket'],
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment'],
[/".*?"/, 'string']
],
root: [
[/^\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*er(Diagram)?/, 'typeKeyword', 'erDiagram'],
[/^\s*requirement(Diagram)?/, 'typeKeyword', 'requirementDiagram'],
[/^\s*sankey-beta/m, 'typeKeyword', 'sankey'],
[
/^\s*(C4Context|C4Container|C4Component|C4Dynamic|C4Deployment)/m,
'typeKeyword',
'c4Diagram'
],
configDirectiveHandler,
[/%%[^${].*$/, 'comment']
],
sankey: [
configDirectiveHandler,
[/(title)(.*)/, ['keyword', 'string']],
[/(accTitle|accDescr)(\s*:)(\s*[^\n\r]+$)/, ['keyword', 'delimiter.bracket', 'string']],
[/".*?"/, 'string'],
[/[A-Za-z]+/, 'string'],
[/\s*\d+/, 'number'],
[/,/, 'delimiter.bracket'],
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment']
],
sequenceDiagram: [
configDirectiveHandler,
[/(title:?|accDescription)([^\n\r;]*$)/, ['keyword', 'string']],
[/(autonumber)([^\S\n\r]+off[^\S\n\r]*$)/, ['keyword', 'keyword']],
[/(autonumber)((?:[^\S\n\r]+\d+){2}[^\S\n\r]*$)/, ['keyword', 'number']],
[/(autonumber)([^\S\n\r]+\d+[^\S\n\r]*$)/, ['keyword', 'number']],
[
/(link\s+)(.*?)(:)(\s*.*?)(\s*@)(\s*[^\n\r;]+)/,
['keyword', 'variable', 'delimiter.bracket', 'string', 'delimiter.bracket', 'string']
],
[
/((?:links|properties)\s+)([^\n\r:]*?)(:\s+)/,
[
{ token: 'keyword' },
{ token: 'variable' },
{
next: '@sequenceDiagramLinksProps',
nextEmbedded: 'javascript',
token: 'delimiter.bracket'
}
]
],
[
/[A-Za-z][\w$]*/,
{
cases: {
'@default': 'variable',
'@sequenceDiagramBlockKeywords': 'typeKeyword',
'@sequenceDiagramKeywords': 'keyword'
}
}
],
[/(--?>?>|--?[)x])[+-]?/, 'transition'],
[/(:)([^\n:]*?$)/, ['delimiter.bracket', 'string']],
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment']
],
sequenceDiagramLinksProps: [
// [/^:/, { token: 'delimiter.bracket', nextEmbedded: 'json' }],
[/$|;/, { next: '@pop', nextEmbedded: '@pop', token: 'delimiter.bracket' }]
],
stateDiagram: [
configDirectiveHandler,
[/note[^:]*$/, { token: 'typeKeyword', next: 'stateDiagramNote' }],
[/note[^:]*$/, { next: 'stateDiagramNote', token: 'typeKeyword' }],
['hide empty description', 'keyword'],
[/^\s*state\s(?!.*{)/, 'keyword'],
[/(<<)(fork|join|choice)(>>)/, 'annotation'],
@@ -476,9 +535,9 @@ export const initEditor = (monacoEditor: typeof Monaco): void => {
/[A-Za-z][\w$]*/,
{
cases: {
'@default': 'variable',
'@stateDiagramBlockKeywords': 'typeKeyword',
'@stateDiagramKeywords': 'keyword',
'@default': 'variable'
'@stateDiagramKeywords': 'keyword'
}
}
],
@@ -490,99 +549,40 @@ export const initEditor = (monacoEditor: typeof Monaco): void => {
[/\[.*?]/, 'string']
],
stateDiagramNote: [
[/^\s*end note$/, { token: 'typeKeyword', next: '@pop' }],
[/^\s*end note$/, { next: '@pop', token: 'typeKeyword' }],
[/.*/, 'string']
],
erDiagram: [
configDirectiveHandler,
[/(title|accDescription)(.*$)/, ['keyword', 'string']],
[/[|}][o|](--|\.\.)[o|][{|]/, 'transition'],
[/".*?"/, 'string'],
[/(:)(.*?$)/, ['delimiter.bracket', 'string']],
[/[:{}]/, 'delimiter.bracket'],
[/([A-Za-z]+)(\s+[A-Za-z]+)/, ['type', 'variable']],
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment'],
[/[A-Z_a-z-][\w$]*/, 'variable']
],
requirementDiagram: [
configDirectiveHandler,
[/->|<-|-/, 'transition'],
[/(\d+\.)*\d+/, 'number'],
[
/[A-Z_a-z-][\w$]*/,
{
cases: {
'@requirementDiagramBlockKeywords': 'typeKeyword',
'@default': 'variable'
}
}
],
[/[/:{}]/, 'delimiter.bracket'],
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment'],
[/".*?"/, 'string']
],
c4Diagram: [
configDirectiveHandler,
[/(title|accDescription)(.*$)/, ['keyword', 'string']],
[/\(/, { token: 'delimiter.bracket', next: 'c4DiagramParenthesis' }],
[
/[A-Z_a-z-][\w$]*/,
{
cases: {
'@c4DiagramBlockKeywords': 'typeKeyword',
'@c4DiagramKeywords': 'keyword',
'@default': 'variable'
}
}
],
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment']
],
c4DiagramParenthesis: [
[/,/, 'delimiter.bracket'],
[/\)/, { next: '@pop', token: 'delimiter.bracket' }],
[/[^),]/, 'string']
],
sankey: [
configDirectiveHandler,
[/(title)(.*)/, ['keyword', 'string']],
[/(accTitle|accDescr)(\s*:)(\s*[^\n\r]+$)/, ['keyword', 'delimiter.bracket', 'string']],
[/".*?"/, 'string'],
[/[A-Za-z]+/, 'string'],
[/\s*\d+/, 'number'],
[/,/, 'delimiter.bracket'],
[/%%[^$]([^%]*(?!%%$)%?)*$/, 'comment']
]
}
});
monacoEditor.editor.defineTheme('mermaid-dark', {
base: 'vs-dark',
inherit: true,
colors: {},
inherit: true,
rules: [
{ token: 'typeKeyword', foreground: '9650c8', fontStyle: 'bold' },
{ token: 'transition', foreground: '008800', fontStyle: 'bold' },
{ token: 'identifier', foreground: '9cdcfe' }
{ fontStyle: 'bold', foreground: '9650c8', token: 'typeKeyword' },
{ fontStyle: 'bold', foreground: '008800', token: 'transition' },
{ foreground: '9cdcfe', token: 'identifier' }
]
});
monacoEditor.editor.defineTheme('mermaid', {
base: 'vs',
inherit: true,
colors: {},
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' },
{ token: 'identifier', foreground: '9cdcfe' }
{ fontStyle: 'bold', foreground: '9650c8', token: 'typeKeyword' },
{ foreground: '649696', token: 'keyword' },
{ fontStyle: 'bold', foreground: 'ff0000', token: 'custom-error' },
{ foreground: 'AA8500', token: 'string' },
{ fontStyle: 'bold', foreground: '008800', token: 'transition' },
{ fontStyle: 'bold', foreground: '000000', token: 'delimiter.bracket' },
{ foreground: '4b4b96', token: 'annotation' },
{ foreground: '4b4b96', token: 'number' },
{ foreground: '888c89', token: 'comment' },
{ foreground: 'A22889', token: 'variable' },
{ foreground: '2BDEA8', token: 'type' },
{ foreground: '9cdcfe', token: 'identifier' }
]
});
@@ -597,16 +597,16 @@ export const initEditor = (monacoEditor: typeof Monaco): void => {
monacoEditor.languages.setLanguageConfiguration('mermaid', {
autoClosingPairs: [
{
open: '(',
close: ')'
close: ')',
open: '('
},
{
open: '{',
close: '}'
close: '}',
open: '{'
},
{
open: '[',
close: ']'
close: ']',
open: '['
}
],
brackets: [
+6 -6
View File
@@ -25,6 +25,11 @@ export class PanZoomState {
public updateElement(diagramView: SVGElement, { pan, zoom }: Pick<State, 'pan' | 'zoom'>) {
this.pzoom = panzoom(diagramView, {
center: true,
controlIconsEnabled: false,
fit: true,
maxZoom: 12,
minZoom: 0.2,
onPan: (pan) => {
this.pan = pan;
this.zoom = this.pzoom?.getZoom();
@@ -41,13 +46,8 @@ export class PanZoomState {
this.onPanZoomChange?.(this.pan, this.zoom);
}
},
controlIconsEnabled: false,
panEnabled: true,
zoomEnabled: true,
fit: true,
center: true,
maxZoom: 12,
minZoom: 0.2
zoomEnabled: true
});
this.pzoom.disableDblClickZoom();
+7 -7
View File
@@ -204,6 +204,13 @@ function getBrowserStorage(
connect();
}
},
deleteValue(key: string) {
browserStorage.removeItem(key);
},
getValue(key: string): any {
const value = browserStorage.getItem(key);
return deserialize(value);
},
removeListener(key: string, listener: (newValue: any) => void) {
const index = listeners.indexOf({ key, listener });
if (index !== -1) {
@@ -213,13 +220,6 @@ function getBrowserStorage(
disconnect();
}
},
getValue(key: string): any {
const value = browserStorage.getItem(key);
return deserialize(value);
},
deleteValue(key: string) {
browserStorage.removeItem(key);
},
setValue(key: string, value: any) {
browserStorage.setItem(key, serialize(value));
}
+17 -17
View File
@@ -21,12 +21,12 @@ export const defaultState: State = {
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
`,
grid: true,
mermaid: formatJSON({
theme: 'default'
}),
rough: false,
updateDiagram: true,
grid: true
updateDiagram: true
};
const urlParseFailedState = `flowchart TD
@@ -47,20 +47,20 @@ export const currentState: ValidatedState = (() => {
const state = get(inputStateStore);
return {
...state,
serialized: serializeState(state),
errorMarkers: [],
editorMode: state.editorMode ?? 'code',
error: undefined,
editorMode: state.editorMode ?? 'code'
errorMarkers: [],
serialized: serializeState(state)
};
})();
const processState = async (state: State) => {
const processed: ValidatedState = {
...state,
serialized: '',
errorMarkers: [],
editorMode: state.editorMode ?? 'code',
error: undefined,
editorMode: state.editorMode ?? 'code'
errorMarkers: [],
serialized: ''
};
// No changes should be done to fields part of `state`.
try {
@@ -96,12 +96,12 @@ const processState = async (state: State) => {
processed.error = new Error(errorString);
const marker: MarkerData = {
severity: 8, // Error
startLineNumber: realLineNumber,
startColumn: first_column,
endLineNumber: last_line + (realLineNumber - first_line),
endColumn: last_column + (first_column === last_column ? 0 : 5),
message: errorString || 'Syntax error'
endLineNumber: last_line + (realLineNumber - first_line),
message: errorString || 'Syntax error',
severity: 8, // Error
startColumn: first_column,
startLineNumber: realLineNumber
};
processed.errorMarkers = [marker];
} catch (error) {
@@ -125,15 +125,15 @@ export const urlsStore = derived([stateStore], ([{ code, serialized }]) => {
const { krokiRendererUrl, rendererUrl } = env;
const png = `${rendererUrl}/img/${serialized}?type=png`;
return {
png,
svg: `${rendererUrl}/svg/${serialized}`,
kroki: `${krokiRendererUrl}/mermaid/svg/${pakoSerde.serialize(code)}`,
mdCode: `[![](${png})](${window.location.protocol}//${window.location.host}${window.location.pathname}#${serialized})`,
view: `/view#${serialized}`,
mermaidChart: {
save: `${MCBaseURL}/app/plugin/save?state=${serialized}`,
playground: `${MCBaseURL}/play#${serialized}`
}
},
png,
svg: `${rendererUrl}/svg/${serialized}`,
view: `/view#${serialized}`
};
});
+12 -12
View File
@@ -9,10 +9,10 @@ export const initAnalytics = async (): Promise<void> => {
try {
const { default: Plausible } = await import('plausible-tracker');
plausible = Plausible({
domain: env.domain,
hashMode: false,
// All tracked stats are public and available at https://p.mermaid.live/mermaid.live
apiHost: env.analyticsUrl
apiHost: env.analyticsUrl,
domain: env.domain,
hashMode: false
});
} catch (error) {
console.log(error);
@@ -42,7 +42,7 @@ export const saveStatistics = ({
const length = countLines(code);
const lengthBucket = getBucket(length);
const renderTimeMsBucket = getBucket(renderTime);
logEvent('render', { diagramType, lengthBucket, renderTimeMsBucket, isRough });
logEvent('render', { diagramType, isRough, lengthBucket, renderTimeMsBucket });
};
const getBucket = (length: number): string => {
@@ -77,19 +77,19 @@ const minutesToMilliSeconds = (minutes: number): number => {
const defaultDelay = minutesToMilliSeconds(1);
const delaysPerEvent = {
render: minutesToMilliSeconds(5),
panZoom: minutesToMilliSeconds(10),
playgroundToggle: 0,
bannerClick: defaultDelay,
copyClipboard: defaultDelay,
download: defaultDelay,
copyMarkdown: defaultDelay,
download: defaultDelay,
history: defaultDelay,
loadGist: defaultDelay,
loadSampleDiagram: defaultDelay,
renderDiagram: defaultDelay,
history: defaultDelay,
migration: defaultDelay,
panZoom: minutesToMilliSeconds(10),
playgroundToggle: 0,
render: minutesToMilliSeconds(5),
renderDiagram: defaultDelay,
themeChange: defaultDelay,
bannerClick: defaultDelay,
version: defaultDelay
} as const;
export type AnalyticsEvent = keyof typeof delaysPerEvent;
@@ -102,7 +102,7 @@ export const logEvent = (
if (!plausible) {
return;
}
const key = data ? JSON.stringify({ name, data }) : name;
const key = data ? JSON.stringify({ data, name }) : name;
if (timeouts.has(key)) {
clearTimeout(timeouts.get(key));
} else {
+5 -5
View File
@@ -1,5 +1,5 @@
<script lang="ts">
import DiagramDocButton from '$/components/DiagramDocButton.svelte';
import DiagramDocButton from '$/components/DiagramDocumentationButton.svelte';
import History from '$/components/History/History.svelte';
import McTooltip from '$/components/MCTooltip.svelte';
import PanZoomToolbar from '$/components/PanZoomToolbar.svelte';
@@ -39,14 +39,14 @@
const editorTabs: Tab[] = [
{
icon: CodeIcon,
id: 'code',
title: 'Code',
icon: CodeIcon
title: 'Code'
},
{
icon: GearIcon,
id: 'config',
title: 'Config',
icon: GearIcon
title: 'Config'
}
];