Commit efe218a
Release candidate 11.14.0 (#7526)
* fix(wardley): Handle dual-label evolution stages and evolve syntax
1. Fix evolution stage parsing to combine name + secondName (e.g., "Genesis / Concept")
2. Fix Evolve rule to accept ID/NAME_WITH_SPACES, not just STRING
3. Fix NAME_WITH_SPACES regex to not match digits after spaces
- Now matches "Campfire Kettle" but stops at "Kettle" in "Kettle 0.5"
- Pattern: /[A-Za-z][A-Za-z0-9_()&]*(?:\s+[A-Za-z][A-Za-z0-9_()&]*)*/
This fixes:
- "parses dual-label evolution stages with slashes" test
- "parses evolve statements" test
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(wardley): Prevent NAME_WITH_SPACES from matching newlines
Changed \s+ to [ \t]+ in NAME_WITH_SPACES regex to only match spaces
and tabs, not newlines. This prevents the terminal from consuming line
breaks and causing "Expecting NEWLINE or EOF" errors.
Fixes:
- "parses custom evolution stages" test
- "parses dual-label evolution stages with slashes" test
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(wardley): Fix pipeline parent name and bidirectional flow
1. Pipeline rule now accepts ID/NAME_WITH_SPACES for parent, not just STRING
- Allows `pipeline Kettle {` without quotes
2. Reorder LINK_PORT alternatives to match longest first (+<> before +< and +>)
- Fixes bidirectional flow detection (was matching +< instead of +<>)
Fixes:
- "parses pipeline blocks with single-coordinate components" test
- "handles quoted identifiers, inline labels, and converts coordinates to percentages" test
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(wardley): Support negative label offsets and optional arrow in links
1. Label rule now accepts INT with optional minus sign for negative offsets
- Changed from WARDLEY_NUMBER to INT with negX/negY flags
- Handle negative values in wardleyParser.ts
2. Link arrow is now optional when LINK_PORT is present
- Allows syntax like `"Mobile App" +<> API` without explicit arrow
Fixes:
- "parses pipeline blocks with single-coordinate components" test
- "handles quoted identifiers, inline labels, and converts coordinates to percentages" test
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(wardley): Allow parentheses after spaces in component names
Fixed NAME_WITH_SPACES terminal regex to allow parentheses, digits, and
underscores after spaces. This enables component names like "byte pair
encoding (BPE)" to parse correctly.
Previously, the pattern required letters after spaces which rejected
component names with parentheses like "(BPE)" after spaces.
Changed pattern from:
(?:[ \t]+[A-Za-z][A-Za-z0-9_()&]*)*
To:
(?:[ \t]+[A-Za-z0-9_()&]+)*
Fixes E2E test "should render GPT Tokeniser Architecture"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(wardley): Allow integer coordinates in annotations
Extended WARDLEY_NUMBER terminal to match both decimals (0.5) and
integers (1, 100) to support annotations syntax like [1, 0].
The previous regex /[0-9]+\.[0-9]+/ only matched decimals, causing
parsing errors for integer coordinates in the annotations statement.
Changed to: /[0-9]+\.[0-9]+|[0-9]+/
Fixes GPT Tokeniser test which uses `annotations [1, 0]`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* chore(wardley): Remove dead code from valueConverter
Removed unused case handlers for terminals that no longer exist in the
grammar (COMPONENT_NAME, EVOLUTION_NAME, TEXT_UNTIL_BRACKET, TEXT_LINE).
These were remnants from earlier grammar iterations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(wardley): Improve coordinate validation error message
Clarified the error message for invalid coordinates to explain that
values can be either 0-1 (decimal, converted to percentage) or 0-100
(percentage, used as-is).
Before: "must be between 0 and 1 (0-100)"
After: "must be between 0-1 (decimal) or 0-100 (percentage)"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat(wardley): Make area dimensions configurable
Added `areaWidth` and `areaHeight` configuration options to allow users
to customize the size of area rectangles in Wardley diagrams.
New config options:
- `areaWidth`: Width of area rectangles in pixels (default: 120)
- `areaHeight`: Height of area rectangles in pixels (default: 80)
Example usage:
```
%%{init: {'wardley-beta': {'areaWidth': 150, 'areaHeight': 100}}}%%
wardley-beta
area "My Area" [0.5, 0.5]
```
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor(wardley): Remove area feature (not in OWM spec)
Removed the `area` feature as it is not part of the standard Online
Wardley Maps (OWM) specification. This keeps the implementation aligned
with the official OWM syntax.
Removed:
- `area` grammar rule and KW_AREA terminal
- Area parsing, building, and rendering code
- WardleyArea interface and related types
- areaWidth/areaHeight config options
- Area test case
- Area documentation section
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: pie: Don't sort, keep order. Keep color order constant.
* Adds Tachi Code to browser extensions list
* sample of what I want to see change
* add show data label outside bar but don't do anything with it yet
* progress commit
return unchanged arrow function to inline
look at extreme cases
reduce duplication and improve naming
[autofix.ci] apply automated fixes
improve example cases to highlight incongruity
some hacks for easier debugging
wip of removing font width requirement for horizontal out of bar stuff
remove some prior experimentation we don't need anymore
simplified horizontal handling
much simpler methodology seems to work across different examples
* add cypress tests
* add documentation
* fixes to cypress test
* fix line removed by accident
* docs format and content fixes
* add release version label to markdown heading within docs
* add changeset
* fix: align branch label background with text for multi-line labels in LR GitGraph
The background rectangle for branch labels was misaligned with the text
when branch names contained multi-line text (e.g. "Feature A\n(ongoing)")
in LR layout. The old transform used `pos - bbox.height / 2` which caused
the rect to shift further up as text height increased, while the text
position remained centered at `pos - 1`.
Fixed by using a constant y-offset (`pos - 11`) in the transform,
derived from the constraint that the rect center must equal the text
center regardless of bbox.height.
Closes #7362
* fix typo introduced when addressing merge conflicts
* fix more typos introduced while addressing merge conflict
* fix demo index
* change order of docs in nav bar so new diagram is at the bottom
* add an example
* use example from issue to improve examples
* make treeview demo page consistent with treemap demo page (it's fancier)
* add changeset
* fix examples failing test
* add failing parser tests for treeview
* wip understanding parser
* parser WIP
* fix naming conflict
* handle null case
* add indent tests
* adjust indent test (affected by whitespace handling?)
* indent tests behave differently locally to pipeline. comment out to check review branch
* possible option is to return indent length instead of actual indent (speculative since indent works locally, but not in pipeline)
* Revert "possible option is to return indent length instead of actual indent (speculative since indent works locally, but not in pipeline)"
This reverts commit b85199f.
* test
* Revert "Revert "possible option is to return indent length instead of actual indent (speculative since indent works locally, but not in pipeline)""
This reverts commit 209d262.
* try this again in pipeline
* this reordering made a difference locally
* issue with treeview accessibility test is because of fragility with whitespace in front of content that should not have leading whitespace. is it just the test that is fragile?
* update docs to include link to langium docs and playground
* fix: make treemap title and labels theme-aware for dark background readability
* restore comment ignoring, and comment
* fix: scope node/edge element IDs to diagram SVG to prevent duplicates
When multiple mermaid diagrams appear on the same page, internal SVG
element IDs for nodes and edges collide (e.g., flowchart-A-0 appears
twice). This causes invalid HTML (WCAG 4.1.1), broken url(#...) refs,
and CSS selectors matching the wrong element.
Prefix all internal element IDs with the diagram's SVG element ID
(e.g., mermaid-0-flowchart-A-0), following the same pattern used for
marker IDs in PR #4825.
Changes:
- render.ts: prefix all node domIds before layout
- edges.js: prefix edge path IDs with diagram ID
- createGraph.ts: prefix edge label node IDs
- flowDb.ts/classDb.ts: add setDiagramId(), defer click handler
domId lookup to bind time so prefixed IDs are used
- flowRenderer/classRenderer: call setDiagramId() before getData()
- flowRenderer: fix link selector to use domId instead of id
Affects all diagram types that go through the unified render path:
flowchart, class, state, ER, requirement, mindmap.
https://claude.ai/code/session_01FPVnyf54nFQNQnhZ7dSWCE
* chore: add node-compile-cache to .gitignore
https://claude.ai/code/session_01FPVnyf54nFQNQnhZ7dSWCE
* test: trim unique DOM ID tests from 355 to 161 lines
Extract addFlowVertex helper to deduplicate verbose addVertex calls.
Remove three describe blocks that only tested local mock functions
(string concatenation), keeping all tests that exercise real FlowDB/ClassDB
code and the full collision simulation.
https://claude.ai/code/session_01FPVnyf54nFQNQnhZ7dSWCE
* refactor: clean up diagramId code per review feedback
- Rename setDiagramId param from `id` to `svgElementId` for clarity
- Add setDiagramId to DiagramDB interface to centralize the contract
- Remove stale "defer lookUpDomId" comments in classDb.ts
- Remove PR #4825 reference from render.ts comment
https://claude.ai/code/session_01FPVnyf54nFQNQnhZ7dSWCE
* refactor: centralize diagramId field and setter into ScopedDiagramDB base class
Extract shared `diagramId` field and `setDiagramId` setter from FlowDB
and ClassDB into a new abstract base class `ScopedDiagramDB`. Both DB
classes now extend it instead of duplicating the field and method.
https://claude.ai/code/session_01FPVnyf54nFQNQnhZ7dSWCE
* Revert "refactor: centralize diagramId field and setter into ScopedDiagramDB base class"
This reverts commit 7245574.
* fix: ensure unique SVG element IDs across multiple mermaid diagrams
Fix unscoped element IDs in clusters.js (5 locations), defaultMindmapNode.ts,
and kanbanRenderer.ts that caused duplicate DOM IDs when multiple diagrams
with identical node names appeared on the same page.
Add self-enforcing integration test that renders two identical diagrams for
every registered diagram type and asserts no duplicate element IDs. The test
auto-detects new diagram types via the registry and fails if they're not
covered. Legacy renderers with known issues use it.fails to document them.
Add runtime duplicate-ID warning in mermaid.run() (debug log level only)
with a pre-filled GitHub issue link for easy reporting.
Add Cypress tests for browser-level multi-diagram ID uniqueness verification.
https://claude.ai/code/session_01QCm1SAitm8ZpLjjsk7eFv3
* chore: add generated .d.ts files from examples package build
These type declaration files are generated by the prepare script during
pnpm install. Adding them to avoid untracked file warnings.
https://claude.ai/code/session_01QCm1SAitm8ZpLjjsk7eFv3
* Revert "chore: add generated .d.ts files from examples package build"
This reverts commit 10002cf.
* chore: gitignore generated .d.ts files from examples package
https://claude.ai/code/session_01QCm1SAitm8ZpLjjsk7eFv3
* simplify: drop runtime warning and test over-engineering
New diagram types are added ~once per 5 months. The 4-category test
taxonomy (unified/simple/legacy/jsdom-incompatible), self-enforcement
registry check, and runtime duplicate-ID warning were not worth the
maintenance cost. Simplified to a flat list of diagram tests that
covers all types where IDs should be unique.
https://claude.ai/code/session_01QCm1SAitm8ZpLjjsk7eFv3
* refactor: drop domId fallback in clusters.js, extract Cypress helper
Remove `|| node.id` fallback from clusters.js — every code path that
calls insertCluster (dagre, cose-bilkent, kanban) already sets domId.
The fallback silently hid missing domId bugs instead of surfacing them.
Extract assertNoDuplicateIds into cypress/helpers/util.ts and use it
in both marker_unique_id and multi_diagram_unique_ids specs.
https://claude.ai/code/session_01QCm1SAitm8ZpLjjsk7eFv3
* fix: namespace marker/element IDs with diagram ID to prevent collisions
Prefix all hardcoded SVG marker IDs (arrowhead, filled-head, crosshead,
sequencenumber, etc.) and element IDs with the diagram's unique ID in
sequence, journey, timeline, gantt, and C4 renderers. This prevents
cross-diagram ID collisions when multiple diagrams render on the same page.
Covers: sequence (12 markers), journey (arrowhead), timeline (arrowhead),
C4 (arrowhead, arrowend, filled-head, crosshead, sequencenumber, plus
database/computer/clock symbols), and gantt (task + exclude-day IDs).
https://claude.ai/code/session_01QCm1SAitm8ZpLjjsk7eFv3
* test: add sequence, journey, timeline, gantt, C4 to multi-diagram ID uniqueness tests
Extends the parametrized renderTwoAndCheckIds test suite to cover all 5
diagram types that previously had hardcoded marker/element IDs. Also fixes
a pre-existing bug in timeline's svgDraw.js where node IDs were
`node-undefined` (now uses a monotonic counter prefixed with diagram ID).
All 19 diagram types now pass the duplicate-ID stress test.
https://claude.ai/code/session_01QCm1SAitm8ZpLjjsk7eFv3
* test: add meta-test enforcing ID uniqueness coverage for all diagram types
Adds a meta-test that cross-references the detector registry against the
test map, so any new diagram type added to mermaid will fail CI unless it
has a corresponding ID uniqueness test (or is explicitly excluded with a
justification).
Also documents block and architecture as known-failing (pre-existing ID
collision bugs tracked via it.fails), and excludes mindmap (cytoscape
JSDOM limitation, uses unified pipeline so IDs are correct).
https://claude.ai/code/session_01QCm1SAitm8ZpLjjsk7eFv3
* test: add comprehensive stress tests for multi-diagram ID uniqueness
Exercises the ID scoping mechanism under adversarial conditions:
- 5x identical diagrams for 10 different diagram types (flowchart, class,
ER, state, sequence, gantt, pie, C4, journey, timeline)
- Complex graphs with 20 nodes and fan-out topologies
- Nested subgraphs (3 levels deep)
- Mixed diagram types on the same page (up to 10 types simultaneously)
- FlowDB/ClassDB unit-level stress with 10-100 instances
- Sequential render stability and clear/reset cycles
- Adversarial node names that mimic diagramId prefixes
- SVG marker definition uniqueness (sequence, C4)
- Edge label ID uniqueness across renders
- Kanban, git graph, requirement, XY chart, quadrant, sankey
- Diagram ID prefix propagation verification
https://claude.ai/code/session_01MtKnkbaUyKZY6R5vTrMNam
* fix: scope journey task line IDs with diagramId to prevent collisions
The journey diagram's svgDraw.js used bare `task0`, `task1`, etc. as
element IDs without any diagram-scoped prefix. This worked by accident
because the module-level taskCount never reset, but was fragile and
inconsistent with the ID scoping pattern used by all other diagram types.
Fix:
- Store the diagramId passed to initGraphics()
- Reset taskCount on each render via initGraphics()
- Prefix task line IDs with diagramId (e.g. `mermaid-0-task0`)
https://claude.ai/code/session_01MtKnkbaUyKZY6R5vTrMNam
* test: add targeted journey task-line ID test, remove stress tests
Add a focused regression test that verifies journey diagram task line
IDs are scoped with the diagramId prefix. This test fails against the
pre-fix code (bare "task0"/"task1" IDs) and passes after the fix
("journey-a-task0"/"journey-b-task0").
Remove the large stress test file — the targeted test plus the existing
multi-diagram-id-uniqueness suite provide sufficient coverage.
https://claude.ai/code/session_01MtKnkbaUyKZY6R5vTrMNam
* refactor: trim journey task-line ID test by reusing renderTwoAndCheckIds
https://claude.ai/code/session_01MtKnkbaUyKZY6R5vTrMNam
* test: add comprehensive stress tests for multi-diagram ID uniqueness
Add 43 stress tests covering scenarios beyond the basic two-diagram tests:
- Scale: 10 and 20 identical diagrams of 11 different types (flowchart,
class, sequence, journey, timeline, gantt, C4, state, ER, pie, git)
- Cross-type: mixed diagram types rendered into a single container
- Subgraphs/clusters: nested and multi-level subgraph ID isolation
- Large diagrams: 50-node flowcharts, 20-message sequences, 20-class
diagrams, 15-task journeys
- Minimal diagrams: single-node/single-message edge cases
- DiagramId boundaries: hyphenated, underscored, numeric-prefixed IDs
- Sequential re-rendering: clear-and-rerender and append-without-clear
- Module-level counter resets: journey taskCount and timeline nodeCount
- SVG marker/defs scoping: sequence, flowchart, and C4 markers
- DB-layer scoping: FlowDB and ClassDB lookUpDomId under 5x stress
- Kanban pre-flight domId injection
- Gantt special characters in task IDs
All 43 tests pass, confirming the ID uniqueness fix holds under stress.
https://claude.ai/code/session_012gG2dXNE8BJAZfHJjs96aX
* fix: resolve three ID-scoping issues found during stress testing
1. flowDb.ts lookUpDomId fallback: when called with an ID not in the
vertex map (e.g. subgraph IDs), the fallback now applies the
diagramId prefix instead of returning the bare ID.
2. sequence/svgDraw.js drawActorTypeControl: remove the `|| ''`
fallback on conf.diagramId that produced colliding marker IDs
(e.g. "-filled-head-control") when multiple sequence diagrams
share a page. The renderer always sets conf.diagramId before
rendering, so the fallback was masking a potential collision.
3. Eliminate module-level diagramId variables in sequence, journey,
and timeline renderers to prevent race conditions in concurrent
or SSR rendering scenarios:
- sequenceRenderer.ts: use conf.diagramId instead of redundant
module-level diagramId variable
- journey/svgDraw.js: pass diagramId as parameter to drawTask
instead of reading from module scope
- timeline/svgDraw.js: pass diagramId as parameter to drawTask,
drawNode, and defaultBkg; also fixes timeline drawTask which
was missing the diagramId prefix entirely ("task0" vs
"diagramId-task0")
- timeline/timelineRenderer.ts: pass diagramId through drawTasks
and drawEvents instead of reading from module-level
currentDiagramId
Adds 5 regression tests that would have failed before these fixes.
https://claude.ai/code/session_012gG2dXNE8BJAZfHJjs96aX
* fix: remove diagramId ternary fallbacks — always prefix
lookUpDomId in flowDb and classDb, and createGraph's edge-label
domId, all had `diagramId ? prefixed : bare` ternaries. Since the
render pipeline always calls setDiagramId before any lookups, the
bare-ID fallback just silently masked missing diagramId bugs. Now
these always prefix, making a missing setDiagramId call surface
immediately.
https://claude.ai/code/session_012gG2dXNE8BJAZfHJjs96aX
* chore: added pnpm changeset
* [autofix.ci] apply automated fixes
* fix: replace dead/wrong domId fallbacks with loud failures
The `|| node.id` / `|| vertex.id` / `: edge.id` fallbacks are dead
code — render.ts always sets domId before shape/edge functions run.
Worse, if reached, they'd silently produce unscoped IDs, reintroducing
the duplicate-ID bug this PR fixes.
Changes:
- defaultMindmapNode.ts: throw on missing domId, use node.domId directly
- flowRenderer-v3-unified.ts: throw on missing domId, use vertex.domId
- edges.js: rename `id` param to `diagramId`, throw if missing, drop
ternary fallback to bare edge.id
* fix: use diagramId instead of undefined id in insertEdge edge markers
The addEdgeMarkers call on line 777 referenced `id` which was never
defined in insertEdge's scope — the parameter is named `diagramId`.
This caused:
- ESLint no-undef lint failure
- ReferenceError at runtime in all diagrams using the unified renderer
- All unit tests and e2e tests to fail
Also adds unit tests for the three defensive throw guards introduced
in the PR (insertEdge, flowRenderer, defaultMindmapNode) to achieve
100% coverage on new code.
https://claude.ai/code/session_01JzR5nomkuYcHxMJ67FMuW4
* fix: resolve E2E test failures caused by ID-prefixed SVG elements
The PR's ID-prefixing changes caused three categories of E2E failures:
1. Double <a> wrapping in flowRenderer: The link-wrapping loop (lines
68-105) was dead code before the PR because vertex.id never matched
the rendered element's actual ID. The PR's switch to vertex.domId
activated this dead code, creating a second <a> inside .node that
broke cy.contains().find('.node') in Cypress. Fix: remove the
redundant loop since nodes.ts (lines 36-51) already wraps link
nodes in <svg:a> during rendering, including sandbox support
(target="_top"). The removed sandboxElement and doc variables were
only used by this redundant loop and had no other consumers in the
function — sandbox mode is fully preserved via nodes.ts.
2. Edge animation selectors: path#L_A_B_0 no longer matches because
edge IDs are now prefixed with diagramId. Fix: use attribute
selectors path[id$="-L_A_B_0"].
3. Gantt/rerender selectors: rect#cl1, text#cl1-text, and
[id^=flowchart-A] no longer match prefixed IDs. Fix: use
[id$="-cl1"], [id$="-cl1-text"], and [id*=flowchart-A].
https://claude.ai/code/session_012TZWtntRQbGFN6Sk9qDuhE
* fix: prefix gantt task IDs in click handlers to match rendered element IDs
The gantt click handler (pushFun in ganttDb.js) used document.querySelector
with the raw task ID (e.g., "cl2"), but the renderer now sets element IDs
as "${diagramId}-${taskId}" (e.g., "mermaid-0-cl2"). This meant click
event listeners were never attached, breaking all gantt click interactions
(both URL navigation and function callbacks) in the E2E tests.
Fix: Add setDiagramId to ganttDb.js (matching the pattern used by
flowDb.ts and classDb.ts), call it from the gantt renderer's draw
function, and use the prefixed ID in pushFun's querySelector calls.
https://claude.ai/code/session_012TZWtntRQbGFN6Sk9qDuhE
* fix: update CSS ID selectors to match prefixed SVG element IDs
The PR prefixes all SVG marker IDs with the diagram container ID
(e.g., `mermaid-0-arrowhead` instead of `arrowhead`), but the CSS
styles.js files still used hardcoded `#arrowhead`, `#crosshead`, etc.
selectors that no longer matched. This caused markers/arrowheads to
lose their themed fill/stroke colors, producing subtle visual diffs
detected by Argos CI.
Replace all `#id` selectors with `[id$="-suffix"]` attribute selectors
that match the new prefixed IDs:
- sequence/styles.js: #arrowhead, #sequencenumber, #crosshead
- class/styles.js: #compositionStart/End, #dependencyStart/End,
#extensionStart/End, #aggregationStart/End, #lollipopStart/End
- state/styles.js: #statediagram-barbEnd, #dependencyStart/End
Also fixes a pre-existing bug in class/styles.js where #dependencyStart
was duplicated instead of having #dependencyEnd.
https://claude.ai/code/session_01DP7eBkBQuMUqZRkvJBdmyS
* fix: give ER background nodes a unique domId to prevent duplicate IDs
The erBox shape creates background nodes by spreading the parent node
and overriding `id` with a '-background' suffix, but the spread also
copies `domId`. Since the SVG element uses `domId || id`, both the
foreground and background nodes ended up with the same DOM ID. This
caused the background-positioning logic in erRenderer-unified.ts to
fail (it selects by `[id*="-background"]`), leaving background nodes
un-positioned and visible as duplicate tables.
https://claude.ai/code/session_01KzNAdiCYp8tZZoBogdbhin
* refactor: drop unnecessary domId fallback in erBox background node
render.ts always sets node.domId before erBox runs, so the
`|| node.id` fallback is dead code.
https://claude.ai/code/session_01KzNAdiCYp8tZZoBogdbhin
* refactor: drop unnecessary domId fallback in erBox shape element
Same rationale as the background node — render.ts guarantees domId
is set before shape rendering.
https://claude.ai/code/session_01KzNAdiCYp8tZZoBogdbhin
* fix: use nullish coalescing fallback for domId in erBox shape
domId is optional on the Node type since it's not yet assigned during
getData(). Use ?? node.id as a defensive fallback, matching the
convention used by every other shape renderer in the codebase.
https://claude.ai/code/session_01UXvz61L5VFDwLmWDqbhfxm
* fix: address code review feedback on duplicate SVG element IDs
- Guard lookUpDomId() against empty diagramId in flowDb.ts and classDb.ts
to prevent malformed IDs like "-flowchart-A-0" when diagramId is unset
- Pass diagramId as a parameter to drawMessage() in sequenceRenderer.ts
instead of mutating the shared conf object
- Update changeset to accurately list covered diagram types and note
that remaining types will be addressed in follow-up PRs
https://claude.ai/code/session_01UDSa3mTe2uhLiTYVn7cXQg
* fix: restore conf.diagramId for svgDraw.js and fix test comments
Red-team found that svgDraw.js drawActorTypeControl() reads
conf.diagramId directly (lines 690, 712), so removing the mutation
would break control actor marker rendering. Keep conf.diagramId
assignment for svgDraw.js compatibility while also passing diagramId
as a clean parameter to drawMessage().
Also fix misleading test comments that said "prefix is just '-'" —
with the empty diagramId guard, no prefix is applied at all.
https://claude.ai/code/session_01UDSa3mTe2uhLiTYVn7cXQg
* refactor: thread diagramId as parameter instead of mutating conf
Remove conf.diagramId mutation entirely. Pass diagramId explicitly
through draw() → drawActors() → drawActor() → drawActorTypeControl()
so svgDraw.js no longer reads diagramId from the shared config object.
https://claude.ai/code/session_01UDSa3mTe2uhLiTYVn7cXQg
* fix: update changeset to minor and reflect full diagram coverage
All diagram types are effectively covered by the unique DOM ID prefixing,
not just a subset. Bump from patch to minor since this is a behavioral
change to generated IDs.
https://claude.ai/code/session_01UDSa3mTe2uhLiTYVn7cXQg
* fix: add ishikawa/venn to ID uniqueness tests and fix architecture test timeout
After merging develop, two new diagram types (ishikawa, venn) were added
upstream but missing from the multi-diagram ID uniqueness test map,
causing the meta-test to fail. The architecture svgDraw test also timed
out under parallel execution due to CPU-intensive cytoscape layout.
- Add ishikawa and venn entries to DIAGRAMS map in
multi-diagram-id-uniqueness.spec.ts
- Increase architecture svgDraw describe timeout to 15s to handle
resource contention during full test suite runs
https://claude.ai/code/session_0195arHUvMWxqnYF8JxcWPru
* refactor(types): correct types for `createText.ts`
Fix the TypeScript types for `createText.ts`, allowing us to remove the
`@ts-nocheck` statement. I've also made sure to get rid of all the `any`
types in this file.
* docs: add a TSDoc comment to `createText()`
* fix: support classDef styling inside composite states
* fix(architecture): scope cytoscape label mapping to edges with labels
The edge stylesheet selector applied `label: 'data(label)'` to all
edges, including those without titles. This caused cytoscape to emit
console warnings about mapping data to elements without corresponding
data fields. Split the edge selector so label mapping only applies via
`edge[label]`, matching the existing `node[label]` guard pattern.
Resolves #6031
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add small TSDoc comment to decodeEntities()
I'm not exactly sure why `decodeEntities()` is needed and what it does,
but I added a brief comment to make it a bit more clear that it's
**NOT** decoding HTML entities, but just decoding what `encodeEntities`
is doing.
* refactor: `decodeEntities` if `htmlLabels: false`
In the `createText()` function, we are calling `decodeEntities()` on the
input if `htmlLabels: true`, but we weren't doing it `htmlLabels: false`
was set.
I can't seem to find anywhere this is actually impacting diagrams, since
we're calling `decodeEntities()` already normally before calling
`createText()`, hence why this is just a `refactor` commit.
Original-commit: #7297
Co-authored-by: chandershekhar22 <chandersj.it.22@nitj.ac.in>
* fix: prevent escaping `<` and `&` when `htmlLabels: false`
When creating labels using `htmlLabels: false`, e.g.
```mermaid
---
config:
htmlLabels: false
---
flowchart TD
A[2 < 4 && 12 > 14]
```
The SVG node label gets rendered as
`2 < 4 && 12 > 14`. This is fine for HTML text, where we
use `.innerHTML` to set the value. But for non-HTML Labels, we use
`.textContent`, so we need to pass the unescaped values.
Ideally we would stop calling DOMPurify on this label when
`.textContent` is used, since the content doesn't need to be sanitized,
but adding a quick `<`/`>`/`&`-> `<`/`>`/`&` also works.
I've adapted this commit from #6406.
Closes: #6406
Co-authored-by: khalil <5alil.landolsi@gmail.com>
* refactor: handle `node.padding==undefined`
TypeScript wasn't catching these earlier, since `bbox` was `any`,
but now that it's been typed correctly, all the `node.padding` uses in
expressions with `bbox` are throwing TypeScript errors.
* refactor(types): assert `.textContent` is non-null
According to MDN, this is only `null` if the `Node` is a `Document`.
I'm not 100% sure why TypeScript is throwing an error on this, since my
VS Code shows that `Element.textContent` will never be `null`, since
`Document` can never be an `Element`, but we do have other non-null
assertions for this scattered over the place.
See: https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent
* refactor(types): type known `<div>` elements
We know that the output of `createText` when `htmlLabels: true` is set
is a `<foreignObject>` that contains a `<div>`, so this can fix our
TypeScript errors.
* fix(sequence): add catch-all rule for ID lexer state to prevent hang
The sequence diagram JISON parser had no catch-all rule in the exclusive
ID lexer state. When input like `participant X asAlias:text` was parsed
(missing space after "as"), none of the ID-state rules could match due
to the colon terminating the character class match before end-of-line.
This caused a lexer error that could hang browsers depending on error
recovery behavior.
Add a catch-all `<ID>[^\n]+` rule that produces an INVALID token when
no other ID-state rule matches, ensuring the parser always makes
progress and produces a clean parse error.
Resolves #6399
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test: fix duplicate `createText` test case
See: #7436 (review)
* refactor: remove unused requirement box unescaping
Replacing `<` and `>` in requirement shapes is no longer
necessary, now that `createText` does it automatically when `htmlLabels:
false`.
* fix(flowchart): warn when style targets a non-existent node
Resolves #7040
When a `style` statement references a node that hasn't been defined
(e.g., `style A fill:#f00` when only `AA` exists), log a warning
instead of silently creating a phantom node. The node is still created
for backward compatibility, but the warning helps users catch typos.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(classDiagram): remove broken inline annotation example
Resolves #7143
The docs TIP blockquote recommended `class Shape <<interface>>` as
"inline" annotation syntax, but this is not valid — the parser grammar
has no rule for annotations after classIdentifier. Only the separate
line (`<<interface>> Shape`) and nested (`{ <<interface>> }`) syntaxes
are supported.
Removed the misleading TIP section. Added tests verifying both valid
annotation syntaxes match the remaining docs examples.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(gantt): document valid duration token formats
Resolves #7212
Added a "Duration format" section to gantt.md listing valid unit
suffixes (ms, s, h, d, w, M, y) with examples. Also notes that decimal
values are supported and invalid tokens are silently ignored.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use `<<` for requirement edge labels
Before
aac86f7 (fix: edge label rendering for ER and requirement diagrams when flowchart: { htmlLabels: false }, 2026-01-06),
we used to use `<<` for requirement edge labels.
However, due to a bug in `createText` with `useHtmlLabels: false`,
where `<` was being rendered as `<`, we updated it to `«`.
Now that this bug has been fixed in
57b70b3 (fix: prevent escaping `<` and `&` when `htmlLabels: false`, 2026-03-02),
we can revert this change and go back to using `<<`.
We have to encode it as `<<` instead of `<<`, as otherwise
`marked` treats it as HTML.
No changelog should be necessary, assuming this gets merged before the
next release.
* Add vertical timeline
* [autofix.ci] apply automated fixes
* add release version
* [autofix.ci] apply automated fixes
* add visual regression test
* handle string fontSize correctly
* Update gitignore
* Update gitignore
* chore(dev-deps): upgrade pnpm to v10.30.3
See: https://github.com/pnpm/pnpm/releases/tag/v10.30.3
* build: set a 3 day `minimumReleaseAge` for NPM
Set a 3 day `minimumReleaseAge` dependency cooldown for NPN dependencies,
so that we never automatically upgrade to a dependency that is less than
3 days old.
This helps avoid supply-chain attacks and prevents issues with NPM
packages being unpublished.
If we do need to manually update something, we can use
`minimumReleaseAgeExclude` for this.
See: https://blog.yossarian.net/2025/11/21/We-should-all-be-using-dependency-cooldowns
See: https://docs.renovatebot.com/presets-security/#securityminimumreleaseagenpm
See: https://pnpm.io/settings#minimumreleaseage
* ci(renovate): add dependency cooldown for CI/Docker
@renovatebot supports these for Docker images hosted on docker.io, and
most GitHub tags, but only for the `major`, `minor`, and `patch`
updates.
Digest updates usually won't work.
See: https://docs.renovatebot.com/key-concepts/minimum-release-age/#which-registries-support-release-timestamps
See: https://docs.renovatebot.com/key-concepts/minimum-release-age/#which-update-types-take-minimumreleaseage-into-account
See: renovatebot/renovate#39781 (reply in thread)
* fix(classDiagram): support inline annotation syntax (class Shape <<interface>>)
Add grammar rules to classStatement for inline annotations instead of
removing the docs example. Supports three forms:
- class Shape <<interface>>
- class Shape <<interface>> { members }
- class Shape <<interface>> {}
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: fix wording nit and rename changeset file
- "either way" → "in all cases" for three annotation methods
- Rename changeset to match fix approach
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Version Packages
* issue 1331 - draw children under same g
* fix: add E2E snapshot test and changeset for state diagram root <g> grouping
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: update .gitignore to include architecture-randomize.html in demos/dev
* feat(architecture): enable architecture diagram tests and add randomization demo
- Re-enabled tests for architecture diagrams, ensuring deterministic layouts.
- Added a new test for complex deeply-nested diagrams.
- Introduced a new HTML demo for testing architecture randomization configurations.
* feat(architecture): add `randomize` option for architecture diagrams layout
- Introduced a new `randomize` configuration option to allow random initial node positions in architecture diagrams.
- Updated the configuration schema and types to include the new option, defaulting to `false` for deterministic layouts.
- Modified the architecture renderer to utilize the `randomize` setting during layout calculations.
* refactor(architecture): standardize syntax in architecture diagram tests
- Updated the syntax for connections and labels in architecture diagram tests for consistency.
- Added a new test case to validate rendering with the `randomize` option set to true, ensuring no errors occur during the process.
* update parser to require spaces around content
* fix formatting
* generate new changeset (minor)
* support customising text colour and line colour separately - still need to check docs and e2e for this, but not theming
* update cypress
* reviewing other examples, it seems more consistent to refer to label than text eg labelFontSize and labelColor
* fix missed examples
* regenerate changeset
* make custom formatting examples more exaggerated to convey meaning more clearly
* new changeset
* add link to ishikawa diagram
* remove redundant change sets
* add theme support for data label colour in xy chart
* update changeset as per feedback
* use feat prefix in changeset
* fix: address PR review issues for duplicate SVG element IDs
- Restore .gitignore entries lost during merge conflict resolution
- Fix block diagram duplicate IDs by adding diagramId support to blockDB
and prefixing node domIds and edge IDs in renderHelpers
- Fix architecture diagram duplicate IDs by adding diagramId to
ArchitectureDB and prefixing all element IDs in svgDraw
- Move block/architecture from known-failing to passing tests
- Reset timeline taskCount in initGraphics to prevent counter leaks
- Add diagramId to LayoutData TypeScript interface for type safety
- Remove dead insertDynamicNumber function from C4 svgDraw
- Remove redundant `const diagramId = id` alias in sequence renderer
- Standardize domId fallback from ?? to || in erBox.ts
https://claude.ai/code/session_01SPyLYoNghEHAXG6a5Vtr2X
* fix: update architecture svgDraw test selectors for prefixed IDs
The test used un-prefixed selectors like `#group-api` and `[id^=service-]`
which no longer match after IDs are prefixed with the diagram's SVG element ID.
https://claude.ai/code/session_01SPyLYoNghEHAXG6a5Vtr2X
* docs: regenerate LayoutData docs for diagramId property
https://claude.ai/code/session_01SPyLYoNghEHAXG6a5Vtr2X
* Add IntelliJ Idea integration with Mermaid Visualizer
* [autofix.ci] apply automated fixes
* turn on data labels for Render all the theme color e2e test
* fix pnpm lock file
* merge v11.13.0 to develop
* fix: ER diagram parsing for numeric entity identifier "1"
The lexer now correctly tokenizes "1" followed by whitespace and a digit
as the ONLY_ONE cardinality token. This fixes parsing errors when using
"1" as an entity name on the right side of a relationship with cardinality 1.
Fixes #7472
* fix: prevent long pie chart titles from being clipped
When a pie chart has a long title (e.g. "Weekly Grocery Consumption for
a Family of 4"), the title text was clipped on the left side because the
SVG viewBox did not account for the title width.
The title is centered at x = pieWidth/2 in SVG coordinates. If the title
is wider than pieWidth, it extends past x=0 and gets clipped since the
viewBox started at x=0.
Fixed by measuring the rendered title width and expanding the viewBox
to accommodate it when the title is wider than the chart + legend area.
Closes #5567
* rework: use viewBox expansion for wide titles instead of group shifting
Replace the group-shift approach with direct viewBox expansion using
Math.min(0, titleLeft) / Math.max(chartAndLegendWidth, titleRight).
This correctly handles all overflow cases (left, right, or both)
without needing conditional group transforms.
Also rename legendWidth to chartAndLegendWidth for clarity.
* fix(ishikawa): preserve cause hierarchy when effect is indented more than causes
Set baseLevel from the first cause instead of the effect line, so
relative indentation between causes is preserved regardless of effect
indentation. Previously, all causes were clamped to level 1 when the
effect had higher indentation, destroying the parent-child hierarchy.
Resolves #7469
* test(ishikawa): add e2e visual test for indented effect with dedented causes
Adds snapshot test covering the scenario from #7469 where the effect
line is indented more than its causes.
* test: add boundary test for multi-digit numeric entity identifier
Add test case using entity "12" to ensure lexer fix covers
all numeric identifiers, not just single digit 1.
Refs #7472
* fix(treemap): add changeset and dark theme Cypress snapshot tests
Add a patch changeset for the theme-aware color fix.
Add Cypress snapshot tests verifying treemap readability on dark
and neutral themes.
Resolves #7218
* docs(gantt): add missing minutes (m) unit to duration format table
The parseDuration regex in ganttDb.js already supports 'm' for minutes,
and ganttDb.spec.ts has an existing test for it. Add the missing row.
* add spec
* chore: update mermaid version to minor for architecture diagram changes
* docs(architecture): add configuration section for `randomize` option in architecture diagrams
- Introduced a new section in the architecture documentation detailing the `randomize` option for initial node positions.
- Provided examples for enabling randomization via frontmatter and `mermaid.initialize()`.
- Updated the configuration table to include the new option and its default behavior.
* feat(schema): add `randomize` option to configuration schema
* fix typo in renovate config
* fix naming conflict
* regenerate lockfile
* add unit test for multi diagram id uniqueness
* chore: remove accidental planning/guide files from PR
Remove files that were accidentally committed and flagged by reviewers:
- PR_READY.md
- PR_SUBMISSION_GUIDE.md
- WARDLEY_MAPS_USER_GUIDE.md
- WARDLEY_MAPS_MEDIUM_GUIDE.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* renovate config typo take 2
* oops I brought back the first typo
* fix: preserve original arrow types when splitting labeled edges
When an edge with a label gets split into two sub-edges (edge-to-label
and edge-from-label) in createGraph.ts, the arrow types were being
hardcoded instead of preserving the original edge's arrow types. This
caused labeled open edges (using --- syntax) to incorrectly show
arrowheads, and bidirectional labeled edges to lose their start arrows.
Now edgeToLabel preserves the original arrowTypeStart and edgeFromLabel
preserves the original arrowTypeEnd, fixing the rendering for all
labeled edge types.
Fixes #6289
* refactor: remove dead createGraphWithElements function, keep regression test
The createGraphWithElements function in createGraph.ts was exported but
never imported anywhere in the codebase. The original fix modified this
dead code path, which had no runtime effect.
The active code path in flowDb.ts already correctly handles arrow_open
edges by setting arrowTypeStart/End to 'none'. No edge splitting occurs
for labeled edges in the dagre layout — labels are rendered as floating
SVG elements positioned at the edge midpoint.
Removed the entire dead code file and kept the Cypress regression test
for open edge arrowhead behavior.
* Merge pull request #7501 from mermaid-js/feature/neo-look-base
feature: implement neo look and themes for mermaid diagrams
* fix: apply classDef styles correctly to divider element
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
* fix: iupdate branch label positioning
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
---------
Co-authored-by: tractorjuice <129532814+tractorjuice@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Danny Milosavljevic <gitea@fake.local>
Co-authored-by: David Septimus <davidseptimus@gmail.com>
Co-authored-by: leentaylor <leentaylor@gmail.com>
Co-authored-by: Lee Taylor <84303927+lee-treehouse@users.noreply.github.com>
Co-authored-by: Varun Chawla <varun_6april@hotmail.com>
Co-authored-by: Adam <adam@mymac.local>
Co-authored-by: Varun Chawla <34209028+veeceey@users.noreply.github.com>
Co-authored-by: Alex Turner <alex@turntrout.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Alois Klink <alois@aloisklink.com>
Co-authored-by: Knut Sveidqvist <knsv@users.noreply.github.com>
Co-authored-by: kibanana <kyw017763@gmail.com>
Co-authored-by: Knut Sveidqvist <knsv@sveido.com>
Co-authored-by: chandershekhar22 <chandersj.it.22@nitj.ac.in>
Co-authored-by: khalil <5alil.landolsi@gmail.com>
Co-authored-by: TATSUNO “Taz” Yasuhiro <ytatsuno.jp@gmail.com>
Co-authored-by: Sidharth Vinod <sidharthv96@gmail.com>
Co-authored-by: Sidharth Vinod <github@sidharth.dev>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: dripcoding <dripcoding@gmail.com>
Co-authored-by: knsv-bot <knsv-bot@macos.shared>
Co-authored-by: Jeroen Smink <jeroensmink98@gmail.com>
Co-authored-by: Alex9583 <37045839+Alex9583@users.noreply.github.com>
Co-authored-by: GhassenS <ghassensiala12@gmail.com>
Co-authored-by: omkarht <omkar@mermaidchart.com>
Co-authored-by: darshanr0107 <darshan@mermaidchart.com>1 parent d2b5b2b commit efe218a
File tree
293 files changed
+15849
-2246
lines changed- .build
- .changeset
- .cspell
- cypress
- helpers
- integration
- other
- rendering
- platform
- demos
- dev
- docs
- community
- config/setup
- defaultConfig/variables
- mermaid
- interfaces
- type-aliases
- ecosystem
- syntax
- packages
- examples/src
- examples
- mermaid
- src
- diagram-api
- diagrams
- architecture
- block
- c4
- class
- parser
- er
- parser
- flowchart
- parser
- gantt
- git
- ishikawa
- kanban
- mindmap
- pie
- requirement
- sequence
- parser
- state
- parser
- timeline
- parser
- treeView
- treemap
- user-journey
- wardley
- xychart
- chartBuilder
- docs
- .vitepress
- community
- ecosystem
- syntax
- rendering-util
- rendering-elements
- shapes
- schemas
- tests
- themes
- utils
- parser
- src
- language
- treeView
- wardley
- tests
- tiny
- scripts
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
293 files changed
+15849
-2246
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| 30 | + | |
30 | 31 | | |
31 | 32 | | |
32 | 33 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
0 commit comments