diff --git a/cypress/platform/per.html b/cypress/platform/per.html index a6d3397c3..c9987d84f 100644 --- a/cypress/platform/per.html +++ b/cypress/platform/per.html @@ -90,24 +90,23 @@ stateDiagram-v2 >
-      stateDiagram
-       StateID
-
+      stateDiagram-v2
+      [*] --> First
+      state First {
+          [*] --> second
+          second --> [*]
+      }
 
 
     
-      stateDiagram
-        direction LR
-        [*] --> A
-        A --> B
-        B --> C
-        state B {
-          direction LR
-          a --> b
-        }
-        B --> D
+      flowchart LR
+        A[Start] --Some text--> B(Continue)
+        B --> C{Evaluate}
+        C -- One --> D[Option 1]
+        C -- Two --> E[Option 2]
+        C -- Three --> F[fa:fa-car Option 3]
     
+ + + diff --git a/docs/neo-style-to-do b/docs/neo-style-to-do index 936f2cc30..2cf300a3e 100644 --- a/docs/neo-style-to-do +++ b/docs/neo-style-to-do @@ -1,5 +1,12 @@ 1. Paddings of node labels for neo and classic does not differ, which it should. Status: Fixed -2. When layout is set to "elk" and look is "neo", the drop shadow is not present -3. Drop-shadows are not present for flow-charts, even if look is "neo" -4. When look is "neo" and theme is "forest", the border of nodes is visible, which should not be the case -5. When look is "neo" and "theme" is "neo", the background color shall be white +2. When layout is set to "elk" and look is "neo", the drop shadow is not present. Status: Fixed +3. Drop-shadows are not present for flow-charts, even if look is "neo". Status: Fixed +4. When look is "neo" and theme is "forest", the border of nodes is visible, which should not be the case: Status: Fixed +5. When look is "neo" and "theme" is "neo", the background color shall be white. Status: Fixed +6. Composite states contains borders in neo. Status: Fixed +7. Nested states contains borders in neo. Status: Fixed +8. The font-size of node labels seems a bit off. +9. When selecting look=neo and theme for composite stated, the height differs. +10. Drop-shadows for non-rectangular shapes are not supported: Status: Fixed +11. Gradient +12. Rx,Ry of rects do not apply any longer diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts index 20b9634c2..76905fdf4 100644 --- a/packages/mermaid/src/config.type.ts +++ b/packages/mermaid/src/config.type.ts @@ -68,7 +68,7 @@ export interface MermaidConfig { * Defines which main look to use for the diagram. * */ - look?: 'classic' | 'handdrawn'; + look?: 'classic' | 'handdrawn' | 'neo'; /** * Defines the seed to be used when using handdrawn look. This is important for the automated tests as they will always find differences without the seed. The default value is 0 which gives a random seed. * diff --git a/packages/mermaid/src/diagrams/state/stateRenderer-v3-unified.ts b/packages/mermaid/src/diagrams/state/stateRenderer-v3-unified.ts index 2ade9ee24..cdb67682d 100644 --- a/packages/mermaid/src/diagrams/state/stateRenderer-v3-unified.ts +++ b/packages/mermaid/src/diagrams/state/stateRenderer-v3-unified.ts @@ -7,6 +7,7 @@ import { setupViewPortForSVG } from '../../rendering-util/setupViewPortForSVG.js import type { LayoutData } from '../../rendering-util/types.js'; import utils from '../../utils.js'; import { CSS_DIAGRAM, DEFAULT_NESTED_DOC_DIR } from './stateCommon.js'; +import { lookUpDomId } from '../flowchart/flowDb'; /** * Get the direction from the statement items. @@ -87,7 +88,7 @@ export const draw = async function ( data4Layout.markers = ['barb']; } data4Layout.diagramId = id; - // console.log('REF1:', data4Layout); + console.log('REF1:', data4Layout); await render(data4Layout, svg, element, positions); const padding = 8; utils.insertTitle( diff --git a/packages/mermaid/src/rendering-util/rendering-elements/clusters.js b/packages/mermaid/src/rendering-util/rendering-elements/clusters.js index 8d802a3f5..c1e624e69 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/clusters.js +++ b/packages/mermaid/src/rendering-util/rendering-elements/clusters.js @@ -168,7 +168,8 @@ const roundedWithTitle = (parent, node) => { .attr('id', node.id) .attr('data-et', 'node') .attr('data-node', 'true') - .attr('data-id', node.id); + .attr('data-id', node.id) + .attr('data-look', node.look); // add the rect const outerRectG = shapeSvg.insert('g', ':first-child'); @@ -255,7 +256,8 @@ const roundedWithTitle = (parent, node) => { .attr('x', x) .attr('y', y) .attr('width', width) - .attr('height', node.height + padding); + .attr('height', node.height + padding) + .attr('data-look', node.look); innerRect .attr('class', 'inner') .attr('x', x) diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/drawRect.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/drawRect.ts index bef59decc..3c4933bf4 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/drawRect.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/drawRect.ts @@ -24,7 +24,6 @@ export const drawRect = async (parent: SVGAElement, node: Node, options: RectOpt log.info('IPI node = ', node); let rect; - node.look = look; let { rx, ry } = node; const { cssStyles } = node; @@ -48,11 +47,25 @@ export const drawRect = async (parent: SVGAElement, node: Node, options: RectOpt rect.attr('class', 'basic label-container').attr('style', cssStyles); } else { rect = shapeSvg.insert('rect', ':first-child'); + let gradient = shapeSvg.append('linearGradient'); - let rectClass = 'basic label-container'; - if (node.look === 'neo') { - rectClass += ' state-shadow-neo'; - } + gradient + .attr('id', 'gradient') + .attr('gradientUnits', 'userSpaceOnUse') + .attr('spreadMethod', 'pad'); + + gradient + .append('svg:stop') + .attr('offset', '0%') + .attr('stop-color', '#eb0042') + .attr('stop-opacity', 1); + + gradient + .append('svg:stop') + .attr('offset', '100%') + .attr('stop-color', '#0042eb') + .attr('stop-opacity', 1); + const rectClass = 'basic label-container'; rect .attr('class', rectClass) @@ -64,7 +77,8 @@ export const drawRect = async (parent: SVGAElement, node: Node, options: RectOpt .attr('x', x) .attr('y', y) .attr('width', totalWidth) - .attr('height', totalHeight); + .attr('height', totalHeight) + .attr('stroke', 'url(#gradient)'); } updateNodeBounds(node, rect); diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/roundedRect.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/roundedRect.ts index 827c938a2..a061a2b1c 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/roundedRect.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/roundedRect.ts @@ -4,7 +4,6 @@ import { getConfig } from '$root/diagram-api/diagramAPI.js'; export const roundedRect = async (parent: SVGAElement, node: Node) => { const { look } = getConfig(); - node.look = look; const options = { rx: node.look === 'neo' ? 3 : 5, ry: node.look === 'neo' ? 3 : 5, @@ -12,9 +11,9 @@ export const roundedRect = async (parent: SVGAElement, node: Node) => { labelPaddingX: node.look === 'neo' ? node.padding * 2 : node.padding, labelPaddingY: node.look === 'neo' ? node.padding : node.padding, classes: '', - labelPaddingX: (node?.padding || 0) * 1, - labelPaddingY: (node?.padding || 0) * 1, } as RectOptions; + console.log('Perra1, node, options: ', node, options); + return drawRect(parent, node, options); }; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/state.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/state.ts index d73f114bd..34c06c6aa 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/state.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/state.ts @@ -4,8 +4,6 @@ import { getConfig } from '$root/diagram-api/diagramAPI.js'; export const state = async (parent: SVGAElement, node: Node) => { const { look } = getConfig(); - node.look = look; - const options = { rx: node.look === 'neo' ? 3 : 5, ry: node.look === 'neo' ? 3 : 5, diff --git a/packages/mermaid/src/schemas/config.schema.yaml b/packages/mermaid/src/schemas/config.schema.yaml index 398b32bfe..03e619553 100644 --- a/packages/mermaid/src/schemas/config.schema.yaml +++ b/packages/mermaid/src/schemas/config.schema.yaml @@ -79,6 +79,7 @@ properties: enum: - classic - handdrawn + - neo default: 'classic' handdrawnSeed: description: | diff --git a/packages/mermaid/src/styles.ts b/packages/mermaid/src/styles.ts index 8cc5767b6..ae849540d 100644 --- a/packages/mermaid/src/styles.ts +++ b/packages/mermaid/src/styles.ts @@ -73,10 +73,40 @@ const getStyles = ( stroke: ${options.nodeBorder}; } - [data-look="neo"].node rect { - stroke: ${options.nodeBorder}; - stroke: red !important + [data-look="neo"].node rect, [data-look="neo"].node polygon { + //stroke: none; + stroke: ${options.useGradient ? 'url(#gradient)' : options.nodeBorder}; + filter: drop-shadow( 1px 2px 2px rgba(185,185,185,1.0) ); + rx: 3; + ry: 3; } + + [data-look="neo"].node rect, [data-look="neo"].node circle, [data-look="neo"].node polygon { + //stroke: $(options.nodeBorder); + stroke: ${options.useGradient ? 'url(#gradient)' : options.nodeBorder}; + filter: drop-shadow( 1px 2px 2px rgba(185,185,185,1.0) ); + rx: 3; + ry: 3; + } + + [data-look="neo"].node circle{ + stroke: $(options.nodeBorder); + stroke: ${options.useGradient ? 'url(#gradient)' : options.nodeBorder}; + filter: drop-shadow( 1px 2px 2px rgba(185,185,185,1.0) ); + fill: #000000; + rx: 3; + ry: 3; + } + + [data-look="neo"].statediagram-cluster rect { + fill: ${options.compositeTitleBackground}; + stroke: ${options.useGradient ? 'url(#gradient)' : options.nodeBorder}; + //stroke: none; + stroke-width: 1px; + rx: 3; + ry: 3; + } + ${userStyles} `; }; diff --git a/packages/mermaid/src/themes/index.js b/packages/mermaid/src/themes/index.js index 979d83bfa..8bfe5a1bd 100644 --- a/packages/mermaid/src/themes/index.js +++ b/packages/mermaid/src/themes/index.js @@ -4,6 +4,7 @@ import { getThemeVariables as defaultThemeVariables } from './theme-default.js'; import { getThemeVariables as forestThemeVariables } from './theme-forest.js'; import { getThemeVariables as neutralThemeVariables } from './theme-neutral.js'; import { getThemeVariables as neoThemeVariables } from './theme-neo.js'; +import { getThemeVariables as gradientThemeVariables } from './theme-gradient.js'; export default { base: { @@ -24,4 +25,7 @@ export default { neo: { getThemeVariables: neoThemeVariables, }, + gradient: { + getThemeVariables: gradientThemeVariables, + }, }; diff --git a/packages/mermaid/src/themes/theme-gradient.js b/packages/mermaid/src/themes/theme-gradient.js new file mode 100644 index 000000000..843f1cf45 --- /dev/null +++ b/packages/mermaid/src/themes/theme-gradient.js @@ -0,0 +1,372 @@ +import { darken, lighten, adjust, invert, isDark, toRgba } from 'khroma'; +import { mkBorder } from './theme-helpers.js'; +import { + oldAttributeBackgroundColorEven, + oldAttributeBackgroundColorOdd, +} from './erDiagram-oldHardcodedValues.js'; + +class Theme { + constructor() { + /** # Base variables */ + /** + * - Background - used to know what the background color is of the diagram. This is used for + * deducing colors for instance line color. Default value is #f4f4f4. + */ + this.background = '#ffffff'; + + this.primaryColor = '#cccccc'; + this.mainBkg = '#ffffff'; + + this.noteBkgColor = '#fff5ad'; + this.noteTextColor = '#333'; + + this.THEME_COLOR_LIMIT = 12; + this.radius = 3; + // dark + + this.fontFamily = '"trebuchet ms", verdana, arial, sans-serif'; + this.fontSize = '10px'; + + // Neo-specific + this.nodeBorder = '#550000'; + this.stateBorder = 'none'; + } + updateColors() { + // The || is to make sure that if the variable has been defined by a user override that value is to be used + + /* Main */ + this.primaryTextColor = this.primaryTextColor || (this.darkMode ? '#eee' : '#333'); // invert(this.primaryColor); + this.secondaryColor = this.secondaryColor || adjust(this.primaryColor, { h: -120 }); + this.tertiaryColor = this.tertiaryColor || adjust(this.primaryColor, { h: 180, l: 5 }); + + this.primaryBorderColor = this.primaryBorderColor || mkBorder(this.primaryColor, this.darkMode); + this.secondaryBorderColor = + this.secondaryBorderColor || mkBorder(this.secondaryColor, this.darkMode); + this.tertiaryBorderColor = + this.tertiaryBorderColor || mkBorder(this.tertiaryColor, this.darkMode); + this.noteBorderColor = this.noteBorderColor || mkBorder(this.noteBkgColor, this.darkMode); + this.noteBkgColor = this.noteBkgColor || '#fff5ad'; + this.noteTextColor = this.noteTextColor || '#333'; + + this.secondaryTextColor = this.secondaryTextColor || invert(this.secondaryColor); + this.tertiaryTextColor = this.tertiaryTextColor || invert(this.tertiaryColor); + this.lineColor = this.lineColor || invert(this.background); + this.arrowheadColor = this.arrowheadColor || invert(this.background); + this.textColor = this.textColor || this.primaryTextColor; + + // TODO: should this instead default to secondaryBorderColor? + this.border2 = this.border2 || this.tertiaryBorderColor; + + /* Flowchart variables */ + this.nodeBkg = this.nodeBkg || this.primaryColor; + this.mainBkg = this.mainBkg || this.primaryColor; + this.nodeBorder = this.nodeBorder || this.primaryBorderColor; + this.clusterBkg = this.clusterBkg || this.tertiaryColor; + this.clusterBorder = this.clusterBorder || this.tertiaryBorderColor; + this.defaultLinkColor = this.defaultLinkColor || this.lineColor; + this.titleColor = this.titleColor || this.tertiaryTextColor; + this.edgeLabelBackground = + this.edgeLabelBackground || + (this.darkMode ? darken(this.secondaryColor, 30) : this.secondaryColor); + this.nodeTextColor = this.nodeTextColor || this.primaryTextColor; + /* Sequence Diagram variables */ + + // this.actorBorder = lighten(this.border1, 0.5); + this.actorBorder = this.actorBorder || this.primaryBorderColor; + this.actorBkg = this.actorBkg || this.mainBkg; + this.actorTextColor = this.actorTextColor || this.primaryTextColor; + this.actorLineColor = this.actorLineColor || this.actorBorder; + this.labelBoxBkgColor = this.labelBoxBkgColor || this.actorBkg; + this.signalColor = this.signalColor || this.textColor; + this.signalTextColor = this.signalTextColor || this.textColor; + this.labelBoxBorderColor = this.labelBoxBorderColor || this.actorBorder; + this.labelTextColor = this.labelTextColor || this.actorTextColor; + this.loopTextColor = this.loopTextColor || this.actorTextColor; + this.activationBorderColor = this.activationBorderColor || darken(this.secondaryColor, 10); + this.activationBkgColor = this.activationBkgColor || this.secondaryColor; + this.sequenceNumberColor = this.sequenceNumberColor || invert(this.lineColor); + + /* Gantt chart variables */ + + this.sectionBkgColor = this.sectionBkgColor || this.tertiaryColor; + this.altSectionBkgColor = this.altSectionBkgColor || 'white'; + this.sectionBkgColor = this.sectionBkgColor || this.secondaryColor; + this.sectionBkgColor2 = this.sectionBkgColor2 || this.primaryColor; + this.excludeBkgColor = this.excludeBkgColor || '#eeeeee'; + this.taskBorderColor = this.taskBorderColor || this.primaryBorderColor; + this.taskBkgColor = this.taskBkgColor || this.primaryColor; + this.activeTaskBorderColor = this.activeTaskBorderColor || this.primaryColor; + this.activeTaskBkgColor = this.activeTaskBkgColor || lighten(this.primaryColor, 23); + this.gridColor = this.gridColor || 'lightgrey'; + this.doneTaskBkgColor = this.doneTaskBkgColor || 'lightgrey'; + this.doneTaskBorderColor = this.doneTaskBorderColor || 'grey'; + this.critBorderColor = this.critBorderColor || '#ff8888'; + this.critBkgColor = this.critBkgColor || 'red'; + this.todayLineColor = this.todayLineColor || 'red'; + this.taskTextColor = this.taskTextColor || this.textColor; + this.taskTextOutsideColor = this.taskTextOutsideColor || this.textColor; + this.taskTextLightColor = this.taskTextLightColor || this.textColor; + this.taskTextColor = this.taskTextColor || this.primaryTextColor; + this.taskTextDarkColor = this.taskTextDarkColor || this.textColor; + this.taskTextClickableColor = this.taskTextClickableColor || '#003163'; + + /* Sequence Diagram variables */ + + this.personBorder = this.personBorder || this.primaryBorderColor; + this.personBkg = this.personBkg || this.mainBkg; + + /* state colors */ + this.transitionColor = this.transitionColor || this.lineColor; + this.transitionLabelColor = this.transitionLabelColor || this.textColor; + /* The color of the text tables of the states*/ + this.stateLabelColor = this.stateLabelColor || this.stateBkg || this.primaryTextColor; + + this.stateBkg = this.stateBkg || this.mainBkg; + this.labelBackgroundColor = this.labelBackgroundColor || this.stateBkg; + this.compositeBackground = this.compositeBackground || this.background || this.tertiaryColor; + this.altBackground = this.altBackground || '#f0f0f0'; + this.compositeTitleBackground = this.compositeTitleBackground || this.mainBkg; + this.compositeBorder = this.compositeBorder || this.nodeBorder; + this.innerEndBackground = this.nodeBorder; + this.errorBkgColor = this.errorBkgColor || this.tertiaryColor; + this.errorTextColor = this.errorTextColor || this.tertiaryTextColor; + this.transitionColor = this.transitionColor || this.lineColor; + this.specialStateColor = this.lineColor; + + /* Color Scale */ + /* Each color-set will have a background, a foreground and a border color */ + this.cScale0 = this.cScale0 || this.primaryColor; + this.cScale1 = this.cScale1 || this.secondaryColor; + this.cScale2 = this.cScale2 || this.tertiaryColor; + this.cScale3 = this.cScale3 || adjust(this.primaryColor, { h: 30 }); + this.cScale4 = this.cScale4 || adjust(this.primaryColor, { h: 60 }); + this.cScale5 = this.cScale5 || adjust(this.primaryColor, { h: 90 }); + this.cScale6 = this.cScale6 || adjust(this.primaryColor, { h: 120 }); + this.cScale7 = this.cScale7 || adjust(this.primaryColor, { h: 150 }); + this.cScale8 = this.cScale8 || adjust(this.primaryColor, { h: 210, l: 150 }); + this.cScale9 = this.cScale9 || adjust(this.primaryColor, { h: 270 }); + this.cScale10 = this.cScale10 || adjust(this.primaryColor, { h: 300 }); + this.cScale11 = this.cScale11 || adjust(this.primaryColor, { h: 330 }); + if (this.darkMode) { + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScale' + i] = darken(this['cScale' + i], 75); + } + } else { + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScale' + i] = darken(this['cScale' + i], 25); + } + } + + // Setup the inverted color for the set + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScaleInv' + i] = this['cScaleInv' + i] || invert(this['cScale' + i]); + } + // Setup the peer color for the set, useful for borders + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + if (this.darkMode) { + this['cScalePeer' + i] = this['cScalePeer' + i] || lighten(this['cScale' + i], 10); + } else { + this['cScalePeer' + i] = this['cScalePeer' + i] || darken(this['cScale' + i], 10); + } + } + + // Setup the label color for the set + this.scaleLabelColor = this.scaleLabelColor || this.labelTextColor; + + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScaleLabel' + i] = this['cScaleLabel' + i] || this.scaleLabelColor; + } + + const multiplier = this.darkMode ? -4 : -1; + for (let i = 0; i < 5; i++) { + this['surface' + i] = + this['surface' + i] || + adjust(this.mainBkg, { h: 180, s: -15, l: multiplier * (5 + i * 3) }); + this['surfacePeer' + i] = + this['surfacePeer' + i] || + adjust(this.mainBkg, { h: 180, s: -15, l: multiplier * (8 + i * 3) }); + } + + /* class */ + this.classText = this.classText || this.textColor; + + /* user-journey */ + this.fillType0 = this.fillType0 || this.primaryColor; + this.fillType1 = this.fillType1 || this.secondaryColor; + this.fillType2 = this.fillType2 || adjust(this.primaryColor, { h: 64 }); + this.fillType3 = this.fillType3 || adjust(this.secondaryColor, { h: 64 }); + this.fillType4 = this.fillType4 || adjust(this.primaryColor, { h: -64 }); + this.fillType5 = this.fillType5 || adjust(this.secondaryColor, { h: -64 }); + this.fillType6 = this.fillType6 || adjust(this.primaryColor, { h: 128 }); + this.fillType7 = this.fillType7 || adjust(this.secondaryColor, { h: 128 }); + + /* pie */ + this.pie1 = this.pie1 || this.primaryColor; + this.pie2 = this.pie2 || this.secondaryColor; + this.pie3 = this.pie3 || this.tertiaryColor; + this.pie4 = this.pie4 || adjust(this.primaryColor, { l: -10 }); + this.pie5 = this.pie5 || adjust(this.secondaryColor, { l: -10 }); + this.pie6 = this.pie6 || adjust(this.tertiaryColor, { l: -10 }); + this.pie7 = this.pie7 || adjust(this.primaryColor, { h: +60, l: -10 }); + this.pie8 = this.pie8 || adjust(this.primaryColor, { h: -60, l: -10 }); + this.pie9 = this.pie9 || adjust(this.primaryColor, { h: 120, l: 0 }); + this.pie10 = this.pie10 || adjust(this.primaryColor, { h: +60, l: -20 }); + this.pie11 = this.pie11 || adjust(this.primaryColor, { h: -60, l: -20 }); + this.pie12 = this.pie12 || adjust(this.primaryColor, { h: 120, l: -10 }); + this.pieTitleTextSize = this.pieTitleTextSize || '25px'; + this.pieTitleTextColor = this.pieTitleTextColor || this.taskTextDarkColor; + this.pieSectionTextSize = this.pieSectionTextSize || '17px'; + this.pieSectionTextColor = this.pieSectionTextColor || this.textColor; + this.pieLegendTextSize = this.pieLegendTextSize || '17px'; + this.pieLegendTextColor = this.pieLegendTextColor || this.taskTextDarkColor; + this.pieStrokeColor = this.pieStrokeColor || 'black'; + this.pieStrokeWidth = this.pieStrokeWidth || '2px'; + this.pieOuterStrokeWidth = this.pieOuterStrokeWidth || '2px'; + this.pieOuterStrokeColor = this.pieOuterStrokeColor || 'black'; + this.pieOpacity = this.pieOpacity || '0.7'; + + /* quadrant-graph */ + this.quadrant1Fill = this.quadrant1Fill || this.primaryColor; + this.quadrant2Fill = this.quadrant2Fill || adjust(this.primaryColor, { r: 5, g: 5, b: 5 }); + this.quadrant3Fill = this.quadrant3Fill || adjust(this.primaryColor, { r: 10, g: 10, b: 10 }); + this.quadrant4Fill = this.quadrant4Fill || adjust(this.primaryColor, { r: 15, g: 15, b: 15 }); + this.quadrant1TextFill = this.quadrant1TextFill || this.primaryTextColor; + this.quadrant2TextFill = + this.quadrant2TextFill || adjust(this.primaryTextColor, { r: -5, g: -5, b: -5 }); + this.quadrant3TextFill = + this.quadrant3TextFill || adjust(this.primaryTextColor, { r: -10, g: -10, b: -10 }); + this.quadrant4TextFill = + this.quadrant4TextFill || adjust(this.primaryTextColor, { r: -15, g: -15, b: -15 }); + this.quadrantPointFill = + this.quadrantPointFill || isDark(this.quadrant1Fill) + ? lighten(this.quadrant1Fill) + : darken(this.quadrant1Fill); + this.quadrantPointTextFill = this.quadrantPointTextFill || this.primaryTextColor; + this.quadrantXAxisTextFill = this.quadrantXAxisTextFill || this.primaryTextColor; + this.quadrantYAxisTextFill = this.quadrantYAxisTextFill || this.primaryTextColor; + this.quadrantInternalBorderStrokeFill = + this.quadrantInternalBorderStrokeFill || this.primaryBorderColor; + this.quadrantExternalBorderStrokeFill = + this.quadrantExternalBorderStrokeFill || this.primaryBorderColor; + this.quadrantTitleFill = this.quadrantTitleFill || this.primaryTextColor; + + /* xychart */ + this.xyChart = { + backgroundColor: this.xyChart?.backgroundColor || this.background, + titleColor: this.xyChart?.titleColor || this.primaryTextColor, + xAxisTitleColor: this.xyChart?.xAxisTitleColor || this.primaryTextColor, + xAxisLabelColor: this.xyChart?.xAxisLabelColor || this.primaryTextColor, + xAxisTickColor: this.xyChart?.xAxisTickColor || this.primaryTextColor, + xAxisLineColor: this.xyChart?.xAxisLineColor || this.primaryTextColor, + yAxisTitleColor: this.xyChart?.yAxisTitleColor || this.primaryTextColor, + yAxisLabelColor: this.xyChart?.yAxisLabelColor || this.primaryTextColor, + yAxisTickColor: this.xyChart?.yAxisTickColor || this.primaryTextColor, + yAxisLineColor: this.xyChart?.yAxisLineColor || this.primaryTextColor, + plotColorPalette: + this.xyChart?.plotColorPalette || + '#FFF4DD,#FFD8B1,#FFA07A,#ECEFF1,#D6DBDF,#C3E0A8,#FFB6A4,#FFD74D,#738FA7,#FFFFF0', + }; + + /* requirement-diagram */ + this.requirementBackground = this.requirementBackground || this.primaryColor; + this.requirementBorderColor = this.requirementBorderColor || this.primaryBorderColor; + this.requirementBorderSize = this.requirementBorderSize || '1'; + this.requirementTextColor = this.requirementTextColor || this.primaryTextColor; + this.relationColor = this.relationColor || this.lineColor; + this.relationLabelBackground = + this.relationLabelBackground || + (this.darkMode ? darken(this.secondaryColor, 30) : this.secondaryColor); + this.relationLabelColor = this.relationLabelColor || this.actorTextColor; + + /* git */ + this.git0 = this.git0 || this.primaryColor; + this.git1 = this.git1 || this.secondaryColor; + this.git2 = this.git2 || this.tertiaryColor; + this.git3 = this.git3 || adjust(this.primaryColor, { h: -30 }); + this.git4 = this.git4 || adjust(this.primaryColor, { h: -60 }); + this.git5 = this.git5 || adjust(this.primaryColor, { h: -90 }); + this.git6 = this.git6 || adjust(this.primaryColor, { h: +60 }); + this.git7 = this.git7 || adjust(this.primaryColor, { h: +120 }); + if (this.darkMode) { + this.git0 = lighten(this.git0, 25); + this.git1 = lighten(this.git1, 25); + this.git2 = lighten(this.git2, 25); + this.git3 = lighten(this.git3, 25); + this.git4 = lighten(this.git4, 25); + this.git5 = lighten(this.git5, 25); + this.git6 = lighten(this.git6, 25); + this.git7 = lighten(this.git7, 25); + } else { + this.git0 = darken(this.git0, 25); + this.git1 = darken(this.git1, 25); + this.git2 = darken(this.git2, 25); + this.git3 = darken(this.git3, 25); + this.git4 = darken(this.git4, 25); + this.git5 = darken(this.git5, 25); + this.git6 = darken(this.git6, 25); + this.git7 = darken(this.git7, 25); + } + this.gitInv0 = this.gitInv0 || invert(this.git0); + this.gitInv1 = this.gitInv1 || invert(this.git1); + this.gitInv2 = this.gitInv2 || invert(this.git2); + this.gitInv3 = this.gitInv3 || invert(this.git3); + this.gitInv4 = this.gitInv4 || invert(this.git4); + this.gitInv5 = this.gitInv5 || invert(this.git5); + this.gitInv6 = this.gitInv6 || invert(this.git6); + this.gitInv7 = this.gitInv7 || invert(this.git7); + this.branchLabelColor = + this.branchLabelColor || (this.darkMode ? 'black' : this.labelTextColor); + this.gitBranchLabel0 = this.gitBranchLabel0 || this.branchLabelColor; + this.gitBranchLabel1 = this.gitBranchLabel1 || this.branchLabelColor; + this.gitBranchLabel2 = this.gitBranchLabel2 || this.branchLabelColor; + this.gitBranchLabel3 = this.gitBranchLabel3 || this.branchLabelColor; + this.gitBranchLabel4 = this.gitBranchLabel4 || this.branchLabelColor; + this.gitBranchLabel5 = this.gitBranchLabel5 || this.branchLabelColor; + this.gitBranchLabel6 = this.gitBranchLabel6 || this.branchLabelColor; + this.gitBranchLabel7 = this.gitBranchLabel7 || this.branchLabelColor; + + this.tagLabelColor = this.tagLabelColor || this.primaryTextColor; + this.tagLabelBackground = this.tagLabelBackground || this.primaryColor; + this.tagLabelBorder = this.tagBorder || this.primaryBorderColor; + this.tagLabelFontSize = this.tagLabelFontSize || '10px'; + this.commitLabelColor = this.commitLabelColor || this.secondaryTextColor; + this.commitLabelBackground = this.commitLabelBackground || this.secondaryColor; + this.commitLabelFontSize = this.commitLabelFontSize || '10px'; + + /* -------------------------------------------------- */ + /* EntityRelationship diagrams */ + + this.attributeBackgroundColorOdd = + this.attributeBackgroundColorOdd || oldAttributeBackgroundColorOdd; + this.attributeBackgroundColorEven = + this.attributeBackgroundColorEven || oldAttributeBackgroundColorEven; + /* -------------------------------------------------- */ + } + calculate(overrides) { + if (typeof overrides !== 'object') { + // Calculate colors form base colors + this.updateColors(); + return; + } + + const keys = Object.keys(overrides); + + // Copy values from overrides, this is mainly for base colors + keys.forEach((k) => { + this[k] = overrides[k]; + }); + + // Calculate colors form base colors + this.updateColors(); + // Copy values from overrides again in case of an override of derived value + keys.forEach((k) => { + this[k] = overrides[k]; + }); + } +} + +export const getThemeVariables = (userOverrides) => { + const theme = new Theme(); + theme.calculate(userOverrides); + return theme; +}; diff --git a/packages/mermaid/src/themes/theme-neo.js b/packages/mermaid/src/themes/theme-neo.js index 7aadaa93a..9591c1971 100644 --- a/packages/mermaid/src/themes/theme-neo.js +++ b/packages/mermaid/src/themes/theme-neo.js @@ -15,8 +15,7 @@ class Theme { this.background = '#ffffff'; this.primaryColor = '#cccccc'; - //this.mainBkg = '#ffffff'; - this.mainBkg = '#ecedfe'; + this.mainBkg = '#ffffff'; this.noteBkgColor = '#fff5ad'; this.noteTextColor = '#333'; @@ -31,6 +30,7 @@ class Theme { // Neo-specific this.nodeBorder = 'none'; this.stateBorder = 'none'; + this.useGradient = false; } updateColors() { // The || is to make sure that if the variable has been defined by a user override that value is to be used