-
-
Notifications
You must be signed in to change notification settings - Fork 351
[toggle-group][toggle] type safety #3173
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
commit: |
Bundle size report
Check out the code infra dashboard for more information about this PR. |
787028e to
84ff83c
Compare
84ff83c to
b5ae7e4
Compare
✅ Deploy Preview for base-ui ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Signed-off-by: Michael Hazan <michaelhazan@hilma.tech>
f39e177 to
81f77e4
Compare
81f77e4 to
a3ea128
Compare
Signed-off-by: Michael Hazan <michaelhazan@hilma.tech>
|
@mj12albert sorry it took me so long, work had me backed up 😅 it should be good now, because |
LukasTy
left a comment
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.
@michaldudak, is this still relevant after merging #3770?
|
@LukasTy, yes, I haven't noticed this PR. It's basically an equivalent of what I've recently done in #3788. This approach has a small issue we discussed internally: When Toggle's
Also, I'm afraid we can't use |
|
@michaldudak Thanks for sharing more details. 🙏 |
|
We discussed this with the team and agreed that we can proceed with this implementation ignoring the potentially incorrect types. To further prevent surprises, we can add a dev-time warning when a Toggle within a ToggleGroup doesn't have an explicit value. @michaelhazan, would you like to continue working on this? |
Sure! |
…group-type-safety
|
@michaldudak Hey! should be good now.. |
…oggleGroup` values
LukasTy
left a comment
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.
Thank you for your effort. 🙏
Leaving a few suggestions and one discussion point.
| export namespace ToggleGroup { | ||
| export type State = ToggleGroupState; | ||
| export type Props = ToggleGroupProps; | ||
| export type Props<Value extends string> = ToggleGroupProps<Value>; |
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.
Correct me if I'm wrong, but is there a use case for why we still need the generic here? 🤔
As far as I can see, it only helps with type inference, like if you have the following:
type Alignment = 'horizontal' | 'vertical';
const alignments: Alignment[] = ['horizontal', 'vertical'];
<ToggleGroup
multiple
defaultValue={alignments}
// this is going to know that the type is `Alignment` instead of plain string as it is now
value={}
>But, the current types don't seem to block the above usage as well.
If we go with this, then we should probably adjust other components (i.e., RadioGroup, CheckboxGroup) accordingly.
WDYT @michaldudak?
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.
I think this is useful and addresses #3756
(it should also be able to infer the value arg in onValueChange I assume)
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.
Gotcha. Makes sense, especially given we already have others noticing this shortcoming. 👍
I think we need to do a follow-up and address this issue for all relevant components.
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.
@LukasTy would you like me to fix it in this pr? or leave it for now?
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.
I think we can keep this one isolated to these specific components.
WDYT?
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.
for sure
0780e10 to
9cdae80
Compare
…o check for it also made the generic type in `ToggleGroup` & `Toggle` default to `string` to match the behavior in `SliderRootProps`.
9cdae80 to
cf9b46e
Compare
|
@LukasTy fixed! did i get that right? 😅 please note i've also set the props's generic type to equal |
| useIsoLayoutEffect(() => { | ||
| if (groupContext && valueProp === undefined) { | ||
| warn( | ||
| 'A `<Toggle>` component rendered in a `<ToggleGroup>` has no explicit `value` prop. This can cause type issues between the Toggle Group and Toggle values. Provide the `<Toggle>` with a `value` prop matching the `<ToggleGroup>` values prop type.', |
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.
What type issue does this cause?
This seems like a clumsy but legit way to use toggle group without values:
<ToggleGroup>
<Toggle onPressedChange={setState1} />
<Toggle onPressedChange={setState2} />
</ToggleGroup>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.
I think Michal raised this point that in case the <ToggleGroup> defaultValue would have a type of Alignment[], then you'd end up in a slight type discrepancy, because internally a Toggle without a value would have generated an internal value type of string.
However, this is a very edge case condition. 🤔
Would it make more sense if the warning would be shown only in your case (no value on the Toggle and no default and no direct value on the Toggle Group)?
Closes #3142.
Closes #3756.
Note
Originally this was meant to only introduce generic types to the
ToggleGroup, but i realized while working on this thatToggletoo had to be changed to handle a generic value.