sketchboard-app 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +144 -23
- package/package.json +1 -1
- package/public/assets/{CodeMirrorEditor-DLdTFwmz.js → CodeMirrorEditor-CuIBSOZ0.js} +2 -2
- package/public/assets/{CodeMirrorEditor-DLdTFwmz.js.map → CodeMirrorEditor-CuIBSOZ0.js.map} +1 -1
- package/public/assets/{index-DPcDil7M.js → index-6ESeQJx8.js} +6 -6
- package/public/assets/{index-DPcDil7M.js.map → index-6ESeQJx8.js.map} +1 -1
- package/public/index.html +1 -1
- package/public/sitemap.xml +1 -1
- package/public/sw.js +1 -1
- package/public/sw.js.map +1 -1
package/README.md
CHANGED
|
@@ -1,46 +1,167 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
```
|
|
4
|
+
╔═══════════════════════════════════════════════════════╗
|
|
5
|
+
║ ║
|
|
6
|
+
║ ✏ S K E T C H B O A R D ║
|
|
7
|
+
║ ║
|
|
8
|
+
║ Draw · Save · Share · Collaborate ║
|
|
9
|
+
║ ║
|
|
10
|
+
╚═══════════════════════════════════════════════════════╝
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**A local-first whiteboard that lives on your machine.**
|
|
14
|
+
No account. No cloud. No setup. Just draw.
|
|
15
|
+
|
|
16
|
+
[](https://www.npmjs.com/package/sketchboard-app)
|
|
17
|
+
[](https://www.npmjs.com/package/sketchboard-app)
|
|
18
|
+
[](LICENSE)
|
|
19
|
+
[](https://nodejs.org)
|
|
20
|
+
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Install & Run
|
|
4
26
|
|
|
5
|
-
|
|
27
|
+
### Run instantly (no install needed)
|
|
6
28
|
|
|
7
29
|
```bash
|
|
8
30
|
npx sketchboard-app
|
|
9
31
|
```
|
|
10
32
|
|
|
11
|
-
|
|
33
|
+
Your browser opens automatically at **http://localhost:4321**.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
### Install globally (launch from anywhere, zero wait)
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm install -g sketchboard-app
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Then just type:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
sketchboard
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
### Uninstall
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm uninstall -g sketchboard-app
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
12
58
|
|
|
13
59
|
## Features
|
|
14
60
|
|
|
15
|
-
- **Zero
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
19
|
-
- **
|
|
61
|
+
- **Zero config** — one command, instant whiteboard
|
|
62
|
+
- **Saves to your machine** — drawings stored as JSON files in `~/.sketchboard/`
|
|
63
|
+
- **My Drawings sidebar** — browse, rename, load, and delete all your drawings
|
|
64
|
+
- **Ctrl+S** — save with unsaved-changes indicator in the toolbar
|
|
65
|
+
- **Share links** — generate a public read-only link for any drawing
|
|
66
|
+
- **Live collaboration** — real-time multi-user sessions over socket.io
|
|
67
|
+
- **Full export** — PNG, SVG, clipboard, or `.excalidraw` file
|
|
68
|
+
- **Light & dark theme** — auto-synced across the entire UI
|
|
69
|
+
- **Offline-capable** — works without internet once loaded
|
|
70
|
+
- **Cross-platform** — Windows, macOS, Linux
|
|
20
71
|
|
|
21
|
-
|
|
72
|
+
---
|
|
22
73
|
|
|
23
|
-
|
|
74
|
+
## Usage
|
|
24
75
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
76
|
+
```
|
|
77
|
+
╔═══════════════════════════════════════╗
|
|
78
|
+
║ SketchBoard ║
|
|
79
|
+
╠═══════════════════════════════════════╣
|
|
80
|
+
║ URL : http://localhost:4321 ║
|
|
81
|
+
║ Data : ~/.sketchboard ║
|
|
82
|
+
╚═══════════════════════════════════════╝
|
|
83
|
+
```
|
|
30
84
|
|
|
31
|
-
|
|
85
|
+
### Custom port
|
|
32
86
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
87
|
+
```bash
|
|
88
|
+
PORT=8888 npx sketchboard-app
|
|
89
|
+
# or with global install:
|
|
90
|
+
PORT=8888 sketchboard
|
|
91
|
+
```
|
|
37
92
|
|
|
38
|
-
|
|
93
|
+
### Custom data directory
|
|
39
94
|
|
|
40
95
|
```bash
|
|
41
|
-
|
|
96
|
+
SKETCHBOARD_DATA=/path/to/my/drawings npx sketchboard-app
|
|
42
97
|
```
|
|
43
98
|
|
|
99
|
+
### Environment variables
|
|
100
|
+
|
|
101
|
+
| Variable | Default | Description |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| `PORT` | `4321` | Port the server listens on |
|
|
104
|
+
| `SKETCHBOARD_DATA` | `~/.sketchboard` | Where drawings are stored |
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Where your data lives
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
~/.sketchboard/
|
|
112
|
+
drawings/
|
|
113
|
+
<uuid>.json ← one file per drawing (permanent)
|
|
114
|
+
library.json ← your saved shape library
|
|
115
|
+
collab/ ← live collaboration room scenes
|
|
116
|
+
collab-files/ ← collaboration image files
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
| OS | Path |
|
|
120
|
+
|---|---|
|
|
121
|
+
| Windows | `C:\Users\<you>\.sketchboard\` |
|
|
122
|
+
| macOS | `/Users/<you>/.sketchboard/` |
|
|
123
|
+
| Linux | `/home/<you>/.sketchboard/` |
|
|
124
|
+
|
|
125
|
+
Plain JSON files — easy to back up, move, or sync with any tool.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Keyboard shortcuts
|
|
130
|
+
|
|
131
|
+
| Shortcut | Action |
|
|
132
|
+
|---|---|
|
|
133
|
+
| `Ctrl+S` / `Cmd+S` | Save current drawing |
|
|
134
|
+
| `Ctrl+Z` | Undo |
|
|
135
|
+
| `Ctrl+Shift+Z` | Redo |
|
|
136
|
+
| `V` | Selection tool |
|
|
137
|
+
| `R` | Rectangle |
|
|
138
|
+
| `E` | Ellipse |
|
|
139
|
+
| `A` | Arrow |
|
|
140
|
+
| `T` | Text |
|
|
141
|
+
| `P` | Pencil / freehand |
|
|
142
|
+
| `Delete` | Delete selected |
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Troubleshooting
|
|
147
|
+
|
|
148
|
+
| Problem | Fix |
|
|
149
|
+
|---|---|
|
|
150
|
+
| Port 4321 already in use | `PORT=5678 npx sketchboard-app` |
|
|
151
|
+
| Browser does not open | Manually visit `http://localhost:4321` |
|
|
152
|
+
| Old version cached by npx | `npx --yes sketchboard-app@latest` |
|
|
153
|
+
| `EACCES` error on Linux/Mac | `sudo npm install -g sketchboard-app` |
|
|
154
|
+
| Drawings not saving | Check `~/.sketchboard/drawings/` is writable |
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Credits
|
|
159
|
+
|
|
160
|
+
Built on top of **[Excalidraw](https://github.com/excalidraw/excalidraw)** — the excellent open-source hand-drawn whiteboard (MIT licensed).
|
|
161
|
+
SketchBoard adds local persistence, drawing management, and the npm package layer.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
44
165
|
## License
|
|
45
166
|
|
|
46
167
|
MIT
|
package/package.json
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as o,j as L}from"./index-
|
|
2
|
-
//# sourceMappingURL=CodeMirrorEditor-
|
|
1
|
+
import{r as o,j as L}from"./index-6ESeQJx8.js";import{S as R,C,E as n,a as x,k as y,h as D,l as S,d as T,p as H,r as N,b as j,c as z,s as w,D as g,H as E,t as r}from"./codemirror.chunk-CLhMQAUm.js";import"./mermaid-to-excalidraw-D-aVQaad.js";const G=R.define({token(e){return e.match(/^%%.*$/)?"comment":e.match(/^"(?:[^"\\]|\\.)*"/)?"string":e.match(/^(flowchart|graph|sequenceDiagram|classDiagram|stateDiagram|erDiagram|gantt|pie|mindmap|journey|gitGraph|timeline|quadrantChart|sankey|xychart)\b/i)||e.match(/^(TB|TD|BT|RL|LR)\b/)||e.match(/^(subgraph|end|participant|actor|loop|alt|else|opt|par|critical|break|rect|note|over|activate|deactivate|title|section|class|style|linkStyle|classDef|click)\b/i)?"keyword":e.match(/^[-.=<>|ox]+>/)||e.match(/^<[-.=<>|ox]+/)||e.match(/^--+|\.\.+|==+/)?"operator":e.match(/^[[\](){}|<>]/)?"bracket":e.match(/^[A-Za-z_][A-Za-z0-9_]*/)?"variableName":e.match(/^\d+(\.\d+)?/)?"number":e.match(/^[,:;]/)?"punctuation":(e.eatSpace()||e.next(),null)}});function M(){return G}const q=n.theme({"&":{backgroundColor:"#1e1e1e",color:"#d4d4d4"},".cm-content":{caretColor:"#fff"},".cm-cursor":{borderLeftColor:"#fff"},".cm-gutters":{backgroundColor:"#1e1e1e",color:"#858585",border:"none"},".cm-activeLineGutter":{backgroundColor:"#2a2a2a"},".cm-activeLine":{backgroundColor:"#2a2a2a"},".cm-errorLine":{backgroundColor:"rgba(255, 0, 0, 0.15)"}},{dark:!0}),A=E.define([{tag:r.keyword,color:"#569cd6"},{tag:r.string,color:"#ce9178"},{tag:r.comment,color:"#6a9955"},{tag:r.number,color:"#b5cea8"},{tag:r.operator,color:"#d4d4d4"},{tag:r.punctuation,color:"#d4d4d4"},{tag:r.variableName,color:"#9cdcfe"},{tag:r.bracket,color:"#ffd700"}]),B=n.theme({"&":{backgroundColor:"#ffffff",color:"#1e1e1e"},".cm-content":{caretColor:"#000"},".cm-cursor":{borderLeftColor:"#000"},".cm-gutters":{backgroundColor:"#fff",color:"#999",border:"none"},".cm-activeLineGutter":{backgroundColor:"#e8e8e8"},".cm-activeLine":{backgroundColor:"#e8e8e8"},".cm-errorLine":{backgroundColor:"rgba(255, 0, 0, 0.1)"}}),Z=E.define([{tag:r.keyword,color:"#0000ff"},{tag:r.string,color:"#a31515"},{tag:r.comment,color:"#008000"},{tag:r.number,color:"#098658"},{tag:r.operator,color:"#1e1e1e"},{tag:r.punctuation,color:"#1e1e1e"},{tag:r.variableName,color:"#001080"},{tag:r.bracket,color:"#af00db"}]),_=g.line({class:"cm-errorLine"}),P=(e,c)=>{if(!e||e<1||e>c.lines)return n.decorations.of(g.none);const s=c.line(e);return n.decorations.of(g.set([_.range(s.from)]))},v=e=>e==="dark"?[q,w(A)]:[B,w(Z)],I=({value:e,onChange:c,onKeyboardSubmit:s,placeholder:m,theme:l,errorLine:h})=>{const d=o.useRef(null),i=o.useRef(null),p=o.useRef(c),f=o.useRef(s),k=o.useRef(new C),b=o.useRef(new C);return p.current=c,f.current=s,o.useEffect(()=>{if(!d.current)return;const t=k.current,a=new n({state:x.create({doc:e,extensions:[y.of([{key:"Mod-Enter",run:()=>{var u;return(u=f.current)==null||u.call(f),!0}},{key:"Mod-Shift-z",run:N,preventDefault:!0}]),n.updateListener.of(u=>{u.docChanged&&p.current(u.state.doc.toString())}),D(),y.of([...j,...z]),S(),n.lineWrapping,t.of(v(l)),b.current.of([]),M(),T({drawRangeCursor:!0}),...m?[H(m)]:[]]}),parent:d.current});return i.current=a,a.focus(),()=>{a.destroy(),i.current=null}},[]),o.useEffect(()=>{const t=i.current;t&&t.dispatch({effects:k.current.reconfigure(v(l))})},[l]),o.useEffect(()=>{const t=i.current;t&&t.dispatch({effects:b.current.reconfigure(P(h,t.state.doc))})},[h]),o.useEffect(()=>{const t=i.current;if(!t)return;const a=t.state.doc.toString();e!==a&&t.dispatch({changes:{from:0,to:a.length,insert:e}})},[e]),L("div",{ref:d,className:"ttd-dialog-input ttd-dialog-input--codemirror"})};export{I as default};
|
|
2
|
+
//# sourceMappingURL=CodeMirrorEditor-CuIBSOZ0.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeMirrorEditor-DLdTFwmz.js","sources":["../../../packages/excalidraw/components/TTDDialog/mermaid-lang-lite.ts","../../../packages/excalidraw/components/TTDDialog/CodeMirrorEditor.tsx"],"sourcesContent":["import { StreamLanguage } from \"@codemirror/language\";\n\nconst mermaidStreamParser = StreamLanguage.define({\n token(stream) {\n // Comments: %%...\n if (stream.match(/^%%.*$/)) {\n return \"comment\";\n }\n\n // Strings\n if (stream.match(/^\"(?:[^\"\\\\]|\\\\.)*\"/)) {\n return \"string\";\n }\n\n // Diagram type keywords (at start of line or after whitespace)\n if (\n stream.match(\n /^(flowchart|graph|sequenceDiagram|classDiagram|stateDiagram|erDiagram|gantt|pie|mindmap|journey|gitGraph|timeline|quadrantChart|sankey|xychart)\\b/i,\n )\n ) {\n return \"keyword\";\n }\n\n // Direction keywords\n if (stream.match(/^(TB|TD|BT|RL|LR)\\b/)) {\n return \"keyword\";\n }\n\n // Keywords\n if (\n stream.match(\n /^(subgraph|end|participant|actor|loop|alt|else|opt|par|critical|break|rect|note|over|activate|deactivate|title|section|class|style|linkStyle|classDef|click)\\b/i,\n )\n ) {\n return \"keyword\";\n }\n\n // Arrows: -->, ---, -.->, ===>, etc.\n if (stream.match(/^[-.=<>|ox]+>/)) {\n return \"operator\";\n }\n if (stream.match(/^<[-.=<>|ox]+/)) {\n return \"operator\";\n }\n if (stream.match(/^--+|\\.\\.+|==+/)) {\n return \"operator\";\n }\n\n // Labels in brackets/parens: [text], (text), {text}, ((text)), etc.\n if (stream.match(/^[[\\](){}|<>]/)) {\n return \"bracket\";\n }\n\n // Node IDs (alphanumeric)\n if (stream.match(/^[A-Za-z_][A-Za-z0-9_]*/)) {\n return \"variableName\";\n }\n\n // Numbers\n if (stream.match(/^\\d+(\\.\\d+)?/)) {\n return \"number\";\n }\n\n // Punctuation\n if (stream.match(/^[,:;]/)) {\n return \"punctuation\";\n }\n\n // Skip whitespace\n if (stream.eatSpace()) {\n return null;\n }\n\n // Skip any other character\n stream.next();\n return null;\n },\n});\n\nexport function mermaidLite() {\n return mermaidStreamParser;\n}\n","import { useEffect, useRef } from \"react\";\nimport {\n Decoration,\n EditorView,\n keymap,\n lineNumbers,\n placeholder as cmPlaceholder,\n drawSelection,\n} from \"@codemirror/view\";\nimport { Compartment, EditorState, type Extension } from \"@codemirror/state\";\nimport {\n defaultKeymap,\n history,\n historyKeymap,\n redo,\n} from \"@codemirror/commands\";\nimport { syntaxHighlighting, HighlightStyle } from \"@codemirror/language\";\nimport { tags } from \"@lezer/highlight\";\n\nimport type { Theme } from \"@excalidraw/element/types\";\n\nimport { mermaidLite } from \"./mermaid-lang-lite\";\n\nexport interface CodeMirrorEditorProps {\n value: string;\n onChange: (value: string) => void;\n onKeyboardSubmit?: () => void;\n placeholder?: string;\n theme: Theme;\n errorLine?: number | null;\n}\n\n// ---- Dark theme ----\n\nconst darkTheme = EditorView.theme(\n {\n \"&\": {\n backgroundColor: \"#1e1e1e\",\n color: \"#d4d4d4\",\n },\n \".cm-content\": { caretColor: \"#fff\" },\n \".cm-cursor\": { borderLeftColor: \"#fff\" },\n \".cm-gutters\": {\n backgroundColor: \"#1e1e1e\",\n color: \"#858585\",\n border: \"none\",\n },\n \".cm-activeLineGutter\": { backgroundColor: \"#2a2a2a\" },\n \".cm-activeLine\": { backgroundColor: \"#2a2a2a\" },\n \".cm-errorLine\": { backgroundColor: \"rgba(255, 0, 0, 0.15)\" },\n },\n { dark: true },\n);\n\nconst darkHighlight = HighlightStyle.define([\n { tag: tags.keyword, color: \"#569cd6\" },\n { tag: tags.string, color: \"#ce9178\" },\n { tag: tags.comment, color: \"#6a9955\" },\n { tag: tags.number, color: \"#b5cea8\" },\n { tag: tags.operator, color: \"#d4d4d4\" },\n { tag: tags.punctuation, color: \"#d4d4d4\" },\n { tag: tags.variableName, color: \"#9cdcfe\" },\n { tag: tags.bracket, color: \"#ffd700\" },\n]);\n\n// ---- Light theme ----\n\nconst lightTheme = EditorView.theme({\n \"&\": {\n backgroundColor: \"#ffffff\",\n color: \"#1e1e1e\",\n },\n \".cm-content\": { caretColor: \"#000\" },\n \".cm-cursor\": { borderLeftColor: \"#000\" },\n \".cm-gutters\": {\n backgroundColor: \"#fff\",\n color: \"#999\",\n border: \"none\",\n },\n \".cm-activeLineGutter\": { backgroundColor: \"#e8e8e8\" },\n \".cm-activeLine\": { backgroundColor: \"#e8e8e8\" },\n \".cm-errorLine\": { backgroundColor: \"rgba(255, 0, 0, 0.1)\" },\n});\n\nconst lightHighlight = HighlightStyle.define([\n { tag: tags.keyword, color: \"#0000ff\" },\n { tag: tags.string, color: \"#a31515\" },\n { tag: tags.comment, color: \"#008000\" },\n { tag: tags.number, color: \"#098658\" },\n { tag: tags.operator, color: \"#1e1e1e\" },\n { tag: tags.punctuation, color: \"#1e1e1e\" },\n { tag: tags.variableName, color: \"#001080\" },\n { tag: tags.bracket, color: \"#af00db\" },\n]);\n\n// ---- Error line decoration ----\n\nconst errorLineDeco = Decoration.line({ class: \"cm-errorLine\" });\n\nconst getErrorLineExtension = (\n errorLine: number | null | undefined,\n doc: { line(n: number): { from: number }; lines: number },\n): Extension => {\n if (!errorLine || errorLine < 1 || errorLine > doc.lines) {\n return EditorView.decorations.of(Decoration.none);\n }\n const line = doc.line(errorLine);\n return EditorView.decorations.of(\n Decoration.set([errorLineDeco.range(line.from)]),\n );\n};\n\n// ---- Helpers ----\n\nconst getThemeExtensions = (theme: Theme) => {\n if (theme === \"dark\") {\n return [darkTheme, syntaxHighlighting(darkHighlight)];\n }\n return [lightTheme, syntaxHighlighting(lightHighlight)];\n};\n\nconst CodeMirrorEditor = ({\n value,\n onChange,\n onKeyboardSubmit,\n placeholder,\n theme,\n errorLine,\n}: CodeMirrorEditorProps) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const viewRef = useRef<EditorView | null>(null);\n const onChangeRef = useRef(onChange);\n const onKeyboardSubmitRef = useRef(onKeyboardSubmit);\n const themeCompartmentRef = useRef(new Compartment());\n const errorLineCompartmentRef = useRef(new Compartment());\n\n onChangeRef.current = onChange;\n onKeyboardSubmitRef.current = onKeyboardSubmit;\n\n useEffect(() => {\n if (!containerRef.current) {\n return;\n }\n\n const themeCompartment = themeCompartmentRef.current;\n\n const view = new EditorView({\n state: EditorState.create({\n doc: value,\n extensions: [\n keymap.of([\n {\n key: \"Mod-Enter\",\n run: () => {\n onKeyboardSubmitRef.current?.();\n return true;\n },\n },\n // historyKeymap binds Mod-Shift-z only on Mac; add it for all platforms\n { key: \"Mod-Shift-z\", run: redo, preventDefault: true },\n ]),\n EditorView.updateListener.of((update) => {\n if (update.docChanged) {\n onChangeRef.current(update.state.doc.toString());\n }\n }),\n history(),\n keymap.of([...defaultKeymap, ...historyKeymap]),\n lineNumbers(),\n EditorView.lineWrapping,\n themeCompartment.of(getThemeExtensions(theme)),\n errorLineCompartmentRef.current.of([]),\n mermaidLite(),\n drawSelection({ drawRangeCursor: true }),\n ...(placeholder ? [cmPlaceholder(placeholder)] : []),\n ],\n }),\n parent: containerRef.current,\n });\n\n viewRef.current = view;\n view.focus();\n\n return () => {\n view.destroy();\n viewRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Swap theme dynamically via compartment\n useEffect(() => {\n const view = viewRef.current;\n if (!view) {\n return;\n }\n view.dispatch({\n effects: themeCompartmentRef.current.reconfigure(\n getThemeExtensions(theme),\n ),\n });\n }, [theme]);\n\n // Update error line highlight\n useEffect(() => {\n const view = viewRef.current;\n if (!view) {\n return;\n }\n view.dispatch({\n effects: errorLineCompartmentRef.current.reconfigure(\n getErrorLineExtension(errorLine, view.state.doc),\n ),\n });\n }, [errorLine]);\n\n // Sync external value changes into EditorView\n useEffect(() => {\n const view = viewRef.current;\n if (!view) {\n return;\n }\n const currentDoc = view.state.doc.toString();\n if (value !== currentDoc) {\n view.dispatch({\n changes: { from: 0, to: currentDoc.length, insert: value },\n });\n }\n }, [value]);\n\n return (\n <div\n ref={containerRef}\n className=\"ttd-dialog-input ttd-dialog-input--codemirror\"\n />\n );\n};\n\nexport default CodeMirrorEditor;\n"],"names":["mermaidStreamParser","StreamLanguage","stream","mermaidLite","darkTheme","EditorView","darkHighlight","HighlightStyle","tags","lightTheme","lightHighlight","errorLineDeco","Decoration","getErrorLineExtension","errorLine","doc","line","getThemeExtensions","theme","syntaxHighlighting","CodeMirrorEditor","value","onChange","onKeyboardSubmit","placeholder","containerRef","useRef","viewRef","onChangeRef","onKeyboardSubmitRef","themeCompartmentRef","Compartment","errorLineCompartmentRef","useEffect","themeCompartment","view","EditorState","keymap","_a","redo","update","history","defaultKeymap","historyKeymap","lineNumbers","drawSelection","cmPlaceholder","currentDoc","jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CodeMirrorEditor-CuIBSOZ0.js","sources":["../../../packages/excalidraw/components/TTDDialog/mermaid-lang-lite.ts","../../../packages/excalidraw/components/TTDDialog/CodeMirrorEditor.tsx"],"sourcesContent":["import { StreamLanguage } from \"@codemirror/language\";\n\nconst mermaidStreamParser = StreamLanguage.define({\n token(stream) {\n // Comments: %%...\n if (stream.match(/^%%.*$/)) {\n return \"comment\";\n }\n\n // Strings\n if (stream.match(/^\"(?:[^\"\\\\]|\\\\.)*\"/)) {\n return \"string\";\n }\n\n // Diagram type keywords (at start of line or after whitespace)\n if (\n stream.match(\n /^(flowchart|graph|sequenceDiagram|classDiagram|stateDiagram|erDiagram|gantt|pie|mindmap|journey|gitGraph|timeline|quadrantChart|sankey|xychart)\\b/i,\n )\n ) {\n return \"keyword\";\n }\n\n // Direction keywords\n if (stream.match(/^(TB|TD|BT|RL|LR)\\b/)) {\n return \"keyword\";\n }\n\n // Keywords\n if (\n stream.match(\n /^(subgraph|end|participant|actor|loop|alt|else|opt|par|critical|break|rect|note|over|activate|deactivate|title|section|class|style|linkStyle|classDef|click)\\b/i,\n )\n ) {\n return \"keyword\";\n }\n\n // Arrows: -->, ---, -.->, ===>, etc.\n if (stream.match(/^[-.=<>|ox]+>/)) {\n return \"operator\";\n }\n if (stream.match(/^<[-.=<>|ox]+/)) {\n return \"operator\";\n }\n if (stream.match(/^--+|\\.\\.+|==+/)) {\n return \"operator\";\n }\n\n // Labels in brackets/parens: [text], (text), {text}, ((text)), etc.\n if (stream.match(/^[[\\](){}|<>]/)) {\n return \"bracket\";\n }\n\n // Node IDs (alphanumeric)\n if (stream.match(/^[A-Za-z_][A-Za-z0-9_]*/)) {\n return \"variableName\";\n }\n\n // Numbers\n if (stream.match(/^\\d+(\\.\\d+)?/)) {\n return \"number\";\n }\n\n // Punctuation\n if (stream.match(/^[,:;]/)) {\n return \"punctuation\";\n }\n\n // Skip whitespace\n if (stream.eatSpace()) {\n return null;\n }\n\n // Skip any other character\n stream.next();\n return null;\n },\n});\n\nexport function mermaidLite() {\n return mermaidStreamParser;\n}\n","import { useEffect, useRef } from \"react\";\nimport {\n Decoration,\n EditorView,\n keymap,\n lineNumbers,\n placeholder as cmPlaceholder,\n drawSelection,\n} from \"@codemirror/view\";\nimport { Compartment, EditorState, type Extension } from \"@codemirror/state\";\nimport {\n defaultKeymap,\n history,\n historyKeymap,\n redo,\n} from \"@codemirror/commands\";\nimport { syntaxHighlighting, HighlightStyle } from \"@codemirror/language\";\nimport { tags } from \"@lezer/highlight\";\n\nimport type { Theme } from \"@excalidraw/element/types\";\n\nimport { mermaidLite } from \"./mermaid-lang-lite\";\n\nexport interface CodeMirrorEditorProps {\n value: string;\n onChange: (value: string) => void;\n onKeyboardSubmit?: () => void;\n placeholder?: string;\n theme: Theme;\n errorLine?: number | null;\n}\n\n// ---- Dark theme ----\n\nconst darkTheme = EditorView.theme(\n {\n \"&\": {\n backgroundColor: \"#1e1e1e\",\n color: \"#d4d4d4\",\n },\n \".cm-content\": { caretColor: \"#fff\" },\n \".cm-cursor\": { borderLeftColor: \"#fff\" },\n \".cm-gutters\": {\n backgroundColor: \"#1e1e1e\",\n color: \"#858585\",\n border: \"none\",\n },\n \".cm-activeLineGutter\": { backgroundColor: \"#2a2a2a\" },\n \".cm-activeLine\": { backgroundColor: \"#2a2a2a\" },\n \".cm-errorLine\": { backgroundColor: \"rgba(255, 0, 0, 0.15)\" },\n },\n { dark: true },\n);\n\nconst darkHighlight = HighlightStyle.define([\n { tag: tags.keyword, color: \"#569cd6\" },\n { tag: tags.string, color: \"#ce9178\" },\n { tag: tags.comment, color: \"#6a9955\" },\n { tag: tags.number, color: \"#b5cea8\" },\n { tag: tags.operator, color: \"#d4d4d4\" },\n { tag: tags.punctuation, color: \"#d4d4d4\" },\n { tag: tags.variableName, color: \"#9cdcfe\" },\n { tag: tags.bracket, color: \"#ffd700\" },\n]);\n\n// ---- Light theme ----\n\nconst lightTheme = EditorView.theme({\n \"&\": {\n backgroundColor: \"#ffffff\",\n color: \"#1e1e1e\",\n },\n \".cm-content\": { caretColor: \"#000\" },\n \".cm-cursor\": { borderLeftColor: \"#000\" },\n \".cm-gutters\": {\n backgroundColor: \"#fff\",\n color: \"#999\",\n border: \"none\",\n },\n \".cm-activeLineGutter\": { backgroundColor: \"#e8e8e8\" },\n \".cm-activeLine\": { backgroundColor: \"#e8e8e8\" },\n \".cm-errorLine\": { backgroundColor: \"rgba(255, 0, 0, 0.1)\" },\n});\n\nconst lightHighlight = HighlightStyle.define([\n { tag: tags.keyword, color: \"#0000ff\" },\n { tag: tags.string, color: \"#a31515\" },\n { tag: tags.comment, color: \"#008000\" },\n { tag: tags.number, color: \"#098658\" },\n { tag: tags.operator, color: \"#1e1e1e\" },\n { tag: tags.punctuation, color: \"#1e1e1e\" },\n { tag: tags.variableName, color: \"#001080\" },\n { tag: tags.bracket, color: \"#af00db\" },\n]);\n\n// ---- Error line decoration ----\n\nconst errorLineDeco = Decoration.line({ class: \"cm-errorLine\" });\n\nconst getErrorLineExtension = (\n errorLine: number | null | undefined,\n doc: { line(n: number): { from: number }; lines: number },\n): Extension => {\n if (!errorLine || errorLine < 1 || errorLine > doc.lines) {\n return EditorView.decorations.of(Decoration.none);\n }\n const line = doc.line(errorLine);\n return EditorView.decorations.of(\n Decoration.set([errorLineDeco.range(line.from)]),\n );\n};\n\n// ---- Helpers ----\n\nconst getThemeExtensions = (theme: Theme) => {\n if (theme === \"dark\") {\n return [darkTheme, syntaxHighlighting(darkHighlight)];\n }\n return [lightTheme, syntaxHighlighting(lightHighlight)];\n};\n\nconst CodeMirrorEditor = ({\n value,\n onChange,\n onKeyboardSubmit,\n placeholder,\n theme,\n errorLine,\n}: CodeMirrorEditorProps) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const viewRef = useRef<EditorView | null>(null);\n const onChangeRef = useRef(onChange);\n const onKeyboardSubmitRef = useRef(onKeyboardSubmit);\n const themeCompartmentRef = useRef(new Compartment());\n const errorLineCompartmentRef = useRef(new Compartment());\n\n onChangeRef.current = onChange;\n onKeyboardSubmitRef.current = onKeyboardSubmit;\n\n useEffect(() => {\n if (!containerRef.current) {\n return;\n }\n\n const themeCompartment = themeCompartmentRef.current;\n\n const view = new EditorView({\n state: EditorState.create({\n doc: value,\n extensions: [\n keymap.of([\n {\n key: \"Mod-Enter\",\n run: () => {\n onKeyboardSubmitRef.current?.();\n return true;\n },\n },\n // historyKeymap binds Mod-Shift-z only on Mac; add it for all platforms\n { key: \"Mod-Shift-z\", run: redo, preventDefault: true },\n ]),\n EditorView.updateListener.of((update) => {\n if (update.docChanged) {\n onChangeRef.current(update.state.doc.toString());\n }\n }),\n history(),\n keymap.of([...defaultKeymap, ...historyKeymap]),\n lineNumbers(),\n EditorView.lineWrapping,\n themeCompartment.of(getThemeExtensions(theme)),\n errorLineCompartmentRef.current.of([]),\n mermaidLite(),\n drawSelection({ drawRangeCursor: true }),\n ...(placeholder ? [cmPlaceholder(placeholder)] : []),\n ],\n }),\n parent: containerRef.current,\n });\n\n viewRef.current = view;\n view.focus();\n\n return () => {\n view.destroy();\n viewRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Swap theme dynamically via compartment\n useEffect(() => {\n const view = viewRef.current;\n if (!view) {\n return;\n }\n view.dispatch({\n effects: themeCompartmentRef.current.reconfigure(\n getThemeExtensions(theme),\n ),\n });\n }, [theme]);\n\n // Update error line highlight\n useEffect(() => {\n const view = viewRef.current;\n if (!view) {\n return;\n }\n view.dispatch({\n effects: errorLineCompartmentRef.current.reconfigure(\n getErrorLineExtension(errorLine, view.state.doc),\n ),\n });\n }, [errorLine]);\n\n // Sync external value changes into EditorView\n useEffect(() => {\n const view = viewRef.current;\n if (!view) {\n return;\n }\n const currentDoc = view.state.doc.toString();\n if (value !== currentDoc) {\n view.dispatch({\n changes: { from: 0, to: currentDoc.length, insert: value },\n });\n }\n }, [value]);\n\n return (\n <div\n ref={containerRef}\n className=\"ttd-dialog-input ttd-dialog-input--codemirror\"\n />\n );\n};\n\nexport default CodeMirrorEditor;\n"],"names":["mermaidStreamParser","StreamLanguage","stream","mermaidLite","darkTheme","EditorView","darkHighlight","HighlightStyle","tags","lightTheme","lightHighlight","errorLineDeco","Decoration","getErrorLineExtension","errorLine","doc","line","getThemeExtensions","theme","syntaxHighlighting","CodeMirrorEditor","value","onChange","onKeyboardSubmit","placeholder","containerRef","useRef","viewRef","onChangeRef","onKeyboardSubmitRef","themeCompartmentRef","Compartment","errorLineCompartmentRef","useEffect","themeCompartment","view","EditorState","keymap","_a","redo","update","history","defaultKeymap","historyKeymap","lineNumbers","drawSelection","cmPlaceholder","currentDoc","jsx"],"mappings":"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"}
|