--- robots: noindex, nofollow tags: pitch --- # Icons project ### Problem - **bundle size** - Icons in theme create bloat as they are not tree-shakable. Currently we have over 190 icons that will be imported for Teams theme always. That means that even if a client uses only one icon, they will have in their bundle all icons defined in the Teams theme. - **type safety** - The icons are used currently via the `Icon` component, where tha name prop as a string defines which icon the user wants to render. As the icons are defined in the theme, we have no way of ensuring type safety on this prop, so if the name of the icon is misspelled or the icon was removed from the theme, we won't be able to catch possible regressions. - **custom props** - Sometimes some icons may need to support additional properties, which are not generic enough to be included in the Icon component, like `danger`, `brand` etc. For example the brand icons word, excel, powerpoint needs to support regular icon as well as brand icon, containing the brand colors. - **tightly coupling template & styles** - We are tightly coupling the icon's template and their styles inside the theme, which is wrong. The theme should only provide the theming of the components, not their template. - **performance & memory consumption** - Regarding the performance of the icons, at this moment there is a lot of room for improvement as on every icon render, we have to pick up the icon from the theme based on the name and than render it. Further more, from memory consumption, the caching of the icons contains the `name` in the key, as it is used on the styles, which means that for each different icon we will have new entry in the cache key. - **ability for using custom icon set** - Currently we are implicitly tying the users to use the icons that we have in the theme, as all styles are defined based on them. Adding different set of icons, will means changing the styles for all components that contains icon, which makes the composition really hard. ### Appetite Let's start from the bundle size. Following what other libraries do, icon per component is the best approach for this. This will allow us to easily remove big chunk of the theme object and bundle it as a separate package, where tree shaking can get rid of the not used icons. With this approach we will also be able to separate the template for the icon and the theme. Further more this will gain in 15% better performance on the svg icons. As each icon is a separate component, user's can extend the props API too. Lastly, if the users have different set of icons, they can use their own, or create Fluent like icons using a factory that we will provide. ### Solution - remove hard icon dependencies inside the Fluent components [done] - create a factory for generating icons [done] - migrate existing icons to component per icon [done] - update component's icon props and styles - create code-mods for easier update on client's side - create a new docs and an easy search icon experience + download package - investigate different options for svg icons [done] - create a factory for generating svg icons for v7 - create package for the v7 svg icons ### Risks (Rabbit holes) - Clients may have icons as part of their internal component's API and then they are just spreading the props on the Fluent components. This may require by-hand checking/changes of the icon prop. - Fabric's clients may want to go with font icons for the time being, which means that we will have to support two packages of utilities + icons ### Out of scope (No-gos) We are not going to provide a solution with this proposal for the font icons. We want to move towards svg icons for all office clients. More info on this decision can be fined here: https://hackmd.io/0_yGVz_AQjmn0aFbFgCadw