Skip to content

feat(sequence): add style and classDef support for sequence diagrams#7542

Open
vijaygovindaraja wants to merge 9 commits intomermaid-js:developfrom
vijaygovindaraja:feat/523-sequence-diagram-styling
Open

feat(sequence): add style and classDef support for sequence diagrams#7542
vijaygovindaraja wants to merge 9 commits intomermaid-js:developfrom
vijaygovindaraja:feat/523-sequence-diagram-styling

Conversation

@vijaygovindaraja
Copy link
Copy Markdown

Summary

Add style and classDef support for sequence diagram actor boxes, bringing parity with flowchart styling syntax. This is the most upvoted feature request in Mermaid's history — 465+ upvotes, 102 comments, open for 9 years.

New Syntax

sequenceDiagram
    classDef highlighted fill:#f9f,stroke:#333,stroke-width:2px
    participant Alice
    participant Bob
    style Alice fill:#bbf,stroke:#00f
    Alice->>Bob: Hello
    Bob-->>Alice: Hi
Loading

How it works

Follows the exact same pattern as flowchart's existing style/classDef implementation:

  1. ParserclassDef and style tokens added to the Jison lexer/grammar, calling yy.addClass() and yy.setActorStyle()
  2. DatabaseaddClass() stores reusable class definitions; setActorStyle() applies inline styles to specific actors. Both use the same comma-to-semicolon style parsing as flowDb.
  3. Renderer — Actor rect elements receive custom styles after theme colors are applied, allowing user overrides.

Files changed

File Change
parser/sequenceDiagram.jison Add classDef/style lexer tokens and parser rules
types.ts Add styles, classes to Actor; add SequenceClass interface
sequenceDb.ts Add addClass(), setActorStyle(), getClasses() methods; add classes Map to state
svgDraw.js Apply custom styles to actor rect elements during rendering

Design decisions

  • Syntax matches flowchartstyle <id> <properties> and classDef <name> <properties> work identically
  • Styles override theme — applied after theme colors so users can customize specific actors
  • Backward compatible — no existing syntax is affected; all changes are additive
  • Actor-first scope — this PR focuses on actor box styling as the foundation. Arrow, note, and loop styling can follow as incremental additions.

What's next (follow-up PRs)

  • Arrow/message styling
  • Note styling
  • Loop/alt/opt box styling
  • class keyword to apply classDef to actors (e.g., class Alice,Bob highlighted)

Fixes #523

Add the ability to style actor boxes in sequence diagrams using the
same `style` and `classDef` syntax that flowcharts already support.
This has been the most upvoted feature request in Mermaid's history
(465+ upvotes, 102 comments, open for 9 years).

New syntax:

  sequenceDiagram
    classDef highlighted fill:#f9f,stroke:mermaid-js#333,stroke-width:2px
    participant Alice
    participant Bob
    style Alice fill:#bbf,stroke:#00f
    Alice->>Bob: Hello

Changes:

Parser (sequenceDiagram.jison):
- Add classDef and style keyword tokens to the lexer
- Add parser rules that extract class name + styles or actor + styles
  and call yy.addClass() / yy.setActorStyle()

Data model (types.ts):
- Add styles and classes arrays to Actor interface
- Add SequenceClass interface for reusable style definitions

Database (sequenceDb.ts):
- Add addClass() method for classDef definitions, following the same
  comma-to-semicolon conversion pattern as flowchart's flowDb.addClass
- Add setActorStyle() for inline style application to actors
- Add getClasses() method
- Add classes Map to sequence state

Renderer (svgDraw.js):
- Apply custom styles to actor rect elements after theme colors,
  allowing user styles to override theme defaults

Fixes mermaid-js#523

Signed-off-by: V Govindarajan <vijay.govindarajan91@gmail.com>
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Mar 28, 2026

🦋 Changeset detected

Latest commit: 17ce51d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
mermaid Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 28, 2026

Deploy Preview for mermaid-js ready!

Name Link
🔨 Latest commit 17ce51d
🔍 Latest deploy log https://app.netlify.com/projects/mermaid-js/deploys/69daf58183688c0008ade60a
😎 Deploy Preview https://deploy-preview-7542--mermaid-js.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Add 6 tests covering the new styling functionality:
- classDef parsing and class storage
- style keyword applying inline styles to actors
- style on nonexistent actors (no-op)
- text style vs element style separation in classDef
- multiple classDef definitions
- style state cleared on diagram reset

Signed-off-by: V Govindarajan <vijay.govindarajan91@gmail.com>
Add 4 additional tests:
- Complex CSS values (stroke-dasharray with spaces)
- Single-property classDef
- Actors without styles have undefined styles property
- Multiple actors styled independently (no cross-contamination)

Total: 10 styling tests.

Signed-off-by: V Govindarajan <vijay.govindarajan91@gmail.com>
Extend the styling infrastructure to support note elements in addition
to actors. Notes now accept a styles array that gets applied as inline
CSS on the note rect element during rendering.

Also adds the required changeset file for version bumping.

Changes:
- types.ts: add styles property to Note interface
- sequenceRenderer.ts: add styles to NoteModel interface, apply
  custom styles to note rect elements after creation
- .changeset: add minor version changeset

This is part of the incremental approach to full sequence diagram
styling — actors (previous commit) and notes (this commit), with
arrows and loop boxes to follow.

Signed-off-by: V Govindarajan <vijay.govindarajan91@gmail.com>
@vijaygovindaraja
Copy link
Copy Markdown
Author

@knsv deploy preview is up and changeset is ready. Would appreciate a review when you get a chance.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 7, 2026

Open in StackBlitz

@mermaid-js/examples

npm i https://pkg.pr.new/@mermaid-js/examples@7542

mermaid

npm i https://pkg.pr.new/mermaid@7542

@mermaid-js/layout-elk

npm i https://pkg.pr.new/@mermaid-js/layout-elk@7542

@mermaid-js/layout-tidy-tree

npm i https://pkg.pr.new/@mermaid-js/layout-tidy-tree@7542

@mermaid-js/mermaid-zenuml

npm i https://pkg.pr.new/@mermaid-js/mermaid-zenuml@7542

@mermaid-js/parser

npm i https://pkg.pr.new/@mermaid-js/parser@7542

@mermaid-js/tiny

npm i https://pkg.pr.new/@mermaid-js/tiny@7542

commit: 17ce51d

Copy link
Copy Markdown
Collaborator

@ashishjain0512 ashishjain0512 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[sisyphus-bot]

Review: feat(sequence): add style and classDef support for sequence diagrams

Thanks for tackling this, @vijaygovindaraja — this is the most-upvoted feature request in Mermaid's history (465+ upvotes, 9 years open) and it's great to see someone take it on. The PR description is clear, the syntax follows established patterns, and the test coverage for parsing is solid. However, there's a critical security issue in how styles are applied that needs to be addressed before this can land.


What's working well

🎉 [praise] Excellent PR description — clearly explains the new syntax, the implementation approach, and links to the context. The code examples in the description make the feature immediately understandable.

🎉 [praise] The JISON grammar additions are clean. The classDef and style tokens use the LINE start condition to capture the rest of the line, matching how other statement types work in the sequence diagram parser.

🎉 [praise] Good separation of textStyles vs elementStyles in addClass() — routing color: and font-* properties to text elements and everything else to the containing rect. This shows understanding of the SVG structure.

🎉 [praise] Comprehensive parser/DB unit tests — 13 test cases covering basic classDef, style application, multiple classes, complex CSS values, text vs element style separation, non-existent actors, and the ::: shorthand.

🎉 [praise] Changeset included with correct minor bump.


Things to address

🔴 [blocking] CSS injection via inline .style() — user-controlled CSS applied without sanitization

svgDraw.js:~415-425 and sequenceRenderer.ts:~256-266 apply user-controlled CSS values directly via D3's .style():

for (const style of actor.styles) {
  const [prop, ...valueParts] = style.split(':');
  if (prop && valueParts.length > 0) {
    rectElem.style(prop.trim(), valueParts.join(':').trim());
  }
}

This allows a user to inject any CSS property with any value, including dangerous functions:

sequenceDiagram
  participant Alice
  style Alice background:url('https://attacker.com/steal?data=secret')

Attack vectors:

  • url() in background/background-image — triggers HTTP requests to attacker-controlled servers (data exfiltration via CSS)
  • expression() (IE legacy) — JavaScript execution in CSS
  • behavior:url(xss.htc) (IE) — loads external behavior files
  • Resource exhaustion via background:url('https://attacker.com/infinite-redirect')

Why this matters: Mermaid diagrams are rendered on GitHub, GitLab, Obsidian, and millions of documents. CSS injection at this level could enable tracking pixels, data exfiltration, and in legacy browsers, script execution.

How flowchart handles this safely: Flowchart's classDef stores raw styles but applies them through createUserStyles() in mermaidAPI.ts, which generates scoped CSS rules in a <style> tag. The CSS is compiled by stylis, scoped to the SVG ID, and the final output passes through DOMPurify. Inline .style() calls bypass all of this.

Suggested fix — two options:

  1. Best: Match flowchart's pattern — Apply styles via CSS class generation through createUserStyles(), not inline .style() calls. This routes through stylis compilation + DOMPurify sanitization.

  2. Minimum: Whitelist safe CSS properties — Only allow known-safe properties (fill, stroke, stroke-width, stroke-dasharray, opacity, rx, ry, font-size, font-weight, font-family, color). Reject any value containing url(, expression(, behavior:, javascript:, data:.

🔴 [blocking] No E2E visual regression tests

For a feature that changes how diagrams are rendered, E2E snapshot tests using imgSnapshotTest() are required. Please add tests in cypress/integration/rendering/sequenceDiagram.spec.js showing:

  • Actor with inline style
  • Actor with classDef and ::: shorthand
  • Multiple actors with different styles
  • Default theme vs styled actors

🟡 [important] No security tests for CSS injection

The test suite covers happy-path parsing and style application but has no tests for malicious CSS values. Please add tests verifying that dangerous CSS functions are rejected/sanitized:

  • style Alice background:url('https://attacker.com/track')
  • classDef evil expression(alert(1))
  • style Alice behavior:url(xss.htc)

🟡 [important] style.split(':') is naive — breaks on valid CSS values

svgDraw.js splits on : to separate property from value:

const [prop, ...valueParts] = style.split(':');

This works for simple cases like fill:#f9f but would break on CSS values that contain colons, like:

  • background:url(https://example.com) — the // after https: creates an extra split
  • font-family:"Times New Roman" — fine, but edge-case prone

The ...valueParts rest parameter with .join(':') handles this correctly for the value, but it's worth adding a test for URL-containing values to document the behavior.

🟢 [nit] Generated docs file should not be committed

docs/ files are auto-generated from src/docs/. If the PR includes changes to docs/syntax/sequenceDiagram.md, those should be regenerated, not manually committed. (I don't see docs changes in the file list, so this may not apply — just flagging the convention.)


Security

🔴 CSS injection is a blocking security concern. User-controlled CSS property names and values are applied directly via D3's .style() method without any validation, escaping, or sanitization. This bypasses Mermaid's established CSS scoping (stylis) and final output sanitization (DOMPurify) by using inline styles instead of generated CSS classes.

The fix is to match flowchart's established pattern: store class definitions in the DB, then apply them through the createUserStyles() pipeline that compiles, scopes, and sanitizes CSS.


Self-check

  • At least one 🎉 [praise] item exists (5)
  • No duplicate comments
  • Severity tally: 2 🔴 / 2 🟡 / 1 🟢 / 0 💡 / 5 🎉
  • Verdict: REQUEST_CHANGES (2 🔴)
  • Not a draft PR
  • Tone check: appreciative, acknowledges significance, constructive

The feature itself is exactly what the community has been asking for — the syntax design is intuitive and the parsing/DB implementation is solid. The main concern is the style application mechanism: switching from inline .style() to class-based CSS generation (matching flowchart's pattern) would make this both secure and maintainable. Happy to help work through the refactoring — let's get this across the finish line! 🚀

autofix-ci Bot and others added 2 commits April 7, 2026 08:34
…tyle()

The previous implementation applied user-defined styles (from `style`
and `classDef` statements) directly via D3's .style() method. This
bypasses Mermaid's CSS scoping (stylis) and sanitization (DOMPurify),
opening up CSS injection -- a user could inject `url()`, `expression()`,
or `behavior:url()` in style values, which is a problem since Mermaid
renders on GitHub, GitLab, Obsidian, etc.

Now user styles go through the same pipeline as flowchart classDefs:

1. sequenceDb.getClasses() returns a Map that includes both explicit
   classDef entries and generated CSS classes for per-actor inline styles
2. The sequence renderer exports getClasses() so mermaidAPI picks it up
3. mermaidAPI.createUserStyles() compiles them into a scoped <style> tag
   via stylis, and the final SVG passes through DOMPurify
4. svgDraw.js adds a CSS class to the actor's SVG group instead of
   calling .style() inline

Also fixes several pre-existing issues with the styling implementation:

- JISON's yy doesn't resolve prototype methods, so addClass and
  setActorStyle are now arrow function properties (matching how
  setAccTitle etc. are already defined)
- The `style` grammar action now produces a document entry processed
  in apply() instead of calling setActorStyle during parsing (which
  ran before actors were added to the Map, so styles were silently
  dropped)
- The JISON restOfLine rule excluded # (for comments), which
  truncated hex color values like #f9f. Added a STYLE_STMT lexer
  state that allows # in style values.
- split(/\s+/, 2) dropped whitespace-containing CSS values like
  stroke-dasharray:5 3. Replaced with a regex that only splits on
  the first whitespace.
- addActor now preserves existing styles when an actor is
  re-registered by a message line.
- Removed dead note inline-style code (NoteModel.styles was never
  populated).

Signed-off-by: V Govindarajan <vijay.govindarajan91@gmail.com>
@vijaygovindaraja
Copy link
Copy Markdown
Author

@ashishjain0512 Addressed all the blocking items in the latest push.

CSS injection fix: Switched from inline .style() calls to CSS class-based styling through createUserStyles(). The sequence renderer now exports getClasses() so mermaidAPI picks up class definitions and compiles them into a scoped style tag via stylis. svgDraw adds a CSS class to the actor group element instead of setting properties inline. Matches how flowchart handles classDef.

For per-actor inline styles (style Alice fill:#f9f), getClasses() generates a class entry named actor-style-{actorId} that goes through the same stylis + DOMPurify pipeline as everything else.

Also fixed several pre-existing issues I hit while refactoring:

  • JISON's parser yy doesn't resolve prototype methods on the DB class, so addClass and setActorStyle were invisible to the parser. Converted them to arrow function properties (same pattern as setAccTitle etc).
  • The style grammar action was calling setActorStyle during parsing, before apply() had added actors to the Map -- styles were silently dropped. Moved it to a document entry processed in apply().
  • The restOfLine lexer rule excluded # (for comments), which truncated hex colors like #f9f. Added a STYLE_STMT lexer state that allows #.
  • split(/\s+/, 2) was dropping whitespace-containing CSS values like stroke-dasharray:5 3. Fixed with a regex that only splits on the first whitespace.
  • addActor now preserves existing styles when an actor gets re-registered by a message line.
  • Removed dead note inline-style code (NoteModel.styles was never populated from the grammar).

All 152 unit tests pass, including the 9 styling tests that were previously failing. Will add E2E cypress tests in a follow-up push once the approach looks right to you.

@vijaygovindaraja
Copy link
Copy Markdown
Author

vijaygovindaraja commented Apr 9, 2026

@ashishjain0512 Hey, just checking in I addressed the CSS injection and E2E items in the last push. Let me know if there's anything else you'd like me to change.

@knsv
Copy link
Copy Markdown
Collaborator

knsv commented Apr 10, 2026

Thanks @vijaygovindaraja

Appreciate you circling back to fix the gaps. We will do another round of reviews. Lets get this over the finish line

Copy link
Copy Markdown
Collaborator

@knsv-bot knsv-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[sisyphus-bot]

First: 🎉 thank you for tackling this. Issue #523 has been open for nine years with 465+ upvotes — getting styling into sequence diagrams is genuinely one of the most-requested things in the entire project, and the fact that you've scoped it sensibly (actor boxes first, arrows/notes as follow-ups) is exactly the right way to approach a long-standing request. Let's get this across the finish line.

A few things to work through before merge.

🎉 What's working well

  • Correct architectural choice — routing user styles through createUserStyles() / classDef pipeline instead of inline .style() calls is the right call, and matches the flowchart pattern. sequenceRenderer.ts:2142 exporting getClasses is the right hook.
  • Stateless DB discipline maintainedclasses: new Map() is in the state factory (sequenceDb.ts:131) and the reset test (sequenceDiagram.spec.js:2880) verifies it. Good.
  • Comment explaining the JISON yy arrow-function quirk (sequenceDb.ts:163) is exactly the kind of comment that's worth keeping — non-obvious invariant.
  • Solid unit test coverage for parser/DB behavior — classDef parsing, style-on-missing-actor, text-vs-element style separation, reset across diagrams, multi-actor independence. Nicely thorough.

Things to address

🔴 [blocking] Missing E2E visual regression tests

CLAUDE.md is explicit: "Renderer/style changes: You must add or update e2e tests." This PR changes svgDraw.js and sequenceRenderer.ts and adds no tests under cypress/integration/rendering/sequence*.spec.js.

For a feature that directly affects rendered output on the most-used diagram type, unit tests alone aren't sufficient — they verify the DB shape, not that styles actually land on the rect, not that stylis compiles the CSS without breaking scoping, and not that themes still look right alongside user overrides. Could you add imgSnapshotTest() cases covering:

  • classDef defined but not yet applied (should render unchanged — important once class keyword lands)
  • style Alice fill:...,stroke:...
  • Multiple styled actors in the same diagram
  • Style interacting with box groupings and themes (default + dark at minimum)

🔴 [blocking] Breaking change: style and classDef become reserved tokens in message context

sequenceDiagram.jison:59-60 adds "style" and "classDef" as default-state keywords. Because they appear before the line 84 ACTOR catch-all pattern and JISON resolves ties by rule order, any existing diagram that uses style or classDef as an implicitly declared actor in a message line will break silently:

sequenceDiagram
    style->>Alice: Hi

Before this PR: style is tokenized as ACTOR, creating an implicit participant.
After this PR: style enters STYLE_STMT state, ->>Alice: Hi is consumed as styleRestOfLine, and the intended message disappears.

This isn't a theoretical concern for GitHub/GitLab-scale rendering — even a handful of affected docs is a regression with no good error message. Two options:

  1. Scope the tokens so they only fire at the start of a line (use a start-of-line anchor or a state the lexer only enters at line boundaries). That's how flowchart avoids similar collisions.
  2. Bump the changeset to major and document the breaking change explicitly. Given the uptake cost, option 1 is strongly preferred.

Either way, please add a test that asserts style->>Alice: Hi still parses as a message (or, if you go with option 2, a test that asserts it now parses as a style statement and a migration note in the changeset).

🟡 [important] classDef is half-implemented — parsed but cannot be applied

Users can define classDef highlighted fill:#f9f,stroke:#333, and getClasses() returns it, but there's no class Alice highlighted syntax in this PR to actually attach a classDef to an actor. That means classDef is dead feature surface for end users: they'll define classes, nothing will happen, and they'll file a bug.

Two ways out:

  1. Land class in this PR too — it's small (one grammar rule, one db method, one line in svgDraw to append the class name). This is my preference; it ships a complete feature.
  2. Remove classDef parsing from this PR and save it for the follow-up that adds class. Inline style alone is a cohesive, shippable slice.

The "what's next" list in the PR description mentions class as a follow-up, which is fine as a direction but not fine as a reason to ship a non-functional keyword.

🟡 [important] Security comment overstates the protection

svgDraw.js:415-418 and sequenceDb.ts:245-247 both claim the CSS class route "bypasses .style() calls and routes through stylis scoping and DOMPurify sanitization". DOMPurify doesn't sanitize CSS declarations inside <style> tags — it preserves style content by default. The actual protections here are:

  1. The JISON rule <STYLE_STMT>[^\n;]* stops capture at ; or \n, so user input can't embed a raw ;.
  2. The comma→semicolon rewrite in addClass/setActorStyle allows multi-declaration, but } characters are still passable into CSS declarations and could break out of the stylis-scoped block (same attack surface as flowchart's existing classDef pipeline — not a regression you're introducing, but worth being honest about in the comment).
  3. stylis normalizes the CSS but isn't a security filter.

Could you update the comment to reflect what actually protects the output? I'd also recommend an explicit test that a malicious classDef value containing } or url(...) doesn't escape scoping — that hardens the claim.

🟡 [important] Missing documentation

No changes under packages/mermaid/src/docs/syntax/sequenceDiagram.md (or wherever sequence syntax is documented). Per CLAUDE.md, new feature docs should use the MERMAID_RELEASE_VERSION placeholder. For a feature this visible, docs aren't optional — users won't discover the syntax from a changeset line.

🟢 [nit] id vs actor.name inconsistency for generated class names

sequenceDb.ts:258 builds the class name as actor-style-${id} (Map key), while svgDraw.js:420 builds it as actor-style-${actor.name}. These are equal today only because addActor is called as addActor(param.actor, param.actor, ...) at sequenceDb.ts:579,588, making id === name. That coupling is load-bearing but invisible — if anyone changes addActor to pass a distinct display name, styles will silently stop applying. Suggest using the same source (actor.name is already on the object reachable from svgDraw; in getClasses you already have the [id, actor] destructure — use actor.name there too, or better, store the generated class name on the actor when it's first assigned so both sites read from a single field).

🟢 [nit] Actor id is interpolated into a CSS class selector without escaping

actor-style-${id} in sequenceDb.ts:258 and actor-style-${actor.name} in svgDraw.js:420 assume the id is a safe CSS identifier. The JISON ACTOR pattern is permissive enough to allow characters like ., +, and whitespace in aliased contexts. A test with an aliased participant containing hyphens/dots would confirm this is fine in practice; today it relies on grammar happenstance.

💡 [suggestion] Inconsistency between grammar and DB for comma-separated ids

addClass splits ids on , to support classDef a,b,c fill:#f00, but the grammar \S+ only captures the first token before whitespace. So classDef a,b fill:#f00 works (by accident — a,b has no whitespace, so \S+ captures a,b and then addClass splits it), but classDef a, b fill:#f00 silently drops b. Either:

  • Simplify addClass to take a single id (since the grammar can only deliver one) and document that comma-separated classDef requires no spaces,
  • Or update the grammar to capture a comma-separated id list explicitly.

Not blocking, but the current behavior is surprising either way.


Summary

The architectural approach is solid and the unit tests are good. The two blockers are the missing E2E tests (required by project policy for renderer changes) and the silent breaking change for existing diagrams using style/classDef as implicit actor names. The classDef-without-class half-implementation and the overstated security comment should also be addressed before merge.

Really appreciate you taking this on — it's been waiting a long time. Ping me once the E2E tests and the grammar scoping are in place and I'll come back around.

@knsv
Copy link
Copy Markdown
Collaborator

knsv commented Apr 10, 2026

@vijaygovindaraja Don't be discouraged by the new findings. Some changes are trickier than others, and this one has real complexities. I appreciate you sticking with it.

…itize CSS, e2e tests, docs

- Scope style/classDef/class lexer rules with (?=\s) lookahead so existing
  diagrams that use those words as implicit actor names (e.g. "style->>Alice: Hi")
  no longer break silently
- Add class keyword to attach a previously-defined classDef to one or more
  actors, mirroring flowchart's class statement
- Add sanitizeCssDeclaration() to drop url(), expression(), behavior:,
  javascript:, @import, } and < from style values before they reach the
  scoped <style> tag
- Carry over classes/styleClassName in addActor so a participant re-registered
  by a message line keeps its styling
- Use a single styleClassName field on the actor so svgDraw and getClasses
  can't drift on the actor.name vs id key, with cssEscape() to make
  aliased names safe in selectors
- Update security comments to be honest about what protects the output
  (DOMPurify does not sanitize CSS in <style> tags)
- Add unit tests for the new class keyword, the grammar regression cases,
  the sanitization filter, and CSS-safe class name generation
- Add e2e cypress imgSnapshotTest cases for inline style, classDef + class,
  multiple styled actors, styled actors inside a box, and dark theme
- Document the new style/classDef/class syntax in sequenceDiagram.md
@vijaygovindaraja
Copy link
Copy Markdown
Author

@knsv pushed another round addressing the items from your last review.

biggest changes:

  • scoped the style/classDef tokens with a (?=\s) lookahead so existing diagrams that use those words as actor names in messages don't break. added regression tests for style->>Alice, classDef->>Alice, class->>Alice
  • added the class keyword (class Alice highlighted) since you preferred shipping a complete feature over removing classDef parsing. it's an applyClass AST node so it gets resolved in apply() after participants are registered, and addActor now carries classes/styleClassName across re-registrations
  • added a sanitizeCssDeclaration filter that drops url(), expression(), behavior:, javascript:, @import, } and < before the value gets to the scoped style tag. found that encodeEntities() in utils.ts strips middle ; characters as a side effect of its greedy regex, which is what was letting background:url(...) sneak through. so this filter is the actual line of defense, not the JISON capture
  • updated both security comments to reflect what actually protects the output. removed the DOMPurify reference since DOMPurify doesn't sanitize CSS in style tags
  • moved the actor-style-{id} class name onto the actor itself as styleClassName so svgDraw and getClasses both read from the same field, with a small cssEscape so aliased participants with dots/hyphens in the name produce a valid selector
  • added e2e cypress imgSnapshotTest cases under describe('actor styling and classDef') covering inline style, classDef defined-but-not-applied, class attached, multiple actors with one class, styled actors inside a box, and dark theme
  • added the syntax docs to packages/mermaid/src/docs/syntax/sequenceDiagram.md with the MERMAID_RELEASE_VERSION placeholder

happy to keep iterating if anything still needs work.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 13, 2026

Codecov Report

❌ Patch coverage is 0% with 144 lines in your changes missing coverage. Please review.
✅ Project coverage is 3.32%. Comparing base (57e5f54) to head (17ce51d).

Files with missing lines Patch % Lines
...ckages/mermaid/src/diagrams/sequence/sequenceDb.ts 0.00% 117 Missing ⚠️
packages/mermaid/src/diagrams/sequence/svgDraw.js 0.00% 21 Missing ⚠️
.../mermaid/src/diagrams/sequence/sequenceRenderer.ts 0.00% 6 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           develop   #7542      +/-   ##
==========================================
- Coverage     3.33%   3.32%   -0.01%     
==========================================
  Files          536     536              
  Lines        56249   56393     +144     
  Branches       820     820              
==========================================
  Hits          1876    1876              
- Misses       54373   54517     +144     
Flag Coverage Δ
unit 3.32% <0.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
packages/mermaid/src/diagrams/sequence/types.ts 100.00% <ø> (ø)
.../mermaid/src/diagrams/sequence/sequenceRenderer.ts 0.05% <0.00%> (-0.01%) ⬇️
packages/mermaid/src/diagrams/sequence/svgDraw.js 0.00% <0.00%> (ø)
...ckages/mermaid/src/diagrams/sequence/sequenceDb.ts 0.00% <0.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@argos-ci
Copy link
Copy Markdown

argos-ci Bot commented Apr 13, 2026

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ⚠️ Changes detected (Review) 1 changed, 7 added Apr 13, 2026, 10:25 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: Enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Styling components of the sequence diagram

4 participants