The purpose of this design doc is to present and describe the different decisions and research required to achieve a smooth migration from Fluent UI Northstar (v0) to Fluent UI v9 in the Teams verticals monorepo.
The verticals repository has all reusable UI code in the @microsoft/modernworkplace-ui-core
repo. All northstar exports are done through @microsoft/modernworkplace-ui-core/src/components/northstar
. Although the deep import is considered an antipattern in the JS ecosystem, the good thing is that this import is used consistently throughout.
We can simply create a new export path @microsoft/modernworkplace-ui-core/src/components/fluentui
as the primary export path of v9 components and do a gradual migration.
The existence of this export path if no code is used should not impact any of the production code.
Currently the packages inside the verticals apps repo are using mergeStyleSets
from @uifabric
:
It's convenient, since the syntax is very similar to @griffel
All style files are under the pattern ComponentName.styles.ts
, what can facilitate automation with codemodes.
Let's take the FacePile
styles for example, currently we have:
By convernting it to griffel
it will look like:
There is already a library that will automatically try to migrate northstar styles to v9 styles: https://github.com/YuanboXue-Amber/style-transform-tool
A demo of this library can be seen: https://yellow-meadow-005156603.1.azurestaticapps.net/
This library will not work out of the box on mergeStyleSets but the expected format is similar so we can reuse some of the code in there to help create tooling that will.
Since the styles are all consistently in .styles.ts
files, once we have tooling in place to do this automatically, it should be fairly easy to run.
The modern workplace repo currently uses @uifabric/merge-styles@7.19.1
as the main styling solution of choice. Running some benchmarks that were implemented in https://github.com/microsoft/griffel/pull/252 we can see the following results
NOTE: That build time optimizations were not applied for Griffel (v9) styling, the values could potentially be further improved by applying build time optimizations
You can see that in the purely runtime scenario Griffel could already be ~30% increase to styling performance.
Northstar will be deprecated since Teams is heavily investing into the migration of northstar to v9 for improved performance and other API related benefits.
We can create an eslint rule in eslint-plugin-modernworkplace
that will throw an error for any new imports of northstar components to promote new code using v9 components.
v9 can can be used side by side with northstar without any problems. If there are any problems discovered with using the two component libraries together, that is a bug that should be reported to the Fluent UI team.
Below is the usage statistics of northstar component usage at the moment of 11/10/2022
Count | Component |
---|---|
149 | Flex |
99 | Text |
67 | Button |
26 | Box |
17 | Divider |
14 | Input |
13 | Dropdown |
12 | Header |
12 | Avatar |
11 | Dialog |
10 | Skeleton |
10 | FormField |
10 | Ref |
9 | FlexItem |
9 | Checkbox |
8 | Provider |
8 | MenuButton |
8 | Table |
8 | Tooltip |
6 | TextArea |
6 | List |
6 | Loader |
6 | Popup |
5 | FormLabel |
5 | FormTextArea |
5 | Accordion |
4 | ListItem |
4 | Label |
4 | Image |
3 | Datepicker |
2 | Breadcrumb |
2 | Pill |
2 | FormInput |
1 | Grid |
1 | Segment |
1 | FormDatepicker |
1 | Alert |
1 | SplitButton |
1 | Portal |
1 | Status |
1 | RadioGroup |
1 | Toolbar |
It's quite clear the the most often used components are simpler layout components. The top three components add up in usages more than all other compnents combined:
For simpler components, (especially the most used components as they are quite simple) we should look into the possibility of creating codemods for automatic migration to avoid as much developer manual work as possible.
Below is a snapshot of all icons used in the MWT repo as of 11/10/2022
Current Icon | V9 Icon Equivalent |
---|---|
CloseIcon | |
CalendarIcon | |
AcceptIcon | |
ChevronDownIcon | |
ParticipantAddIcon | |
AddIcon | |
SearchIcon | |
LocationIcon | |
CheckmarkCircleIcon | |
CircleIcon | |
ChevronStartIcon | |
RedbangIcon | |
ExclamationCircleIcon | |
EditIcon | |
MoreIcon | |
ArrowDownIcon | |
FilesEmptyIcon | |
TrashCanIcon | |
InfoIcon | |
OpenOutsideIcon | |
ArrowRightIcon | |
ChevronEndIcon | |
ErrorIcon | |
ArchiveIcon | |
LinkIcon | |
SettingsIcon | |
ChevronEndMediumIcon | |
UserFriendsIcon | |
ArrowUpIcon | |
ApprovalsAppbarIcon | |
TeamCreateIcon | |
CalendarAgendaIcon | |
QuestionCircleIcon | |
BookmarkIcon | |
FormatIcon | |
FilesUploadIcon | |
OneDriveIcon | |
ThumbtackIcon | |
ThumbtackSlashIcon | |
UndoIcon | |
ExcelColorIcon | |
FilesCodeIcon | |
FilesHtmlColoredIcon | |
FilesPdfColoredIcon | |
FilesPictureColoredIcon | |
FilesSoundIcon | |
FilesTextColoredIcon | |
FilesVideoIcon | |
FilesZipIcon | |
FluidFileIcon | |
OneNoteColorIcon | |
PowerPointColorIcon | |
VisioColorIcon | |
WordColorIcon | |
SyncIcon | |
TabsIcon | |
ExclamationTriangleIcon | |
UrgentIcon | |
AttachmentIcon | |
RetryIcon | |
FilterIcon | |
ShiftActivityIcon | |
WorkOrSchoolIcon |
We should finish the above mapping of V9 icons to northstar icons.
Icon migration can be done separately to any components and the intended design of V9 icons is that they can be used with northstar components.
We should also look into codemods for icon migration once we have a complete mapping.
A catalog of v9 icons is available https://react.fluentui.dev/?path=/docs/concepts-developer-icons-icons-catalog–page
We can assume that we have the encapsulation of v9 setup described earlier.
The TeamsContextProvider
componnet is responsible for applying all providers that is used by modern workplace controls. In this way, we can simply add the FluentProvider
to the main provider. This would incur some minor bundlesize, but would not impact any northstar code and enables the use of v9 components in the entire repo.
packages\modernworkplace-react-hooks\src\useTeamsContext\TeamsContextProvider.tsx
Here is an example of a more complex migration.
lets take FacePile
as example and see what would need to be done in order to migrate the Avatar
Component used inside.
First we would need to use FluentProvider
in the following places:
So the replacement in packages\modernworkplace-ui-core\src\components\facePile\FacePile.tsx is simple enough as:
One final touch, we need one more update in the styles since we are not exporting avatarClassName
in v9 but avatarClassNames
which is an object with class names for each slots. So the final change in the styles
file would be:
We have migration instructions for several components, here we used Avatar Migration
Check the accessibility migration doc where it exaplains how to migrate the 4 possible properties that an accessibility behavior has. For attributes we should add them directly to the component.
Let's take packages\modernworkplace-ui-members\src\Members.tsx as example, where it's using gridBehavior
:
Here we are replacing the focus zone property by using react-tabster
If we had a custom behavior such has:
That could be replaced by:
There is no visual regression testing in the modern workplace repo, therefore any visual regression will have to be done manually during migration. However what level of visual regression allowed should be discussed with designers since v9 is using the Fluent language which is intended to be the future design of all M365 experiences
All unit tests that break as a result of migration should be investigated and fixed.
There are performance tests setup for the LoanManager
scenario. In order have an accurate perf tests between northstar and v0 we should try to quickly migrate LoanManager
related controls to v9 and run the existing performance tests
Bundle size is measured by looking at the final size of the js bundle that is built with the production webpack config. We can measure the bundle size of just integrating the FluentProvider at the start to see the initial impact and keep measuring as components as migrated