diff --git a/.changeset/fix-architecture-label-width-floor.md b/.changeset/fix-architecture-label-width-floor.md new file mode 100644 index 00000000000..8429822bea5 --- /dev/null +++ b/.changeset/fix-architecture-label-width-floor.md @@ -0,0 +1,5 @@ +--- +'mermaid': patch +--- + +fix: floor architecture-beta service label width at 90px so long single-word labels (e.g. `ClickHouse`) no longer wrap mid-character at small `iconSize` values diff --git a/cypress/integration/rendering/architecture/architecture.spec.ts b/cypress/integration/rendering/architecture/architecture.spec.ts index dd52aa8cf9e..36d56681c4d 100644 --- a/cypress/integration/rendering/architecture/architecture.spec.ts +++ b/cypress/integration/rendering/architecture/architecture.spec.ts @@ -356,6 +356,24 @@ describe('architecture diagram', () => { { architecture: { randomize: true }, screenshot: false } ); }); + it('should keep long single-word service labels on one line at small iconSize', () => { + // Regression test for the label-width floor. At `iconSize: 50`, the + // historical width (`iconSize * 1.5 = 75px`) was too narrow to fit common + // single-word labels like "ClickHouse", causing mid-character wraps. + // The fix floors the label-area width at 90px so + // these labels stay on one line. Multi-word labels still wrap on word + // boundaries. + imgSnapshotTest( + `architecture-beta + service ch(database)[ClickHouse] + service pg(database)[Postgres] + service mb(server)[MessageBroker] + ch:R --> L:pg + pg:R --> L:mb + `, + { architecture: { iconSize: 50 } } + ); + }); }); describe('architecture - fcose layout knobs', () => { diff --git a/packages/mermaid/src/diagrams/architecture/svgDraw.ts b/packages/mermaid/src/diagrams/architecture/svgDraw.ts index 3191123ae0a..de01f20517d 100644 --- a/packages/mermaid/src/diagrams/architecture/svgDraw.ts +++ b/packages/mermaid/src/diagrams/architecture/svgDraw.ts @@ -291,7 +291,11 @@ export const drawServices = async function ( service.title, { useHtmlLabels: false, - width: iconSize * 1.5, + // Floor at 120px so long single-word labels (e.g. "ClickHouse", "MessageBroker") + // don't wrap mid-character at small iconSize. 120 matches the natural width at the + // default iconSize (80 * 1.5 = 120) — so the floor is a no-op at the default and + // only kicks in for iconSize values below 80. + width: Math.max(iconSize * 1.5, 120), classes: 'architecture-service-label', }, config