mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-08-15 14:29:25 +02:00
#5237 making styles take preceedence and adding test
This commit is contained in:
@@ -110,6 +110,7 @@ strikethrough
|
||||
stringifying
|
||||
struct
|
||||
STYLECLASS
|
||||
STYLEDEF
|
||||
STYLEOPTS
|
||||
subcomponent
|
||||
subcomponents
|
||||
|
@@ -558,6 +558,29 @@ stateDiagram-v2
|
||||
{ logLevel: 0, fontFamily: 'courier' }
|
||||
);
|
||||
});
|
||||
it(' can have styles applied ', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
AState
|
||||
style AState fill:#636,border:1px solid red,color:white;
|
||||
`,
|
||||
{ logLevel: 0, fontFamily: 'courier' }
|
||||
);
|
||||
});
|
||||
it(' should let styles take preceedence over classes', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
AState: Should NOT be white
|
||||
BState
|
||||
classDef exampleStyleClass fill:#fff,color: blue;
|
||||
class AState,BState exampleStyleClass
|
||||
style AState fill:#636,border:1px solid red,color:white;
|
||||
`,
|
||||
{ logLevel: 0, fontFamily: 'courier' }
|
||||
);
|
||||
});
|
||||
});
|
||||
it('1433: should render a simple state diagram with a title', () => {
|
||||
imgSnapshotTest(
|
||||
|
@@ -75,12 +75,127 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="diagram" class="mermaid">
|
||||
flowchart LR
|
||||
<h4>Case 1</h4>
|
||||
<div class="flex">
|
||||
<pre id="diagram" class="mermaid">
|
||||
stateDiagram-v2
|
||||
AState: Should NOT be white
|
||||
BState
|
||||
classDef exampleStyleClass fill:#fff,color: blue;
|
||||
class AState,BState exampleStyleClass
|
||||
style AState fill:#636,border:1px solid red,color:white;
|
||||
</pre>
|
||||
<pre id="diagram" class="mermaid">
|
||||
%%{init: {"look": "classic"} }%%
|
||||
stateDiagram-v2
|
||||
AState: Should NOT be white
|
||||
BState
|
||||
classDef exampleStyleClass fill:#fff,color: blue;
|
||||
class AState,BState exampleStyleClass
|
||||
style AState fill:#636,border:1px solid red,color:white;
|
||||
</pre>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
stateDiagram-v2
|
||||
|
||||
Apa --AA--> C
|
||||
</pre
|
||||
>
|
||||
classDef exampleStyleClass background:#bbb,border:1px solid red;
|
||||
a --> b
|
||||
class a exampleStyleClass
|
||||
%% a:::exampleStyleClass
|
||||
</pre>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
stateDiagram
|
||||
direction TB
|
||||
|
||||
accTitle: This is the accessible title
|
||||
accDescr: This is an accessible description
|
||||
|
||||
classDef notMoving fill:white
|
||||
classDef movement font-style:italic;
|
||||
classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
|
||||
|
||||
[*] --> Still:::notMoving
|
||||
Still --> [*]
|
||||
Still --> Moving:::movement
|
||||
Moving --> Still
|
||||
Moving --> Crash:::movement
|
||||
Crash:::badBadEvent --> [*]
|
||||
</pre>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
stateDiagram-v2
|
||||
MyState
|
||||
note left of MyState : I am a leftie
|
||||
note right of MyState : I am a rightie
|
||||
|
||||
</pre>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
stateDiagram
|
||||
%% direction LR
|
||||
|
||||
state C0 {
|
||||
A0 --> B0
|
||||
}
|
||||
|
||||
C0 --> Apa0
|
||||
|
||||
</pre>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
stateDiagram
|
||||
direction LR
|
||||
|
||||
|
||||
state C1 {
|
||||
A1 --> B1
|
||||
}
|
||||
|
||||
C1 --> Apa1
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
<h4>Case 2</h4>
|
||||
<div class="flex">
|
||||
<pre id="diagram" class="mermaid2">
|
||||
stateDiagram
|
||||
direction LR
|
||||
state Gorilla0 {
|
||||
state Apa0 {
|
||||
A0 --> B0
|
||||
}
|
||||
|
||||
}
|
||||
Apa --> Gorilla0:Label
|
||||
A0 --> C0
|
||||
%% C1: "`This is C`"
|
||||
</pre>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
stateDiagram
|
||||
direction LR
|
||||
state Apa1 {
|
||||
A1
|
||||
}
|
||||
|
||||
Apa11 --> Apa1
|
||||
A1 --> C1
|
||||
%% C1: "`This is C`"
|
||||
</pre>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
stateDiagram
|
||||
[*] --> Level1
|
||||
|
||||
state Level1 {
|
||||
[*] --> Level2
|
||||
|
||||
state Level2 {
|
||||
[*] --> level2
|
||||
level2 --> Level3
|
||||
|
||||
state Level3 {
|
||||
[*] --> level3
|
||||
level3 --> [*]
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
flowchart LR
|
||||
subgraph Apa["Apa"]
|
||||
@@ -127,20 +242,7 @@ Apa --> C
|
||||
A --> B & C["C"]
|
||||
</pre
|
||||
>
|
||||
<pre id="diagram" class="mermaid">
|
||||
stateDiagram
|
||||
direction LR
|
||||
state Gorilla0 {
|
||||
state Apa0 {
|
||||
A0 --> B0
|
||||
}
|
||||
|
||||
}
|
||||
Apa0 --> C0
|
||||
A0 --> C0
|
||||
C1: "`This is C`"
|
||||
</pre
|
||||
>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
flowchart LR
|
||||
subgraph Gorilla
|
||||
@@ -180,7 +282,7 @@ stateDiagram
|
||||
|
||||
</pre
|
||||
>
|
||||
<pre id="diagram" class="mermaid">
|
||||
<pre id="diagram" class="mermaid2">
|
||||
flowchart LR
|
||||
Apa --Hello--> C
|
||||
|
||||
@@ -318,7 +420,7 @@ stateDiagram-v2
|
||||
mermaid.initialize({
|
||||
// theme: 'base',
|
||||
// handdrawnSeed: 12,
|
||||
// look: 'handdrawn',
|
||||
look: 'handdrawn',
|
||||
// 'elk.nodePlacement.strategy': 'NETWORK_SIMPLEX',
|
||||
// layout: 'dagre',
|
||||
// layout: 'elk',
|
||||
|
@@ -221,41 +221,46 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
describe('style statement for a state (style)', () => {
|
||||
describe('defining (style)', () => {
|
||||
it('has "style" as a keyword, an id, and can set a css style attribute', function () {
|
||||
stateDiagram.parser.parse(`
|
||||
stateDiagram-v2
|
||||
style id1 background:#bbb;`);
|
||||
|
||||
stateDiagram.parser.parse(`stateDiagram-v2
|
||||
id1
|
||||
style id1 background:#bbb`);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
const data4Layout = stateDiagram.parser.yy.getData();
|
||||
|
||||
// const styleClasses = stateDb.getClasses();
|
||||
// expect(styleClasses.get('exampleClass').styles.length).toEqual(1);
|
||||
// expect(styleClasses.get('exampleClass').styles[0]).toEqual('background:#bbb');
|
||||
expect(data4Layout.nodes[0].cssStyles).toEqual(['background:#bbb']);
|
||||
});
|
||||
it('has "style" as a keyword, an id, and can set a css style attribute', function () {
|
||||
stateDiagram.parser.parse(`stateDiagram-v2
|
||||
id1
|
||||
id2
|
||||
style id1,id2 background:#bbb`);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
const data4Layout = stateDiagram.parser.yy.getData();
|
||||
|
||||
expect(data4Layout.nodes[0].cssStyles).toEqual(['background:#bbb']);
|
||||
expect(data4Layout.nodes[1].cssStyles).toEqual(['background:#bbb']);
|
||||
});
|
||||
|
||||
it('has handles multiple ids', function () {
|
||||
stateDiagram.parser.parse(`
|
||||
stateDiagram-v2
|
||||
style id1,id2 background:#bbb;`);
|
||||
it('can define multiple attributes separated by commas', function () {
|
||||
stateDiagram.parser.parse(`stateDiagram-v2
|
||||
id1
|
||||
id2
|
||||
style id1,id2 background:#bbb, font-weight:bold, font-style:italic;`);
|
||||
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
const data4Layout = stateDiagram.parser.yy.getData();
|
||||
|
||||
// const styleClasses = stateDb.getClasses();
|
||||
// expect(styleClasses.get('exampleClass').styles.length).toEqual(1);
|
||||
// expect(styleClasses.get('exampleClass').styles[0]).toEqual('background:#bbb');
|
||||
expect(data4Layout.nodes[0].cssStyles).toEqual([
|
||||
'background:#bbb',
|
||||
'font-weight:bold',
|
||||
'font-style:italic',
|
||||
]);
|
||||
expect(data4Layout.nodes[1].cssStyles).toEqual([
|
||||
'background:#bbb',
|
||||
'font-weight:bold',
|
||||
'font-style:italic',
|
||||
]);
|
||||
});
|
||||
|
||||
// it('can define multiple attributes separated by commas', function () {
|
||||
// stateDiagram.parser.parse(
|
||||
// 'stateDiagram-v2\n classDef exampleClass background:#bbb, font-weight:bold, font-style:italic;'
|
||||
// );
|
||||
// stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
// const styleClasses = stateDb.getClasses();
|
||||
// expect(styleClasses.get('exampleClass').styles.length).toEqual(3);
|
||||
// expect(styleClasses.get('exampleClass').styles[0]).toEqual('background:#bbb');
|
||||
// expect(styleClasses.get('exampleClass').styles[1]).toEqual('font-weight:bold');
|
||||
// expect(styleClasses.get('exampleClass').styles[2]).toEqual('font-style:italic');
|
||||
// });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -202,13 +202,13 @@ const extract = (_doc) => {
|
||||
ids.forEach((id) => {
|
||||
const state = getState(id);
|
||||
if (state !== undefined) {
|
||||
state.styles = styles;
|
||||
state.styles = styles.map((s) => s.replace(/;/g, '')?.trim());
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
case STMT_APPLYCLASS:
|
||||
setStyle(item.id.trim(), item.styleClass);
|
||||
setCssClass(item.id.trim(), item.styleClass);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
@@ -198,7 +198,16 @@ export const createText = (
|
||||
} = {},
|
||||
config: MermaidConfig
|
||||
) => {
|
||||
log.info('createText', text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground);
|
||||
log.info(
|
||||
'IPI createText',
|
||||
text,
|
||||
style,
|
||||
isTitle,
|
||||
classes,
|
||||
useHtmlLabels,
|
||||
isNode,
|
||||
addSvgBackground
|
||||
);
|
||||
if (useHtmlLabels) {
|
||||
// TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
|
||||
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
import styles from '../../../../dist/diagrams/packet/styles';
|
||||
|
||||
// Striped fill like start or fork nodes in state diagrams
|
||||
export const solidStateFill = (color: string) => {
|
||||
@@ -22,31 +21,33 @@ export const compileStyles = (node: Node) => {
|
||||
// node.cssStyles is an array of styles directly set on the node
|
||||
|
||||
// concat the arrays and remove duplicates such that the values from node.cssStyles are used if there are duplicates
|
||||
return [...(node.cssCompiledStyles || []), ...(node.cssStyles || [])];
|
||||
const stylesMap = styles2Map([...(node.cssCompiledStyles || []), ...(node.cssStyles || [])]);
|
||||
return { stylesMap, stylesArray: [...stylesMap] };
|
||||
};
|
||||
|
||||
export const styles2Map = (styles: string[]) => {
|
||||
const styleMap = new Map();
|
||||
const styleMap = new Map<string, string>();
|
||||
styles.forEach((style) => {
|
||||
const [key, value] = style.split(':');
|
||||
styleMap.set(key.trim(), value.trim());
|
||||
styleMap.set(key.trim(), value?.trim());
|
||||
});
|
||||
return styleMap;
|
||||
};
|
||||
|
||||
export const styles2String = (node: Node) => {
|
||||
const styles = compileStyles(node);
|
||||
const { stylesArray } = compileStyles(node);
|
||||
const labelStyles: string[] = [];
|
||||
const nodeStyles: string[] = [];
|
||||
|
||||
styles.forEach((style) => {
|
||||
const [key, value] = style.split(':');
|
||||
stylesArray.forEach((style) => {
|
||||
const key = style[0];
|
||||
if (key === 'color') {
|
||||
labelStyles.push(style);
|
||||
labelStyles.push(style.join(':') + ' !important');
|
||||
} else {
|
||||
nodeStyles.push(style);
|
||||
nodeStyles.push(style.join(':') + ' !important');
|
||||
}
|
||||
});
|
||||
|
||||
return { labelStyles: labelStyles.join(';'), nodeStyles: nodeStyles.join(';') };
|
||||
};
|
||||
|
||||
@@ -55,18 +56,16 @@ export const styles2String = (node: Node) => {
|
||||
export const userNodeOverrides = (node: Node, options: any) => {
|
||||
const { themeVariables, handdrawnSeed } = getConfig();
|
||||
const { nodeBorder, mainBkg } = themeVariables;
|
||||
const styles = compileStyles(node);
|
||||
const { stylesArray: styles, stylesMap } = compileStyles(node);
|
||||
|
||||
// index the style array to a map object
|
||||
const styleMap = styles2Map(styles);
|
||||
|
||||
const result = Object.assign(
|
||||
{
|
||||
roughness: 0.7,
|
||||
fill: styleMap.get('fill') || mainBkg,
|
||||
fill: stylesMap.get('fill') || mainBkg,
|
||||
fillStyle: 'hachure', // solid fill
|
||||
fillWeight: 3.5,
|
||||
stroke: styleMap.get('stroke') || nodeBorder,
|
||||
stroke: stylesMap.get('stroke') || nodeBorder,
|
||||
seed: handdrawnSeed,
|
||||
strokeWidth: 1.3,
|
||||
},
|
||||
|
Reference in New Issue
Block a user