diff --git a/cypress/integration/rendering/classDiagram.spec.js b/cypress/integration/rendering/classDiagram.spec.js index 427b4cf0b..dd79303b8 100644 --- a/cypress/integration/rendering/classDiagram.spec.js +++ b/cypress/integration/rendering/classDiagram.spec.js @@ -423,4 +423,82 @@ describe('Class diagram', () => { ); cy.get('svg'); }); + + it('should render class diagram with newlines in title', () => { + imgSnapshotTest(` + classDiagram + Animal <|-- \`Du\nck\` + Animal : +int age + Animal : +String gender + Animal: +isMammal() + Animal: +mate() + class \`Du\nck\` { + +String beakColor + +String featherColor + +swim() + +quack() + } + `); + cy.get('svg'); + }); + + it('should render class diagram with many newlines in title', () => { + imgSnapshotTest(` + classDiagram + class \`This\nTitle\nHas\nMany\nNewlines\` { + +String Also + -Stirng Many + #int Members + +And() + -Many() + #Methods() + } + `); + }); + + it('should render with newlines in title and an annotation', () => { + imgSnapshotTest(` + classDiagram + class \`This\nTitle\nHas\nMany\nNewlines\` { + +String Also + -Stirng Many + #int Members + +And() + -Many() + #Methods() + } + <<Interface>> \`This\nTitle\nHas\nMany\nNewlines\` + `); + }); + + it('should handle newline title in namespace', () => { + imgSnapshotTest(` + classDiagram + namespace testingNamespace { + class \`This\nTitle\nHas\nMany\nNewlines\` { + +String Also + -Stirng Many + #int Members + +And() + -Many() + #Methods() + } + } + `); + }); + + it('should handle newline in string label', () => { + imgSnapshotTest(` + classDiagram + class A["This has\na newline!"] { + +String boop + -Int beep + #double bop + } + + class B["This title also has\na newline"] + B : +with(more) + B : -methods() + `); + }); }); diff --git a/packages/mermaid/src/dagre-wrapper/nodes.js b/packages/mermaid/src/dagre-wrapper/nodes.js index 410703f6c..6c6733358 100644 --- a/packages/mermaid/src/dagre-wrapper/nodes.js +++ b/packages/mermaid/src/dagre-wrapper/nodes.js @@ -917,7 +917,9 @@ const class_box = (parent, node) => { ((-1 * maxHeight) / 2 + verticalPos + lineHeight / 2) + ')' ); - verticalPos += classTitleBBox.height + rowPadding; + //get the height of the bounding box of each member if exists + const memberBBox = lbl?.getBBox(); + verticalPos += (memberBBox?.height ?? 0) + rowPadding; }); verticalPos += lineHeight; @@ -935,7 +937,8 @@ const class_box = (parent, node) => { 'transform', 'translate( ' + -maxWidth / 2 + ', ' + ((-1 * maxHeight) / 2 + verticalPos) + ')' ); - verticalPos += classTitleBBox.height + rowPadding; + const memberBBox = lbl?.getBBox(); + verticalPos += (memberBBox?.height ?? 0) + rowPadding; }); rect