Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(react-utilities): slot API react v17/18 support #31548

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

bsunderhus
Copy link
Contributor

@bsunderhus bsunderhus commented Jun 3, 2024

Previous Behavior

Slots API breaks on v18! 💣

ReactNode

The ReactNode type became more specific (there was a type leak on ReactFragment type where {} was a valid type, and {} in typescript allows any of the primitive types but null or undefined more info about this, here's a playground), and due to that specificity our declaration of what a slot is starts breaking on @types/react@18

// v17
type ReactText = string | number;
type ReactChild = ReactElement | ReactText;
// 💣💣💣
type ReactFragment = {} | ReactNodeArray;
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
// v18
type ReactNode =
        | ReactElement
        | string
        | number
        | Iterable<ReactNode>
        | ReactPortal
        | boolean
        | null
        | undefined
        | DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES[
            keyof DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES
        ];

Here's a playground showcasing the error

RefAttributes

React.RefAttributes is the ref property. In react v17 that would be equivalent to:

// v17
interface RefAttributes<T> {
  ref?: Ref<T>
}

Now in react v18 it became:

// v18
interface RefAttributes<T> {
  // 💣💣💣💣
  ref?: LegacyRef<T>
}

LegacyRef includes the support to use string as a valid reference value. This will break into our API 💣💣

New Behavior

  1. Introduces new type SlotPropsDataType in favor of UnknownSlotProps https://github.com/microsoft/fluentui/pull/31548/files#diff-06ee7aed2b4bc7589d4c744c7c6649fbee2ff0129915f344768e361a6cfb4dcdR5-R10
  2. Updates SlotShorthandValue to support Iterable<ReactNode> instead of ReactNode[] (v18 modification)
  3. Updates WithSlotRenderFunction to properly include render function method (Fixes Can't use children render function in slots without Typescript errors #27090)
  4. Introduces new type WithoutSlotRenderFunction
    • as SlotPropsDataType does not have the requirement of children?: ReactNode the render function signature will leak, and this is a mistake in two scenarios:
      1. The Primary slot on ComponentProps should not have a render function
      2. The return SlotComponentType properties should not have a render function
  5. Removes VoidFunctionComponent from Slot generic signature (it is deprecated and redundant type, ComponentType covers the same use case)
  6. cloneTriggerTree updates signature to properly assume the possibility of more than just ReactNode from children value.
  7. ForwardRefComponent and getIntrinsicElementProps updates to stop using React.RefAttributes (in the v18 upgrade this type now support LegacyRef, which we do not support)

What are the Breaking Changes here?

  1. Every single method or type that used to depend on UnknownSlotProps and now depends on SlotPropsDataType became less strict
  2. ComponentProps now explicitly removes render function signatures from primary slot (this was already supposed to be like that, it's a bugfix IMO)
  3. ComponentState explicitly removes render function signatures to ensure things were as they we before

Technically, if the client is using Slot, ComponentProps, ComponentState, an slot.* there'll be no breaking changes (as we are just moving verifications from one type to another) but if that is not the case then we could have some false positives due to the wider signature of SlotPropsDataType

Related Issue(s)

@bsunderhus bsunderhus self-assigned this Jun 3, 2024
@github-actions github-actions bot added this to the April Project Cycle Q1 2024 milestone Jun 3, 2024
@fabricteam
Copy link
Collaborator

fabricteam commented Jun 3, 2024

Perf Analysis (@fluentui/react-components)

Scenario Render type Master Ticks PR Ticks Iterations Status
FluentProviderWithTheme virtual-rerender 32 38 10 Possible regression
All results

Scenario Render type Master Ticks PR Ticks Iterations Status
Avatar mount 630 622 5000
Button mount 303 309 5000
Field mount 1158 1128 5000
FluentProvider mount 683 704 5000
FluentProviderWithTheme mount 84 85 10
FluentProviderWithTheme virtual-rerender 32 38 10 Possible regression
FluentProviderWithTheme virtual-rerender-with-unmount 81 77 10
MakeStyles mount 865 871 50000
Persona mount 1786 1737 5000
SpinButton mount 1369 1421 5000
SwatchPicker mount 1663 1640 5000

Copy link

codesandbox-ci bot commented Jun 3, 2024

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.

@fabricteam
Copy link
Collaborator

fabricteam commented Jun 3, 2024

📊 Bundle size report

Package & Exports Baseline (minified/GZIP) PR Change
react-accordion
Accordion (including children components)
104.529 kB
32.097 kB
104.575 kB
32.114 kB
46 B
17 B
react-avatar
Avatar
49.303 kB
15.815 kB
49.353 kB
15.833 kB
50 B
18 B
react-avatar
AvatarGroup
20.106 kB
7.968 kB
20.153 kB
7.985 kB
47 B
17 B
react-avatar
AvatarGroupItem
63.447 kB
20.034 kB
63.497 kB
20.053 kB
50 B
19 B
react-badge
Badge
25.954 kB
8.595 kB
26.001 kB
8.608 kB
47 B
13 B
react-badge
CounterBadge
26.733 kB
8.872 kB
26.78 kB
8.888 kB
47 B
16 B
react-badge
PresenceBadge
25.719 kB
9.457 kB
25.766 kB
9.47 kB
47 B
13 B
react-breadcrumb
@fluentui/react-breadcrumb - package
113.699 kB
31.498 kB
113.748 kB
31.512 kB
49 B
14 B
react-button
Button
37.104 kB
10.766 kB
37.151 kB
10.782 kB
47 B
16 B
react-button
CompoundButton
43.518 kB
12.068 kB
43.565 kB
12.082 kB
47 B
14 B
react-button
MenuButton
41.916 kB
12.119 kB
41.962 kB
12.137 kB
46 B
18 B
react-button
SplitButton
49.93 kB
13.696 kB
49.978 kB
13.712 kB
48 B
16 B
react-button
ToggleButton
53.037 kB
12.528 kB
53.083 kB
12.544 kB
46 B
16 B
react-card
Card - All
101.238 kB
28.624 kB
101.288 kB
28.642 kB
50 B
18 B
react-card
Card
94.022 kB
26.806 kB
94.068 kB
26.821 kB
46 B
15 B
react-card
CardFooter
14.355 kB
5.79 kB
14.401 kB
5.807 kB
46 B
17 B
react-card
CardHeader
16.878 kB
6.666 kB
16.924 kB
6.682 kB
46 B
16 B
react-card
CardPreview
14.42 kB
5.922 kB
14.466 kB
5.936 kB
46 B
14 B
react-checkbox
Checkbox
35.105 kB
12.075 kB
35.157 kB
12.091 kB
52 B
16 B
react-combobox
Combobox (including child components)
104.398 kB
34.199 kB
104.444 kB
34.224 kB
46 B
25 B
react-combobox
Dropdown (including child components)
104.984 kB
34.114 kB
105.036 kB
34.143 kB
52 B
29 B
react-components
react-components: Button, FluentProvider & webLightTheme
69.14 kB
20.137 kB
69.186 kB
20.153 kB
46 B
16 B
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
218.197 kB
63.203 kB
218.256 kB
63.243 kB
59 B
40 B
react-components
react-components: FluentProvider & webLightTheme
44.447 kB
14.59 kB
44.493 kB
14.606 kB
46 B
16 B
react-components
react-components: entire library
1.097 MB
271.096 kB
1.097 MB
271.134 kB
104 B
38 B
react-datepicker-compat
DatePicker Compat
223.64 kB
63.299 kB
223.686 kB
63.324 kB
46 B
25 B
react-dialog
Dialog (including children components)
99.724 kB
29.912 kB
99.77 kB
29.936 kB
46 B
24 B
react-divider
Divider
21.328 kB
7.953 kB
21.374 kB
7.969 kB
46 B
16 B
react-field
Field
23.384 kB
8.891 kB
23.43 kB
8.911 kB
46 B
20 B
react-image
Image
15.36 kB
6.236 kB
15.406 kB
6.249 kB
46 B
13 B
react-input
Input
28.014 kB
9.444 kB
28.066 kB
9.464 kB
52 B
20 B
react-label
Label
14.671 kB
5.99 kB
14.717 kB
6.008 kB
46 B
18 B
react-link
Link
17.192 kB
6.98 kB
17.238 kB
6.998 kB
46 B
18 B
react-list-preview
List
88.626 kB
26.435 kB
88.673 kB
26.45 kB
47 B
15 B
react-list-preview
ListItem
112.155 kB
33.274 kB
112.201 kB
33.289 kB
46 B
15 B
react-menu
Menu (including children components)
151.856 kB
45.848 kB
151.914 kB
45.891 kB
58 B
43 B
react-menu
Menu (including selectable components)
154.537 kB
46.326 kB
154.595 kB
46.362 kB
58 B
36 B
react-message-bar
MessageBar (all components)
24.722 kB
9.205 kB
24.769 kB
9.217 kB
47 B
12 B
react-persona
Persona
56.194 kB
17.695 kB
56.244 kB
17.713 kB
50 B
18 B
react-popover
Popover
128.329 kB
40.143 kB
128.375 kB
40.166 kB
46 B
23 B
react-progress
ProgressBar
17.084 kB
6.891 kB
17.131 kB
6.907 kB
47 B
16 B
react-provider
FluentProvider
24.623 kB
8.893 kB
24.669 kB
8.91 kB
46 B
17 B
react-radio
Radio
32.672 kB
10.343 kB
32.718 kB
10.359 kB
46 B
16 B
react-radio
RadioGroup
15.762 kB
6.423 kB
15.808 kB
6.442 kB
46 B
19 B
react-select
Select
27.724 kB
10.123 kB
27.776 kB
10.144 kB
52 B
21 B
react-slider
Slider
37.169 kB
12.538 kB
37.215 kB
12.549 kB
46 B
11 B
react-spinbutton
SpinButton
36.102 kB
11.827 kB
36.155 kB
11.846 kB
53 B
19 B
react-spinner
Spinner
25.245 kB
8.539 kB
25.293 kB
8.556 kB
48 B
17 B
react-swatch-picker
@fluentui/react-swatch-picker - package
103.736 kB
30.073 kB
103.784 kB
30.087 kB
48 B
14 B
react-switch
Switch
35.319 kB
11.314 kB
35.365 kB
11.325 kB
46 B
11 B
react-table
DataGrid
160.458 kB
45.536 kB
160.514 kB
45.544 kB
56 B
8 B
react-table
Table (Primitives only)
42.643 kB
13.82 kB
42.709 kB
13.852 kB
66 B
32 B
react-table
Table as DataGrid
131.312 kB
36.37 kB
131.377 kB
36.401 kB
65 B
31 B
react-table
Table (Selection only)
70.499 kB
19.962 kB
70.565 kB
19.995 kB
66 B
33 B
react-table
Table (Sort only)
69.142 kB
19.573 kB
69.208 kB
19.606 kB
66 B
33 B
react-tag-picker
@fluentui/react-tag-picker - package
182.31 kB
54.807 kB
182.362 kB
54.828 kB
52 B
21 B
react-tags
InteractionTag
15.199 kB
6.157 kB
15.245 kB
6.178 kB
46 B
21 B
react-tags
Tag
29.027 kB
9.528 kB
29.074 kB
9.544 kB
47 B
16 B
react-tags
TagGroup
82.197 kB
24.362 kB
82.245 kB
24.374 kB
48 B
12 B
react-text
Text - Default
17.061 kB
6.723 kB
17.107 kB
6.741 kB
46 B
18 B
react-text
Text - Wrappers
20.242 kB
7.048 kB
20.288 kB
7.067 kB
46 B
19 B
react-textarea
Textarea
26.572 kB
9.755 kB
26.624 kB
9.772 kB
52 B
17 B
react-timepicker-compat
TimePicker
107.387 kB
35.758 kB
107.433 kB
35.758 kB
46 B
react-toast
Toast (including Toaster)
97.816 kB
29.438 kB
97.872 kB
29.457 kB
56 B
19 B
react-tooltip
Tooltip
55.517 kB
19.515 kB
55.563 kB
19.534 kB
46 B
19 B
Unchanged fixtures
Package & Exports Size (minified/GZIP)
global-context
createContext
510 B
328 B
global-context
createContextSelector
537 B
339 B
react-calendar-compat
Calendar Compat
149.573 kB
39.871 kB
react-jsx-runtime
Classic Pragma
1.057 kB
530 B
react-jsx-runtime
JSX Dev Runtime
3.771 kB
1.643 kB
react-jsx-runtime
JSX Runtime
4.367 kB
1.874 kB
react-motion
@fluentui/react-motion - createMotionComponent()
4.303 kB
1.899 kB
react-motion
@fluentui/react-motion - createPresenceComponent()
5.038 kB
2.229 kB
react-motion
@fluentui/react-motion - PresenceGroup
1.714 kB
819 B
react-overflow
hooks only
12.81 kB
4.821 kB
react-portal
Portal
14.563 kB
5.118 kB
react-portal-compat
PortalCompatProvider
8.39 kB
2.64 kB
react-positioning
usePositioning
27.057 kB
9.698 kB
react-utilities
SSRProvider
180 B
160 B
🤖 This report was generated against aacbb429c6bf89dae83efcd03ce9cf237e6e13be

@bsunderhus bsunderhus force-pushed the react-utilities/chore--slot-API-react-v17/18-support branch 6 times, most recently from 3421071 to 9a444bd Compare June 5, 2024 13:57
@bsunderhus bsunderhus marked this pull request as ready for review June 5, 2024 16:17
@bsunderhus bsunderhus force-pushed the react-utilities/chore--slot-API-react-v17/18-support branch from 3279340 to a54bb34 Compare June 6, 2024 11:47
@bsunderhus bsunderhus requested a review from behowell as a code owner June 6, 2024 12:59
@bsunderhus bsunderhus force-pushed the react-utilities/chore--slot-API-react-v17/18-support branch 3 times, most recently from c906ba8 to fcc5a3b Compare June 6, 2024 15:23
@bsunderhus bsunderhus requested a review from a team as a code owner June 6, 2024 15:23
@bsunderhus bsunderhus force-pushed the react-utilities/chore--slot-API-react-v17/18-support branch 4 times, most recently from 0e6f5ba to b7ee301 Compare June 6, 2024 20:04
@bsunderhus bsunderhus force-pushed the react-utilities/chore--slot-API-react-v17/18-support branch 8 times, most recently from a558e3a to d0da8f9 Compare July 27, 2024 17:12
@bsunderhus bsunderhus force-pushed the react-utilities/chore--slot-API-react-v17/18-support branch from d0da8f9 to 60621f6 Compare August 16, 2024 09:03
@bsunderhus bsunderhus force-pushed the react-utilities/chore--slot-API-react-v17/18-support branch 6 times, most recently from b37c3df to ce2cfbb Compare August 22, 2024 08:01
@bsunderhus bsunderhus force-pushed the react-utilities/chore--slot-API-react-v17/18-support branch from ce2cfbb to 4b3bba1 Compare August 22, 2024 12:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants