In this article, we’re going to use what we’ve learned in previous articles of the series to build something awesome using Google’s Material Design Icon collection. We will create a tool to automatically create an icon Library using the 10,000+ icons included in the collection, ready to distribute to the Monday Studio designers.
You’ve probably been there before — a pile of assets you need to turn into a Library. You import some of them into your document, organize them neatly into a grid, rinse, and repeat. Just thinking about it gives you a headache. Automating this process will free your mind to think about the important things you need to do with these icons, once they’re ready to use.
Repetitive work — while good for improving some skills — is a morale killer. You want your team happy and motivated, not pushing pixels around mindlessly. And it takes time, too — time your team could be doing more important work. Automating this task literally pays for itself the minute you start using the tool.
Building this kind of automation will teach you the basis for more ambitious work. You don’t need to stop here — you can integrate Sketch into many of your existing workflows by adding some glue and translation layers to connect your different systems.
What we’ll build
We’re splitting the work we’ll do in this project into three steps:
- Read and parse SVG data into something we can use in JavaScript.
- Translate that data into something Sketch understands.
- Store the data in a
.sketch
document using the file format tooling we’ve used in previous articles in this series.
We’ll use a few existing node libraries and tools. That’ll keep the amount of wheel-reinventing to a reasonable minimum.
What you’ll need
To follow along, you’ll need to be fairly familiar with TypeScript, and have a reasonably recent version of node
installed. And for this article, some familiarity with JavaScript is useful. For code editing, we recommend Visual Studio Code. You don’t need Sketch or a Mac — you can run the sample code on any operating system.
These are the building blocks we’re going to use for our project:
- svgson — a tool that converts SVG into JavaScript objects. We’ll use it for the first stage.
- svg-points — which turns SVG points to paths, and vice-versa. Will be useful for the second stage.
- @sketch-hq/sketch-file-format-ts — which will make it easy — and enjoyable — to create Sketch files from TypeScript for the third stage.
Along with the building blocks, we will need to write some glue code and a minimal translator to translate the SVG code used in Material Design Icons into Sketch objects.
We’ve included all the code for the project in this GitHub repository. We’ll go over the more interesting parts here, and you can refer to the GitHub repository to read the actual code in all its glory.
Let’s go!
Sourcing and generating our Sketch Library from scratch
If you take a look in the src
folder, you’ll see we’ve split the code into three modules:
sketch-svg
— transforms SVG data into Sketch objectssketch-blocks
— a collection of helpers which makes it easier for us to create those Sketch objectsto-file
— takes care of storing data in a file that Sketch can open
src/index.ts
combines all of these, and that means we can:
Read SVG files from disk
const files = glob.sync('assets/material-design-icons/src/**/**/**/*.svg')
files.forEach((file, index) => {
const svgData = fs.readFileSync(file, { encoding: 'utf8', flag: 'r' })
...
})
Parse SVG code into a JavaScript object
Using svgson
we can turn SVG data into an object that we can easily use in JavaScript. The parseSync
function does all the magic:
const json = parseSync(svgData)
Once the SVG data is converted into an AST, we can access its attributes like regular JavaScript objects:
const width: number = parseFloat(json.attributes.width) || 100
const height: number = parseFloat(json.attributes.height) || 100
It also allows us to traverse the nodes in the SVG document using idiomatic JavaScript code:
json.children.forEach((child, index) => {
symbolMaster.layers.push(s2v.parse(child, index))
})
Create Sketch objects to hold data
For each SVG file, we will create a SymbolMaster
object that will hold the icon in our Sketch document.
If you use Visual Code Studio to edit your code, TypeScript will help you autocomplete all the required attributes for a Sketch object.
Typing all that information every time is pretty boring, so we added a few helpers in sketch-blocks
to make our life easier:
var symbolMaster: FileFormat.SymbolMaster = sketchBlocks.emptySymbolMaster(...)
Translating the SVG data into valid Sketch objects required some trial and error (especially when it came to path point coordinates).
{200,150}
on a layer that’s 400 × 150 pixels, you’d set its coordinates to {0.5,1}
in Sketch.
To keep things as simple as possible, some of the more complex features in SVG (like matrix transformations) our proof of concept project does not support some of the more. You may see a couple of icons here that are not looking perfect, but most of them should look good.
Saving the Sketch document
Once we have our data ready, we need to save it in a format Sketch can open. For that, the to-file
module provides us with a very straightforward method: toFile(contents, path)
To get an idea of what contents
needs to look like, check the saveFile
function in the main index.ts
file.
Testing our work
There’s an Action in the repo that runs yarn start
after each commit, and stores the resulting asset as an artifact you can download from the ‘Actions’ tab on GitHub. If you want to learn more about Actions, we’ll be covering that in our next article in the series.
Wrap up
You now know how to automate the creation of an icon Library. You can use this knowledge for other automations such as dynamically generating shapes from external data sources, or writing an importer for a format Sketch does not directly support.
If you want to keep exploring, see if you can extend the code to implement more SVG features. Or try publishing the Library on a public web page (maybe using GitHub Pages), with an RSS feed to receive automatic updates in Sketch.
In the next article, we’ll see in more detail how we can use GitHub Actions to run all these automations for us, without having to intervene at all.