|
| 1 | +/** |
| 2 | + * Mermaid `base` theme variables drawn from the app's tokens, so diagrams match the editor and |
| 3 | + * charts instead of Mermaid's stock palette. Mermaid derives shades from these with its own colour |
| 4 | + * library, so every token read here must resolve to a plain hex or rgb value. |
| 5 | + */ |
| 6 | +export function readMermaidThemeVariables( |
| 7 | + element: Element, |
| 8 | + darkMode: boolean |
| 9 | +): Record<string, string | boolean> { |
| 10 | + const styles = getComputedStyle(element) |
| 11 | + const token = (name: string) => { |
| 12 | + const value = styles.getPropertyValue(name).trim() |
| 13 | + if (!value) throw new Error(`Missing diagram theme token ${name}`) |
| 14 | + return value |
| 15 | + } |
| 16 | + const background = token('--bg') |
| 17 | + const node = token('--surface-2') |
| 18 | + const muted = token('--surface-4') |
| 19 | + const subtle = token('--surface-5') |
| 20 | + const border = token('--border') |
| 21 | + const text = token('--text-primary') |
| 22 | + const body = token('--text-body') |
| 23 | + const line = token('--text-icon') |
| 24 | + return { |
| 25 | + darkMode, |
| 26 | + fontFamily: getComputedStyle(document.body).fontFamily, |
| 27 | + fontSize: '14px', |
| 28 | + background, |
| 29 | + primaryColor: node, |
| 30 | + primaryTextColor: text, |
| 31 | + primaryBorderColor: border, |
| 32 | + secondaryColor: muted, |
| 33 | + secondaryTextColor: body, |
| 34 | + secondaryBorderColor: border, |
| 35 | + tertiaryColor: subtle, |
| 36 | + tertiaryTextColor: body, |
| 37 | + tertiaryBorderColor: border, |
| 38 | + mainBkg: node, |
| 39 | + nodeBorder: border, |
| 40 | + textColor: body, |
| 41 | + lineColor: token('--workflow-edge'), |
| 42 | + clusterBkg: token('--surface-3'), |
| 43 | + clusterBorder: border, |
| 44 | + edgeLabelBackground: background, |
| 45 | + noteBkgColor: muted, |
| 46 | + noteTextColor: body, |
| 47 | + noteBorderColor: border, |
| 48 | + actorBkg: node, |
| 49 | + actorBorder: border, |
| 50 | + actorTextColor: text, |
| 51 | + actorLineColor: line, |
| 52 | + signalColor: line, |
| 53 | + signalTextColor: body, |
| 54 | + labelBoxBkgColor: subtle, |
| 55 | + labelBoxBorderColor: border, |
| 56 | + labelTextColor: body, |
| 57 | + loopTextColor: body, |
| 58 | + sequenceNumberColor: background, |
| 59 | + pie1: body, |
| 60 | + pie2: line, |
| 61 | + pie3: token('--text-subtle'), |
| 62 | + pie4: token('--text-muted'), |
| 63 | + pieStrokeColor: background, |
| 64 | + pieTitleTextColor: text, |
| 65 | + pieSectionTextColor: background, |
| 66 | + pieLegendTextColor: body, |
| 67 | + } |
| 68 | +} |
| 69 | + |
| 70 | +/** |
| 71 | + * Flowcharts drawn like workflow canvas blocks and edges: rounded cards with a 1.5px outline, |
| 72 | + * 1.5px edges without arrowheads, and subgraphs as rounded subflow containers. Labels are pinned |
| 73 | + * to the font Mermaid measured them with; otherwise they inherit the surrounding document's font |
| 74 | + * and line height and overflow their boxes. Edge rules are scoped to flowchart classes so sequence |
| 75 | + * and other diagrams keep their arrows. |
| 76 | + */ |
| 77 | +export function mermaidWorkflowCss(fontFamily: string): string { |
| 78 | + return ` |
| 79 | + .label, .nodeLabel, .edgeLabel, .label p, .nodeLabel p, .edgeLabel p { |
| 80 | + font-family: ${fontFamily}; font-size: 14px; line-height: 1.5; letter-spacing: normal; |
| 81 | + } |
| 82 | + .edgeLabel, .edgeLabel p { font-size: 12px; } |
| 83 | + .node rect, .node polygon, .node circle, .node path { stroke-width: 1.5px; } |
| 84 | + .node rect { rx: 10px; ry: 10px; } |
| 85 | + .cluster rect { rx: 14px; ry: 14px; stroke-width: 1.5px; } |
| 86 | + .flowchart-link { stroke-width: 1.5px; marker-end: none !important; } |
| 87 | +` |
| 88 | +} |
0 commit comments