--- robots: noindex, nofollow tags: pitch --- # Compose project ## Problem Fluent UI doesn't have a recipe for composing components. Customers don't have ability to add own design terms to existing components or reuse them to create product specific controls. ### Alert's case OOF and urgent are specific for Teams, but are valid design terms at the same time. Currently, there is no way to inject product specific design words. ![](https://i.imgur.com/HjrcOJa.png) Teams use `boolean` variables approach to extend component's style: ```jsx <Alert variables={{ isOff: true }} /> ``` ### Toolbar's case 1. Teams have a Unified Bar control which has completely different design tokens. 2. Toolbar component has well designed tokens to allow different styling. There is no way scecify these tokens for existing styles and Teams should use styles overrides: ##### Regular Toolbar ![](https://i.imgur.com/kLrR8Fd.png) ##### Ubar ![](https://i.imgur.com/Ab1InxL.png) ```javascript const toolbarStyles = ({ variables }) => ({ ...variables.isUbar && { // some styles } }) ``` ## Appetite Fluent Northstar now has ability to solve these issues via `compose()` function. Now it needs to be battle-tested. ### Break internal dependencies Fluent Northstar reuses other components internally, for example `Avatar` reuses `Image` and `Status`. It leads to two issues. #### Styles coupling - changes in `Status` styles will affect it also in `Avatar` - not all design terms are applicable, `Button` in `Dropdown` can not be circular Use `compose()` for existing controls to reduce styling dependencies via composition i.e. `Status` in `Avatar` will become `AvatarStatus`. #### Improve performance Fluent Northstar has an ability to cache styles, however it will not work in the case of inline overiddes (`styles`, `variables` props). Currently all styles are passed to component's slots via `styles` props, this breaks caching. ### Create a prototype for V7 Fluent Northstar contains `compose()`, but it should be also supported by V7. Find out the integration path. ### RFC: to figure out tokens approach Currently Fluent Northstar have separate tokens `ButtonContent`, `MenuItem` etc. What should be an approach there? Should we have tokens only for a root i.e. `Button` & `Menu`? ### RFC: to figure out slots story Currently there is no way to replace slots for composed components in Fluent Northstar. `Button` has a `content` slot represented by `ButtonContent`. Once `Button` will be composed it will become `PrimaryButton`, but still contain `ButtonContent` as a slot. ```jsx <Button> <ButtonContent /> </Button> <PrimaryButton> <ButtonContent /> {/* not way to replace it */} </PrimaryButton> ``` ### Solution - Dogfood `compose()` internally in Fluent Northstar on `Avatar` & `Attachment` components - Prototype `compose()` usage in V7 to find out what can be integration, use `Persona` component ### Risks (Rabbit holes) - Too many breaking changes for Fluent Northstar: - possible removal of props due restriction - styles & tokens will be rearenged ### Out of scope (No-gos) - The idea of `Base` components should be handled separately. - Other Northstar components should be converted to functional and use hooks to be able to use `compose` - Only few Fluent componets will be taken to prove, updates for other will be handled separately