Our icon creation process, from ideation to implementation
Senior Software Developer, UX Engineering @ Air
They're an important part of almost any modern app
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.
Icons are carefully designed on our predefined grid
Requirements:
<svg viewBox="0 0 32 32">
<title>Search</title>
<path d="M24.5,ā¦11,5.5-5.25">
</svg>
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"],
ā¦
}
// 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',
}
Advantages:
// 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>
)
import Icon from '@air/icons'
<Icon name="Search" />
Ready to publish @air/icons
npm
organization name === monorepo namespace
@air/icons
version will use the local, symlinked package@air/icons
will be added remotely from npm
// package.json
"@air/icons": "^0.0.39"
// Append `/native`
import Icon from '@air/icons/native'
// Usage is the same as web
<Icon name="Search" />
ā @chrisnager