Lifecycle of an icon

Our icon creation process, from ideation to implementation

Chris Nager

Senior Software Developer, UX Engineering @ Air

Everyone needs icons

They're an important part of almost any modern app

Gmail desktop
Twitter mobile
Spotify iOS
Air iOS

Problems

  1. Hand-off between design and dev teams can be slow
  2. Duplication across teams or folders with multiple usage patterns
  3. Not a cohesively themed set

Goals

  1. Fast design hand-off āš”ļø
  2. Identical usage and display across platforms šŸ‘Æā€ā™€ļø
  3. Synchronized icon system across teams šŸŒ

Spans many teams

  • Product (need)
  • Design (interpretation, ideation)
  • UX Eng (creation, documentation, publication)
  • Web (implementation)
  • Mobile (implementation)

Our solution

We created a theme-able icon system that is simple to update with live documentation that lives in a single spot and used the same across all our platforms.

āš”ļø

Fast design hand-off

  1. Illustrator





Illustrator

Icons are carefully designed on our predefined grid

Requirements:

  • 32 x 32 bounding box
  • 2-unit wide margin on all sides
  • Stroke-based
  • Theme-able by line weights, line joins, and colors
  • Single, compound shape
  • Visually cohesive family of icons
Icon design grid

āš”ļø

Fast design hand-off

  1. Illustrator
  2. SVG




SVG


Search
<svg viewBox="0 0 32 32">
  <title>Search</title>
  <path d="M24.5,ā€¦11,5.5-5.25">
</svg>

āš”ļø

Fast design hand-off

  1. Illustrator
  2. SVG
  3. Zephyr theming tool



Zephyr icon theming

āš”ļø

Fast design hand-off

  1. Illustrator
  2. SVG
  3. Zephyr theming tool



šŸ‘Æā€ā™€ļø

Identical usage & display across platforms

  1. Monorepo (Yarn Workspaces)





Monorepo (Yarn Workspaces)

All icons are in a single @air/icons package inside our monorepo

// packages/icons/package.json
{
  "name": "@air/icons",
  "version": "0.0.39",
  "main": "dist/index.js",
  "files": ["dist", "native"],
  ā€¦
}

šŸ‘Æā€ā™€ļø

Identical usage & display across platforms

  1. Monorepo (Yarn Workspaces)
  2. TypeScript (+ JSDoc)




TypeScript

// Icons.ts
export type IconName =
  | ā€¦
  | 'Search'
  | 'Tag'

const Icons: { [key in IconName]: string } = {
  ā€¦
  Search: 'M24.5,ā€¦11,5.5-5.25',
  Tag: 'M25,30H7V11lā€¦0,1,1.29',
}

Why TypeScript?

Advantages:

  • Helpful type checking of props
  • IntelliSense code completion

TypeScript + VS Code IntelliSense

Screenshot of code example of `IconName` and `Icon`

šŸ‘Æā€ā™€ļø

Identical usage & display across platforms

  1. Monorepo (Yarn Workspaces)
  2. TypeScript (+ JSDoc)
  3. React (with Hooks!)



// packages/icons/src/index.tsx (simplified)
export interface IconProps {
  name?: IconName;
  title?: string;
  d?: string;
}

const Icon = ({
  name = 'Info',
  title = name,
  d = Icons[name],
}: Partial<IconProps>) => (
  <Svg {...{ title }}>
    <Path {...{ d }} />
  </Svg>
)

Usage

import Icon from '@air/icons'
<Icon name="Search" />

šŸ‘Æā€ā™€ļø

Identical usage & display across platforms

  1. Monorepo (Yarn Workspaces)
  2. TypeScript (+ JSDoc)
  3. React (with Hooks!)
  4. Jest


Jest snapshot tests for our Icon component

šŸ‘Æā€ā™€ļø

Identical usage & display across platforms

  1. Monorepo (Yarn Workspaces)
  2. TypeScript
  3. React (with Hooks!)
  4. Jest
  5. Accessibility

šŸŒ

Synchronized icon system across teams

  1. Zephyr design system (docz, MDX)





Zephyr

Zephyr colors
Zephyr icons

Built on docz with MDX


šŸŒ

Synchronized icon system across teams

  1. Zephyr (docz, MDX)
  2. npm




npm

Ready to publish @air/icons

npm repository

@air

npm organization name === monorepo namespace


  • Within our monorepo, the latest @air/icons version will use the local, symlinked package
  • If a previous version is referenced, @air/icons will be added remotely from npm

šŸŒ

Synchronized icon system across teams

  1. Zephyr (docz, MDX)
  2. npm
  3. iOS (React Native)



iOS (React Native)

// package.json
"@air/icons": "^0.0.39"
// Append `/native`
import Icon from '@air/icons/native'
// Usage is the same as web
<Icon name="Search" />

šŸŒ

Synchronized icon system across teams

  1. Zephyr (docz, MDX)
  2. npm
  3. iOS (React Native)
  4. Future platforms
  5. Github projects

Github projects

"Icon proposals" Github project

Achievements

  1. Quickly get optimized icon SVG paths from design team āš”ļø
  2. Icons are fully tested and usage is identical across all supported app platforms šŸ‘Æā€ā™€ļø
  3. Icon system lives in a shared, versioned package and is live-documented to keep teams in sync šŸŒ

Demo

Party parrot

Thank you

ā€” @chrisnager