-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
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
[Select] Fix incorrect event.target type in onChange #15272
Merged
Merged
Changes from 2 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
073fa25
[docs]: Adding TS demo for MaxWidthDialog
sperry94 678f857
[docs] Prefer casting write instead of read
eps1lon b4b4971
casting MenuItem value, using onChange value param
sperry94 ffc6f5e
[SelectInput] Fix event.target type in onChange callback
eps1lon 5c04e3c
Merge branch 'next' into pr/sperry94/15272
eps1lon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { createStyles, Theme, withStyles, WithStyles } from '@material-ui/core/styles'; | ||
import Button from '@material-ui/core/Button'; | ||
import Dialog, { DialogProps } from '@material-ui/core/Dialog'; | ||
import DialogActions from '@material-ui/core/DialogActions'; | ||
import DialogContent from '@material-ui/core/DialogContent'; | ||
import DialogContentText from '@material-ui/core/DialogContentText'; | ||
import DialogTitle from '@material-ui/core/DialogTitle'; | ||
import FormControl from '@material-ui/core/FormControl'; | ||
import FormControlLabel from '@material-ui/core/FormControlLabel'; | ||
import InputLabel from '@material-ui/core/InputLabel'; | ||
import MenuItem from '@material-ui/core/MenuItem'; | ||
import Select from '@material-ui/core/Select'; | ||
import Switch from '@material-ui/core/Switch'; | ||
|
||
const styles = (theme: Theme) => | ||
createStyles({ | ||
form: { | ||
display: 'flex', | ||
flexDirection: 'column', | ||
margin: 'auto', | ||
width: 'fit-content', | ||
}, | ||
formControl: { | ||
marginTop: theme.spacing(2), | ||
minWidth: 120, | ||
}, | ||
formControlLabel: { | ||
marginTop: theme.spacing(1), | ||
}, | ||
}); | ||
|
||
export type MaxWidthDialogProps = WithStyles<typeof styles>; | ||
|
||
export interface MaxWidthDialogState { | ||
open: boolean; | ||
fullWidth: boolean; | ||
maxWidth: DialogProps['maxWidth']; | ||
} | ||
|
||
class MaxWidthDialog extends React.Component<MaxWidthDialogProps, MaxWidthDialogState> { | ||
state: MaxWidthDialogState = { | ||
open: false, | ||
fullWidth: true, | ||
maxWidth: 'sm', | ||
}; | ||
|
||
handleClickOpen = () => { | ||
this.setState({ open: true }); | ||
}; | ||
|
||
handleClose = () => { | ||
this.setState({ open: false }); | ||
}; | ||
|
||
handleMaxWidthChange = (event: React.ChangeEvent<HTMLSelectElement>) => { | ||
const maxWidth = | ||
event.target.value === 'false' ? false : (event.target.value as DialogProps['maxWidth']); | ||
|
||
this.setState({ maxWidth }); | ||
}; | ||
|
||
handleFullWidthChange = (event: React.ChangeEvent<HTMLInputElement>) => { | ||
this.setState({ fullWidth: event.target.checked }); | ||
}; | ||
|
||
render() { | ||
const { classes } = this.props; | ||
|
||
return ( | ||
<React.Fragment> | ||
<Button variant="outlined" color="primary" onClick={this.handleClickOpen}> | ||
Open max-width dialog | ||
</Button> | ||
<Dialog | ||
fullWidth={this.state.fullWidth} | ||
maxWidth={this.state.maxWidth} | ||
open={this.state.open} | ||
onClose={this.handleClose} | ||
aria-labelledby="max-width-dialog-title" | ||
> | ||
<DialogTitle id="max-width-dialog-title">Optional sizes</DialogTitle> | ||
<DialogContent> | ||
<DialogContentText> | ||
You can set my maximum width and whether to adapt or not. | ||
</DialogContentText> | ||
<form className={classes.form} noValidate> | ||
<FormControl className={classes.formControl}> | ||
<InputLabel htmlFor="max-width">maxWidth</InputLabel> | ||
<Select | ||
value={this.state.maxWidth} | ||
onChange={this.handleMaxWidthChange} | ||
inputProps={{ | ||
name: 'max-width', | ||
id: 'max-width', | ||
}} | ||
> | ||
<MenuItem value="false">false</MenuItem> | ||
<MenuItem value="xs">xs</MenuItem> | ||
<MenuItem value="sm">sm</MenuItem> | ||
<MenuItem value="md">md</MenuItem> | ||
<MenuItem value="lg">lg</MenuItem> | ||
<MenuItem value="xl">xl</MenuItem> | ||
</Select> | ||
</FormControl> | ||
<FormControlLabel | ||
className={classes.formControlLabel} | ||
control={ | ||
<Switch | ||
checked={this.state.fullWidth} | ||
onChange={this.handleFullWidthChange} | ||
value="fullWidth" | ||
/> | ||
} | ||
label="Full width" | ||
/> | ||
</form> | ||
</DialogContent> | ||
<DialogActions> | ||
<Button onClick={this.handleClose} color="primary"> | ||
Close | ||
</Button> | ||
</DialogActions> | ||
</Dialog> | ||
</React.Fragment> | ||
); | ||
} | ||
} | ||
|
||
(MaxWidthDialog as React.ComponentClass<MaxWidthDialogProps, MaxWidthDialogState>).propTypes = { | ||
classes: PropTypes.object.isRequired, | ||
} as any; | ||
|
||
export default withStyles(styles)(MaxWidthDialog); |
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.
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.
Why changing the 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.
This had to be changed because
MenuItem
only acceptsstring | number | string[] | undefined
for its type. The change in thehandleMaxWidthChange
covers converting this back to aboolean
when this value is chosen!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.
Could MenuItem accept
boolean
too?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.
Should be addressed in #15245.
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're breaking quite a bit of DOM/type safety for some tiny conveniences. We could just use an empty string and check for that. Otherwise we need to override the actual DOM types.
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.
It's passed straight down to the DOM node, yes. It's probably better to override this with
unknown
since it is also used as a child ofSelect
. But it's also used without theSelect
context. In different contexts you might be missing the type checking. I think we should use either some type casting or add the runtime overhead that ensures a soundvalue
type. The value ofMenuItem
should not be changed.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.
So should we keep the value of MenuItem as false and cast it to unknown?
Also, will there be issues trying to read event.target.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.
They always end up as strings in the the DOM. With the exception of
Radio
andRadioGroup
no component reads this value though. We try to only use the value from props.I think the
Select
already passes thevalue
as the second argument toonChange
. Thatvalue
is the value from the prop and not the DOM. You could use that instead and just force it into state viaany
/unknown
.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.
ok I see. So the idea is to mostly use the
value
returned as the second param in theonChange
event? I will push a change!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.
Well it depends. If you want the value you passed as a prop you use the second param (type
unknown
). If you want the value in the DOM you useevent.target.value
(typestring
).