# Fluent UI Roadmap: v8, v9, and beyond :::warning :warning: Disclaimer: This is a work in progress. ::: **Please remember to add notes about any breaking changes (or other notable changes) to the [draft release notes]( https://github.com/microsoft/fluentui/blob/master/packages/react-next/RELEASE_NOTES.md).** [toc] ## Tasks/requirements for v8 - [ ] Compose utility is final - [ ] Reviewed with partners - [ ] Used in product - [ ] Function component conversions - [ ] [Elizabeth] `Need Link to what's in scope for v8 regarding function component conversions` - [ ] [David] `[Needs more figurin' out]` ThemeProvider and useTheme exported, can provide the v8 theme - [ ] Documentation for customers complete - [ ] Implement design tokens proposed by design and reviewed by team - [ ] ThemeProvider can accept v0 theme (through) - [ ] ThemeProvider can accept v7 theme - [ ] ThemeProvider can accept v8 theme - [ ] How do styles get injected (merge-styles, css, fela, emotion,?) - [ ] Button (and it's variants) are the new default button - [ ] Styles should work with IE11 - [ ] If we do not have time to get IE11 polyfill in place, we could fallback to having load-themed-styles replace css variables. - [ ] Props have a spec that has been reviewed - [x] is a function component built with compose so that it can be extended - [x] has a base implementation and an extended version with styling - [ ] logic extracted into hook(s) - [ ] has Design/Code tokens (reviewed by team, used in product) - [ ] Tabs (new Pivot work) - [ ] `[TBD not final]` Composed components (Slider, Checkbox, etc) - [ ] styles provided as hook to reduce API surface churn - [ ] Base components - [ ] Minor component improvements - [ ] Pivot responsiveness - [ ] Slider ticks and labels ## Intro This release marks the first of many major releases we have coming up for Fluent UI. ## Release cadence changes TBD - propose some models/future expectations for release cadence > [jslone] Recommend targetting v9 beta release for week of March 8th, with a final release 4-6 weeks after that. > Given we won't have v8 out until October, we aren't likely to turn around another release until 2021 > v9 release should have the goal of setting us up for build 2021 and contain a minimal and useful set of refreshed, converged, tokened components. We could consider releasing these components incrementally in the time leading up to v9. > If v8 and v9 go well and we get in a good rythmn we should consider quarterly releases which refresh components and move things forward > Consideration of releasing smaller package updates ## Release schedule for v8 - Beta release 8/24 - Beta 6 weeks (or until ready) - Estimated final release 10/5 ## What's new in Fluent UI 8 Fluent UI 8 provides significant updates to a small set of components. As we organize going forward, we plan on regularly releasing a set of component refreshes under a major release every quarter. This release focuses on performance, theming, and consolidation of long standing problems. In this major release, we've overhauled the following components: > TODO > | v7 | v8 | |-|-| | | `Button` | | | `ToggleButton` | | | `MenuButton` | | | `SplitButton` | | | `Link` | | | `Checkbox` | | | `Slider` | | | `Toggle` | | | `Slider` | | | `Text` | | | `Stack` | | | `Pivot` | As a general theme, each of these components have a number of common feature improvements: ### ThemeProvider > Converged provider details ### Compat lib > TODO: Compat lib ### Performance improvements Runtime performance of each of these components has improved substantially in both runtime rendering cost and bundle size. For runtime evaluation, we care about 3 numbers: initial render, subsequent re-renders, and unmount time. | | | | ### Shorthand slots support We now support altering and replacing sub-component parts far more predictably and easily. Each of the above components has a contract for shorthand slot props. Take the `Button` component's `icon` shorthand prop. We no longer need `onRender*`, or `*Props` props to tweak this slot. The `icon` (and all supported slot props) can now take a variety of inputs: It can take in a literal value (treated as children of the slot container): ``` <Button icon="😀" /> ``` It can take in JSX: ``` <Button icon={ <AddIcon /> } /> ``` It can take in an props object definition, which will be mixed into the container: > TODO: should this be a different example here that makes more sense? ``` <Button icon={{ 'as': 'span', className: 'iconContainer', children: <AddIcon /> }} /> ``` You can also provide a function to the children, allowing wrapping scenarios (either around the container or around children) to apply: > TODO: We should use label, loader, anything but icon ```tsx <Button icon={{ (children: (Icon, iconProps) => ( <Tooltip ...> <Icon {...iconProps} /> </Tooltip> )}} /> ``` > TODO: Base components > TODO: Icon transition (we went from icon names to JSX icons) > https://medium.com/swlh/fluentui-react-how-we-cut-more-than-30-of-components-bundle-size-by-creating-icons-package-474019d3123 ### Icons to svg ### Richer customization `styles` props provide customization; however the performance is slow and overriding styles becomes an unpreditable guessing game. Theming going forward will follow a different paradigm: Each component will consume a set of css variables. > TODO: Before/after styles injection Example: > TODO: If I'm using mergeStyleSets directly, what's different? > vet a converged solution Instead of this: ``` <Button styles={{ /* inline stuff */ }} /> ``` Do this: ```tsx .ui-button {} .ui-button__icon {} .ui-button__children {} .ui-card__content {} <Button> icon={{ cn:'', as: 'span', children: <Add/> }} content={{...}} children={{ as: 'span', cn: '', 'data-blah': 'sadf', children: 'hello' }} <Button> <button> asdfasdf </button> <Button>children</Button> <Button content=hi icon=foo /> <Button>hi <iconFoo/></Button> <Link href="asdf">children</Link> <Header>children</Header> <PivotItem header={...} content={} /> ``` </Button> ```tsx <Button styles={{ /* inline stuff */ }} /> ``` ```tsx const useClasses = mergeStyleSets({ root: {}, things: {} }); const classes = useClasses(); <Button tokens={} />; ``` ### Recomposition support and base components > TODO ## What's next in v9 and beyond? ### Package granularity changes While we will still continue to release suite packages, we will be moving the actual code into smaller, individual subpackages. These packages will strictly follow semantic versioning, which means they may not align with the suite package's version. #### Motivation: diamond dependencies cause bundle bloat In v7 and prior, all components would be released in one large package with a handful of smaller packages, all lock step major releasing. This meant that an app referencing multiple projects using both v7 and v8 would duplicate EVERYTHING in both versions, regadless of whether or not it was necessary. Going forward, we can minimize possible duplication with conflicting dependencies by applying the following rules: * Export suite packages (e.g. `@fluentui/react`) and subpackages (e.g. `@fluentui/react-button`.) * Suite packages have only export sub packages. * Subpackages export granular components, and have explicit subpackage dependencies. * Subpackages do not depend on suite packages, ever. * All subpackage dependencies will follow semantic versioning explicitly. (We will no longer bump a subpackage to align with the suite package's major number.) This comes with a downside: at a glance you will not know which sub packages work with others. But then, that's really the nature of semantic releases and the npm ecosystem in general. The more granular your package, the more boundaries you have to isolate duplicate code. #### Example: Smaller packages reduces duplication `@fluentui@react` v8 exports: * `@fluentui/react-button` v1 * `@fluentui/react-dropdown` v1 + 50 other packages In the next major release, we make major changes to the dropdown: @fluentui@react v9 exports: * `@fluentui/react-button` v1 * `@fluentui/react-dropdown` v2 + 50 other unchanged packages This means that partners who have mixed dependencies on both v8 and v9 will no longer get duplicates for every file. Both suite packages will resolve to the same sub packages. The app will have both v8 and v9 index files. But only the dropdown, and any dependents, will duplicate. # Things to figure out 1. Component surface: (names, props) 1. Themeprovider - Tokens - Back compat - Forward looking converged theme - Change a token in the converged theme - Works with current/old components - Works with new components - One react context instance - All future components leverage this context to get tokens/theme 1. How we build components - Won't get all the way to a converged internals in 1 Major - Teams needs rails on keeping things performant (Ribbon, others need this too?) - Two customers: - App developer - Can't prevent HOC wrappers. Can give them tools to extend them with different default settings. - Component developer - Compose targets this more. 1. Finalized Theme tokens - Color palette, etc - Can we support auto-generating colors based on brand/theme color? - - Need to follow up # Moved to v9 ## Component convergence Lines of work: - Get all the props convergence figured out - Support the styles prop with a single hook to avoid breaking component surface in this release (for slider, checkbox, etc) - Getting design tokens finalized and brining in component tokens For each component: - [ ] Props have a spec that has been reviewed - [ ] Component is a function component built with compose so that it can be extended - [ ] Each component has a base implementation and an extended version with styling - [ ] Component logic extracted into hook(s) - [ ] Component has tokens (reviewed by team, used in product) --- - [ ] Prop convergence of - [ ] Slider - [ ] Pivot - [ ] Toggle - [ ] Checkbox - [ ] Link - [ ] Image - [ ] ## v0 { siteVariables: { } } v7 { palette: { themePrimary: 'red' } } Supports smooth migration from existing stylesProp/mergeStyles world (especially where everyone is using a bunch of mergeStyles)