Skip to content
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

feat: The phrases nNetwork, nTicket, nTrain and nBus now show the 'n' as an SVG icon #782

Merged
merged 10 commits into from
May 19, 2021
41 changes: 35 additions & 6 deletions src/wmnds/assets/sass/_mixins.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
// 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-mulitplier: 0.9995467185761957; // If we times the height by this value we got the correct width for the n-icon svg

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

// TYPE
// This is to get the size of the font to be used,
// and to scale the line heights based on the font size
Expand All @@ -6,43 +17,61 @@

// Default (16px)
@if $level == 0 {
font-size: 1rem;
$height-and-font-size: 1rem;
font-size: $height-and-font-size;
line-height: 1.5rem;

@include n-icon-styling($height-and-font-size);
}
// Heading 1 (46px)
@if $level == 1 {
$height-and-font-size: 2.875rem * $multiplier;
margin-top: 3rem * $multiplier;
margin-bottom: 2rem * $multiplier;
font-size: 2.875rem * $multiplier;
font-size: $height-and-font-size;
line-height: 3rem * $multiplier;

@include n-icon-styling($height-and-font-size);
}
// Heading 2 (32px)
@if $level == 2 {
$height-and-font-size: 2rem * $multiplier;
margin-top: 3rem * $multiplier;
margin-bottom: 1rem * $multiplier;
font-size: 2rem * $multiplier;
font-size: $height-and-font-size;
line-height: 2.225rem * $multiplier;

@include n-icon-styling($height-and-font-size);
}
// Heading 3 (23px)
@if $level == 3 {
$height-and-font-size: 1.4375rem * $multiplier;
margin-top: 2rem * $multiplier;
margin-bottom: 0.75rem * $multiplier;
font-size: 1.4375rem * $multiplier;
font-size: $height-and-font-size;
line-height: 1.5rem * $multiplier;

@include n-icon-styling($height-and-font-size);
}
// Heading 4 (18px)
@if $level == 4 {
$height-and-font-size: 1.125rem * $multiplier;
margin-top: 1.5rem * $multiplier;
margin-bottom: 0.5rem * $multiplier;
font-size: 1.125rem * $multiplier;
font-size: $height-and-font-size;
line-height: 1.5rem * $multiplier;

@include n-icon-styling($height-and-font-size);
}
// Heading 5 (16px)
@if $level == 5 {
$height-and-font-size: 1rem * $multiplier;
margin-top: 1.5rem * $multiplier;
margin-bottom: 0.5rem * $multiplier;
font-size: 1rem * $multiplier;
font-size: $height-and-font-size;
line-height: 1.5rem * $multiplier;

@include n-icon-styling($height-and-font-size);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/wmnds/components/_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
@import "in-text-step/in-text-step"; // In-text step
@import "link/link"; // Link elements
@import "loader/loader"; // Loader
@import "icon/n-icon/n-icon"; // Styles for n-icon text replacement
@import "message/message"; // Messages
@import "phase-indicator/phase-indicator"; // Phase indicator
@import "table/table"; // Table
Expand Down
50 changes: 50 additions & 0 deletions src/wmnds/components/icon/n-icon/_example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
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

// Otherwise...
const textWithoutN = phraseToReplace.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>`;
// 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>`
);

return modifiedTextNode; // Return modified textNode back
};

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('');

return updatedDOM;
}

// 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);
});
};

export default nIcons;
15 changes: 15 additions & 0 deletions src/wmnds/components/icon/n-icon/_n-icon.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
$base-height: 1rem;
$width-mulitplier: 0.9995467185761957; // If we times the height by this value we got the correct width for the n-icon svg

.wmnds-n-icon {
font-size: inherit;
line-height: inherit;

&__svg {
display: inline-block;
width: calc($base-height * #{$width-mulitplier});
height: $base-height;
fill: currentColor;
vertical-align: revert;
}
}
2 changes: 2 additions & 0 deletions src/www/wmnds-website.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import accordionsJS from '../wmnds/components/accordion/_example';
import travelUpdatesWidgetJs from '../wmnds/patterns/travel-updates/_example';
import searchFilterJs from '../wmnds/patterns/search/search-filter/_example';
import feedbackLoopsJS from '../wmnds/patterns/feedback-loop/_example';
import nIcons from '../wmnds/components/icon/n-icon/_example';

import { componentExample, componentExampleIframe } from './_partials/component-example';

Expand All @@ -35,6 +36,7 @@ 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(),
aToZContentStyleGuide(),
colorPalettes(),
Expand Down