RFC: Portal compatibility#21774
Conversation
09ed2af to
4895a94
Compare
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit b1a22f6:
|
Asset size changesSize Auditor did not detect a change in bundle size for any component! Baseline commit: 43f3fbf79244dfe2557322b1418f73d93bd1b054 (build) |
📊 Bundle size report🤖 This report was generated against 319234c25f29defac6afc728dd109737fd1b803f |
Perf Analysis (
|
| Scenario | Render type | Master Ticks | PR Ticks | Iterations | Status |
|---|---|---|---|---|---|
| Avatar | mount | 1059 | 1074 | 5000 | |
| BaseButton | mount | 1096 | 1075 | 5000 | |
| Breadcrumb | mount | 2887 | 2897 | 1000 | |
| ButtonNext | mount | 549 | 542 | 5000 | |
| Checkbox | mount | 1837 | 1940 | 5000 | |
| CheckboxBase | mount | 1629 | 1656 | 5000 | |
| ChoiceGroup | mount | 5634 | 5682 | 5000 | |
| ComboBox | mount | 1139 | 1166 | 1000 | |
| CommandBar | mount | 11601 | 11497 | 1000 | |
| ContextualMenu | mount | 9519 | 9479 | 1000 | |
| DefaultButton | mount | 1343 | 1321 | 5000 | |
| DetailsRow | mount | 4277 | 4343 | 5000 | |
| DetailsRowFast | mount | 4335 | 4344 | 5000 | |
| DetailsRowNoStyles | mount | 4037 | 4101 | 5000 | |
| Dialog | mount | 2474 | 2490 | 1000 | |
| DocumentCardTitle | mount | 210 | 221 | 1000 | |
| Dropdown | mount | 3691 | 3718 | 5000 | |
| FluentProviderNext | mount | 2009 | 2045 | 5000 | |
| FluentProviderWithTheme | mount | 183 | 188 | 10 | |
| FluentProviderWithTheme | virtual-rerender | 143 | 131 | 10 | |
| FluentProviderWithTheme | virtual-rerender-with-unmount | 219 | 227 | 10 | |
| FocusTrapZone | mount | 2080 | 2086 | 5000 | |
| FocusZone | mount | 1999 | 2051 | 5000 | |
| IconButton | mount | 2067 | 2086 | 5000 | |
| Label | mount | 421 | 429 | 5000 | |
| Layer | mount | 3462 | 3437 | 5000 | |
| Link | mount | 557 | 593 | 5000 | |
| MakeStyles | mount | 1811 | 1826 | 50000 | |
| MenuButton | mount | 1783 | 1793 | 5000 | |
| MessageBar | mount | 2299 | 2262 | 5000 | |
| Nav | mount | 3805 | 3801 | 1000 | |
| OverflowSet | mount | 1268 | 1279 | 5000 | |
| Panel | mount | 2422 | 2445 | 1000 | |
| Persona | mount | 995 | 984 | 1000 | |
| Pivot | mount | 1628 | 1640 | 1000 | |
| PrimaryButton | mount | 1479 | 1500 | 5000 | |
| Rating | mount | 9114 | 9085 | 5000 | |
| SearchBox | mount | 1576 | 1637 | 5000 | |
| Shimmer | mount | 2922 | 2970 | 5000 | |
| Slider | mount | 2495 | 2264 | 5000 | |
| SpinButton | mount | 5893 | 5695 | 5000 | |
| Spinner | mount | 509 | 526 | 5000 | |
| SplitButton | mount | 3648 | 3841 | 5000 | |
| Stack | mount | 637 | 661 | 5000 | |
| StackWithIntrinsicChildren | mount | 2770 | 2753 | 5000 | |
| StackWithTextChildren | mount | 6486 | 6466 | 5000 | |
| SwatchColorPicker | mount | 13462 | 13209 | 5000 | |
| TagPicker | mount | 3023 | 3212 | 5000 | |
| TeachingBubble | mount | 14611 | 14722 | 5000 | |
| Text | mount | 529 | 546 | 5000 | |
| TextField | mount | 1708 | 1651 | 5000 | |
| ThemeProvider | mount | 1380 | 1345 | 5000 | |
| ThemeProvider | virtual-rerender | 704 | 739 | 5000 | |
| ThemeProvider | virtual-rerender-with-unmount | 2165 | 2245 | 5000 | |
| Toggle | mount | 952 | 953 | 5000 | |
| buttonNative | mount | 172 | 176 | 5000 |
Perf Analysis (@fluentui/react-northstar)
Perf tests with no regressions
| Scenario | Current PR Ticks | Baseline Ticks | Ratio |
|---|---|---|---|
| ChatDuplicateMessagesPerf.default | 371 | 337 | 1.1:1 |
| PortalMinimalPerf.default | 208 | 189 | 1.1:1 |
| SkeletonMinimalPerf.default | 444 | 409 | 1.09:1 |
| FormMinimalPerf.default | 512 | 475 | 1.08:1 |
| RefMinimalPerf.default | 272 | 253 | 1.08:1 |
| AnimationMinimalPerf.default | 658 | 617 | 1.07:1 |
| AvatarMinimalPerf.default | 240 | 224 | 1.07:1 |
| DividerMinimalPerf.default | 453 | 424 | 1.07:1 |
| HeaderMinimalPerf.default | 450 | 426 | 1.06:1 |
| IconMinimalPerf.default | 755 | 715 | 1.06:1 |
| LayoutMinimalPerf.default | 452 | 430 | 1.05:1 |
| TableMinimalPerf.default | 486 | 463 | 1.05:1 |
| TextAreaMinimalPerf.default | 635 | 606 | 1.05:1 |
| TooltipMinimalPerf.default | 1236 | 1179 | 1.05:1 |
| ChatWithPopoverPerf.default | 488 | 471 | 1.04:1 |
| LoaderMinimalPerf.default | 786 | 758 | 1.04:1 |
| ReactionMinimalPerf.default | 466 | 450 | 1.04:1 |
| SliderMinimalPerf.default | 1907 | 1827 | 1.04:1 |
| HeaderSlotsPerf.default | 923 | 895 | 1.03:1 |
| ImageMinimalPerf.default | 461 | 448 | 1.03:1 |
| ItemLayoutMinimalPerf.default | 1418 | 1375 | 1.03:1 |
| StatusMinimalPerf.default | 833 | 811 | 1.03:1 |
| AccordionMinimalPerf.default | 181 | 178 | 1.02:1 |
| BoxMinimalPerf.default | 412 | 405 | 1.02:1 |
| ButtonOverridesMissPerf.default | 1969 | 1939 | 1.02:1 |
| ButtonSlotsPerf.default | 668 | 654 | 1.02:1 |
| DropdownManyItemsPerf.default | 814 | 797 | 1.02:1 |
| GridMinimalPerf.default | 414 | 406 | 1.02:1 |
| InputMinimalPerf.default | 1475 | 1447 | 1.02:1 |
| ListWith60ListItems.default | 748 | 732 | 1.02:1 |
| TableManyItemsPerf.default | 2296 | 2242 | 1.02:1 |
| VideoMinimalPerf.default | 775 | 760 | 1.02:1 |
| AlertMinimalPerf.default | 344 | 341 | 1.01:1 |
| CarouselMinimalPerf.default | 581 | 575 | 1.01:1 |
| CheckboxMinimalPerf.default | 3085 | 3042 | 1.01:1 |
| DatepickerMinimalPerf.default | 6437 | 6399 | 1.01:1 |
| DropdownMinimalPerf.default | 3346 | 3311 | 1.01:1 |
| EmbedMinimalPerf.default | 4719 | 4654 | 1.01:1 |
| FlexMinimalPerf.default | 342 | 340 | 1.01:1 |
| ListMinimalPerf.default | 619 | 613 | 1.01:1 |
| RosterPerf.default | 1361 | 1342 | 1.01:1 |
| ProviderMinimalPerf.default | 1289 | 1271 | 1.01:1 |
| CustomToolbarPrototype.default | 4526 | 4481 | 1.01:1 |
| ToolbarMinimalPerf.default | 1101 | 1092 | 1.01:1 |
| TreeMinimalPerf.default | 962 | 950 | 1.01:1 |
| ButtonMinimalPerf.default | 219 | 219 | 1:1 |
| DialogMinimalPerf.default | 875 | 876 | 1:1 |
| ListCommonPerf.default | 766 | 763 | 1:1 |
| MenuButtonMinimalPerf.default | 1941 | 1942 | 1:1 |
| RadioGroupMinimalPerf.default | 559 | 558 | 1:1 |
| SplitButtonMinimalPerf.default | 4937 | 4958 | 1:1 |
| TextMinimalPerf.default | 402 | 404 | 1:1 |
| AttachmentMinimalPerf.default | 197 | 198 | 0.99:1 |
| MenuMinimalPerf.default | 1002 | 1017 | 0.99:1 |
| ProviderMergeThemesPerf.default | 1869 | 1888 | 0.99:1 |
| ChatMinimalPerf.default | 883 | 901 | 0.98:1 |
| LabelMinimalPerf.default | 467 | 475 | 0.98:1 |
| PopupMinimalPerf.default | 692 | 707 | 0.98:1 |
| SegmentMinimalPerf.default | 415 | 422 | 0.98:1 |
| TreeWith60ListItems.default | 219 | 224 | 0.98:1 |
| AttachmentSlotsPerf.default | 1257 | 1296 | 0.97:1 |
| CardMinimalPerf.default | 668 | 690 | 0.97:1 |
| ListNestedPerf.default | 644 | 670 | 0.96:1 |
|
|
||
| #### Pros and Cons | ||
|
|
||
| - 👎 `z-index=1000000` is ugly |
There was a problem hiding this comment.
another pro+con (combined) is that to solve the css vars, we need a context anyway, not storing an extra z-index in it doesn't change that fact
|
|
||
| In the prototype the publisher component is called `CompatHostV9`: | ||
|
|
||
| - it reads current classes from `useThemeClassName()` |
There was a problem hiding this comment.
apps could also just create their own class name instead of useThemeClassName (i.e. use useThemeStyleTag instead.
Maybe we should include that as an option and also list pros/cons
There was a problem hiding this comment.
I am not sure that it's a realistic case... useThemeClassName() and matching context are still required to be used to make Fluent components working otherwise heavy recomposition of every component that uses Portal will be required.
For custom components I still see sense to use our Portal instead of custom ones (it handles SSR). IMO if customers are creating custom portals and do not use useThemeClassName() to get classes with CSS variables they have bigger problem than compatibility 🐱
theerebuss
left a comment
There was a problem hiding this comment.
I'm pro introducing the compat Context because:
- Cleanest solution (no "deps" on older code)
- We don't double down on values that will become harder to change in the future
My only two concerns are communication on this and cleanup in the future.
Is it the user's concern to remove the compat context once no longer needed?
|
|
||
| #### Pros and Cons | ||
|
|
||
| - 👎 (_out of scope?_) possible singleton issues due multiple versions that could be present in an app |
There was a problem hiding this comment.
if this will happen applications will break. if we decide to go with this appraoch this package should never major bump
There was a problem hiding this comment.
That's true and I think that it's a valid requirement.
There was a problem hiding this comment.
It would be great to start marking singleton packages with singleton: true in the package.json. We've run into situations where this metadata would be beneficial elsewhere. For example, we could detect dupe singletons in an app graph and fail the build on detection.
There was a problem hiding this comment.
@dzearing can you pls point us to existing tooling that is capable to check such a scenario ? I'd rather avoid adding some undocumented magic which is not part of standard package.json json schema. If we can document/automate I'm ok with that.
Hotell
left a comment
There was a problem hiding this comment.
LGTM, lets wait for agreement from redmond folks.
|
@microsoft/cxe-red & @microsoft/cxe-coastal can you please review? |
khmakoto
left a comment
There was a problem hiding this comment.
Took another look after yesterday's discussion and it LGTM.
|
ping @GeoffCox as he's working on v8 transition tools and docs |
|
We have an offline sync about this RFC few weeks ago (17th March) with @khmakoto, @levithomason, @ling1726, @miroslavstastny & @GeoffCox. The summary:
|
Co-authored-by: ling1726 <[email protected]>
Yes, it user's concern. But I think it that it's okay, once customers will stop to use |
|
@layershifter The problem we are trying to solve is that portals are stacked on top of each other when nested right ? <V8Portal>
<v9Portal />
<v8Portal>In this case we should make sure that the v9 portal renders over the v8 portal. V8 already has a mechanism to modify z-index for layers (Link to docs) <Callout layerProps={{ className: overrideZIndex }} />In this case I propose 2 ways of going forward portalProps (naming not binding) for componentsOur components that use portals should expose a similar <Popover portalProps={{ className: overrideZIndex }} />
<Tooltip portalProps={{ className: overrideZIndex }} />
<Menu portalProps={{ className: overrideZIndex }} />Compatware for v9We can continue the idea of compat context for v9 to set zindex <V9PortalCompat zIndex={1000000}>
<V9Portal />
<v9PortalCompat /> |
|
Probably out of topic of this particular RFC, but regarding z-indexes on root elements: It should be avoided at all cost . instead we can leverage isolation. That would mitigate those z-indexes battles in a convenient way. Not sure that adding another property to our components API to basically "hack/workaround" things is the proper way forward. |
Sorry, but I didn't get how |
right, as I mentioned this is probably Out of topic for this RFC, but as you started convo regarding z-indexes I wanted to add my POV on the topic. this solution would "help" I guess only if we changed the css definition in v8, but I guess that's a no go. hope it's clear now |
Correct, effectively it's this case (modified CodeSandbox). I don't see any other solution than applying the same |
Summary
This RFC has enough approvals and if there will be no additional input I am going to merge it on Wednesday. Cheers 🍻 |
* RFC: Portal compatibility * Update rfcs/react-components/convergence/portal-compat.md Co-authored-by: ling1726 <[email protected]> Co-authored-by: ling1726 <[email protected]>
* RFC: Portal compatibility * Update rfcs/react-components/convergence/portal-compat.md Co-authored-by: ling1726 <[email protected]> Co-authored-by: ling1726 <[email protected]>


Summary
This RFC proposes introduce compatibility between components in different Fluent UI versions that use
ReactDOM.createPortal()via:z-indexRelated Issue(s)
Provides solution for #21333.
Preview