-
-
Notifications
You must be signed in to change notification settings - Fork 7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor fontawesome icon usage. #6282
base: develop
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: 2fb7bc2 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
✅ Deploy Preview for mermaid-js ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
commit: |
Note: Some e2e tests are failing as they were using fontawesome icon in them but the test file was not importing fontawesome cdn |
…saurabh/refactor-fontawesome-icon-usage
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work! This will make me very happy in the mermaid-cli
project too!
As far as I can tell, your code and approach looks great to me! But I think we need some work before we can merge this.
I think we need to do the following before we merge this PR:
- E2E tests! Can you write some visual regression tests that work before and after this feature so we can see if there are any visual anomalies? You might want to try various themes too, to make sure the icon colors are still the same as they are currently.
- Documentation updates:
- I think you forgot to update your PR description and changeset for a81c318
- You're not updating mindmaps in this PR. I think this is fine, as long as it's in the PR description, changeset, and docs.
- Please update the documentation for FontAwesome in https://mermaid.js.org too
const iconRegex = /(fas|fab|far|fa|fal|fak|fad):fa-([a-z-]+)/g; | ||
const classNameMap = { | ||
fas: 'fa-solid', | ||
fab: 'fa-brands', | ||
far: 'fa-regular', | ||
fa: 'fa', | ||
fal: 'fa-light', | ||
fad: 'fa-duotone', | ||
fak: 'fak', | ||
} as const; | ||
const matches = [...text.matchAll(iconRegex)]; | ||
if (matches.length === 0) { | ||
return text; | ||
} | ||
|
||
let newText = text; | ||
|
||
for (const match of matches) { | ||
const [fullMatch, prefix, iconName] = match; | ||
const className = classNameMap[prefix]; | ||
const registeredIconName = `${prefix}:${iconName}`; | ||
|
||
try { | ||
const isFreeIcon = await isIconAvailable(registeredIconName); | ||
if (!isFreeIcon) { | ||
log.warn(`Icon ${registeredIconName} is a pro icon.`); | ||
newText = newText.replace(fullMatch, `<i class='${className} fa-${iconName}'></i>`); | ||
continue; | ||
} | ||
const faIcon = await getIconSVG(registeredIconName, undefined, { class: 'label-icon' }); | ||
if (faIcon) { | ||
newText = newText.replace(fullMatch, faIcon); | ||
} | ||
} catch (error) { | ||
log.error(`Error processing ${registeredIconName}:`, error); | ||
} | ||
} | ||
return newText; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue(blocking): I'm not sure why we still need the free/pro difference, or the different class names. Can we change this function to output the exact same thing if users haven't set an icon pack?
suggestion: Maybe something like the following (we should probably also update the function TSDoc comment too):
const iconRegex = /(fas|fab|far|fa|fal|fak|fad):fa-([a-z-]+)/g; | |
const classNameMap = { | |
fas: 'fa-solid', | |
fab: 'fa-brands', | |
far: 'fa-regular', | |
fa: 'fa', | |
fal: 'fa-light', | |
fad: 'fa-duotone', | |
fak: 'fak', | |
} as const; | |
const matches = [...text.matchAll(iconRegex)]; | |
if (matches.length === 0) { | |
return text; | |
} | |
let newText = text; | |
for (const match of matches) { | |
const [fullMatch, prefix, iconName] = match; | |
const className = classNameMap[prefix]; | |
const registeredIconName = `${prefix}:${iconName}`; | |
try { | |
const isFreeIcon = await isIconAvailable(registeredIconName); | |
if (!isFreeIcon) { | |
log.warn(`Icon ${registeredIconName} is a pro icon.`); | |
newText = newText.replace(fullMatch, `<i class='${className} fa-${iconName}'></i>`); | |
continue; | |
} | |
const faIcon = await getIconSVG(registeredIconName, undefined, { class: 'label-icon' }); | |
if (faIcon) { | |
newText = newText.replace(fullMatch, faIcon); | |
} | |
} catch (error) { | |
log.error(`Error processing ${registeredIconName}:`, error); | |
} | |
} | |
return newText; | |
// The letters 'bklrs' stand for possible endings of the fontawesome prefix (e.g. 'fab' for brands, 'fak' for fa-kit) // cspell: disable-line | |
return text.replace( | |
/(fa[bklrs]?):fa-([\w-]+)/g, // cspell: disable-line | |
(fullMatch, prefix, iconName) => { | |
const registeredIconName = `${prefix}:${iconName}`; | |
if (await isIconAvailable(registeredIconName)) { | |
return await getIconSVG(registeredIconName, undefined, { class: 'label-icon' }); | |
} else { | |
// fall back to FontAwesome CSS | |
return `<i class='${s.replace(':', ' ')}'></i>`; | |
} | |
}, | |
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will update regex but as of the text.replace() does not take async call back so we will have to update with other way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, that makes sense! Good catch.
The next question is, can we write it in such a way that uses Promise.all()
to download these icon packets in parallel? (although maybe it's overkill to write the code like that, since it will only result in a performance improvement if you're using multiple icon packs in the same node label).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 2fb7bc2
const expected = | ||
"This is an icon: <i class='fa fa-user'></i> and <i class='fab fa-github'></i>"; | ||
const output = await replaceIconSubstring(input); | ||
const expected = `This is an icon: <i class='fa fa-user'></i> and <i class='fa-brands fa-github'></i>`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question(blocking): Why has the class changed from fab
to fa-brands
and is this a breaking change? Do we need to put this info in the PR description and changeset entry?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 16573d9
pnpm-lock.yaml
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion(non-blocking but recommended): I think you can revert these changes, since it looks like these pnpm-lock.yaml
are not needed for your PR, but will just increase the risk of merge conflicts by a lot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated in 83a6e69
…saurabh/refactor-fontawesome-icon-usage
…mermaid:mermaid-js/mermaid into saurabh/refactor-fontawesome-icon-usage
📑 Summary
<i>
tagSee mermaid-js/mermaid-cli#474
📏 Design Decisions
When text contains a FontAwesome icon reference:
<i>
tag with icon classUpdate to styles.
path
elements insidenode
class. Now we are overriding this style to havefill: currentColor
also reverting stroke and stroke-width to default📋 Tasks
Make sure you
MERMAID_RELEASE_VERSION
is used for all new features.pnpm changeset
and following the prompts. Changesets that add features should beminor
and those that fix bugs should bepatch
. Please prefix changeset messages withfeat:
,fix:
, orchore:
.