[core] Type custom onChange implementations with a generic react event#21552
Merged
[core] Type custom onChange implementations with a generic react event#21552
onChange implementations with a generic react event#21552Conversation
eps1lon
commented
Jun 23, 2020
| fullWidth?: boolean; | ||
| icon?: string | React.ReactElement; | ||
| label?: React.ReactNode; | ||
| onChange?: (event: React.ChangeEvent<{ checked: boolean }>, value: any) => void; |
Member
Author
There was a problem hiding this comment.
I don't know why the target should implement checked. Probably some wrong c&p while refactoring.
oliviertassinari
approved these changes
Jun 23, 2020
Member
oliviertassinari
left a comment
There was a problem hiding this comment.
Awesome, I was leaning in the same direction. I think that it could be interesting to add a test case for #20191 too (don't we solve this issue too?).
Member
Author
Yes! Thanks for linking it. It's the same underlying issue. Will add the same test. I'm also checking out again why our docs were working fine |
5e423d2 to
31f261c
Compare
onChange as a generic react eventonChange implementations with a generic react event
3211703 to
4977b6f
Compare
oliviertassinari
approved these changes
Jun 24, 2020
This was referenced Jun 26, 2020
2 tasks
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #17454
Closes #20191
for:
Accordion(formerExpansionPanel)BottomNavigationSliderTabsThese components do not necessarily dispatch a react change event. They only passes whatever event triggered the change in value. I don't want to type it as exact as possible (
FocusEvent | ClickEvent) because that restricts our implementation. We simply say that it's any react event at this point. You would have to narrow it later anyway which we can always do later if there are legitimate use cases.The takeaway from this typing is that
event.targetis not interchangeable with arefon the component.event.targetcould point to any element that the component rendered. It's a bit unfortunate that we overload what is usually considered a change event. We have to make the trade-off at some point: either when passing props (Slider behaves just like any other input: I pass avalueandonChange) or when typing theonChange(event.target === event.currentTarget).Removes
onChangetypes fromBottomNavigationActionandTab. These are overridden anyway and considered private.About OverrideableComponent changes
Let's say we have a component that implements the
componentlikePreviously we assumed that any prop that is implemented by
Buttonis also forwarded to the passedcomponent.However, this is almost never the case e.g. in
Tabwe expect that the givencomponenteither doesn't implementonChangeor as the same type.The reality is that
Tabdoes not forwardonChangeand thereforecomponentnever "sees"onChange.There are some exceptions e.g.
ButtonBaseinterceptshrefbut also passes it along. We currently expect thehrefto be a string but this isn't required if acomponentis passed.Instead of expecting the passed
componentto extend the props ofButtonwe should expectcomponentto implement a separate interface e.g. inthe passed
componentneeds to implement thetargetprop. It doesn't need to implementexternalnor should it ever expect to receive anexternalprop if it is used in<Button />.This change is a bit scary but safe in
next. I'll follow-up in a later PR with more test and experimentation if it makes sense to requirecomponentto implement a certain interface.Future work
React.ChangeEvent<{}>. It works structurally right now but has some implications that can't be expressed via types yet so we need to be careful with using it.