@univerjs/icons is a set of icons designed for office software scenarios., it contains a series of icons and React components, you can use them in your React project.
# npm
npm install @univerjs/icons
# pnpm
pnpm add @univerjs/icons
# yarn
yarn add @univerjs/icons
Use icons just like render a React component:
import { SaveSingle } from '@univerjs/icons';
function App() {
return <SaveSingle />;
}
Because icons are React components, you can pass any SVGElement attributes to them, such as style:
function App() {
return <SaveSingle style={{ color: '#3526de', fontSize: '48px' }} />;
}
<SmileSingle style={{ color: '#3526de', fontSize: '48px' }} />
Instead of adding various props to the icons, we prefer to follow the existing behaviors on the web. This way, we can leverage solutions that people are familiar with and have already been tested.
- All icons have a height and width of 1em, so you can adjust the size of the icon by adjusting the fontSize.
- All monochrome icons can be adjusted in overall color using the color prop.
Additionally: We also provide some multi-colored icons, which have fixed colors.
<Loading style={{ fontSize: '48px' }} />
For some complex situations, such as adjusting the color of specific parts of an icon, we have added a color channel as a parameter for the component. Similar to monochrome icons, this requires prior communication with the designer to determine which parts should be controlled locally.
function App() {
return (
<>
<PaintBucket style={{ fontSize: '48px' }} extend={{ colorChannel1: 'red'}}/>
<PaintBucket style={{ fontSize: '48px' }} extend={{ colorChannel1: 'blue'}}/>
</>
)
}
The icon resources provided by the designer are placed in the svg folder at the root directory. They are organized into different subdirectories to distinguish their categories.
Please note that the names of the source files should be in kebab case, which means all lowercase with hyphens separating words.
We have established a pipeline using gulp to optimize the initial icon resources and generate corresponding React components based on these resources.
Optimizing SVG size: The SVG files submitted by designers are usually generated by editors such as Figma or Sketch, and they often contain a lot of unnecessary attributes (such as id) and non-optimized element properties. Rendering such SVG files directly would result in larger file sizes for icons. Therefore, we use SVGO to optimize the content of SVG files, reducing their size while maintaining rendering quality.
Standardizing icon properties: The original SVGs generally have dimensions that match the designer's canvas size, making them unsuitable for different usage scenarios with varying sizes. Additionally, colors are typically predetermined by designers and cannot be changed arbitrarily. In this step, we standardize attributes within SVG tags, such as width
, height
, strokeColor
, etc.
Generating icon components: Finally, we will generate a corresponding React component for each SVG source file.
interface IconProps extends React.SVGAttributes<SVGElement> {
/**
* The color of the icon.
*/
color?: string
/**
* The extend color of the icon.
*/
extend?: {
colorChannel1?: string
}
}
React component solution has outstanding advantages in the following two aspects:
On-demand usage. Some technical solutions, including SVG sprite and iconfont, will cause icons to be used on demand. This means that the icons packaged into the final resources are not actually used by you, but all the icons provided by the icon library. Although it is possible to generate a sprite or iconfont containing only the icons you use through some technical means, this process is quite cumbersome. In comparison, @univerjs/icons is a tree-shakable tool library where unused icons will not be included in the final output, and your bundler will automatically handle this process for you.
Rendering effect. Iconfonts appear blurry when zoomed in on webkit-based browsers, while SVGs do not blur because they are vector graphics. Additionally, since iconfonts are generally loaded asynchronously, there may be issues with delayed rendering of icons.
Runtime modification. Due to React components' dynamic nature, we can modify the rendering effects of icons at runtime.
The reason for not using base64 scheme is due to size: Base64 encoding method increases code size compared to its original form which does not seem like an elegant solution.