diff --git a/.changeset/proud-seahorses-wash.md b/.changeset/proud-seahorses-wash.md index 3384f28e9..8b844b679 100644 --- a/.changeset/proud-seahorses-wash.md +++ b/.changeset/proud-seahorses-wash.md @@ -2,4 +2,4 @@ 'mermaid': patch --- -Registered icons are now embedded as SVGs inside diagram. If an icon is not available in the registered icons it will still use tag +FontAwesome icons can now be embedded as SVGs in flowcharts if they are registered via `mermaid.registerIconPacks`. diff --git a/cypress/platform/e2e.html b/cypress/platform/e2e.html index 7418da094..f6f6e783b 100644 --- a/cypress/platform/e2e.html +++ b/cypress/platform/e2e.html @@ -18,6 +18,9 @@ .exClass { fill: greenyellow !important; } + .label-icon { + border: none; + } diff --git a/docs/syntax/flowchart.md b/docs/syntax/flowchart.md index a7b9738d9..5bf0b9638 100644 --- a/docs/syntax/flowchart.md +++ b/docs/syntax/flowchart.md @@ -1916,13 +1916,9 @@ If a class is named default it will be assigned to all classes without specific ## Basic support for fontawesome -It is possible to add icons from fontawesome and registered icon pack. +It is possible to add icons from fontawesome. -Mermaid supports icons from registered icon packs. Follow the instructions provided [here](../config/icons.md) to register your icon packs. - -The registered icons can be accessed via the syntax #registered icon pack name#:#icon name#. - -The fontawesome icons are accessed via the syntax fa:#icon class name#. +The icons are accessed via the syntax fa:#icon class name#. ```mermaid-example flowchart TD @@ -1940,6 +1936,17 @@ flowchart TD B-->E(A fa:fa-camera-retro perhaps?) ``` +There are two ways to display these FontAwesome icons: + +### Register FontAwesome icon packs (v11.4.2+) + +You can register your own FontAwesome icon pack, to register follow the instructions provided [here](../config/icons.md). + +> **Note** +> Note that it will fall back to FontAwesome CSS if FontAwesome packs are not registered. + +### Register FontAwesome CSS + Mermaid supports Font Awesome if the CSS is included on the website. Mermaid does not have any restriction on the version of Font Awesome that can be used. diff --git a/packages/mermaid/src/docs/syntax/flowchart.md b/packages/mermaid/src/docs/syntax/flowchart.md index 0ee5f39d6..b54dcce45 100644 --- a/packages/mermaid/src/docs/syntax/flowchart.md +++ b/packages/mermaid/src/docs/syntax/flowchart.md @@ -1231,13 +1231,9 @@ If a class is named default it will be assigned to all classes without specific ## Basic support for fontawesome -It is possible to add icons from fontawesome and registered icon pack. +It is possible to add icons from fontawesome. -Mermaid supports icons from registered icon packs. Follow the instructions provided [here](../config/icons.md) to register your icon packs. - -The registered icons can be accessed via the syntax #registered icon pack name#:#icon name#. - -The fontawesome icons are accessed via the syntax fa:#icon class name#. +The icons are accessed via the syntax fa:#icon class name#. ```mermaid-example flowchart TD @@ -1247,6 +1243,18 @@ flowchart TD B-->E(A fa:fa-camera-retro perhaps?) ``` +There are two ways to display these FontAwesome icons: + +### Register FontAwesome icon packs (v11.4.2+) + +You can register your own FontAwesome icon pack, to register follow the instructions provided [here](../config/icons.md). + +```note +Note that it will fall back to FontAwesome CSS if FontAwesome packs are not registered. +``` + +### Register FontAwesome CSS + Mermaid supports Font Awesome if the CSS is included on the website. Mermaid does not have any restriction on the version of Font Awesome that can be used. diff --git a/packages/mermaid/src/rendering-util/createText.ts b/packages/mermaid/src/rendering-util/createText.ts index 5c1b210e6..fec3a077f 100644 --- a/packages/mermaid/src/rendering-util/createText.ts +++ b/packages/mermaid/src/rendering-util/createText.ts @@ -184,34 +184,25 @@ function updateTextContentAndStyles(tspan: any, wrappedLine: MarkdownWord[]) { * @returns string with fontawesome icons as svg if the icon is registered otherwise as i tags */ export async function replaceIconSubstring(text: string) { - // The letters 'bklrs' stand for possible endings of the fontawesome prefix (e.g. 'fab' for brands, 'fak' for fa-kit) // cspell: disable-line - const iconRegex = /(fa[bklrs]?):fa-([\w-]+)/g; // cspell: disable-line + const pendingReplacements: Promise[] = []; + // cspell: disable-next-line + text.replace(/(fa[bklrs]?):fa-([\w-]+)/g, (fullMatch, prefix, iconName) => { + pendingReplacements.push( + (async () => { + const registeredIconName = `${prefix}:${iconName}`; + if (await isIconAvailable(registeredIconName)) { + return await getIconSVG(registeredIconName, undefined, { class: 'label-icon' }); + } else { + return ``; + } + })() + ); + return fullMatch; + }); - const matches = [...text.matchAll(iconRegex)]; - if (matches.length === 0) { - return text; - } - - const replacements = await Promise.all( - matches.map(async ([fullMatch, prefix, iconName]) => { - const registeredIconName = `${prefix}:${iconName}`; - try { - const isIconRegistered = await isIconAvailable(registeredIconName); - const replacement = isIconRegistered - ? await getIconSVG(registeredIconName, undefined, { class: 'label-icon' }) - : ``; - return { fullMatch, replacement }; - } catch (error) { - log.error(`Error processing ${registeredIconName}:`, error); - return { fullMatch, replacement: fullMatch }; - } - }) - ); - - return replacements.reduce( - (text, { fullMatch, replacement }) => text.replace(fullMatch, replacement), - text - ); + const replacements = await Promise.all(pendingReplacements); + // cspell: disable-next-line + return text.replace(/(fa[bklrs]?):fa-([\w-]+)/g, () => replacements.shift() ?? ''); } // Note when using from flowcharts converting the API isNode means classes should be set accordingly. When using htmlLabels => to sett classes to'nodeLabel' when isNode=true otherwise 'edgeLabel'