@zombie-mermaid/core 2.2.1
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/LICENSE +22 -0
- package/dist/index.cjs +29 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1236 -0
- package/dist/index.d.ts +1236 -0
- package/dist/index.js +888 -0
- package/dist/index.js.map +1 -0
- package/package.json +35 -0
- package/src/__tests__/click-directive.test.ts +63 -0
- package/src/__tests__/color-utils.test.ts +186 -0
- package/src/__tests__/diagram-type.test.ts +28 -0
- package/src/__tests__/text-metrics.test.ts +486 -0
- package/src/__tests__/theme-palette-contrast.test.ts +84 -0
- package/src/__tests__/theme.test.ts +162 -0
- package/src/click-directive.ts +106 -0
- package/src/color-utils.ts +205 -0
- package/src/diagram-type.ts +35 -0
- package/src/direction-override.ts +46 -0
- package/src/direction.ts +56 -0
- package/src/generated/mono-font-subset.ts +32 -0
- package/src/index.ts +34 -0
- package/src/init-directive.ts +248 -0
- package/src/multiline-utils.ts +275 -0
- package/src/statements.ts +197 -0
- package/src/style-directives.ts +214 -0
- package/src/text-metrics.ts +520 -0
- package/src/theme.ts +712 -0
- package/src/types.ts +670 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1236 @@
|
|
|
1
|
+
import { ElkNode } from 'elkjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test-only: reset the title-id counter so id assertions in tests don't
|
|
5
|
+
* depend on how many titled diagrams earlier tests in the same file rendered.
|
|
6
|
+
* Not part of the public API (not re-exported from src/index.ts).
|
|
7
|
+
*/
|
|
8
|
+
export declare function __resetSvgTitleIdCounterForTests(): void;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Parse a `click <id> ...` statement and record the resulting
|
|
12
|
+
* {@link NodeInteraction} in `interactions`, keyed by whatever id scheme the
|
|
13
|
+
* caller's diagram type uses (flowchart/state node id, class diagram class
|
|
14
|
+
* id, ...).
|
|
15
|
+
*
|
|
16
|
+
* Supported forms:
|
|
17
|
+
* click id "url" ["tooltip"] [_blank|_self|_parent|_top]
|
|
18
|
+
* click id href "url" ["tooltip"] [_blank|_self|_parent|_top]
|
|
19
|
+
* click id call fn() ["tooltip"]
|
|
20
|
+
* click id callback fn() ["tooltip"]
|
|
21
|
+
*
|
|
22
|
+
* A line that doesn't match `click <id> ...` at all is a no-op — callers are
|
|
23
|
+
* expected to have already gated on a leading `click` keyword before calling
|
|
24
|
+
* this (see the `/^click\s+/i` checks at each call site) purely so this
|
|
25
|
+
* function's own regex can stay anchored to the id capture.
|
|
26
|
+
*/
|
|
27
|
+
export declare function applyClickStatement(line: string, interactions: Map<string, NodeInteraction>): void;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Fold an init config into render options.
|
|
31
|
+
*
|
|
32
|
+
* Caller-supplied options always win: a directive supplies a default, never
|
|
33
|
+
* an override. See the module header for why.
|
|
34
|
+
*/
|
|
35
|
+
export declare function applyInitConfig(options: RenderOptions, config: InitConfig): RenderOptions;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Build the CSS variable derivation rules for the SVG <style> block.
|
|
39
|
+
*
|
|
40
|
+
* When an optional variable (--line, --accent, etc.) is set on the SVG or
|
|
41
|
+
* a parent element, it's used directly. When unset, the fallback computes
|
|
42
|
+
* a blended value from --fg and --bg using color-mix().
|
|
43
|
+
*
|
|
44
|
+
* `nonce`, when given, lands on the `<style>` element as a `nonce`
|
|
45
|
+
* attribute — see `styleOpenTag()`.
|
|
46
|
+
*
|
|
47
|
+
* `font` is user-supplied input. When it's a CSS `var(...)` reference (e.g.
|
|
48
|
+
* `var(--font-family-body)`, letting the SVG inherit a host page's
|
|
49
|
+
* design-system font), the Google Fonts `@import` is skipped — it would
|
|
50
|
+
* otherwise URL-encode the literal `var(...)` string into a `family=` query
|
|
51
|
+
* param and produce a guaranteed no-op request — and the value is emitted
|
|
52
|
+
* unquoted, since a quoted string isn't parsed as a `var()` call by CSS.
|
|
53
|
+
*
|
|
54
|
+
* The `@import` is likewise skipped when `font` is a font *stack* (a
|
|
55
|
+
* comma-separated list, e.g. `"ui-sans-serif, system-ui, sans-serif"`) or a
|
|
56
|
+
* single CSS generic family keyword (e.g. `"system-ui"`) — see
|
|
57
|
+
* `isFontStackOrGenericFamily`. Neither names a single concrete font that
|
|
58
|
+
* Google Fonts could host, so importing one always produces a dead,
|
|
59
|
+
* always-404 request (#223). This is additive to the `var()` skip above,
|
|
60
|
+
* and only affects the `@import` decision — the `text { font-family: ... }`
|
|
61
|
+
* rule still renders the literal value exactly as it does today.
|
|
62
|
+
*
|
|
63
|
+
* Any other value is treated as a literal font name: sanitized and quoted
|
|
64
|
+
* exactly as before.
|
|
65
|
+
*
|
|
66
|
+
* `hasMonoFont`'s `.mono` rule (class-diagram method signatures, ER-diagram
|
|
67
|
+
* attribute types) never reaches out to Google Fonts at all — it used to
|
|
68
|
+
* `@import` 'JetBrains Mono' from Google's CDN, a third-party network
|
|
69
|
+
* dependency a published library's default SVG output had no business
|
|
70
|
+
* making (#1061, filed as a follow-up from #1059's ASCII-side self-hosting
|
|
71
|
+
* fix). It now embeds {@link SVG_MONO_FONT_FACE_CSS} — a small, subsetted
|
|
72
|
+
* (Basic Latin + Latin-1 Supplement), self-hosted `@font-face` as a base64
|
|
73
|
+
* `woff2` data URI, generated by scripts/build-mono-font-subset.ts into
|
|
74
|
+
* ./generated/mono-font-subset.ts — directly in the SVG's own `<style>`
|
|
75
|
+
* block. Unlike `font` above, this isn't caller-configurable: it's the same
|
|
76
|
+
* embed for every consumer, on by default, with no network request either
|
|
77
|
+
* way — a strict improvement over the dead-or-alive CDN fetch it replaces,
|
|
78
|
+
* and the only way a *standalone* SVG (no surrounding host page providing
|
|
79
|
+
* its own copy of the font) renders `.mono` text correctly out of the box.
|
|
80
|
+
*/
|
|
81
|
+
export declare function buildStyleBlock(font: string, hasMonoFont: boolean, nonce?: string): string;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Options applicable to class diagrams (`classDiagram`). Class diagrams use
|
|
85
|
+
* fixed internal padding/spacing (not `padding`/`nodeSpacing`/
|
|
86
|
+
* `layerSpacing`) and have no `direction` or `curve` concept; `interactivity`
|
|
87
|
+
* gates `click`-based links only — there's no edge-animation concept to gate.
|
|
88
|
+
*/
|
|
89
|
+
export declare type ClassRenderOptions = CommonRenderOptions & Pick<RenderOptions, 'fontSizes' | 'interactivity' | 'layoutCache'>;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Options every diagram type honors: theming (colors, font), the shared
|
|
93
|
+
* strict-CSP/accessibility/output controls, and the post-render
|
|
94
|
+
* `resolveColors` pass. Every other `RenderOptions` field applies to only a
|
|
95
|
+
* subset of diagram types — see the per-type types below.
|
|
96
|
+
*/
|
|
97
|
+
export declare type CommonRenderOptions = Pick<RenderOptions, 'bg' | 'fg' | 'line' | 'accent' | 'muted' | 'surface' | 'border' | 'font' | 'transparent' | 'embedSource' | 'resolveColors' | 'nonce' | 'styleAttribute' | 'title' | 'decorative'>;
|
|
98
|
+
|
|
99
|
+
/** How an edge path is interpolated between its routed points. */
|
|
100
|
+
export declare type CurveStyle = 'linear' | 'basis' | 'natural' | 'step' | 'stepBefore' | 'stepAfter';
|
|
101
|
+
|
|
102
|
+
/** Default bg/fg when no colors are provided (zinc light) */
|
|
103
|
+
export declare const DEFAULTS: Readonly<{
|
|
104
|
+
bg: string;
|
|
105
|
+
fg: string;
|
|
106
|
+
}>;
|
|
107
|
+
|
|
108
|
+
/** Human-readable note about directive keys that were parsed but not applied. */
|
|
109
|
+
export declare function describeIgnored(config: InitConfig): string[];
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Detect the diagram type from the mermaid source text.
|
|
113
|
+
* Returns the type keyword used for routing to the correct pipeline.
|
|
114
|
+
*
|
|
115
|
+
* The header keyword is the first *statement*, not the first line: Mermaid
|
|
116
|
+
* allows `;` as a statement separator, so `flowchart TD;A-->B` has its header
|
|
117
|
+
* and first edge on one line. Uses the same splitter every parser uses, so
|
|
118
|
+
* routing and parsing can never disagree about where the header ends.
|
|
119
|
+
*/
|
|
120
|
+
export declare function detectDiagramType(text: string): DiagramType;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Diagram color configuration.
|
|
124
|
+
*
|
|
125
|
+
* Required: bg + fg give you a clean mono diagram.
|
|
126
|
+
* Optional: line, accent, muted, surface, border bring in richer color
|
|
127
|
+
* from Shiki themes or custom palettes. Each falls back to a color-mix()
|
|
128
|
+
* derivation from bg + fg if not set.
|
|
129
|
+
*/
|
|
130
|
+
export declare interface DiagramColors {
|
|
131
|
+
/** Background color → CSS variable --bg */
|
|
132
|
+
bg: string;
|
|
133
|
+
/** Foreground / primary text color → CSS variable --fg */
|
|
134
|
+
fg: string;
|
|
135
|
+
/** Edge/connector color → CSS variable --line */
|
|
136
|
+
line?: string;
|
|
137
|
+
/** Arrow heads, highlights, special nodes → CSS variable --accent */
|
|
138
|
+
accent?: string;
|
|
139
|
+
/** Secondary text, edge labels → CSS variable --muted */
|
|
140
|
+
muted?: string;
|
|
141
|
+
/** Node/box fill tint → CSS variable --surface */
|
|
142
|
+
surface?: string;
|
|
143
|
+
/** Node/group stroke color → CSS variable --border */
|
|
144
|
+
border?: string;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** The diagram types this library can detect and route to a renderer. */
|
|
148
|
+
export declare type DiagramType = 'flowchart' | 'sequence' | 'class' | 'er' | 'xychart';
|
|
149
|
+
|
|
150
|
+
export declare type Direction = 'TD' | 'TB' | 'LR' | 'BT' | 'RL';
|
|
151
|
+
|
|
152
|
+
export declare type EdgeStyle = 'solid' | 'dotted' | 'thick'
|
|
153
|
+
/** `A ~~~ B` — participates in layout but draws no line or arrowhead. */
|
|
154
|
+
| 'invisible';
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Options applicable to ER diagrams (`erDiagram`). ER diagrams use fixed
|
|
158
|
+
* internal padding/spacing and ignore `curve` and `interactivity` (no
|
|
159
|
+
* animated edges or `click` links in this renderer's ER support), but do
|
|
160
|
+
* honor `direction` (applied before layout via `withDirectionOverride`).
|
|
161
|
+
*/
|
|
162
|
+
export declare type ErRenderOptions = CommonRenderOptions & Pick<RenderOptions, 'direction' | 'fontSizes' | 'layoutCache'>;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Escape a string for use as an XML/HTML attribute value.
|
|
166
|
+
* Escapes quotes and ampersands to prevent attribute injection.
|
|
167
|
+
*
|
|
168
|
+
* Deliberately distinct from `escapeXml()` above: attribute values in this
|
|
169
|
+
* codebase are always double-quoted, so single quotes don't need escaping —
|
|
170
|
+
* `escapeXml()` escapes them too (for safe embedding in either quote style),
|
|
171
|
+
* which would change output if reused here.
|
|
172
|
+
*/
|
|
173
|
+
export declare function escapeAttr(value: string): string;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Escape special XML characters in text content.
|
|
177
|
+
*/
|
|
178
|
+
export declare function escapeXml(text: string): string;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Scan a whole diagram for init directives and merge them.
|
|
182
|
+
*
|
|
183
|
+
* Later directives win over earlier ones, matching Mermaid, where a second
|
|
184
|
+
* directive overrides the first.
|
|
185
|
+
*/
|
|
186
|
+
export declare function extractInitConfig(lines: string[]): InitConfig;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Options applicable to flowchart (`graph` / `flowchart`) and state
|
|
190
|
+
* (`stateDiagram-v2`) diagrams — both share `DiagramType: 'flowchart'` and
|
|
191
|
+
* the same layout/render pipeline (src/layout-engine.ts, src/renderer.ts),
|
|
192
|
+
* so they share one option shape. `componentSpacing` is currently a no-op
|
|
193
|
+
* everywhere (accepted for forward compatibility only) but grouped here
|
|
194
|
+
* since it's spacing-shaped like `padding`/`nodeSpacing`/`layerSpacing`.
|
|
195
|
+
*/
|
|
196
|
+
export declare type FlowchartRenderOptions = CommonRenderOptions & Pick<RenderOptions, 'padding' | 'nodeSpacing' | 'layerSpacing' | 'componentSpacing' | 'mergeEdges' | 'direction' | 'curve' | 'fontSizes' | 'interactivity' | 'layoutCache'>;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Serialize a color as `#rrggbb` when fully opaque, otherwise as
|
|
200
|
+
* `rgba(r, g, b, a)` — the two forms every SVG consumer (browsers, resvg,
|
|
201
|
+
* librsvg, Inkscape) agrees on.
|
|
202
|
+
*/
|
|
203
|
+
export declare function formatCssColor(c: RgbaColor): string;
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Extract diagram colors from a Shiki theme object.
|
|
207
|
+
* Works with any VS Code / TextMate theme loaded by Shiki.
|
|
208
|
+
*
|
|
209
|
+
* Maps editor UI colors to diagram roles:
|
|
210
|
+
* editor.background → bg
|
|
211
|
+
* editor.foreground → fg
|
|
212
|
+
* editorLineNumber.fg → line (optional)
|
|
213
|
+
* focusBorder / keyword → accent (optional)
|
|
214
|
+
* comment token → muted (optional)
|
|
215
|
+
* editor.selectionBackground→ surface (optional)
|
|
216
|
+
* editorWidget.border → border (optional)
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* import { getSingletonHighlighter } from 'shiki'
|
|
221
|
+
* import { fromShikiTheme } from 'zombie-mermaid'
|
|
222
|
+
*
|
|
223
|
+
* const hl = await getSingletonHighlighter({ themes: ['tokyo-night'] })
|
|
224
|
+
* const colors = fromShikiTheme(hl.getTheme('tokyo-night'))
|
|
225
|
+
* const svg = renderMermaidSVG(code, colors)
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
export declare function fromShikiTheme(theme: ShikiThemeLike): DiagramColors;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Get the relative width of a single character.
|
|
232
|
+
*
|
|
233
|
+
* Returns a normalized width ratio where:
|
|
234
|
+
* - 0.0 = zero-width (combining marks)
|
|
235
|
+
* - 0.3 = space
|
|
236
|
+
* - 0.4 = narrow (i, l, t, f, j, I, 1)
|
|
237
|
+
* - 0.8 = semi-narrow (r)
|
|
238
|
+
* - 1.0 = average lowercase
|
|
239
|
+
* - 1.2 = wide lowercase / uppercase
|
|
240
|
+
* - 1.5 = very wide (W, M)
|
|
241
|
+
* - 2.0 = fullwidth (CJK, emoji)
|
|
242
|
+
*/
|
|
243
|
+
export declare function getCharWidth(char: string): number;
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Pick a readable text color for a given fill color.
|
|
247
|
+
*
|
|
248
|
+
* If `fill` is a concrete, resolvable hex color, returns pure black or
|
|
249
|
+
* white depending on the fill's perceptual luminance (threshold 0.5: light
|
|
250
|
+
* fills get dark text, dark fills get light text). If `fill` is undefined
|
|
251
|
+
* or isn't a resolvable color (a `var(...)` reference, a named CSS color,
|
|
252
|
+
* or malformed input), returns `fallback` unchanged so callers don't guess
|
|
253
|
+
* at colors they can't actually evaluate.
|
|
254
|
+
*/
|
|
255
|
+
export declare function getReadableTextColor(fill: string | undefined, fallback: string): string;
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Whether `char` has an exact measured Inter advance in `INTER_ADVANCES`,
|
|
259
|
+
* as opposed to falling through to a coarse character-class bucket or the
|
|
260
|
+
* default width in `getCharWidth`. Exported only so tests can assert the
|
|
261
|
+
* table covers every printable ASCII character (U+0020–U+007E) — a gap
|
|
262
|
+
* here means a real character silently degrades to an approximate width.
|
|
263
|
+
*/
|
|
264
|
+
export declare function hasMeasuredAdvance(char: string): boolean;
|
|
265
|
+
|
|
266
|
+
/** Configuration a diagram can set for itself via `%%{init: ...}%%`. */
|
|
267
|
+
export declare interface InitConfig {
|
|
268
|
+
theme?: string;
|
|
269
|
+
/** Flowchart edge interpolation. */
|
|
270
|
+
curve?: CurveStyle;
|
|
271
|
+
/** Recognized but not acted on — see `IGNORED_KEYS`. */
|
|
272
|
+
ignored: string[];
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/** True when `value` is one of the five directions Mermaid recognizes. */
|
|
276
|
+
export declare function isDirection(value: string): value is Direction;
|
|
277
|
+
|
|
278
|
+
/** True if `line` is an init directive. */
|
|
279
|
+
export declare function isInitDirective(line: string): boolean;
|
|
280
|
+
|
|
281
|
+
/** Fonts whose glyphs all share one advance width. */
|
|
282
|
+
export declare function isMonospaceFont(font: string): boolean;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Check if a single character (code point) is "wide" — i.e. renders as two
|
|
286
|
+
* columns in a monospace terminal / two grid cells wide instead of one.
|
|
287
|
+
* Covers CJK/kana/hangul/fullwidth-form characters (via `isFullwidth`) as
|
|
288
|
+
* well as emoji. Shared by the SVG text-measurement path (`getCharWidth`
|
|
289
|
+
* above) and the ASCII grid's display-width helpers
|
|
290
|
+
* (`src/ascii/display-width.ts`), so both agree on what counts as wide.
|
|
291
|
+
*/
|
|
292
|
+
export declare function isWideChar(char: string): boolean;
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Opt-in bounded LRU cache for `elkLayoutSync()` results.
|
|
296
|
+
*
|
|
297
|
+
* Off by default — `elkLayoutSync()` only consults a cache when one is
|
|
298
|
+
* explicitly passed in, so existing callers see no behavior change.
|
|
299
|
+
* Create one with `createLayoutCache()` and reuse it across renders (e.g.
|
|
300
|
+
* module scope, or a `useRef` in React) — a fresh cache per render defeats
|
|
301
|
+
* the point.
|
|
302
|
+
*
|
|
303
|
+
* The `map`/`maxSize` fields are implementation detail exposed only so
|
|
304
|
+
* `elkLayoutSync()` (and tests) can read/mutate them directly without a
|
|
305
|
+
* class; treat a `LayoutCache` as opaque from outside this module.
|
|
306
|
+
*/
|
|
307
|
+
export declare interface LayoutCache {
|
|
308
|
+
/* Excluded from this release type: map */
|
|
309
|
+
/* Excluded from this release type: maxSize */
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/** Standard line height ratio for multi-line text (1.3 = 130% of font size) */
|
|
313
|
+
export declare const LINE_HEIGHT_RATIO = 1.3;
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Measure multi-line text dimensions.
|
|
317
|
+
*
|
|
318
|
+
* Splits text on newlines and returns the maximum width across all lines,
|
|
319
|
+
* total height based on line count, and the split lines for rendering.
|
|
320
|
+
*
|
|
321
|
+
* @param text - The text to measure (may contain \n)
|
|
322
|
+
* @param fontSize - Font size in pixels
|
|
323
|
+
* @param fontWeight - Font weight (affects width slightly)
|
|
324
|
+
* @returns Metrics including width, height, lines array, and lineHeight
|
|
325
|
+
*/
|
|
326
|
+
export declare function measureMultilineText(text: string, fontSize: number, fontWeight: number): MultilineMetrics;
|
|
327
|
+
|
|
328
|
+
export declare function measureTextWidth(text: string, fontSize: number, fontWeight: number): number;
|
|
329
|
+
|
|
330
|
+
export declare interface MermaidEdge {
|
|
331
|
+
source: string;
|
|
332
|
+
target: string;
|
|
333
|
+
label?: string;
|
|
334
|
+
style: EdgeStyle;
|
|
335
|
+
/** Whether to render an arrowhead at the start (source end) of the edge */
|
|
336
|
+
hasArrowStart: boolean;
|
|
337
|
+
/** Whether to render an arrowhead at the end (target end) of the edge */
|
|
338
|
+
hasArrowEnd: boolean;
|
|
339
|
+
/**
|
|
340
|
+
* Terminator shape at the source end when it's a circle/cross marker
|
|
341
|
+
* (`o--`/`x--`) rather than a plain arrowhead. Undefined for a regular
|
|
342
|
+
* `<`-style arrowhead or no marker at all — `hasArrowStart` alone still
|
|
343
|
+
* governs whether anything is drawn there. Currently consumed by the
|
|
344
|
+
* ASCII renderer only (see issue #330); the SVG renderer still draws a
|
|
345
|
+
* plain arrowhead for these.
|
|
346
|
+
*/
|
|
347
|
+
startMarker?: 'circle' | 'cross';
|
|
348
|
+
/** Terminator shape at the target end (`--o`/`--x`). See `startMarker`. */
|
|
349
|
+
endMarker?: 'circle' | 'cross';
|
|
350
|
+
/** Edge id from `A e1@--> B` (Mermaid v11.10.0+), for `e1@{ ... }` and CSS targeting */
|
|
351
|
+
id?: string;
|
|
352
|
+
/** Set by `e1@{ animate: true }` — renders as a marching-ants dash */
|
|
353
|
+
animate?: boolean;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export declare interface MermaidGraph {
|
|
357
|
+
direction: Direction;
|
|
358
|
+
nodes: Map<string, MermaidNode>;
|
|
359
|
+
edges: MermaidEdge[];
|
|
360
|
+
subgraphs: MermaidSubgraph[];
|
|
361
|
+
classDefs: Map<string, Record<string, string>>;
|
|
362
|
+
/** Maps node IDs to their class names (from `class X className` or `:::className` shorthand) */
|
|
363
|
+
classAssignments: Map<string, string>;
|
|
364
|
+
/** Maps node IDs to inline styles (from `style X fill:#f00,stroke:#333`) */
|
|
365
|
+
nodeStyles: Map<string, Record<string, string>>;
|
|
366
|
+
/** Maps edge indices (or 'default') to inline styles from `linkStyle` directives */
|
|
367
|
+
linkStyles: Map<number | 'default', Record<string, string>>;
|
|
368
|
+
/** Maps node IDs to interactions declared by `click` statements */
|
|
369
|
+
interactions: Map<string, NodeInteraction>;
|
|
370
|
+
/** Configuration the diagram set for itself via `%%{init: ...}%%` */
|
|
371
|
+
initConfig?: InitConfig;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
export declare interface MermaidNode {
|
|
375
|
+
id: string;
|
|
376
|
+
label: string;
|
|
377
|
+
shape: NodeShape;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export declare interface MermaidSubgraph {
|
|
381
|
+
id: string;
|
|
382
|
+
label: string;
|
|
383
|
+
nodeIds: string[];
|
|
384
|
+
children: MermaidSubgraph[];
|
|
385
|
+
/** Optional direction override for this subgraph's internal layout */
|
|
386
|
+
direction?: Direction;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export declare const MIX: {
|
|
390
|
+
/** Primary text: near-full fg */
|
|
391
|
+
readonly text: 100;
|
|
392
|
+
/** Secondary text (group headers): fg mixed at 60% */
|
|
393
|
+
readonly textSec: 60;
|
|
394
|
+
/** Muted text (edge labels, notes): fg mixed at 40% */
|
|
395
|
+
readonly textMuted: 40;
|
|
396
|
+
/** Faint text (de-emphasized): fg mixed at 25% */
|
|
397
|
+
readonly textFaint: 25;
|
|
398
|
+
/** Edge/connector lines: fg mixed at 50% for clear visibility */
|
|
399
|
+
readonly line: 50;
|
|
400
|
+
/** Arrow head fill: fg mixed at 85% for clear visibility */
|
|
401
|
+
readonly arrow: 85;
|
|
402
|
+
/** Node fill tint: fg mixed at 3% */
|
|
403
|
+
readonly nodeFill: 3;
|
|
404
|
+
/** Node/group stroke: fg mixed at 20% */
|
|
405
|
+
readonly nodeStroke: 20;
|
|
406
|
+
/** Group header band tint: fg mixed at 5% */
|
|
407
|
+
readonly groupHeader: 5;
|
|
408
|
+
/** Inner divider strokes: fg mixed at 12% */
|
|
409
|
+
readonly innerStroke: 12;
|
|
410
|
+
/** Key badge background opacity (ER diagrams) */
|
|
411
|
+
readonly keyBadge: 10;
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Mix `fg` into `bg` at `pct` percent — the shape every MIX entry in
|
|
416
|
+
* packages/core/src/theme.ts uses (`color-mix(in srgb, var(--fg) N%, var(--bg))`).
|
|
417
|
+
* Returns `fg` unchanged when either input isn't a concrete color this
|
|
418
|
+
* module can parse (a `var(...)` reference, a named color).
|
|
419
|
+
*/
|
|
420
|
+
export declare function mixHexColors(fg: string, bg: string, pct: number): string;
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Evaluate `color-mix(in srgb, c1 p1%, c2 p2%)` per CSS Color Module
|
|
424
|
+
* Level 5 (https://www.w3.org/TR/css-color-5/#color-mix): percentages are
|
|
425
|
+
* normalized so they sum to 100 (a sum under 100 additionally scales the
|
|
426
|
+
* result's alpha by `sum / 100`), and the two colors are interpolated in
|
|
427
|
+
* premultiplied-alpha space, so mixing an opaque color toward
|
|
428
|
+
* `transparent` fades its alpha without darkening it.
|
|
429
|
+
*
|
|
430
|
+
* `p1`/`p2` follow the spec's omission rules: pass `undefined` for an
|
|
431
|
+
* omitted percentage (both omitted → 50/50; one omitted → 100 minus the
|
|
432
|
+
* other). Returns null when both percentages are zero, which the spec
|
|
433
|
+
* defines as invalid.
|
|
434
|
+
*/
|
|
435
|
+
export declare function mixSrgb(c1: RgbaColor, c2: RgbaColor, p1?: number, p2?: number): RgbaColor | null;
|
|
436
|
+
|
|
437
|
+
/** Metrics for multi-line text measurement */
|
|
438
|
+
export declare interface MultilineMetrics {
|
|
439
|
+
/** Maximum line width in pixels */
|
|
440
|
+
width: number;
|
|
441
|
+
/** Total height in pixels (lines × lineHeight) */
|
|
442
|
+
height: number;
|
|
443
|
+
/** Individual lines after splitting */
|
|
444
|
+
lines: string[];
|
|
445
|
+
/** Computed line height in pixels */
|
|
446
|
+
lineHeight: number;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* An interaction attached to a node by a `click` statement.
|
|
451
|
+
*
|
|
452
|
+
* This renderer emits static SVG and never executes diagram-supplied script,
|
|
453
|
+
* so a `call`/callback binding is parsed but not invoked — see
|
|
454
|
+
* docs/diagrams.md and docs/decisions/no-script-interactivity.md. An `href`
|
|
455
|
+
* becomes a real SVG link and a tooltip becomes a `<title>`.
|
|
456
|
+
*/
|
|
457
|
+
export declare interface NodeInteraction {
|
|
458
|
+
/** `click A "https://..."` — rendered as an <a> wrapper */
|
|
459
|
+
href?: string;
|
|
460
|
+
/** Link target, e.g. `_blank` */
|
|
461
|
+
target?: string;
|
|
462
|
+
/** Tooltip text — rendered as a <title> child */
|
|
463
|
+
tooltip?: string;
|
|
464
|
+
/**
|
|
465
|
+
* `click A call fn()` — the raw expression text (`fn()`), exposed as data
|
|
466
|
+
* only. Nothing in the rendered SVG carries it and the library never
|
|
467
|
+
* evaluates it; a host that trusts its diagram source reads it from
|
|
468
|
+
* `parseMermaid(source).interactions` and binds behaviour to the node's
|
|
469
|
+
* `data-id` attribute itself:
|
|
470
|
+
*
|
|
471
|
+
* ```ts
|
|
472
|
+
* for (const [id, { callback }] of parseMermaid(source).interactions) {
|
|
473
|
+
* if (callback === 'showDetail()') {
|
|
474
|
+
* svgRoot.querySelector(`[data-id="${id}"]`)
|
|
475
|
+
* ?.addEventListener('click', () => showDetail(id))
|
|
476
|
+
* }
|
|
477
|
+
* }
|
|
478
|
+
* ```
|
|
479
|
+
*/
|
|
480
|
+
callback?: string;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
export declare type NodeShape = 'rectangle' | 'rounded' | 'diamond' | 'stadium' | 'circle' | 'subroutine' | 'doublecircle' | 'hexagon' | 'cylinder' | 'asymmetric' | 'trapezoid' | 'trapezoid-alt' | 'parallelogram' | 'parallelogram-alt' | 'state-start' | 'state-end' | 'document' | 'stacked-document' | 'stacked-process' | 'card' | 'lined-process' | 'divided-process' | 'window-pane' | 'triangle' | 'flipped-triangle' | 'filled-circle' | 'crossed-circle' | 'fork-join' | 'notched-pentagon' | 'sloped-rectangle' | 'flag' | 'bow-tie-rectangle' | 'half-rounded-rectangle' | 'brace' | 'brace-right' | 'braces' | 'bolt' | 'text' | 'anchor';
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Normalize label text: strip surrounding quotes, convert <br> tags and
|
|
487
|
+
* literal \n sequences to newline characters. Strips unsupported HTML tags
|
|
488
|
+
* but preserves formatting tags (<b>, <i>, <u>, <s>) for SVG rendering.
|
|
489
|
+
*/
|
|
490
|
+
export declare function normalizeBrTags(label: string): string;
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Parse a concrete CSS color value into sRGB components.
|
|
494
|
+
*
|
|
495
|
+
* Accepts the forms this library's own theme system produces or documents:
|
|
496
|
+
* hex literals (`#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`), `rgb()`/`rgba()`,
|
|
497
|
+
* and the `transparent` keyword. Anything else — CSS named colors, `hsl()`,
|
|
498
|
+
* `var(...)`, an unresolved `color-mix(...)` — returns null so the caller
|
|
499
|
+
* can leave it untouched rather than guess.
|
|
500
|
+
*/
|
|
501
|
+
export declare function parseCssColor(value: string): RgbaColor | null;
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Parse a hex color string into 0-255 RGB components, ignoring any alpha
|
|
505
|
+
* digits. Returns null for anything that isn't a well-formed hex literal
|
|
506
|
+
* (e.g. `var(--foo)`, named CSS colors, or attribute-injection payloads) —
|
|
507
|
+
* the caller should treat those as unresolvable and fall back.
|
|
508
|
+
*/
|
|
509
|
+
export declare function parseHexColor(value: string): [number, number, number] | null;
|
|
510
|
+
|
|
511
|
+
/** Parse a hex color literal (3/4/6/8 digits) into an RgbaColor, or null. */
|
|
512
|
+
export declare function parseHexRgba(value: string): RgbaColor | null;
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Parse an init directive's payload.
|
|
516
|
+
*
|
|
517
|
+
* Returns `undefined` when the line is not a directive or its payload cannot
|
|
518
|
+
* be parsed. A malformed directive is ignored rather than fatal: Mermaid
|
|
519
|
+
* treats config as advisory, and failing an entire diagram over a stray brace
|
|
520
|
+
* in a comment-like construct would be a poor trade.
|
|
521
|
+
*/
|
|
522
|
+
export declare function parseInitDirective(line: string): InitConfig | undefined;
|
|
523
|
+
|
|
524
|
+
/** Parse "fill:#f00,stroke:#333" style property strings into a Record */
|
|
525
|
+
export declare function parseStyleProps(propsStr: string): Record<string, string>;
|
|
526
|
+
|
|
527
|
+
export declare interface Point {
|
|
528
|
+
x: number;
|
|
529
|
+
y: number;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
export declare interface PositionedEdge {
|
|
533
|
+
source: string;
|
|
534
|
+
target: string;
|
|
535
|
+
label?: string;
|
|
536
|
+
style: EdgeStyle;
|
|
537
|
+
hasArrowStart: boolean;
|
|
538
|
+
hasArrowEnd: boolean;
|
|
539
|
+
/** Full path including bends — array of {x, y} points */
|
|
540
|
+
points: Point[];
|
|
541
|
+
/** Layout-computed label center position (avoids label-label collisions) */
|
|
542
|
+
labelPosition?: Point;
|
|
543
|
+
/** Inline styles resolved from `linkStyle` directives — override theme defaults */
|
|
544
|
+
inlineStyle?: Record<string, string>;
|
|
545
|
+
/** Edge id from `A e1@--> B`, emitted as data-id for CSS targeting */
|
|
546
|
+
id?: string;
|
|
547
|
+
/** Set by `e1@{ animate: true }` — renders as a marching-ants dash */
|
|
548
|
+
animate?: boolean;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
export declare interface PositionedGraph {
|
|
552
|
+
width: number;
|
|
553
|
+
height: number;
|
|
554
|
+
nodes: PositionedNode[];
|
|
555
|
+
edges: PositionedEdge[];
|
|
556
|
+
groups: PositionedGroup[];
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
export declare interface PositionedGroup {
|
|
560
|
+
id: string;
|
|
561
|
+
label: string;
|
|
562
|
+
x: number;
|
|
563
|
+
y: number;
|
|
564
|
+
width: number;
|
|
565
|
+
height: number;
|
|
566
|
+
children: PositionedGroup[];
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
export declare interface PositionedNode {
|
|
570
|
+
id: string;
|
|
571
|
+
label: string;
|
|
572
|
+
shape: NodeShape;
|
|
573
|
+
x: number;
|
|
574
|
+
y: number;
|
|
575
|
+
width: number;
|
|
576
|
+
height: number;
|
|
577
|
+
/** Inline styles resolved from classDef + explicit `style` statements — override theme defaults */
|
|
578
|
+
inlineStyle?: Record<string, string>;
|
|
579
|
+
/** Custom class name assigned via `class A className` or `:::className` shorthand — emitted onto the rendered element's `class` attribute so external CSS can target it */
|
|
580
|
+
className?: string;
|
|
581
|
+
/** Interaction from a `click` statement — an href wraps the node in an <a> */
|
|
582
|
+
interaction?: NodeInteraction;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Render a multi-line text element with proper vertical centering.
|
|
587
|
+
*
|
|
588
|
+
* For single-line text, returns a simple <text> element.
|
|
589
|
+
* For multi-line text (containing \n), returns <text> with <tspan> children.
|
|
590
|
+
* Inline formatting tags (<b>, <i>, <u>, <s>) are rendered as SVG attributes.
|
|
591
|
+
*
|
|
592
|
+
* @param text - The text to render (may contain \n and formatting tags)
|
|
593
|
+
* @param cx - Center x coordinate
|
|
594
|
+
* @param cy - Center y coordinate
|
|
595
|
+
* @param fontSize - Font size in pixels
|
|
596
|
+
* @param attrs - Additional SVG attributes (e.g., 'text-anchor="middle" fill="var(--_text)"')
|
|
597
|
+
* @param baselineShift - Baseline shift for vertical alignment (default 0.35)
|
|
598
|
+
* @returns SVG text element string
|
|
599
|
+
*/
|
|
600
|
+
export declare function renderMultilineText(text: string, cx: number, cy: number, fontSize: number, attrs: string, baselineShift?: number): string;
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Render a multi-line text element with a background rectangle (pill).
|
|
604
|
+
*
|
|
605
|
+
* Used for edge labels that need a background for readability.
|
|
606
|
+
*
|
|
607
|
+
* @param text - The text to render (may contain \n)
|
|
608
|
+
* @param cx - Center x coordinate
|
|
609
|
+
* @param cy - Center y coordinate
|
|
610
|
+
* @param textWidth - Pre-calculated text width (max line width)
|
|
611
|
+
* @param textHeight - Pre-calculated text height (lines × lineHeight)
|
|
612
|
+
* @param fontSize - Font size in pixels
|
|
613
|
+
* @param padding - Padding around text
|
|
614
|
+
* @param textAttrs - SVG attributes for the text element
|
|
615
|
+
* @param bgAttrs - SVG attributes for the background rect
|
|
616
|
+
* @returns SVG elements string (rect + text)
|
|
617
|
+
*/
|
|
618
|
+
export declare function renderMultilineTextWithBackground(text: string, cx: number, cy: number, textWidth: number, textHeight: number, fontSize: number, padding: number, textAttrs: string, bgAttrs: string): string;
|
|
619
|
+
|
|
620
|
+
export declare interface RenderOptions {
|
|
621
|
+
/** Background color → CSS variable --bg. Default: '#FFFFFF' */
|
|
622
|
+
bg?: string;
|
|
623
|
+
/** Foreground / primary text color → CSS variable --fg. Default: '#27272A' */
|
|
624
|
+
fg?: string;
|
|
625
|
+
/** Edge/connector color → CSS variable --line */
|
|
626
|
+
line?: string;
|
|
627
|
+
/** Arrow heads, highlights → CSS variable --accent */
|
|
628
|
+
accent?: string;
|
|
629
|
+
/** Secondary text, edge labels → CSS variable --muted */
|
|
630
|
+
muted?: string;
|
|
631
|
+
/** Node/box fill tint → CSS variable --surface */
|
|
632
|
+
surface?: string;
|
|
633
|
+
/** Node/group stroke color → CSS variable --border */
|
|
634
|
+
border?: string;
|
|
635
|
+
/** Font family for all text. Default: 'Inter' */
|
|
636
|
+
font?: string;
|
|
637
|
+
/** Canvas padding in px. Default: 40. Flowchart/state diagrams only — class/ER diagrams use fixed internal padding. */
|
|
638
|
+
padding?: number;
|
|
639
|
+
/** Horizontal spacing between sibling nodes. Default: 28. Flowchart/state diagrams only — class/ER diagrams use fixed internal spacing. */
|
|
640
|
+
nodeSpacing?: number;
|
|
641
|
+
/** Vertical spacing between layers. Default: 48. Flowchart/state diagrams only — class/ER diagrams use fixed internal spacing. */
|
|
642
|
+
layerSpacing?: number;
|
|
643
|
+
/** Currently unused — accepted for forward compatibility but not read anywhere. */
|
|
644
|
+
componentSpacing?: number;
|
|
645
|
+
/** Whether to bundle overlapping fan-out/fan-in edge paths into shared trunks to reduce visual clutter. Default: true */
|
|
646
|
+
mergeEdges?: boolean;
|
|
647
|
+
/**
|
|
648
|
+
* Force the diagram's layout direction, overriding the one its source
|
|
649
|
+
* declares — a flowchart's `graph LR` / `flowchart TD` header, or a state
|
|
650
|
+
* diagram's / ER diagram's top-level `direction LR` line. Applied after
|
|
651
|
+
* parsing and before layout, so the source text is never rewritten and
|
|
652
|
+
* `parseMermaid()` output is unaffected.
|
|
653
|
+
*
|
|
654
|
+
* Replaces only the *top-level* direction. A nested subgraph's or
|
|
655
|
+
* composite state's own `direction` line still applies on top of this
|
|
656
|
+
* override, exactly as it does on top of the diagram's own header — the
|
|
657
|
+
* override behaves as if the caller had written that direction in the
|
|
658
|
+
* source header, nothing more.
|
|
659
|
+
*
|
|
660
|
+
* Flowchart, state, and ER diagrams only — the three diagram types that
|
|
661
|
+
* have a direction concept to override. Sequence, class, and XY-chart
|
|
662
|
+
* diagrams ignore it (no error; output is identical with or without it).
|
|
663
|
+
*
|
|
664
|
+
* Unset (the default) keeps the source's direction, so existing output is
|
|
665
|
+
* unchanged. See issue #276.
|
|
666
|
+
*/
|
|
667
|
+
direction?: Direction;
|
|
668
|
+
/** Render with transparent background (no background style on SVG). Default: false */
|
|
669
|
+
transparent?: boolean;
|
|
670
|
+
/**
|
|
671
|
+
* Render-target-scoped interactivity level. Declarative only — this
|
|
672
|
+
* library never emits `<script>`; see
|
|
673
|
+
* docs/decisions/no-script-interactivity.md for the tier model this maps
|
|
674
|
+
* to (tier 1: `<title>`/text; tier 2: `<a href>`, CSS `:hover`, CSS
|
|
675
|
+
* animation; tier 3: `click ... call fn()`, recorded as data, never
|
|
676
|
+
* executed). Default: `'static'`.
|
|
677
|
+
*
|
|
678
|
+
* - `'none'` — strips flowchart/state-diagram edge animation
|
|
679
|
+
* (`e1@{ animate: true }`), and strips `click`-based links
|
|
680
|
+
* (`<a href>`) and `<title>` tooltips. Intended for print/rasterized
|
|
681
|
+
* output: a CSS `@keyframes` animation would otherwise silently
|
|
682
|
+
* render as a single static frame with no indication that motion
|
|
683
|
+
* was intended, and a link is meaningless once rasterized.
|
|
684
|
+
* - `'static'` — default. Tier 1 + tier 2 minus motion: `click`-based
|
|
685
|
+
* links and `<title>` tooltips still render, but flowchart/state-diagram
|
|
686
|
+
* edge animation does not — a diagram that opts into
|
|
687
|
+
* `e1@{ animate: true }` renders as a still line unless `'full'` is
|
|
688
|
+
* requested. xychart hover tooltips stay off unless requested via
|
|
689
|
+
* `'full'` or the deprecated `interactive: true` below. This is a
|
|
690
|
+
* breaking change from earlier releases, where `'static'` (and the
|
|
691
|
+
* default) still animated — animation is tier-2 *motion*, which the
|
|
692
|
+
* stricter `'static'` reading excludes; see the ADR.
|
|
693
|
+
* - `'full'` — also enables flowchart/state-diagram edge animation and
|
|
694
|
+
* xychart hover tooltips.
|
|
695
|
+
*/
|
|
696
|
+
interactivity?: 'none' | 'static' | 'full';
|
|
697
|
+
/**
|
|
698
|
+
* @deprecated Use `interactivity` instead. Enable hover tooltips on chart
|
|
699
|
+
* data points (xychart only). Default: false.
|
|
700
|
+
*
|
|
701
|
+
* When `interactivity` is not set, this boolean still controls xychart
|
|
702
|
+
* tooltips as before (`true` behaves like `interactivity: 'full'` for
|
|
703
|
+
* that one effect). When `interactivity` *is* set, it takes precedence
|
|
704
|
+
* and this field is ignored.
|
|
705
|
+
*/
|
|
706
|
+
interactive?: boolean;
|
|
707
|
+
/** Stamp the original diagram source onto the root `<svg>` as a `data-src` attribute (HTML-escaped). Default: false */
|
|
708
|
+
embedSource?: boolean;
|
|
709
|
+
/**
|
|
710
|
+
* Replace every CSS `var(--…)` and `color-mix(…)` in the output with its
|
|
711
|
+
* computed sRGB value (`#rrggbb`, or `rgba()` when translucent), using
|
|
712
|
+
* the same mix percentages the `<style>` block declares (see
|
|
713
|
+
* `MIX` in src/theme.ts — there is one table, not a copy). Default: false.
|
|
714
|
+
*
|
|
715
|
+
* Browsers evaluate both natively, so the default output stays a live
|
|
716
|
+
* function of its CSS custom properties (docs/theming.md). Rasterizers
|
|
717
|
+
* and non-browser SVG consumers — resvg, librsvg, Inkscape, ImageMagick —
|
|
718
|
+
* implement neither and render the whole theme as black; turn this on
|
|
719
|
+
* for any output headed to one of them (GitHub issue #456).
|
|
720
|
+
*
|
|
721
|
+
* Trade-off: the result is a fixed palette. Overriding `--bg`/`--fg` on
|
|
722
|
+
* the embedded SVG no longer restyles it, and passing a `var(...)`
|
|
723
|
+
* reference as a color (the React live-theming pattern) has nothing to
|
|
724
|
+
* resolve against — such references, and any `var()` this library did
|
|
725
|
+
* not declare itself (e.g. a host-page font variable), are left as-is.
|
|
726
|
+
*/
|
|
727
|
+
resolveColors?: boolean;
|
|
728
|
+
/**
|
|
729
|
+
* CSP nonce to stamp on every `<style>` element in the output (see GitHub
|
|
730
|
+
* issue #216).
|
|
731
|
+
*
|
|
732
|
+
* The renderer styles its SVG with an inline `<style>` element (the theme
|
|
733
|
+
* block; flowcharts with `e1@{ animate: true }` edges and xycharts add a
|
|
734
|
+
* second one). A host page whose `Content-Security-Policy` has a
|
|
735
|
+
* `style-src` without `'unsafe-inline'` blocks those, and the diagram
|
|
736
|
+
* silently renders unstyled. The standard fix is a per-response nonce:
|
|
737
|
+
* the host generates one, lists it as `style-src 'nonce-<value>'`, and
|
|
738
|
+
* puts `nonce="<value>"` on each element it wants to allow. Pass that
|
|
739
|
+
* value here and every emitted `<style>` gets it — one `<style>` left
|
|
740
|
+
* un-nonced is enough to lose the whole diagram's styling, so this is
|
|
741
|
+
* applied at the single shared emission point rather than per diagram
|
|
742
|
+
* type.
|
|
743
|
+
*
|
|
744
|
+
* The value is attribute-escaped on output. An empty string is treated as
|
|
745
|
+
* unset. Default: undefined (no `nonce` attribute).
|
|
746
|
+
*
|
|
747
|
+
* A nonce only authorises `<style>` *elements* — it cannot authorise a
|
|
748
|
+
* `style="…"` *attribute* (browsers apply nonces to elements only), so the
|
|
749
|
+
* root `<svg style="--bg: …">` attribute stays blocked under the same
|
|
750
|
+
* policy. Pair this with `styleAttribute: false` and put the theme
|
|
751
|
+
* variables in your own stylesheet; see that option.
|
|
752
|
+
*/
|
|
753
|
+
nonce?: string;
|
|
754
|
+
/**
|
|
755
|
+
* Emit the root `<svg style="--bg: …; --fg: …; background: var(--bg)">`
|
|
756
|
+
* attribute. Default: true.
|
|
757
|
+
*
|
|
758
|
+
* That attribute is how the theme colours reach the SVG: every rule in
|
|
759
|
+
* the embedded `<style>` block resolves against the `--bg`/`--fg`/…
|
|
760
|
+
* custom properties it sets. Under a strict `Content-Security-Policy`
|
|
761
|
+
* (`style-src` without `'unsafe-inline'`) the browser drops it, and no
|
|
762
|
+
* `nonce` can rescue it — nonces apply to elements, never attributes —
|
|
763
|
+
* so the diagram loses its colours even when the `<style>` element itself
|
|
764
|
+
* is allowed (see GitHub issue #216).
|
|
765
|
+
*
|
|
766
|
+
* Set this to `false` to leave the attribute out entirely. The host must
|
|
767
|
+
* then define the same custom properties on the SVG or an ancestor from
|
|
768
|
+
* its own (nonced or external) stylesheet; `themeCssVariables(options)`
|
|
769
|
+
* returns the exact declaration list the attribute would have carried,
|
|
770
|
+
* so the two can't drift:
|
|
771
|
+
*
|
|
772
|
+
* ```ts
|
|
773
|
+
* const opts = { bg: '#fff', fg: '#000', nonce, styleAttribute: false }
|
|
774
|
+
* const svg = renderMermaidSVG(code, opts)
|
|
775
|
+
* const css = `.diagram svg { ${themeCssVariables(opts)} }`
|
|
776
|
+
* // `<style nonce="…">${css}</style>` + `<div class="diagram">${svg}</div>`
|
|
777
|
+
* ```
|
|
778
|
+
*
|
|
779
|
+
* With the attribute gone, the SVG has no inline `background` either; the
|
|
780
|
+
* declarations from `themeCssVariables()` include it (unless
|
|
781
|
+
* `transparent`) so the host's rule restores it. Only the *root* `style`
|
|
782
|
+
* attribute is affected: a per-node `style A font-family:…` override
|
|
783
|
+
* still renders as that node's own `style` attribute, since it's diagram
|
|
784
|
+
* content rather than theming, and under such a CSP it is simply ignored
|
|
785
|
+
* by the browser. `nonce` and this option are independent — a host using
|
|
786
|
+
* hashes rather than nonces may want only this one.
|
|
787
|
+
*/
|
|
788
|
+
styleAttribute?: boolean;
|
|
789
|
+
/**
|
|
790
|
+
* Accessible name for the rendered SVG (see GitHub issue #215). Rendered
|
|
791
|
+
* as `role="img"` + `aria-labelledby` pointing at a `<title>` child
|
|
792
|
+
* holding this text — the standard SVG/WAI-ARIA technique for naming an
|
|
793
|
+
* inline image. Without a name, assistive tech either treats the SVG as a
|
|
794
|
+
* plain group (every node/edge label announced individually, out of
|
|
795
|
+
* reading order) or skips it — a WCAG 1.1.1 failure for diagrams embedded
|
|
796
|
+
* in a page.
|
|
797
|
+
*
|
|
798
|
+
* Supply your own description of what the diagram shows (e.g. "Flowchart:
|
|
799
|
+
* Build → Test → Ship") — this library does not auto-generate one, since a
|
|
800
|
+
* fabricated summary like "flowchart with 3 nodes" would be a confidently
|
|
801
|
+
* useless accessible name. When omitted, the SVG still gets `role="img"`
|
|
802
|
+
* (so it's read as one image, not a leaky group) but claims no name — the
|
|
803
|
+
* same as an `<img>` with no `alt`.
|
|
804
|
+
*
|
|
805
|
+
* Ignored when `decorative` is true. Default: undefined (no name).
|
|
806
|
+
*
|
|
807
|
+
* If the diagram has a `click A "url"` link, `role="img"` is never
|
|
808
|
+
* applied regardless of this option — see `decorative` below.
|
|
809
|
+
*/
|
|
810
|
+
title?: string;
|
|
811
|
+
/**
|
|
812
|
+
* Mark the diagram as decorative — already described in surrounding
|
|
813
|
+
* prose, so it shouldn't be announced as its own image. Emits
|
|
814
|
+
* `aria-hidden="true"` on the root `<svg>` instead of
|
|
815
|
+
* `role`/`aria-labelledby`/`<title>`; `title`, if also given, is ignored.
|
|
816
|
+
* Default: false
|
|
817
|
+
*
|
|
818
|
+
* Silently overridden (no `aria-hidden`) if the diagram has any
|
|
819
|
+
* `click A "url"` link: that renders as a real, focusable `<a href>`
|
|
820
|
+
* inside the SVG, and `aria-hidden="true"` on an ancestor of a focusable
|
|
821
|
+
* element is an explicit WAI-ARIA violation — assistive tech would drop
|
|
822
|
+
* the link from the accessibility tree while it stays reachable by Tab.
|
|
823
|
+
* `title`, if also given, still applies in that case (see #239).
|
|
824
|
+
*/
|
|
825
|
+
decorative?: boolean;
|
|
826
|
+
/**
|
|
827
|
+
* Edge path interpolation for flowcharts and state diagrams.
|
|
828
|
+
* Default: 'linear'. A diagram's own
|
|
829
|
+
* `%%{init: {"flowchart": {"curve": ...}}}%%` supplies this when the caller
|
|
830
|
+
* does not; an explicit value here always wins.
|
|
831
|
+
*/
|
|
832
|
+
curve?: CurveStyle;
|
|
833
|
+
/**
|
|
834
|
+
* Font size overrides (px). Fields left unspecified fall back to their
|
|
835
|
+
* default. Applies to all diagram types (flowchart, sequence, class, ER).
|
|
836
|
+
*/
|
|
837
|
+
fontSizes?: {
|
|
838
|
+
/** Node label text. Default: 13 */
|
|
839
|
+
nodeLabel?: number;
|
|
840
|
+
/** Edge label text. Default: 11 */
|
|
841
|
+
edgeLabel?: number;
|
|
842
|
+
/** Subgraph header text. Default: 12 */
|
|
843
|
+
groupHeader?: number;
|
|
844
|
+
};
|
|
845
|
+
/**
|
|
846
|
+
* Sequence-diagram layout overrides (px). Fields left unspecified fall
|
|
847
|
+
* back to their default. Sequence diagrams only.
|
|
848
|
+
*/
|
|
849
|
+
sequence?: {
|
|
850
|
+
/** Vertical space per message row. Default: 40 */
|
|
851
|
+
messageRowHeight?: number;
|
|
852
|
+
/** Vertical space between actor boxes and the first message. Default: 20 */
|
|
853
|
+
headerGap?: number;
|
|
854
|
+
/** Actor box height. Default: 40 */
|
|
855
|
+
actorHeight?: number;
|
|
856
|
+
/** Gap between a message arrow and a note positioned directly after it. Default: 8 */
|
|
857
|
+
noteOffsetAfterMessage?: number;
|
|
858
|
+
/** Gap between consecutively stacked notes. Default: 4 */
|
|
859
|
+
noteStackGap?: number;
|
|
860
|
+
};
|
|
861
|
+
/**
|
|
862
|
+
* Opt-in ELK layout cache (see `createLayoutCache()`). When set,
|
|
863
|
+
* `layoutGraphSync()` / `layoutClassDiagramSync()` / `layoutErDiagramSync()`
|
|
864
|
+
* (flowchart/state, class, and ER diagrams — the ELK-based layout
|
|
865
|
+
* engines) skip re-running ELK layout on a cache hit, keyed on a
|
|
866
|
+
* deterministic serialization of the fully-resolved ELK input graph
|
|
867
|
+
* (diagram structure + every layout-affecting option already baked in).
|
|
868
|
+
*
|
|
869
|
+
* Unset (the default) preserves the original always-recompute behavior
|
|
870
|
+
* exactly — this cache is entirely opt-in. Create one instance and
|
|
871
|
+
* reuse it across renders (e.g. module scope, or a `useRef` in React);
|
|
872
|
+
* passing a freshly-created cache on every call defeats the point,
|
|
873
|
+
* since it starts empty each time.
|
|
874
|
+
*/
|
|
875
|
+
layoutCache?: LayoutCache;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
/**
|
|
879
|
+
* Resolve the final inline style for a node from classDefs and nodeStyles.
|
|
880
|
+
*
|
|
881
|
+
* Cascade, weakest to strongest:
|
|
882
|
+
* 1. `classDef default` — Mermaid's implicit base for every node
|
|
883
|
+
* 2. the node's own assigned class (`class A foo` / `A:::foo`)
|
|
884
|
+
* 3. an explicit `style A ...` directive
|
|
885
|
+
*
|
|
886
|
+
* Returns undefined when nothing in the cascade applies, so callers can fall
|
|
887
|
+
* back to theme defaults without an empty-object check.
|
|
888
|
+
*/
|
|
889
|
+
export declare function resolveNodeStyle(nodeId: string, directives: StyleDirectives): Record<string, string> | undefined;
|
|
890
|
+
|
|
891
|
+
/** An sRGB color: 0-255 channels plus a 0-1 alpha. */
|
|
892
|
+
export declare interface RgbaColor {
|
|
893
|
+
r: number;
|
|
894
|
+
g: number;
|
|
895
|
+
b: number;
|
|
896
|
+
a: number;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
/**
|
|
900
|
+
* Accept only link schemes that cannot execute script.
|
|
901
|
+
*
|
|
902
|
+
* A `click` target comes from diagram text, which may be untrusted. An
|
|
903
|
+
* `href` of `javascript:...` (or a `data:` URL containing markup) would turn
|
|
904
|
+
* a rendered diagram into an XSS vector for any page that inlines the SVG, so
|
|
905
|
+
* anything but http/https/mailto and same-document or relative references is
|
|
906
|
+
* dropped rather than emitted.
|
|
907
|
+
*
|
|
908
|
+
* C0 controls are rejected outright, before any other check. The URL parser
|
|
909
|
+
* strips tab and newline from *anywhere* in a URL, so `java\tscript:` reaches
|
|
910
|
+
* a browser as `javascript:` — while the scheme match below sees `java\t…`,
|
|
911
|
+
* finds no scheme, and waves it through as a relative reference. Splitting a
|
|
912
|
+
* blocked scheme with a control character is the whole bypass; there is no
|
|
913
|
+
* legitimate URL with a raw control in it, so the entire range goes.
|
|
914
|
+
*/
|
|
915
|
+
export declare function safeHref(href: string | undefined): string | undefined;
|
|
916
|
+
|
|
917
|
+
/**
|
|
918
|
+
* Validate a user-authored class name (from `:::className` or
|
|
919
|
+
* `class A className`) before it's emitted into the SVG `class` attribute.
|
|
920
|
+
*
|
|
921
|
+
* The parsers already constrain class names to word characters and hyphens
|
|
922
|
+
* (see `splitClassShorthand` above and the flowchart parser's
|
|
923
|
+
* CLASS_SHORTHAND_REGEX), so this is a defense-in-depth allowlist rather
|
|
924
|
+
* than an escaping step — a class name can't be made "safe" by escaping
|
|
925
|
+
* since any character other than a valid CSS identifier character would
|
|
926
|
+
* break the class token itself, not just the surrounding attribute quotes.
|
|
927
|
+
* Anything that doesn't match a valid CSS identifier (letters, digits,
|
|
928
|
+
* underscore, hyphen; not starting with a digit or a hyphen+digit) is
|
|
929
|
+
* dropped rather than emitted.
|
|
930
|
+
*/
|
|
931
|
+
export declare function sanitizeClassName(className: string | undefined): string | undefined;
|
|
932
|
+
|
|
933
|
+
/**
|
|
934
|
+
* Options applicable to sequence diagrams (`sequenceDiagram`). Sequence
|
|
935
|
+
* diagrams ignore `direction`, `curve`, spacing/`layoutCache` (a
|
|
936
|
+
* non-ELK layout), and `interactivity` (no animated edges or `click` links
|
|
937
|
+
* in this renderer's sequence support).
|
|
938
|
+
*/
|
|
939
|
+
export declare type SequenceRenderOptions = CommonRenderOptions & Pick<RenderOptions, 'fontSizes' | 'sequence'>;
|
|
940
|
+
|
|
941
|
+
/** Select the metrics model for subsequent measurements. Called once per render. */
|
|
942
|
+
export declare function setMonospaceMetrics(monospace: boolean): void;
|
|
943
|
+
|
|
944
|
+
/**
|
|
945
|
+
* Minimal subset of Shiki's ThemeRegistrationResolved that we need.
|
|
946
|
+
* We don't import from shiki to avoid a hard dependency.
|
|
947
|
+
*/
|
|
948
|
+
declare interface ShikiThemeLike {
|
|
949
|
+
type?: string;
|
|
950
|
+
colors?: Record<string, string>;
|
|
951
|
+
tokenColors?: Array<{
|
|
952
|
+
scope?: string | string[];
|
|
953
|
+
settings?: {
|
|
954
|
+
foreground?: string;
|
|
955
|
+
};
|
|
956
|
+
}>;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
/**
|
|
960
|
+
* Split the `:::className` shorthand off a node/class identifier.
|
|
961
|
+
*
|
|
962
|
+
* `Animal:::someclass` → `{ id: 'Animal', className: 'someclass' }`;
|
|
963
|
+
* an identifier without the shorthand comes back unchanged with no class.
|
|
964
|
+
* Class names follow CSS identifier conventions (word characters and
|
|
965
|
+
* hyphens), the same constraint the flowchart parser's CLASS_SHORTHAND_REGEX
|
|
966
|
+
* applies.
|
|
967
|
+
*/
|
|
968
|
+
export declare function splitClassShorthand(identifier: string): {
|
|
969
|
+
id: string;
|
|
970
|
+
className?: string;
|
|
971
|
+
};
|
|
972
|
+
|
|
973
|
+
/**
|
|
974
|
+
* Split Mermaid source into trimmed statements, dropping blank lines and
|
|
975
|
+
* `%%` comment lines. See `splitStatementsByLine` for the line-grouped form
|
|
976
|
+
* this flattens.
|
|
977
|
+
*/
|
|
978
|
+
export declare function splitStatements(text: string): Statement[];
|
|
979
|
+
|
|
980
|
+
/**
|
|
981
|
+
* Split Mermaid source into trimmed statements, grouped by the physical
|
|
982
|
+
* source line each one came from — dropping blank lines and `%%` comment
|
|
983
|
+
* lines.
|
|
984
|
+
*
|
|
985
|
+
* Newlines and semicolons both separate statements, matching Mermaid's own
|
|
986
|
+
* `graph TD; A-->B;` form. Comments are removed *before* semicolon splitting
|
|
987
|
+
* so that a `;` inside a comment can't resurrect the rest of that line as
|
|
988
|
+
* code.
|
|
989
|
+
*
|
|
990
|
+
* The grouping is what lets a caller tell a genuine multi-line continuation
|
|
991
|
+
* (crossing from one line's group into the next) apart from an explicit
|
|
992
|
+
* `;`-separated statement on the *same* line (a later entry within one
|
|
993
|
+
* group) — see `src/parser.ts`'s `mergeContinuationLines`, which only
|
|
994
|
+
* treats the former as mergeable.
|
|
995
|
+
*/
|
|
996
|
+
export declare function splitStatementsByLine(text: string): Statement[][];
|
|
997
|
+
|
|
998
|
+
/**
|
|
999
|
+
* One statement produced by the splitter, paired with the 1-based physical
|
|
1000
|
+
* source line it came from.
|
|
1001
|
+
*
|
|
1002
|
+
* `line` is captured while walking `text.split('\n')`, before blank lines
|
|
1003
|
+
* and `%%` comment lines are dropped — so it survives being the original
|
|
1004
|
+
* source line number even though a statement's array index no longer does.
|
|
1005
|
+
* This is what lets every parser built on top of `splitStatements`/
|
|
1006
|
+
* `splitStatementsByLine` report *where* an error is, not just quote back
|
|
1007
|
+
* the offending statement's text (see issue #760).
|
|
1008
|
+
*/
|
|
1009
|
+
export declare interface Statement {
|
|
1010
|
+
text: string;
|
|
1011
|
+
line: number;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
/**
|
|
1015
|
+
* Strip all inline formatting tags from text, keeping only plain text.
|
|
1016
|
+
* Used for text measurement where tag characters shouldn't affect width.
|
|
1017
|
+
*/
|
|
1018
|
+
export declare function stripFormattingTags(text: string): string;
|
|
1019
|
+
|
|
1020
|
+
/** The three maps a styling-aware diagram carries. `MermaidGraph` and
|
|
1021
|
+
* `ClassDiagram` both satisfy this structurally. */
|
|
1022
|
+
export declare interface StyleDirectives {
|
|
1023
|
+
/** Maps class names to their style properties (from `classDef name prop:val`) */
|
|
1024
|
+
classDefs: Map<string, Record<string, string>>;
|
|
1025
|
+
/** Maps node IDs to their assigned class name (from `class A,B name`, `cssClass "A,B" name`, or `A:::name`) */
|
|
1026
|
+
classAssignments: Map<string, string>;
|
|
1027
|
+
/** Maps node IDs to inline styles (from `style X fill:#f00,stroke:#333`) */
|
|
1028
|
+
nodeStyles: Map<string, Record<string, string>>;
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
/**
|
|
1032
|
+
* The opening `<style>` tag every renderer uses — with a `nonce` attribute
|
|
1033
|
+
* when the caller supplied one (see `RenderOptions.nonce`, #216).
|
|
1034
|
+
*
|
|
1035
|
+
* All `<style>` emission points go through this one function so a nonce
|
|
1036
|
+
* can't be missed on one of them: under a nonce-based CSP a single
|
|
1037
|
+
* un-nonced `<style>` is silently dropped by the browser, which for the
|
|
1038
|
+
* theme block means an unstyled diagram with no console hint as to why.
|
|
1039
|
+
*
|
|
1040
|
+
* An empty/whitespace-only nonce is treated as unset — `nonce=""` would
|
|
1041
|
+
* authorise nothing and only mislead a reader into thinking it did.
|
|
1042
|
+
* The value is attribute-escaped; a real nonce is base64 and never needs
|
|
1043
|
+
* escaping, but the option is a plain string and this keeps a stray `"`
|
|
1044
|
+
* from breaking out of the attribute.
|
|
1045
|
+
*/
|
|
1046
|
+
export declare function styleOpenTag(nonce?: string): string;
|
|
1047
|
+
|
|
1048
|
+
/**
|
|
1049
|
+
* How the renderers emit their two inline-style surfaces — the `<style>`
|
|
1050
|
+
* element(s) and the root `<svg style="--bg: …">` attribute. Both exist so a
|
|
1051
|
+
* host page with a strict `Content-Security-Policy` (`style-src` without
|
|
1052
|
+
* `'unsafe-inline'`) can still render diagrams with their colours intact;
|
|
1053
|
+
* see `RenderOptions.nonce` / `RenderOptions.styleAttribute` in packages/core/src/types.ts
|
|
1054
|
+
* and GitHub issue #216. Threaded as one object through every diagram
|
|
1055
|
+
* renderer so the two options can't drift apart per diagram type.
|
|
1056
|
+
*/
|
|
1057
|
+
export declare interface SvgEmitOptions {
|
|
1058
|
+
/** Value for a `nonce` attribute on every emitted `<style>` element. */
|
|
1059
|
+
nonce?: string;
|
|
1060
|
+
/** Emit the root `style="--bg: …"` attribute. Default: true. */
|
|
1061
|
+
styleAttribute?: boolean;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
/**
|
|
1065
|
+
* Build the SVG opening tag with CSS variables set as inline styles.
|
|
1066
|
+
* Only includes optional variables that are actually provided — unset ones
|
|
1067
|
+
* will fall back to the color-mix() derivations in the <style> block.
|
|
1068
|
+
*
|
|
1069
|
+
* `styleAttribute: false` drops the `style="…"` attribute entirely (the
|
|
1070
|
+
* host supplies those declarations from its own stylesheet — see
|
|
1071
|
+
* `themeStyleDeclarations()` and `RenderOptions.styleAttribute`, #216).
|
|
1072
|
+
* Every other attribute — `xmlns`, `viewBox`, `width`/`height`, the
|
|
1073
|
+
* `role`/`aria-*` accessibility attributes, and anything a caller splices
|
|
1074
|
+
* on afterwards (`data-src`, `data-xychart-colors`) — is unaffected.
|
|
1075
|
+
*
|
|
1076
|
+
* Also handles the SVG's accessible name (see `RenderOptions.title` /
|
|
1077
|
+
* `RenderOptions.decorative` in packages/core/src/types.ts, and GitHub issue #215):
|
|
1078
|
+
*
|
|
1079
|
+
* - `decorative: true` → `aria-hidden="true"` on the root, no `role` or
|
|
1080
|
+
* name. Use for a diagram already described in surrounding prose; `title`
|
|
1081
|
+
* is ignored when this is set.
|
|
1082
|
+
* - `title` given (and not decorative) → `role="img"` +
|
|
1083
|
+
* `aria-labelledby="zm-title-N"` on the root, plus a `<title id="zm-title-N">`
|
|
1084
|
+
* as the SVG's first child holding the escaped text. This is the standard
|
|
1085
|
+
* SVG/WAI-ARIA "accessible name via a referenced title element" technique
|
|
1086
|
+
* (see MDN "SVG accessibility" and the WAI-ARIA `img` role: an element
|
|
1087
|
+
* with `role="img"` needs a computed accessible name to be meaningful to
|
|
1088
|
+
* assistive tech; `aria-labelledby` pointing at a `<title>` is the
|
|
1089
|
+
* documented way to supply one for inline SVG).
|
|
1090
|
+
* - Neither given → `role="img"` only, no name. This still stops assistive
|
|
1091
|
+
* tech from treating the SVG as a plain group (which announces every
|
|
1092
|
+
* node/edge label individually, out of reading order — the core bug in
|
|
1093
|
+
* #215), without fabricating a name the library can't honestly claim. It
|
|
1094
|
+
* reads the same as an `<img>` with no `alt`: present as a single image,
|
|
1095
|
+
* unlabeled.
|
|
1096
|
+
*
|
|
1097
|
+
* `hasInteractiveLinks` overrides all of the above (see #239): a `click A
|
|
1098
|
+
* "url"` statement renders a real, focusable `<a href>` inside the SVG, and
|
|
1099
|
+
* both `role="img"` and `aria-hidden="true"` are unsafe on an ancestor of a
|
|
1100
|
+
* focusable element — `role="img"` tells assistive tech to stop descending
|
|
1101
|
+
* into children (the link becomes unreachable by screen reader while still
|
|
1102
|
+
* Tab-focusable), and `aria-hidden="true"` on a focusable descendant is an
|
|
1103
|
+
* explicit WAI-ARIA violation (the link vanishes from the accessibility tree
|
|
1104
|
+
* but not from the tab order). When any node has a link, the root gets no
|
|
1105
|
+
* `role` at all — `decorative` is silently overridden rather than honored,
|
|
1106
|
+
* since aria-hiding a diagram that contains an actionable link is not a safe
|
|
1107
|
+
* request to fulfill — but `title`/`aria-labelledby` still apply if given:
|
|
1108
|
+
* an accessible name is still valid on an element with no explicit role.
|
|
1109
|
+
*
|
|
1110
|
+
* The per-node/per-point `<title>` tooltips added by earlier work (nested
|
|
1111
|
+
* inside `<g>` elements, with no `id` attribute) are unaffected: they never
|
|
1112
|
+
* collide with the root title's generated id, and a root `<title>` alongside
|
|
1113
|
+
* unrelated descendant `<title>` elements is valid SVG.
|
|
1114
|
+
*
|
|
1115
|
+
* @param transparent - If true, omits the background style for transparent SVGs
|
|
1116
|
+
* @param title - Accessible name text. Ignored when `decorative` is true
|
|
1117
|
+
* and there are no interactive links (see `hasInteractiveLinks`).
|
|
1118
|
+
* @param decorative - Marks the SVG as decorative (`aria-hidden="true"`).
|
|
1119
|
+
* Overridden when `hasInteractiveLinks` is true.
|
|
1120
|
+
* @param hasInteractiveLinks - True if any node has a `click`-based `href`.
|
|
1121
|
+
* See #239 — forces no root `role` so the link
|
|
1122
|
+
* stays reachable, regardless of `decorative`.
|
|
1123
|
+
* @param styleAttribute - Emit the root `style="…"` attribute. Default true.
|
|
1124
|
+
*/
|
|
1125
|
+
export declare function svgOpenTag(width: number, height: number, colors: DiagramColors, transparent?: boolean, title?: string, decorative?: boolean, hasInteractiveLinks?: boolean, styleAttribute?: boolean): string;
|
|
1126
|
+
|
|
1127
|
+
export declare type ThemeName = keyof typeof THEMES;
|
|
1128
|
+
|
|
1129
|
+
export declare const THEMES: Record<string, DiagramColors>;
|
|
1130
|
+
|
|
1131
|
+
/**
|
|
1132
|
+
* The exact CSS declaration list the root `<svg style="…">` attribute
|
|
1133
|
+
* carries: the theme custom properties (`--bg`, `--fg`, plus whichever
|
|
1134
|
+
* enrichment variables were actually provided — unset ones fall back to the
|
|
1135
|
+
* color-mix() derivations in the `<style>` block) and, unless `transparent`,
|
|
1136
|
+
* a `background: var(--bg)`.
|
|
1137
|
+
*
|
|
1138
|
+
* Exposed (via `themeCssVariables()` in src/index.ts) so a host that turns
|
|
1139
|
+
* the attribute off with `styleAttribute: false` — because its
|
|
1140
|
+
* Content-Security-Policy forbids `style=` attributes, which a nonce can
|
|
1141
|
+
* never authorise (#216) — can put the very same declarations in its own
|
|
1142
|
+
* stylesheet on a wrapper instead. Single source of truth for the variable
|
|
1143
|
+
* list: `svgOpenTag()` and the helper both call this, so the two can't
|
|
1144
|
+
* drift.
|
|
1145
|
+
*
|
|
1146
|
+
* Emitted compactly (`--bg:#fff;--fg:#000;background:var(--bg)`) rather
|
|
1147
|
+
* than pretty-printed: it's the same string the attribute has always
|
|
1148
|
+
* carried, so default output stays byte-identical. Colour values are the
|
|
1149
|
+
* caller's own `RenderOptions` and are not escaped here — same as before.
|
|
1150
|
+
*/
|
|
1151
|
+
export declare function themeStyleDeclarations(colors: DiagramColors, transparent?: boolean): string;
|
|
1152
|
+
|
|
1153
|
+
/**
|
|
1154
|
+
* Normalize a regex-captured direction token to a `Direction`.
|
|
1155
|
+
*
|
|
1156
|
+
* Accepts `string | undefined` because every call site passes a regex
|
|
1157
|
+
* capture group value (`match[1]`, typed as possibly-`undefined` under
|
|
1158
|
+
* `noUncheckedIndexedAccess`) straight through. Each call site's regex
|
|
1159
|
+
* guards the capture with the same `(TD|TB|LR|BT|RL)` alternation
|
|
1160
|
+
* (case-insensitively), so the group always participates in the match in
|
|
1161
|
+
* practice — but that's a regex-structure guarantee the type checker can't
|
|
1162
|
+
* see across the call site. Validating `undefined` here, instead of
|
|
1163
|
+
* asserting non-null at each call site, turns a hypothetical violation into
|
|
1164
|
+
* a clear, descriptive error rather than a raw `undefined` crash.
|
|
1165
|
+
*/
|
|
1166
|
+
export declare function toDirection(raw: string | undefined): Direction;
|
|
1167
|
+
|
|
1168
|
+
/**
|
|
1169
|
+
* `class A,B className` — attach a style class to one or more nodes.
|
|
1170
|
+
*
|
|
1171
|
+
* Allows an optional trailing semicolon (`class A,B foo;`) — Mermaid treats
|
|
1172
|
+
* it as valid/optional, and `classDef`/`style` already tolerate it via their
|
|
1173
|
+
* `(.+)$` capture. Without this, the semicolon form fails to match here and
|
|
1174
|
+
* falls through to node parsing, rendering a stray node labelled "class".
|
|
1175
|
+
*
|
|
1176
|
+
* Returns true when `line` was a class-assignment statement.
|
|
1177
|
+
*/
|
|
1178
|
+
export declare function tryApplyClassAssignment(line: string, target: StyleDirectives): boolean;
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* `classDef name prop:val,prop:val` — define a named style class.
|
|
1182
|
+
*
|
|
1183
|
+
* Mermaid's `classList` rule accepts a comma-separated list of names
|
|
1184
|
+
* (`classDef a,b font-size:12pt`) in both the flowchart and class grammars;
|
|
1185
|
+
* every name in the list gets the same properties.
|
|
1186
|
+
*
|
|
1187
|
+
* Returns true when `line` was a classDef statement (and has been applied).
|
|
1188
|
+
*/
|
|
1189
|
+
export declare function tryApplyClassDef(line: string, target: StyleDirectives): boolean;
|
|
1190
|
+
|
|
1191
|
+
/**
|
|
1192
|
+
* `cssClass "A,B" className` — the class-diagram grammar's own attachment
|
|
1193
|
+
* form (`cssClassStatement: CSSCLASS STR ALPHA` in classDiagram.jison).
|
|
1194
|
+
* Same effect as `class A,B className`.
|
|
1195
|
+
*
|
|
1196
|
+
* Returns true when `line` was a cssClass statement.
|
|
1197
|
+
*/
|
|
1198
|
+
export declare function tryApplyCssClass(line: string, target: StyleDirectives): boolean;
|
|
1199
|
+
|
|
1200
|
+
/**
|
|
1201
|
+
* `style A,B fill:#f00,stroke:#333` — inline style on specific nodes.
|
|
1202
|
+
* Repeated `style` statements for the same node merge property by property.
|
|
1203
|
+
*
|
|
1204
|
+
* Returns true when `line` was a style statement.
|
|
1205
|
+
*/
|
|
1206
|
+
export declare function tryApplyStyleStatement(line: string, target: StyleDirectives): boolean;
|
|
1207
|
+
|
|
1208
|
+
/**
|
|
1209
|
+
* Return `diagram` with its top-level `direction` replaced by `override`,
|
|
1210
|
+
* or `diagram` itself (same reference) when there is nothing to apply.
|
|
1211
|
+
*
|
|
1212
|
+
* The parsed diagram is never mutated — a shallow clone carries the new
|
|
1213
|
+
* direction, so `parseMermaid()` output a caller holds on to stays exactly
|
|
1214
|
+
* what the parser produced, and a second render of the same parsed object
|
|
1215
|
+
* without the option sees the source direction again.
|
|
1216
|
+
*
|
|
1217
|
+
* `isDirection` re-checks the value at runtime because `Direction` is only
|
|
1218
|
+
* a compile-time guarantee: a plain-JavaScript caller can pass any string.
|
|
1219
|
+
* An unrecognized value is ignored (the diagram's own direction stands)
|
|
1220
|
+
* rather than thrown on — the same lenient treatment every other
|
|
1221
|
+
* `RenderOptions` value gets, e.g. an unknown `interactivity` or `curve`
|
|
1222
|
+
* string falls back to its default instead of failing the render.
|
|
1223
|
+
*/
|
|
1224
|
+
export declare function withDirectionOverride<T extends {
|
|
1225
|
+
direction?: Direction;
|
|
1226
|
+
}>(diagram: T, override: Direction | undefined): T;
|
|
1227
|
+
|
|
1228
|
+
/**
|
|
1229
|
+
* Options applicable to XY charts (`xychart-beta`). XY charts have no
|
|
1230
|
+
* spacing/`direction`/`curve`/`fontSizes`/`layoutCache` concept (layout is
|
|
1231
|
+
* a fixed pixel computation, not ELK-based); `interactivity` (preferred) and
|
|
1232
|
+
* the deprecated `interactive` boolean both gate hover tooltips only.
|
|
1233
|
+
*/
|
|
1234
|
+
export declare type XyChartRenderOptions = CommonRenderOptions & Pick<RenderOptions, 'interactivity' | 'interactive'>;
|
|
1235
|
+
|
|
1236
|
+
export { }
|