Iggy codes

How to add new SVGs in Salesforce Lightning Design System

September 07, 2020

Design Systems are great. (Yes, they are!). They allow us (devs) to develop, and test components right away, showcase them to clients, modify the behaviour on the fly, etc. However, Salesforce Lightning Design System is quite tricky to work with. You need to deep dive into their code to understand how they have implemented it.

I am pretty sure, that if you are a frontend dev, you will mostly work with some UX guys. And probably they will reach out to you because they have designed a new set of icons that align with the client style and not with the default Salesforce stuff. Adding new svgs/icons shouldn’t be too hard and yet, you need to tweak SLDS codebase in order to add your icons.

Let’s… Dive… In…

Gulp

As SLDS internally uses gulp to automate most of the tasks (such as the assets generation task) we will have to create a new one for generating our svgs.

Firstly, create a pair of new folders under the assets one.

cd assets
mkdir my-svgs-sprite
cd my-svgs-sprite
mkdir svg

Now, there is a gulp package that will help us with the svg sprite generation. That package is the gulp-svg-sprite. Install this one with the following :

npm install --save-dev gulp-svg-sprite

Please note that we install the package as a dev dependency and not as a direct dependency.

Awesome. So now that we have everything installed we should create a script under the /scripts/gulp/generate folder that include new gulp tasks (this will generate the symbols and the svgs for production). I called this one svgs.js (SUPER original…)

import  gulp  from  'gulp';
import  path  from  'path';
import  svgSprite  from  'gulp-svg-sprite';
import  paths  from  '../../helpers/paths';

const  distPath  =  path.resolve.bind(path, paths.dist);
// npm run gulp -- generate:spriteSheet
/* Generate the sprite svg */
const  spriteSheetConfig  = {
  mode: {
    symbol: {
      dest:  './svg',
      sprite:  "symbols.svg"
    }
  }
};

export const generateSpriteSheet = () => 
  gulp.src('assets/my-svgs-sprite/svg/*.svg')
      .pipe(svgSprite(spriteSheetConfig))
      .pipe(gulp.dest(distPath('assets/icons/my-svgs-sprite')));

export const generateSvgs  = () =>
  gulp.src('assets/my-svgs-sprite/svg/*.svg')
      .pipe(gulp.dest(distPath('assets/icons/my-svgs'))); 

The first function will generate the symbols svg file in the distPath (‘assets/icons/my-svgs-sprites’). The second one will copy the svgs icons from the assets folder we had created into the specified dist folder.

Let’s include those new tasks in the gulpfile…

//... other imports
import  *  as  svgSpriteSheet  from  './scripts/gulp/generate/svgs';
// ...
gulp.task('generate:spriteSheet', svgSpriteSheet.generateSpriteSheet);
gulp.task('generate:svgs', svgSpriteSheet.generateSvgs);

… and add a script in the package.json.

"build-svgs": "npm run gulp -- generate:svgs && npm run gulp -- generate:spriteSheet",

Finally, modify storybook’s Webpack config…

new  CopyWebpackPlugin([
//....
,{
   from:  path.resolve(paths.dist, 'assets/icons/my-svgs-sprite'),
   to:  'assets/icons/my-svgs-sprite'
},
{
   from:  path.resolve(paths.dist, 'assets/icons/my-svgs'),
   to:  'assets/icons/my-svgs-sprite/svg'
}
])
//...

…and voilà! Now you are able to use those svg icons within SLDS.

After spending time digging into the SLDS code, I started to think this process could actually be extracted. We could technically build a service that does all this work for us, then return a file. That would be a helpful tool (right?).


Iggy Pops - Ignacio Garcia Villanueva

Written by Iggy Pops - Ignacio Garcia Villanueva , a javascript journeyman rocking his way to the top of the JS world. You should follow him on Twitter... he is good!