-
Notifications
You must be signed in to change notification settings - Fork 2.8k
feat(react-components): add react 18 support #34456
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
base: master
Are you sure you want to change the base?
Conversation
Co-authored-by: Martin Hochel <[email protected]>
📊 Bundle size reportUnchanged fixtures
|
Pull request demo site: URL |
import { Caption1, ComponentProps, Slot } from '@fluentui/react-components'; | ||
import type { FluentProviderProps } from '@fluentui/react-provider'; | ||
|
||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Integration tests to cover type issues caught in our partners' codebases.
change/@fluentui-react-accordion-70e37d4f-804b-494a-9d94-31840668c018.json
Outdated
Show resolved
Hide resolved
// but there's no way to retrieve the element type of a slot from the slot definition | ||
// right now without using SLOT_ELEMENT_TYPE_SYMBOL | ||
// TODO: create a method to retrieve the element type of a slot | ||
// eslint-disable-next-line @typescript-eslint/no-deprecated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: lets make this scoped so its immediately obvious which symbol is being referred here ( I assume components
) ?
const {
heading: root = {},
action,
// We should not use components to pass along the base element type of a slot
// but there's no way to retrieve the element type of a slot from the slot definition
// right now without using SLOT_ELEMENT_TYPE_SYMBOL
// TODO: create a method to retrieve the element type of a slot
// eslint-disable-next-line @typescript-eslint/no-deprecated
components
} = state;
packages/react-components/react-menu/library/src/components/MenuItem/useMenuItem.tsx
Show resolved
Hide resolved
...ages/react-components/react-portal/library/src/components/Portal/usePortalMountNode.test.tsx
Outdated
Show resolved
Hide resolved
...ct-components/react-tag-picker/library/src/components/TagPickerButton/useTagPickerButton.tsx
Outdated
Show resolved
Hide resolved
state.components?.[slotName] === undefined || typeof state.components[slotName] === 'string' | ||
? asProp || state.components?.[slotName] || 'div' | ||
: state.components[slotName] | ||
state.components?.[slotName] === undefined || // eslint-disable-line @typescript-eslint/no-deprecated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
state.components?.[slotName] === undefined || // eslint-disable-line @typescript-eslint/no-deprecated | |
// eslint-disable-next-line @typescript-eslint/no-deprecated | |
state.components?.[slotName] === undefined || |
@@ -22,6 +22,6 @@ const metadata: Meta<typeof Breadcrumb> = { | |||
}, | |||
}, | |||
}, | |||
}; | |||
} as Meta<typeof Breadcrumb>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needed for React 18 to workaround the subcomponents Storybook type issue storybookjs/storybook#23170
Lets go! Woohoo!! 🥳 |
Summary
This PR addresses type incompatibilities introduced by React 18 that break our Slots API. Specifically, it fixes issues with
ReactNode
,RefAttributes
, and several slot-related utility types. It also adjusts internal type declarations to better align with actual usage and React’s updated typings.Previous Behavior
1.
ReactNode
Breaking ChangeReact 18 introduced stricter definitions for
ReactNode
, removing the{}
catch-all inReactFragment
. This change breaks our slot typings, which previously relied on the broader compatibility of React 17:React 17:
React 18:
🔗 Playground showing the issue
2.
RefAttributes
ChangeIn React 18,
RefAttributes
now usesLegacyRef<T>
which includes support for string refs — something we don't support in our API.React 17:
React 18:
3.
FC
doesn't provides type forchildren
prop, it should be explicitly definedReact 17:
React 18:
New Behavior
Loosened type constraints in
UnknownSlotProps
Previously, the
children
prop has typeReactNode | undefined
, but this doesn’t work with theSlotRenderFunction
and React 18. This change removes that restriction and to enable usage with React 18.Updated
SlotShorthandValue
to acceptIterable<ReactNode>
React 18 expands
ReactNode
to includeIterable<ReactNode>
, so this change ensures our shorthand slot values also support this structure. This enables support for JSX fragments and iterable rendering.WithSlotRenderFunction
adjusted for manual type assertions in React 18In React 18, implicit inference of slot render functions may not work correctly due to stricter type definitions. Consumers must now use
as
orsatisfies
type assertions when passing a function to slot props.Removed deprecated
VoidFunctionComponent
VoidFunctionComponent
is deprecated and unnecessary sinceComponentType
handles the same use cases. Removing it simplifies our generic types and avoids confusion.cloneTriggerTree
updated for broaderchildren
supportThis utility function now assumes
children
can be more than justReactNode
. It aligns with the loosened constraints and supports broader use cases, including render functions or iterables.Removed usage of
React.RefAttributes
in several utilitiesWith React 18,
RefAttributes
includesLegacyRef
, which supports string refs — something we don’t allow. We’ve replaced it with more precise types to enforce our internal API constraints.Added
{ children?: React.ReactNode }
to fix story/test compatibilitySome stories and test utilities failed under React 18 due to missing
children
prop typing. So the fix is too use theReact.PropsWithChildren<Props>
or explicitly declare thechildren
prop type.React 18 type changes:
Slot render functions must now be manually typed in React 18:
Future Plans
Migrate slot render function away from
children
to a dedicated prop to improve type inference.Related Issues