Skip to content

Commit

Permalink
fix: n-icons now replace text without removing event handlers (#800)
Browse files Browse the repository at this point in the history
* Find and replace is working with plugin

* n-icons is almost working with plugin

* Updated height of SVG n-icon and added more notes

* Uninstalled old package

* Updated JS logic with better comments

* Removed old example

* Set homepage back to how it should be
  • Loading branch information
daylesalmon committed May 25, 2021
1 parent 224c6dd commit 546550f
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 45 deletions.
188 changes: 187 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
},
"dependencies": {
"@sentry/browser": "^6.2.5",
"findandreplacedomtext": "^0.4.6",
"gulp-sass": "^4.1.0",
"iframe-resizer": "^4.3.1",
"path": "^0.12.7"
Expand Down
8 changes: 5 additions & 3 deletions src/wmnds/assets/sass/_mixins.scss
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// This is a helper which will spit out the correct height/width for any svgs within a heading tag
// This is used to overwrite .wmnds-n-icon__svg class defaults in _n-icon.scss
@mixin n-icon-styling($height-and-font-size: 1rem) {
$width-multiplier: 0.9995467185761957; // If we times the height by this value we got the correct width for the n-icon svg
$height-multiplier: 1.04741812336749; // If we multiply the height by this value we got the correct width for the n-icon svg
$rescaled-font: $height-and-font-size * 0.75; // Multiply by 0.75 as the font height is is actually 1/4 smaller than

.wmnds-n-icon__svg {
width: calc(#{$height-and-font-size * $width-multiplier});
height: $height-and-font-size;
width: $rescaled-font;
height: calc(#{$rescaled-font * $height-multiplier});
//
}
}

Expand Down
61 changes: 25 additions & 36 deletions src/wmnds/components/icon/n-icon/_example.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,39 @@
import * as findAndReplaceDOMText from 'findandreplacedomtext'; // https://github.com/padolsey/findAndReplaceDOMText

const nIcons = () => {
// Function to replace text with our icon
const replaceTextWithIcon = (textNode, phraseToReplace) => {
if (!textNode.includes(phraseToReplace)) return textNode; // If textNode doesn't include our matched text, then return
// Convert a html string into an actual HTML node
const convertHtmlStringToNode = htmlString =>
document.createRange().createContextualFragment(htmlString).firstChild;

// Otherwise...
const textWithoutN = phraseToReplace.substring(1); // Chop the first character from our string (the 'n') as it will be replaced with an icon
const convertStringToNode = string => {
const textWithoutN = string.substring(1); // Chop the first character from our string (the 'n') as it will be replaced with an icon
// HTML/SVG of icon we will use
const svgIcon = `
<svg class="wmnds-n-icon__svg">
<title>N-Network icon</title>
<desc>A hexagon with the letter 'n' inside of it.</desc>
<use xlink:href="#wmnds-general-n-ticket" href="#wmnds-general-n-ticket"></use>
</svg>`;
<svg class="wmnds-n-icon__svg">
<title>N-Network icon</title>
<desc>A hexagon with the letter 'n' inside of it.</desc>
<use xlink:href="#wmnds-general-n-ticket" href="#wmnds-general-n-ticket"></use>
</svg>`;
// Then replace our found text with 'n' icon and text without 'n'
const modifiedTextNode = textNode.replace(
new RegExp(phraseToReplace, 'ig'),
`<span class="wmnds-n-icon">${svgIcon}${textWithoutN}</span>`
);
const htmlString = `<span class="wmnds-n-icon">${svgIcon}${textWithoutN}</span>`;

return modifiedTextNode; // Return modified textNode back
return convertHtmlStringToNode(htmlString);
};

function replacePhraseInHTML(htmlEle, phrase) {
const phraseToReplace = phrase;
const insideHTMLTags = new RegExp('(<.+?>|&\\w+;)'); // Get items within HTML </> tags
const textNodes = htmlEle.split(insideHTMLTags).filter(Boolean); // Split on the HTML tags to avoid manipulating attributes etc.

// Loop through textNodes and any that match 'insideHTMLTags', return straight away
// Otherwise, that textNode is ready to be searched for our textToChange
const updatedDOM = textNodes
.map(DOMText =>
insideHTMLTags.test(DOMText) ? DOMText : replaceTextWithIcon(DOMText, phraseToReplace)
)
.join('');
const replaceNText = () => {
const wordsToReplace = /(nNetwork|nTicket|nTrain|nBus)/; // Pipe in any words that we should replace the 'n' with the SVG 'n' icon (not case sensitive)
const bodyEle = document.querySelector('body');

return updatedDOM;
}
// Read https://github.com/padolsey/findAndReplaceDOMText on how this works
findAndReplaceDOMText(bodyEle, {
preset: 'prose',
find: new RegExp(wordsToReplace, 'gi'),
replace: (_portion, match) => convertStringToNode(match[0])
});
};

// START HERE
const bodyElement = document.querySelector('body');
const phrasesToReplace = ['nNetwork', 'nTicket', 'nTrain', 'nBus']; // These are the phrases we want to replace the first char with the 'n' icon SVG (they are not case sensitive - we match on upper and lowercase with regex 'i' on line 17)

// Loop through each phrase and update the DOM body innerHTML with the replaced phrase
phrasesToReplace.forEach(phraseToReplace => {
bodyElement.innerHTML = replacePhraseInHTML(bodyElement.innerHTML, phraseToReplace);
});
replaceNText();
};

export default nIcons;
12 changes: 8 additions & 4 deletions src/wmnds/components/icon/n-icon/_n-icon.scss
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
$base-height: 1rem;
$width-multiplier: 0.9995467185761957; // If we times the height by this value we got the correct width for the n-icon svg
// Part of this file is generated via n-icon-styling function in mixins. This is to ensure we get the right SVG height & width based on the parent font-size.
$base-width: 1rem * 0.75; // Multiply by 0.75 as the font height is is actually 1/4 smaller than
$height-multiplier: 1.04741812336749; // If we multiply the height by this value we got the correct width for the n-icon svg

.wmnds-n-icon {
display: inline-block;
font-size: inherit;
line-height: inherit;
text-decoration: inherit;
text-transform: capitalize;

&__svg {
display: inline-block;
width: calc($base-height * #{$width-multiplier});
height: $base-height;
width: $base-width;
height: calc(#{$base-width} * #{$height-multiplier});
fill: currentColor;
vertical-align: revert;
}
Expand Down
2 changes: 1 addition & 1 deletion src/www/wmnds-website.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ const icons = () => {
window.addEventListener(
'DOMContentLoaded',
(polyfills,
nIcons(), // Make sure this runs first as it breaks event listeners via innerHTML method, TODO: Update this function so it focuses on classes rather than the whole DOM body
icons(),
nIcons(),
aToZContentStyleGuide(),
colorPalettes(),
headerJs(),
Expand Down

0 comments on commit 546550f

Please sign in to comment.