Converged components should follow RFC #18642
Required actions to migrate a component
Checklist
- Remove
defaultProps in useCOMPONENT
- Remove
mergeProps
- Define type for slots
- (optionally) Define
COMPONENTCommons type
- Update types for a component
- Update
getSlots()
- Update
useCOMPONENTStyles()
Remove defaultProps in useCOMPONENT
-export const useCOMPONENT = (props: COMPONENTProps, ref: React.Ref<HTMLElement>, defaultProps?: COMPONENTProps): COMPONENTState => {
+export const useCOMPONENT = (props: COMPONENTProps, ref: React.Ref<HTMLElement>): COMPONENTState => {
📝Check also JSDoc comments for the function and remove defaultProps from there
Remove mergeProps
Before
const state = mergeProps(
{ ref },
props,
resolveShorthandProps(props, COMPONENTShorthandProps)
);
After
const state: COMPONENTState = {
// Props passed at the top-level
disabled,
inline,
// Slots definition
components: { root: "div", icon: "span" },
// Slots
root: getNativeElementProps(props.as, { ref, ...props }),
icon: resolveShorthand(props.icon)
};
props that are affecting component's state or styling should go directly to state object, they should not go to state.root
- event handlers (
onClick, onKeyDown) should go to a matching slot (root, icon)
state.components should have hardcoded values with matching element
state.root should use getNativeElementProps(), ref goes there
state.icon & other slots should use resolveShorthand()
props should not be spreaded to state
Define type for slots
Please define a new type for slots in COMPONENT.types.ts
export type COMPONENTSlots = {
root: ObjectShorthandProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
icon: ObjectShorthandProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
};
(optionally) Define COMPONENTCommons type
If you props that are used in state & props please define a separate interface for them:
export type COMPONENTCommons = {
disabled: boolean;
inline: boolean;
}
📝 All properties are required
Update types for a component
Props
-export interface COMPONENTProps extends ComponentProps<COMPONENTSlots>, React.HTMLAttributes<HTMLElement> {}
+export interface COMPONENTProps extends ComponentProps<COMPONENTSlots>, Partial<COMPONENTCommons> {}
📝 React.HTMLAttributes are not in props anymore
State
-export interface COMPONENTState extends COMPONENTProps {
- ref: React.Ref<HTMLElement>;
-}
+export interface COMPONENTState extends ComponentState<COMPONENTSlots>, COMPONENTCommons {
📝 ref is not a root property of state
Update getSlots()
In renderCOMPONENT():
-const { slots, slotProps } = getSlotsCompat(state, linkShorthandProps);
+const { slots, slotProps } = getSlots<LinkSlots>(state, linkShorthandProps);
Update useCOMPONENTStyles()
const styles = useStyles();
- state.className = mergeClasses(
+ state.root.className = mergeClasses(
styles.root,
- state.className,
+ state.root.className,
);
Utilities
Components
Converged components should follow RFC #18642
Required actions to migrate a component
Checklist
defaultPropsinuseCOMPONENTmergePropsCOMPONENTCommonstypegetSlots()useCOMPONENTStyles()Remove
defaultPropsinuseCOMPONENT📝Check also JSDoc comments for the function and remove
defaultPropsfrom thereRemove
mergePropsBefore
After
propsthat are affecting component's state or styling should go directly tostateobject, they should not go tostate.rootonClick,onKeyDown) should go to a matching slot (root,icon)state.componentsshould have hardcoded values with matching elementstate.rootshould usegetNativeElementProps(),refgoes therestate.icon& other slots should useresolveShorthand()propsshould not be spreaded tostateDefine type for slots
Please define a new type for slots in
COMPONENT.types.ts(optionally) Define
COMPONENTCommonstypeIf you
propsthat are used instate&propsplease define a separate interface for them:📝 All properties are required
Update types for a component
Props
📝
React.HTMLAttributesare not in props anymoreState
📝
refis not a root property ofstateUpdate
getSlots()In
renderCOMPONENT():Update
useCOMPONENTStyles()Utilities
Components
@fluentui/react-accordionRoot as slot implementation #19483@fluentui/react-avatarRefactor Avatar to remove mergeProps #19449@fluentui/react-badgereact-badge: use simplified prop merging #19677@fluentui/react-buttonreact-button - Simplify prop merging #18814@fluentui/react-imagereact-image: Migrate to simplified slots #19745@fluentui/react-linkLink: Refactor to use simplified prop merging #19614@fluentui/react-menuRoot as slot implementation #19483@fluentui/react-textreact-text - Simplified prop merging and root as a slot #19711@fluentui/react-tooltipRefactor Tooltip to remove mergeProps #19428