Skip to content

feat: implemented neo look for mermaid#7376

Draft
omkarht wants to merge 9 commits intofeature/neo-look-basefrom
feature/neo-look-implemented
Draft

feat: implemented neo look for mermaid#7376
omkarht wants to merge 9 commits intofeature/neo-look-basefrom
feature/neo-look-implemented

Conversation

@omkarht
Copy link
Contributor

@omkarht omkarht commented Feb 4, 2026

📑 Summary

This PR implements a new "neo" look for Mermaid diagrams, introducing modern visual styling with gradient borders, drop shadows, and new theme options designed for a sleek, contemporary appearance.

Resolves #

📏 Design Decisions

New Look: neo

Added a new diagram look option neo alongside the existing classic and handDrawn looks. The neo look features:

  • Gradient Borders: Configurable gradient stroke colors for nodes using gradientStart and gradientStop theme variables
  • Additional Padding: Increased label padding within shapes for better text readability and visual balance
  • Drop Shadows: Subtle drop shadow effects on shapes for depth (configurable via dropShadow theme variable)
  • Customizable Stroke Width: Dynamic stroke width configuration through strokeWidth theme variable
  • Data Attribute Styling: Uses data-look="neo" attribute for CSS targeting, enabling clean separation of neo-specific styles

New Themes

Introduced 6 new themes optimized for the neo look:

Theme Description
neo Light mode with gradient borders (blue to red)
neo-dark Dark mode variant of neo theme
redux Clean, minimal styling
redux-dark Dark mode variant of redux
redux-color Redux with colorful accents
redux-dark-color Dark mode with colorful accents

SVG Enhancements

  • Added SVG gradient definitions for gradient border support
  • Added SVG filter definitions for drop shadow effects (both standard and small variants)
  • Theme-aware shadow colors (dark themes use white shadows, light themes use black)

📋 Tasks

Make sure you

  • 📖 have read the contribution guidelines
  • 💻 have added necessary unit/e2e tests.
  • 📓 have added documentation. Make sure MERMAID_RELEASE_VERSION is used for all new features.
  • 🦋 If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. Changesets that add features should be minor and those that fix bugs should be patch. Please prefix changeset messages with feat:, fix:, or chore:.

@changeset-bot
Copy link

changeset-bot bot commented Feb 4, 2026

⚠️ No Changeset found

Latest commit: 79b82e9

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@argos-ci
Copy link

argos-ci bot commented Feb 4, 2026

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

Build Status Details Updated (UTC)
default (Inspect) ⚠️ Changes detected (Review) 137 changed Mar 12, 2026, 10:11 AM

@codecov
Copy link

codecov bot commented Feb 6, 2026

Codecov Report

❌ Patch coverage is 3.66255% with 2341 lines in your changes missing coverage. Please review.
✅ Project coverage is 3.53%. Comparing base (6f3ef3a) to head (79b82e9).

Files with missing lines Patch % Lines
...kages/mermaid/src/themes/theme-redux-dark-color.js 2.26% 388 Missing ⚠️
packages/mermaid/src/themes/theme-redux-color.js 2.30% 381 Missing ⚠️
packages/mermaid/src/themes/theme-redux-dark.js 2.33% 376 Missing ⚠️
packages/mermaid/src/themes/theme-neo-dark.js 2.41% 363 Missing ⚠️
packages/mermaid/src/themes/theme-neo.js 2.50% 350 Missing ⚠️
packages/mermaid/src/themes/theme-redux.js 2.50% 350 Missing ⚠️
packages/mermaid/src/rendering-util/render.ts 0.00% 46 Missing ⚠️
...rc/rendering-util/rendering-elements/edgeMarker.ts 0.00% 25 Missing ⚠️
packages/mermaid/src/styles.ts 0.00% 15 Missing ⚠️
packages/mermaid/src/themes/theme-base.js 0.00% 9 Missing ⚠️
... and 8 more
Additional details and impacted files

Impacted file tree graph

@@                   Coverage Diff                   @@
##           feature/neo-look-base   #7376     +/-   ##
=======================================================
  Coverage                   3.53%   3.53%             
=======================================================
  Files                        496     502      +6     
  Lines                      49144   51566   +2422     
  Branches                     771     771             
=======================================================
+ Hits                        1735    1822     +87     
- Misses                     47409   49744   +2335     
Flag Coverage Δ
unit 3.53% <3.66%> (+<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/config.type.ts 100.00% <ø> (ø)
packages/mermaid/src/themes/index.js 100.00% <100.00%> (ø)
packages/mermaid/src/themes/theme-default.js 95.34% <100.00%> (+0.10%) ⬆️
packages/mermaid/src/mermaidAPI.ts 0.30% <0.00%> (ø)
packages/mermaid/src/diagrams/flowchart/styles.ts 2.12% <0.00%> (-0.10%) ⬇️
...aid/src/rendering-util/rendering-elements/edges.js 0.00% <0.00%> (ø)
...aid/src/rendering-util/rendering-elements/nodes.ts 0.00% <0.00%> (ø)
.../src/rendering-util/rendering-elements/clusters.js 0.00% <0.00%> (ø)
packages/mermaid/src/themes/theme-forest.js 2.40% <0.00%> (-0.06%) ⬇️
packages/mermaid/src/themes/theme-neutral.js 3.03% <0.00%> (-0.07%) ⬇️
... and 11 more
🚀 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.

Copy link
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]

Thanks for this ambitious work, @omkarht — adding a whole new look system with 6 themes to Mermaid is a significant effort, and I appreciate the thoughtful design around gradient borders, drop shadows, and data-attribute-based CSS targeting. Apologies that this has been waiting for review since early February — let's work through the feedback and get this moving.

What's working well

🎉 Clean CSS architecture using [data-look="neo"] attribute selectors. This is the right approach — it allows neo-specific styles to be scoped without polluting the classic or handDrawn look. The data-look attribute set via handleUndefinedAttr(node.look) in nodes.ts follows the existing pattern used by other shape utilities.

🎉 Thorough theme implementation. The 6 new theme files follow the established theme class pattern (constructor → updateColors → calculate). The borderColorArray/bkgColorArray in redux-color themes are well-organized with clear comments. Using khroma color utilities consistently is good practice.

Things to address

🔴 [blocking] — Hardcoded SVG filter IDs in shared render.ts will collide across diagrams

packages/mermaid/src/rendering-util/render.ts:72,85: The drop-shadow filters use hardcoded IDs 'drop-shadow' and 'drop-shadow-small'. When a page has multiple Mermaid diagrams (very common — GitHub renders many per page), all diagrams will create filters with the same IDs. The SVG spec says the first definition wins, so a dark-themed diagram could inherit a light-themed diagram's shadow color or vice versa.

Additionally, these filters are created for every diagram regardless of look — classic and handDrawn diagrams get these filter elements too, even though they don't use them. The filter creation should be:

  1. Scoped to the diagram: Use the SVG ID as prefix, e.g., ${svg.attr('id')}-drop-shadow
  2. Conditional on neo look: Only create when data4Layout.config.look === 'neo'

The CSS in styles.ts that references filter: ${options.dropShadow} would need to match the scoped ID.

🟡 [important] — linearGradient appended outside <defs>

render.ts:97: The gradient is appended directly to svg via svg.append('linearGradient'). Per SVG spec, <linearGradient> must be inside a <defs> element. The filter definitions on lines 70 and 83 correctly use svg.append('defs').append('filter') — the gradient should follow the same pattern:

svg.append('defs').append('linearGradient')

Browsers may render it regardless, but invalid SVG can cause issues with server-side renderers and strict XML parsers (relevant since Mermaid is rendered server-side by GitHub/GitLab).

🟡 [important] — Existing themes default to useGradient: true

theme-base.js, theme-forest.js, theme-neutral.js all set this.useGradient = true. This means the classic look with these themes will create SVG gradient definitions in every diagram, even though the gradient CSS is scoped to [data-look="neo"] and won't visually apply.

Consider defaulting useGradient: false in existing themes and only setting it to true in the neo/redux themes. The theme-default.js correctly has useGradient: false.

🟡 [important] — No-op conditional in clusters.js

packages/mermaid/src/rendering-util/rendering-elements/clusters.js:435-440:

let outerRectClass = 'outer';
if (node.look === 'neo') {
  outerRectClass = 'divider';
} else {
  outerRectClass = 'divider';
}

Both branches set the same value 'divider'. The initial assignment to 'outer' is immediately overwritten. This appears to be unfinished — either the neo branch should use a different class, or this conditional should be removed.

🟡 [important] — No E2E visual regression tests

This PR modifies shared rendering code (render.ts, styles.ts, nodes.ts, edges.js, edgeMarker.ts, clusters.js) and adds a new look option. Visual regression tests in cypress/integration/rendering/ using imgSnapshotTest() are essential to:

  • Verify the neo look renders correctly across multiple diagram types
  • Confirm the classic and handDrawn looks are not regressed by the shared code changes

At minimum, a few snapshot tests with { look: 'neo', theme: 'neo' } and { look: 'neo', theme: 'redux' } for flowchart diagrams would provide baseline coverage.

🟡 [important] — Missing changeset

The changeset checkbox is unchecked. Since this is a significant user-facing feature, it needs:

pnpm changeset

Select minor bump with feat: prefix.

🟡 [important] — Hardcoded #000000 in shared styles

styles.ts:

[data-look="neo"].node circle .state-start {
  fill: #000000;
}

This hardcoded color won't respect theme settings. For dark themes, #000000 on a dark background will be invisible. Use a theme variable instead (e.g., options.nodeBorder or options.textColor).

🟢 [nit] — svgId in CSS url() should be quoted

styles.ts: Several places use 'url(' + svgId + '-gradient)'. If svgId contains special characters (parentheses, spaces), this breaks. Safer: 'url("' + svgId + '-gradient")'. Same applies to the gradient reference in render.ts.

Security

No XSS or injection issues identified. The changes use D3's .attr() for DOM manipulation with config-derived theme variables (not user diagram text). The data-look attribute is set from node.look which comes from the config system ('classic'/'handDrawn'/'neo'), not from user-provided diagram text. The gradientStart/gradientStop values are theme-defined colors. The handleUndefinedAttr utility safely converts undefined values to empty strings. The final SVG passes through DOMPurify sanitization.

Self-check

  • At least one 🎉 [praise] item (2)
  • No duplicate comments
  • Severity tally: 1 🔴 blocking / 6 🟡 important / 1 🟢 nit / 0 💡 suggestion / 2 🎉 praise
  • Verdict matches criteria: REQUEST_CHANGES (🔴 present + 6 🟡)
  • Not a draft PR
  • Tone check: warm, acknowledges delay

Summary

Severity Count
🔴 blocking 1
🟡 important 6
🟢 nit 1
💡 suggestion 0
🎉 praise 2

The core architectural decisions are sound — data-attribute-based CSS scoping, theme class pattern, and shared SVG definitions. The main blocker is the hardcoded filter IDs in shared rendering code, which will cause real issues on pages with multiple diagrams. Once the ID scoping is fixed and the other items are addressed, this will be a solid foundation for the neo look. Let's get this across the finish line!

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants