react-iconpack
==============
This project provides a way to utilize SVG icons in React-based projects with easy fallback to PNGs for browsers that don't have SVG support. It provides three pieces:
- A **Babel plugin**, to track which SVGs you're using in your codebase in order to bundle only those specific graphics. No more shipping assets that you don't even use.
- A **Browserify plugin** that handles the behind-the-scenes aspects of creating your icon library as a require()-able JS module and injecting it into your bundle. This plugin also handles injecting a lightweight React Component which can be utilized to reference graphics.
- A **Webpack plugin** that handles the behind-the-scenes aspects of creating your icon library and injecting it into your bundle. You get the same aforementioned React Icon component that's referenced above, too.
- The aforementioned **React Component**, which transparently handles mapping between SVG and IMG tags in various browsers. It's optimized to be fast, and comes with no external dependencies beyond React itself.
- _**Bonus:**_ react-iconpack ships with **over 1,000 ready to use SVG icons** from various different icon projects. Hit the ground running and avoid the tedious task of gathering all the assets you need.
Note
==============
The files in this repository are considered bleeding-edge at the moment. The version currently available on `npm` uses the instructions below; the new version (when released) will feature the Webpack plugin and potentially drop support for generating PNG assets.
The Webpack plugin currently works, but falls apart when caching builds (either via Webpack or Babel) is turned on. This is because I'm currently investigating the best way to integrate with existing cache solutions instead of rolling my own. If you'd like to help out, clone this repository and install the `devDependencies`, then check out the `webpack-test` folder. The `webpack.config.js` includes an example setup for Webpack integration.
In terms of caching, the only issue is that the Babel plugin can't be re-run on source code that's cached as already built. Where/how to store accrued SVG nodes becomes complex, and slightly dependent on the upstream cache. Would love to hear ideas from others!
Installation and Usage
==============
react-iconpack is currently delivered via npm; if there's some other module vendor system that people want to utilize open a pull request and I'll take a look at it.
npm install react-iconpack
Configuration is pretty straightforward - create an instance of IconPacker and supply the options you want. There are some sensible defaults which are highlighted below.
``` javascript
var IconPacker = require('react-iconpack');
var packer = new IconPacker({
// If you need more details about the packing process
verbose: false,
// An Array of JSX tags that you want this to catch - helpful
// for overriding.
JSXTagNames: ['Icon'],
// Which mode this is running in
mode: 'svg',
// Optional: You can provide your own SVG source directory here.
// IconPacker will then look here for any custom-supplied icons.
svgSourceDirectory: null,
// IconPacker uses svgo behind the scenes, and can pass your
// configuration directly to the SVGO constructor/instance.
svgo: {
plugins: [
{removeViewBox: false}, // We tend to need this kept around
{removeUselessStrokeAndFill: false}, // Can munge graphics
{removeEmptyAttrs: false}, // Can be useful to keep around
{removeDimensions: true} // Needed for PNGs to work properly
]
},
// When you're in PNG mode you can use this object to control
// various options in regards to how your PNG fallbacks are
// rendered. See the "PNG Mode" section below for more details.
png: {
antialias: true,
density: 1000, // Helps for creating crisp PNGs
width: 32, // A general width they'll all be exported to
quality: 90, // A hint to the PNG generator, 0 - 100
compressorQuality: [60, 80], // Optional PNGQuant quality range
background: 'rgba(0,0,0,0)', // Provides transparency
speed: 3, // PNGQuant again - value between 1 and 10
ie6fix: false // Supported by PNGQuant but you'll never need it
}
});
```
Now that you've got your packer set up, you'll need to enable two plugins in your build. First up is the Browserify plugin - this needs to come before the Babel plugin/transform.
``` javascript
// Your Browserify setup, whatever it is
var browserify = require('browserify'),
myBundler = browserify({'...': '...'});
myBundler.plugin(packer.BrowserifyInjector, {});
```
With that set, we just need to add the Babel plugin:
``` javascript
var babelify = require('babelify');
myBundler.transform(babelify.configure({
plugins: [packer.JSXSVGTracker]
}));
```
You're now good to go! These two plugins will talk to each other and handle creating an on-the-fly bundle of the icons you use. An example of your client-side (ES6) code might be:
``` javascript
import React from 'react';
import Icon from 'react-iconpack';
class IconShowcase extends React.Component {
render() {
return ;
}
}
```
To view the available default icons, your best bet is to clone this repo and scope out the _svgs_ folder yourself. When I have time I'll build a github pages site to preview them all or something. Polymer, Font-Awesome and a few others are all available.
The React Component
==============
The included React Component handles a lot of annoying stuff for you. The breakdown of supported properties is below:
```javascript
{
width: 0,
height: 0,
// The icon identifier to be specified.
uri: null,
// react-iconpack default icons come preconfigured with a viewBox
// so that you don't have to think about it, but if you ever need
// to, you can override it here.
viewBox: null,
// This is defaulted as I've found it helps scaling in some
// browsers. YMMV, so override as need be!
preserveAspectRatio: 'xMidYMid meet',
// Accessibility traits! This component will handle mapping between
// accessibility requirement differences between