-
Notifications
You must be signed in to change notification settings - Fork 2.8k
fix(react-components): use custom RefAttributes instead of React.RefAttributes #34590
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "none", | ||
"comment": "fix: use custom RefAttributes instead of React.RefAttributes", | ||
"packageName": "@fluentui/react-migration-v8-v9", | ||
"email": "[email protected]", | ||
"dependentChangeType": "none" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "none", | ||
"comment": "chore: use custom RefAttributes instead of React.RefAttributes", | ||
"packageName": "@fluentui/react-nav-preview", | ||
"email": "[email protected]", | ||
"dependentChangeType": "none" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "none", | ||
"comment": "chore: disable lint error on React.RefAttibute within getIntrinsicElementProps", | ||
"packageName": "@fluentui/react-utilities", | ||
"email": "[email protected]", | ||
"dependentChangeType": "none" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,18 @@ module.exports = { | |
}, | ||
], | ||
'react-compiler/react-compiler': ['error'], | ||
'@typescript-eslint/no-restricted-types': [ | ||
'error', | ||
{ | ||
types: { | ||
'React.RefAttributes': { | ||
message: | ||
'`React.RefAttributes` is leaking string starting @types/[email protected] creating invalid type contracts. Use `RefAttributes` from @fluentui/react-utilities instead', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tbh this is not the most robust rule as it doesn't work on interface extensions, and also doesn't distinguishes about the imports. the autofixer is also naive as it won't provide proper import. for now it's good enough, but in future we will introduce custom rule |
||
fixWith: 'RefAttributes', | ||
}, | ||
}, | ||
}, | ||
], | ||
}, | ||
overrides: [ | ||
// Enable rules requiring type info only for appropriate files/circumstances | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,7 +42,7 @@ export const brandWeb: BrandVariants; | |
export const ButtonShim: React_2.ForwardRefExoticComponent<IBaseButtonProps & React_2.RefAttributes<HTMLButtonElement>>; | ||
|
||
// @public (undocumented) | ||
export const CheckboxShim: React_2.ForwardRefExoticComponent<Pick<ICheckboxProps, "label" | "title" | "className" | "key" | "disabled" | "name" | "defaultChecked" | "id" | "onChange" | "componentRef" | "styles" | "theme" | "checked" | "ariaLabel" | "required" | "ariaDescribedBy" | "ariaLabelledBy" | "ariaPositionInSet" | "ariaSetSize" | "boxSide" | "checkmarkIconProps" | "defaultIndeterminate" | "indeterminate" | "inputProps" | "onRenderLabel"> & React_2.RefAttributes<HTMLInputElement>>; | ||
export const CheckboxShim: React_2.ForwardRefExoticComponent<ICheckboxProps & React_2.RefAttributes<HTMLInputElement>>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is the same API without unwrapping -> result of normalizing patterns and using explicit function types |
||
|
||
// @public | ||
export type ColorVariants = { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,7 @@ const getClassNames = classNamesFunction<ICheckboxStyleProps, ICheckboxStyles>({ | |
useStaticStyles: false, | ||
}); | ||
|
||
export const CheckboxShim = React.forwardRef((props: ICheckboxProps, _ref: React.ForwardedRef<HTMLInputElement>) => { | ||
export const CheckboxShim = React.forwardRef((props, _ref) => { | ||
'use no memo'; | ||
|
||
const { className, styles: stylesV8, onRenderLabel, label, componentRef } = props; | ||
|
@@ -51,6 +51,11 @@ export const CheckboxShim = React.forwardRef((props: ICheckboxProps, _ref: React | |
indicator={{ className: mergeClasses('ms-Checkbox-checkbox', styles.checkbox) }} | ||
/> | ||
); | ||
}); | ||
// NOTE: cast is necessary as `ICheckboxProps` extends React.Ref<HTMLDivElement> which is not compatible with our defined React.Ref<HTMLInputElement> | ||
}) as React.ForwardRefExoticComponent< | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unified pattern with the rest of migration code - in this case simple advance declaration wouldn't match because the ref generic mismatch |
||
ICheckboxProps & | ||
// eslint-disable-next-line @typescript-eslint/no-restricted-types -- this is expected in order to be compatible with v8, as every v8 interface contains `React.RefAttributes` to accept ref as string | ||
React.RefAttributes<HTMLInputElement> | ||
>; | ||
|
||
CheckboxShim.displayName = 'CheckboxShim'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,16 +11,18 @@ type HTMLAttributes = React.HTMLAttributes<any>; | |
* element type. | ||
* | ||
* Equivalent to {@link getNativeElementProps}, but more type-safe. | ||
* | ||
* @param tagName - The slot's default element type (e.g. 'div') | ||
* @param props - The component's props object | ||
* @param excludedPropNames - List of native props to exclude from the returned value | ||
*/ | ||
export const getIntrinsicElementProps = < | ||
Props extends UnknownSlotProps, | ||
ExcludedPropKeys extends Extract<keyof Props, string> = never, | ||
>( | ||
/** The slot's default element type (e.g. 'div') */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is invalid "JSDOC" - moved to proper JSDoc format |
||
tagName: NonNullable<Props['as']>, | ||
/** The component's props object */ | ||
// eslint-disable-next-line @typescript-eslint/no-restricted-types -- in order to not introduce Type Restriction CHANGe which is kinda "breaking change from Types POV", we don't enforce our custom `RefAttributes` in this API, to be compatible with scenarios where non v9 interfaces might be used. This may/will change with React 19 | ||
props: Props & React.RefAttributes<InferredElementRefType<Props>>, | ||
Hotell marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/** List of native props to exclude from the returned value */ | ||
excludedPropNames?: ExcludedPropKeys[], | ||
) => { | ||
// 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.
although api.md changed the type is exactly the same -> thus no bump