diff --git a/cypress/platform/saurabh.html b/cypress/platform/saurabh.html index 45c350756..ecefa9c08 100644 --- a/cypress/platform/saurabh.html +++ b/cypress/platform/saurabh.html @@ -63,23 +63,21 @@
       flowchart TD
-       B2@{ icon: "fa:bell", form: "square", label: "B2 agsyua duadu", pos: "t", h: 80 }@
-       
-
-       W --> B2
-       X --> B2
-       Y --> B2
-       Z --> B2
-       B2 --sas--> C
-
-
+       B2@{ icon: "fa:bell", form: "square", label: "B2 agsyua duadu", pos: "b" }
     
-
-      flowchart TB
-       A --test2--> B2@{ icon: "fa:bell", form: "rounded", label: "B2 aiduaid uyawduad uaduabd uyduadb", pos: "b" }@
-       B2 --test--> C
-       D --> B2 --> E
-       style B2 fill:#f9f,stroke:#333,stroke-width:4px
+    
+      flowchart TD
+        B2@{ icon: "fa:bell", form: "rounded", label: "B2 aiduaid uyawduad uaduabd uyduadb", pos: "b" }
+  
+
+      flowchart TD
+        B2@{ icon: "fa:bell", form: "circle", label: "B2 aiduaid uyawduad uaduabd uyduadb", pos: "b" }
+  
+
+      flowchart TD
+        B2@{ icon: "fa:bell", label: "B2 aiduaid uyawduad uaduabd uyduadb", pos: "b" }
   
@@ -125,7 +123,9 @@
         {
           name: 'fa',
           loader: () =>
-            fetch('https://unpkg.com/@iconify-json/fa6-solid/icons.json').then((res) => res.json()),
+            fetch('https://unpkg.com/@iconify-json/fa6-regular/icons.json').then((res) =>
+              res.json()
+            ),
         },
       ]);
       mermaid.parseError = function (err, hash) {
@@ -137,7 +137,7 @@
       mermaid.initialize({
         // theme: 'base',
         // handdrawnSeed: 12,
-        look: 'classic',
+        // look: 'classic',
         // 'elk.nodePlacement.strategy': 'NETWORK_SIMPLEX',
         // 'elk.nodePlacement.strategy': 'SIMPLE',
         // 'elk.nodePlacement.strategy': 'LAYERED',
diff --git a/docs/config/setup/interfaces/mermaid.LayoutData.md b/docs/config/setup/interfaces/mermaid.LayoutData.md
index 7a8a302d8..4e5b631ff 100644
--- a/docs/config/setup/interfaces/mermaid.LayoutData.md
+++ b/docs/config/setup/interfaces/mermaid.LayoutData.md
@@ -20,7 +20,7 @@
 
 #### Defined in
 
-[packages/mermaid/src/rendering-util/types.ts:122](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L122)
+[packages/mermaid/src/rendering-util/types.ts:125](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L125)
 
 ---
 
@@ -30,7 +30,7 @@
 
 #### Defined in
 
-[packages/mermaid/src/rendering-util/types.ts:121](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L121)
+[packages/mermaid/src/rendering-util/types.ts:124](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L124)
 
 ---
 
@@ -40,4 +40,4 @@
 
 #### Defined in
 
-[packages/mermaid/src/rendering-util/types.ts:120](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L120)
+[packages/mermaid/src/rendering-util/types.ts:123](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L123)
diff --git a/docs/config/setup/interfaces/mermaid.ParseOptions.md b/docs/config/setup/interfaces/mermaid.ParseOptions.md
index 37eacb4cd..52b4af49e 100644
--- a/docs/config/setup/interfaces/mermaid.ParseOptions.md
+++ b/docs/config/setup/interfaces/mermaid.ParseOptions.md
@@ -19,4 +19,4 @@ The `parseError` function will not be called.
 
 #### Defined in
 
-[packages/mermaid/src/types.ts:57](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L57)
+[packages/mermaid/src/types.ts:56](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L56)
diff --git a/docs/config/setup/interfaces/mermaid.ParseResult.md b/docs/config/setup/interfaces/mermaid.ParseResult.md
index 21e89e81d..fb7856a4c 100644
--- a/docs/config/setup/interfaces/mermaid.ParseResult.md
+++ b/docs/config/setup/interfaces/mermaid.ParseResult.md
@@ -36,7 +36,7 @@ Omit.defaultConfig
 
 #### Defined in
 
-[packages/mermaid/src/mermaid.ts:327](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L327)
+[packages/mermaid/src/types.ts:67](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L67)
 
 ---
 
@@ -52,7 +52,7 @@ Omit.diagram
 
 #### Defined in
 
-[packages/mermaid/src/types.ts:72](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L72)
+[packages/mermaid/src/types.ts:63](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L63)
 
 ---
 
diff --git a/docs/config/setup/interfaces/mermaid.RenderResult.md b/docs/config/setup/interfaces/mermaid.RenderResult.md
index f9954437a..4c5604022 100644
--- a/docs/config/setup/interfaces/mermaid.RenderResult.md
+++ b/docs/config/setup/interfaces/mermaid.RenderResult.md
@@ -39,7 +39,7 @@ bindFunctions?.(div); // To call bindFunctions only if it's present.
 
 #### Defined in
 
-[packages/mermaid/src/types.ts:95](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L95)
+[packages/mermaid/src/types.ts:90](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L90)
 
 ---
 
@@ -51,7 +51,7 @@ The diagram type, e.g. 'flowchart', 'sequence', etc.
 
 #### Defined in
 
-[packages/mermaid/src/types.ts:85](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L85)
+[packages/mermaid/src/types.ts:80](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L80)
 
 ---
 
@@ -63,4 +63,4 @@ The svg code for the rendered graph.
 
 #### Defined in
 
-[packages/mermaid/src/types.ts:81](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L81)
+[packages/mermaid/src/types.ts:76](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L76)
diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json
index 7b4b136f3..39e0803f2 100644
--- a/packages/mermaid/package.json
+++ b/packages/mermaid/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@mermaid-chart/mermaid",
-  "version": "11.2.0-b.3",
+  "version": "11.2.0-b.4",
   "description": "Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.",
   "type": "module",
   "module": "./dist/mermaid.core.mjs",
diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.ts b/packages/mermaid/src/diagrams/flowchart/flowDb.ts
index df73b5430..9080f6c88 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowDb.ts
+++ b/packages/mermaid/src/diagrams/flowchart/flowDb.ts
@@ -161,6 +161,7 @@ export const addVertex = function (
       if (!doc.label?.trim() && vertex.text === id) {
         vertex.text = '';
       }
+      vertex.constrainedImage = !!doc.constrainedImage;
     }
     if (doc.w) {
       vertex.assetWidth = Number(doc.w);
@@ -900,6 +901,9 @@ const addNodeFromVertex = (
       img: vertex.img,
       assetWidth: vertex.assetWidth,
       assetHeight: vertex.assetHeight,
+      imageAspectRatio: vertex.imageAspectRatio,
+      defaultWidth: vertex.defaultWidth,
+      constrainedImage: vertex.constrainedImage,
     });
   }
 };
diff --git a/packages/mermaid/src/diagrams/flowchart/types.ts b/packages/mermaid/src/diagrams/flowchart/types.ts
index 97dc54fa7..c60b1e8c1 100644
--- a/packages/mermaid/src/diagrams/flowchart/types.ts
+++ b/packages/mermaid/src/diagrams/flowchart/types.ts
@@ -17,6 +17,9 @@ export interface FlowVertex {
   img?: string;
   assetWidth?: number;
   assetHeight?: number;
+  defaultWidth?: number;
+  imageAspectRatio?: number;
+  constrainedImage?: boolean;
 }
 
 export interface FlowText {
diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/icon.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/icon.ts
index d7ad58de9..b9bdb06b5 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/icon.ts
+++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/icon.ts
@@ -55,9 +55,9 @@ export const icon = async (
 
   const iconShape = shapeSvg.insert(() => iconNode, ':first-child');
   const outerShape = shapeSvg.insert(() => outerNode);
+  const iconElem = shapeSvg.append('g');
 
   if (node.icon) {
-    const iconElem = shapeSvg.append('g');
     iconElem.html(
       `${await getIconSVG(node.icon, { height: iconSize, fallbackPrefix: '' })}`
     );
@@ -71,6 +71,7 @@ export const icon = async (
       `translate(${-iconWidth / 2 - iconX},${topLabel ? outerHeight / 2 - iconHeight - iconY : -outerHeight / 2 - iconY})`
     );
     iconElem.selectAll('path').attr('fill', stylesMap.get('stroke') || nodeBorder);
+    iconElem.attr('class', 'icon');
   }
 
   label.attr(
@@ -83,6 +84,14 @@ export const icon = async (
     `translate(${0},${topLabel ? bbox.height / 2 + labelPadding / 2 : -bbox.height / 2 - labelPadding / 2})`
   );
 
+  if (stylesMap.get('stroke')) {
+    iconElem.selectAll('path').attr('style', `fill: ${stylesMap.get('stroke')}`);
+  }
+
+  if (stylesMap.get('fill')) {
+    iconShape.selectAll('path').attr('style', `stroke: ${stylesMap.get('fill')}`);
+  }
+
   updateNodeBounds(node, outerShape);
 
   node.intersect = function (point) {
diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconCircle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconCircle.ts
index e7551ca65..c810e4a15 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconCircle.ts
+++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconCircle.ts
@@ -21,7 +21,7 @@ export const iconCircle = async (
   node.width = Math.max(iconSize, defaultWidth ?? 0);
   const { shapeSvg, bbox, label } = await labelHelper(parent, node, 'icon-shape default');
 
-  const padding = 20;
+  const padding = node.look === 'neo' ? 30 : 20;
   const labelPadding = node.label ? 8 : 0;
 
   const topLabel = node.pos === 't';
@@ -65,19 +65,28 @@ export const iconCircle = async (
   const outerShape = shapeSvg.insert(() => outerNode);
   iconElem.attr(
     'transform',
-    `translate(${-iconWidth / 2 - iconX},${topLabel ? diameter / 2 - iconHeight - padding + bbox.height / 2 - iconY : -diameter / 2 + padding - bbox.height / 2 - labelPadding / 2 - iconY})`
+    `translate(${-iconWidth / 2 - iconX},${topLabel ? diameter / 2 - iconHeight - padding + bbox.height / 2 - iconY + labelPadding / 2 : -diameter / 2 + padding - bbox.height / 2 - labelPadding / 2 - iconY})`
   );
   iconElem.selectAll('path').attr('fill', stylesMap.get('stroke') || nodeBorder);
+  iconElem.attr('class', 'icon');
   label.attr(
     'transform',
-    `translate(${-bbox.width / 2},${topLabel ? -diameter / 2 - bbox.height / 2 : diameter / 2 - bbox.height / 2 + labelPadding / 2})`
+    `translate(${-bbox.width / 2},${topLabel ? -diameter / 2 - bbox.height / 2 - labelPadding / 2 : diameter / 2 - bbox.height / 2 + labelPadding / 2})`
   );
 
   iconShape.attr(
     'transform',
-    `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2 - labelPadding / 2})`
+    `translate(${0},${topLabel ? bbox.height / 2 + labelPadding / 2 : -bbox.height / 2 - labelPadding / 2})`
   );
 
+  if (stylesMap.get('stroke')) {
+    iconElem.selectAll('path').attr('style', `fill: ${stylesMap.get('stroke')}`);
+  }
+
+  if (stylesMap.get('fill')) {
+    iconShape.selectAll('path').attr('style', `stroke: ${stylesMap.get('fill')}`);
+  }
+
   updateNodeBounds(node, outerShape);
 
   node.intersect = function (point) {
diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconRounded.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconRounded.ts
index 0f5d6199d..dc7926a41 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconRounded.ts
+++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconRounded.ts
@@ -28,8 +28,10 @@ export const iconRounded = async (
 
   const topLabel = node.pos === 't';
 
-  const height = iconSize + halfPadding * 2;
-  const width = iconSize + halfPadding * 2;
+  const padding = node.look === 'neo' ? halfPadding * 2 : halfPadding;
+
+  const height = iconSize + padding * 2;
+  const width = iconSize + padding * 2;
   const { nodeBorder, mainBkg } = themeVariables;
   const { stylesMap } = compileStyles(node);
 
@@ -60,9 +62,9 @@ export const iconRounded = async (
 
   const iconShape = shapeSvg.insert(() => iconNode, ':first-child');
   const outerShape = shapeSvg.insert(() => outerNode);
+  const iconElem = shapeSvg.append('g');
 
   if (node.icon) {
-    const iconElem = shapeSvg.append('g');
     iconElem.html(
       `${await getIconSVG(node.icon, { height: iconSize, fallbackPrefix: '' })}`
     );
@@ -73,9 +75,10 @@ export const iconRounded = async (
     const iconY = iconBBox.y;
     iconElem.attr(
       'transform',
-      `translate(${-iconWidth / 2 - iconX},${topLabel ? outerHeight / 2 - iconHeight - halfPadding - iconY : -outerHeight / 2 + halfPadding - iconY})`
+      `translate(${-iconWidth / 2 - iconX},${topLabel ? outerHeight / 2 - iconHeight - padding - iconY : -outerHeight / 2 + padding - iconY})`
     );
     iconElem.selectAll('path').attr('fill', stylesMap.get('stroke') || nodeBorder);
+    iconElem.attr('class', 'icon');
   }
 
   label.attr(
@@ -88,6 +91,14 @@ export const iconRounded = async (
     `translate(${0},${topLabel ? bbox.height / 2 + labelPadding / 2 : -bbox.height / 2 - labelPadding / 2})`
   );
 
+  if (stylesMap.get('stroke')) {
+    iconElem.selectAll('path').attr('style', `fill: ${stylesMap.get('stroke')}`);
+  }
+
+  if (stylesMap.get('fill')) {
+    iconShape.selectAll('path').attr('style', `stroke: ${stylesMap.get('fill')}`);
+  }
+
   updateNodeBounds(node, outerShape);
 
   node.intersect = function (point) {
diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconSquare.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconSquare.ts
index cb465c031..163486768 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconSquare.ts
+++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconSquare.ts
@@ -27,8 +27,10 @@ export const iconSquare = async (
 
   const topLabel = node.pos === 't';
 
-  const height = iconSize + halfPadding * 2;
-  const width = iconSize + halfPadding * 2;
+  const padding = node.look === 'neo' ? halfPadding * 2 : halfPadding;
+
+  const height = iconSize + padding * 2;
+  const width = iconSize + padding * 2;
   const { nodeBorder, mainBkg } = themeVariables;
   const { stylesMap } = compileStyles(node);
 
@@ -59,9 +61,9 @@ export const iconSquare = async (
 
   const iconShape = shapeSvg.insert(() => iconNode, ':first-child');
   const outerShape = shapeSvg.insert(() => outerNode);
+  const iconElem = shapeSvg.append('g');
 
   if (node.icon) {
-    const iconElem = shapeSvg.append('g');
     iconElem.html(
       `${await getIconSVG(node.icon, { height: iconSize, fallbackPrefix: '' })}`
     );
@@ -72,9 +74,10 @@ export const iconSquare = async (
     const iconY = iconBBox.y;
     iconElem.attr(
       'transform',
-      `translate(${-iconWidth / 2 - iconX},${topLabel ? outerHeight / 2 - iconHeight - halfPadding - iconY : -outerHeight / 2 + halfPadding - iconY})`
+      `translate(${-iconWidth / 2 - iconX},${topLabel ? outerHeight / 2 - iconHeight - padding - iconY : -outerHeight / 2 + padding - iconY})`
     );
     iconElem.selectAll('path').attr('fill', stylesMap.get('stroke') || nodeBorder);
+    iconElem.attr('class', 'icon');
   }
 
   label.attr(
@@ -87,6 +90,14 @@ export const iconSquare = async (
     `translate(${0},${topLabel ? bbox.height / 2 + labelPadding / 2 : -bbox.height / 2 - labelPadding / 2})`
   );
 
+  if (stylesMap.get('stroke')) {
+    iconElem.selectAll('path').attr('style', `fill: ${stylesMap.get('stroke')}`);
+  }
+
+  if (stylesMap.get('fill')) {
+    iconShape.selectAll('path').attr('style', `stroke: ${stylesMap.get('fill')}`);
+  }
+
   updateNodeBounds(node, outerShape);
 
   node.intersect = function (point) {
diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/imageSquare.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/imageSquare.ts
index 551223ef4..0a9932f06 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/imageSquare.ts
+++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/imageSquare.ts
@@ -17,18 +17,22 @@ export const imageSquare = async (
 
   const imageNaturalWidth = Number(img.naturalWidth.toString().replace('px', ''));
   const imageNaturalHeight = Number(img.naturalHeight.toString().replace('px', ''));
+  node.imageAspectRatio = imageNaturalWidth / imageNaturalHeight;
 
   const { labelStyles } = styles2String(node);
 
   node.labelStyle = labelStyles;
 
   const defaultWidth = flowchart?.wrappingWidth;
+  node.defaultWidth = flowchart?.wrappingWidth;
 
   const imageWidth = Math.max(
     node.label ? (defaultWidth ?? 0) : 0,
     node?.assetWidth ?? imageNaturalWidth
   );
-  const imageHeight = node?.assetHeight ?? imageNaturalHeight;
+  const imageHeight = node.constrainedImage
+    ? imageWidth / node.imageAspectRatio
+    : (node?.assetHeight ?? imageNaturalHeight);
   node.width = Math.max(imageWidth, defaultWidth ?? 0);
   const { shapeSvg, bbox, label } = await labelHelper(parent, node, 'image-shape default');
 
diff --git a/packages/mermaid/src/rendering-util/types.ts b/packages/mermaid/src/rendering-util/types.ts
index 510e94b94..ff04af7b0 100644
--- a/packages/mermaid/src/rendering-util/types.ts
+++ b/packages/mermaid/src/rendering-util/types.ts
@@ -69,6 +69,9 @@ export interface Node {
   img?: string;
   assetWidth?: number;
   assetHeight?: number;
+  defaultWidth?: number;
+  imageAspectRatio?: number;
+  constrainedImage?: boolean;
 }
 
 // Common properties for any edge in the system
@@ -100,6 +103,7 @@ export interface Edge {
   pattern?: string;
   thickness?: 'normal' | 'thick' | 'invisible' | 'dotted';
   look?: string;
+  showPoints?: boolean;
 }
 
 export interface RectOptions {
diff --git a/packages/mermaid/src/schemas/config.schema.yaml b/packages/mermaid/src/schemas/config.schema.yaml
index d06f74948..d23aa3f78 100644
--- a/packages/mermaid/src/schemas/config.schema.yaml
+++ b/packages/mermaid/src/schemas/config.schema.yaml
@@ -2036,7 +2036,7 @@ $defs: # JSON Schema definition (maybe we should move these to a separate file)
         description: |
           Defines how mermaid renders curves for flowcharts.
         type: string
-        enum: ['basis', 'linear', 'cardinal','rounded']
+        enum: ['basis', 'linear', 'cardinal', 'rounded']
         default: 'rounded'
       edgeDebug:
         description: |
diff --git a/packages/mermaid/src/styles.ts b/packages/mermaid/src/styles.ts
index 10525a855..a90c737c7 100644
--- a/packages/mermaid/src/styles.ts
+++ b/packages/mermaid/src/styles.ts
@@ -115,6 +115,16 @@ const getStyles = (
     stroke-width: 1px;
   }
 
+  [data-look="neo"].icon-shape .icon path {
+    fill: ${options.useGradient ? 'url(' + svgId + '-gradient)' : options.nodeBorder};
+    filter: ${options.dropShadow};
+  }
+
+    [data-look="neo"].icon-shape path {
+    stroke: ${options.useGradient ? 'url(' + svgId + '-gradient)' : options.nodeBorder};
+    filter: ${options.dropShadow};
+  }
+
   ${userStyles}
 `;
 };
diff --git a/packages/mermaid/src/types.ts b/packages/mermaid/src/types.ts
index 7712dc231..67640325e 100644
--- a/packages/mermaid/src/types.ts
+++ b/packages/mermaid/src/types.ts
@@ -10,6 +10,7 @@ export interface NodeMetaData {
   img?: string;
   w?: string;
   h?: string;
+  constrainedImage?: boolean;
 }
 
 export interface Point {