diff --git a/cypress/integration/rendering/erDiagram-unified.spec.js b/cypress/integration/rendering/erDiagram-unified.spec.js index f6a25933e..8cecba21d 100644 --- a/cypress/integration/rendering/erDiagram-unified.spec.js +++ b/cypress/integration/rendering/erDiagram-unified.spec.js @@ -634,5 +634,19 @@ describe('Entity Relationship Diagram Unified', () => { { ...options, htmlLabels: false } ); }); + + it(`${description}should render entities with styles applied from the default class and other styles`, () => { + imgSnapshotTest( + ` + erDiagram + c[CUSTOMER] + p[PERSON]:::blue + classDef blue stroke:lightblue, color: #0000FF + classDef default fill:pink + style c color:green + `, + { ...options } + ); + }); }); }); diff --git a/docs/syntax/entityRelationshipDiagram.md b/docs/syntax/entityRelationshipDiagram.md index 175899994..3dec08524 100644 --- a/docs/syntax/entityRelationshipDiagram.md +++ b/docs/syntax/entityRelationshipDiagram.md @@ -575,6 +575,12 @@ Similar to the class statement, the shorthand syntax can also apply multiple cla If a class is named default it will be assigned to all classes without specific class definitions. +``` + classDef default fill:#f9f,stroke:#333,stroke-width:4px; +``` + +> **Note:** Custom styles from style or other class statements take priority and will overwrite the default styles. (e.g. The `default` class gives nodes a background color of pink but the `blue` class will give that node a background color of blue if applied.) + ```mermaid-example erDiagram CAR { diff --git a/packages/mermaid/src/diagrams/er/erDb.ts b/packages/mermaid/src/diagrams/er/erDb.ts index 36b9a3eea..7a1e2f025 100644 --- a/packages/mermaid/src/diagrams/er/erDb.ts +++ b/packages/mermaid/src/diagrams/er/erDb.ts @@ -45,7 +45,7 @@ const addEntity = function (name: string, alias = ''): EntityNode { alias, shape: 'erBox', look: getConfig().look || 'default', - cssClasses: ['default'], + cssClasses: 'default', cssStyles: [], }); log.info('Added new entity :', name); @@ -130,7 +130,7 @@ export const getData = function () { for (const entityKey of entities.keys()) { const entityNode = entities.get(entityKey); if (entityNode) { - entityNode.cssCompiledStyles = getCompiledStyles(entityNode.cssClasses!); + entityNode.cssCompiledStyles = getCompiledStyles(entityNode.cssClasses!.split(' ')); nodes.push(entityNode as unknown as Node); } } @@ -193,7 +193,7 @@ export const setClass = function (ids: string[], classNames: string[]) { const entity = entities.get(id); if (entity) { for (const className of classNames) { - entity.cssClasses!.push(className); + entity.cssClasses += ' ' + className; } } } diff --git a/packages/mermaid/src/diagrams/er/erTypes.ts b/packages/mermaid/src/diagrams/er/erTypes.ts index 7670302f0..13f9b2669 100644 --- a/packages/mermaid/src/diagrams/er/erTypes.ts +++ b/packages/mermaid/src/diagrams/er/erTypes.ts @@ -5,7 +5,7 @@ export interface EntityNode { alias: string; shape: string; look?: string; - cssClasses?: string[]; + cssClasses?: string; cssStyles?: string[]; cssCompiledStyles?: string[]; } diff --git a/packages/mermaid/src/diagrams/er/parser/erDiagram.spec.js b/packages/mermaid/src/diagrams/er/parser/erDiagram.spec.js index 6527862dc..48cd3edce 100644 --- a/packages/mermaid/src/diagrams/er/parser/erDiagram.spec.js +++ b/packages/mermaid/src/diagrams/er/parser/erDiagram.spec.js @@ -803,7 +803,7 @@ describe('when parsing ER diagram it...', function () { const entityName = 'CUSTOMER'; erDiagram.parser.parse(`erDiagram\n${entityName}\nclass ${entityName} myClass`); - expect(erDb.getEntity(entityName).cssClasses).toEqual(['default', 'myClass']); + expect(erDb.getEntity(entityName).cssClasses).toBe('default myClass'); }); it('should be possible to assign multiple classes to an entity at the same time', function () { @@ -812,12 +812,7 @@ describe('when parsing ER diagram it...', function () { `erDiagram\n${entityName}\nclass ${entityName} firstClass, secondClass, thirdClass` ); - expect(erDb.getEntity(entityName).cssClasses).toEqual([ - 'default', - 'firstClass', - 'secondClass', - 'thirdClass', - ]); + expect(erDb.getEntity(entityName).cssClasses).toBe('default firstClass secondClass thirdClass'); }); it('should be possible to assign multiple separately defined classes to an entity', function () { @@ -826,7 +821,7 @@ describe('when parsing ER diagram it...', function () { `erDiagram\n${entityName}\nclass ${entityName} firstClass\nclass ${entityName} secondClass` ); - expect(erDb.getEntity(entityName).cssClasses).toEqual(['default', 'firstClass', 'secondClass']); + expect(erDb.getEntity(entityName).cssClasses).toBe('default firstClass secondClass'); }); it('should be possible to configure the default class and have it apply to each entity', function () { @@ -851,8 +846,8 @@ describe('when parsing ER diagram it...', function () { ], ]); - expect(erDb.getEntity(firstEntity).cssClasses).toEqual(['default']); - expect(erDb.getEntity(secondEntity).cssClasses).toEqual(['default']); + expect(erDb.getEntity(firstEntity).cssClasses).toBe('default'); + expect(erDb.getEntity(secondEntity).cssClasses).toBe('default'); expect(erDb.getClasses()).toEqual(expectedOutput); }); @@ -916,7 +911,7 @@ describe('when parsing ER diagram it...', function () { const className = 'myClass'; erDiagram.parser.parse(`erDiagram\n${entityName}:::${className}`); - expect(erDb.getEntity(entityName).cssClasses).toEqual(['default', 'myClass']); + expect(erDb.getEntity(entityName).cssClasses).toBe('default myClass'); }); it('should be possible to assign a class using the shorthand syntax with empty block', function () { @@ -924,7 +919,7 @@ describe('when parsing ER diagram it...', function () { const className = 'myClass'; erDiagram.parser.parse(`erDiagram\n${entityName}:::${className} {}`); - expect(erDb.getEntity(entityName).cssClasses).toEqual(['default', 'myClass']); + expect(erDb.getEntity(entityName).cssClasses).toBe('default myClass'); }); it('should be possible to assign a class using the shorthand syntax with block of attributes', function () { @@ -932,7 +927,7 @@ describe('when parsing ER diagram it...', function () { const className = 'myClass'; erDiagram.parser.parse(`erDiagram\n${entityName}:::${className} {\nstring name\n}`); - expect(erDb.getEntity(entityName).cssClasses).toEqual(['default', 'myClass']); + expect(erDb.getEntity(entityName).cssClasses).toBe('default myClass'); }); it('should be possible to assign multiple classes using the shorthand syntax', function () { @@ -941,7 +936,7 @@ describe('when parsing ER diagram it...', function () { const secondClass = 'secondClass'; erDiagram.parser.parse(`erDiagram\n${entityName}:::${firstClass},${secondClass}`); - expect(erDb.getEntity(entityName).cssClasses).toEqual(['default', 'firstClass', 'secondClass']); + expect(erDb.getEntity(entityName).cssClasses).toBe('default firstClass secondClass'); }); it('should be possible to assign classes using the shorthand syntax after defining an alias', function () { @@ -951,7 +946,7 @@ describe('when parsing ER diagram it...', function () { erDiagram.parser.parse(`erDiagram\n${entityName}[${entityAlias}]:::${myClass}`); expect(erDb.getEntity(entityName).alias).toBe(entityAlias); - expect(erDb.getEntity(entityName).cssClasses).toEqual(['default', 'myClass']); + expect(erDb.getEntity(entityName).cssClasses).toBe('default myClass'); }); it('should be possible to assign classes using the shorthand syntax while defining a relationship', function () { @@ -962,8 +957,8 @@ describe('when parsing ER diagram it...', function () { `erDiagram\n${entityName}:::${myClass} ||--o{ ${otherEntity}:::${myClass} : allows` ); - expect(erDb.getEntity(entityName).cssClasses).toEqual(['default', 'myClass']); - expect(erDb.getEntity(otherEntity).cssClasses).toEqual(['default', 'myClass']); + expect(erDb.getEntity(entityName).cssClasses).toBe('default myClass'); + expect(erDb.getEntity(otherEntity).cssClasses).toBe('default myClass'); }); describe('relationship labels', function () { diff --git a/packages/mermaid/src/docs/syntax/entityRelationshipDiagram.md b/packages/mermaid/src/docs/syntax/entityRelationshipDiagram.md index 6ff3c6abb..46fb7ee86 100644 --- a/packages/mermaid/src/docs/syntax/entityRelationshipDiagram.md +++ b/packages/mermaid/src/docs/syntax/entityRelationshipDiagram.md @@ -378,6 +378,12 @@ Similar to the class statement, the shorthand syntax can also apply multiple cla If a class is named default it will be assigned to all classes without specific class definitions. +``` + classDef default fill:#f9f,stroke:#333,stroke-width:4px; +``` + +> **Note:** Custom styles from style or other class statements take priority and will overwrite the default styles. (e.g. The `default` class gives nodes a background color of pink but the `blue` class will give that node a background color of blue if applied.) + ```mermaid-example erDiagram CAR {