-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
feat: improve RadioButton
and RadioButtonGroup
types
#16648
feat: improve RadioButton
and RadioButtonGroup
types
#16648
Conversation
Changes: - Export prop interfaces for `RadioButton` and `RadioButtonGroup`. - Narrow `onChange` argument type for `RadioButtonGroupProps`. - Reference `RadioButtonProps` for `RadioButtonGroup` types where we are expecting a `RadioButton` value. - Add missing types for component `refs` and event handlers in `RadioButton` and `RadioButtonGroup`. - Simplify `getRadioButtons()` with a type assertion on `children` argument and refactoring to use an early return statement.
✅ Deploy Preview for v11-carbon-react ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify site configuration. |
✅ Deploy Preview for carbon-elements ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
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.
As a review aid, I left a few comments for additional context.
@@ -98,80 +98,85 @@ export interface RadioButtonProps | |||
required?: boolean; | |||
} | |||
|
|||
const RadioButton = React.forwardRef((props: RadioButtonProps, ref) => { |
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.
ref
is now correctly typed.
Most of the following diff below is due to prettier's formatting adjusting the indentation. I recommend viewing with ⚙️ whitespace changes hidden.
value: RadioButtonProps['value'], | ||
name: RadioButtonProps['name'], |
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.
We can directly reference other types within the same interface when the expected value is the same (e.g., props.name
and props.value
are what we're passing to the onChange
handler).
Referencing types this way provides more context and reduces the work later, should RadioButton
types change in the future.
This is also how it was originally typed (See DefinitelyTyped)
const innerLabelClasses = classNames( | ||
`${prefix}--radio-button__label-text`, | ||
{ | ||
[`${prefix}--visually-hidden`]: hideLabel, | ||
} | ||
); |
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.
This was an automatic prettier adjustment.
const uid = useId('radio-button'); | ||
const uniqueId = id || uid; | ||
|
||
function handleOnChange(event: React.ChangeEvent<HTMLInputElement>) { |
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.
As a bonus, I added some missing types while working in these files.
@@ -87,10 +88,11 @@ export interface RadioButtonGroupProps | |||
* the group changes | |||
*/ | |||
onChange?: ( | |||
selection: React.ReactNode, |
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.
The selection
will be the same as the RadioButton
value. ReactNode
is too broad.
if (!selected && (radioButton as ReactElement)?.props.checked) { | ||
newProps.checked = true; | ||
const mappedChildren = React.Children.map( | ||
children as ReactElement<RadioButtonProps>, |
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.
children
is now typed as a RadioButton
allowing us to inherit the types from RadioButtonProps
. Previously, all prop values referenced in this function were typed as any
.
This way, we no longer need to keep asserting the type of radioButton
.
if (!radioButton) { | ||
return; | ||
} |
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.
The null-check from 🔴 184 was moved up here as an early return.
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.
LGTM! 🚀
@@ -230,7 +241,7 @@ const RadioButtonGroup = React.forwardRef( | |||
const divRef = useRef<HTMLDivElement>(null); | |||
|
|||
// Slug is always size `mini` | |||
let normalizedSlug; | |||
let normalizedSlug: ReactElement | undefined; |
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.
This can be done across all components for Type Safety and Clarity
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.
Looks good to me 🔥
e582548
In #16186, the
selection
argument ofRadioButtonGroup
'sonChange
prop was changed toReactNode
instead ofstring | number
as written in the PR description. In addition to fixing that I have added some missing types and improved others.Changelog
RadioButton
andRadioButtonGroup
.onChange
argument type forRadioButtonGroupProps
.RadioButtonProps
forRadioButtonGroup
types where we are expecting aRadioButton
value.refs
and event handlers inRadioButton
andRadioButtonGroup
.getRadioButtons()
with a type assertion onchildren
argument and refactoring to use an early return statement.Testing / Reviewing
RadioButton
andRadioButtonGroup
for type errorsRadioButtons
used inside of a group (e.g., radio buttons are still correctly displayed and the group value changes when radio selections change.)