Skip to content
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

[docs] Add Select TypeScript demos #15288

Merged
merged 12 commits into from
Apr 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions docs/src/pages/demos/selects/ControlledOpenSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React from 'react';
import { makeStyles, Theme } from '@material-ui/core/styles';
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import FormControl from '@material-ui/core/FormControl';
import Select from '@material-ui/core/Select';
import Button from '@material-ui/core/Button';

const useStyles = makeStyles((theme: Theme) => ({
button: {
display: 'block',
marginTop: theme.spacing(2),
},
formControl: {
margin: theme.spacing(1),
minWidth: 120,
},
}));

function ControlledOpenSelect() {
const classes = useStyles();
const [age, setAge] = React.useState<string | number>('');
const [open, setOpen] = React.useState(false);

function handleChange(event: React.ChangeEvent<{ value: unknown }>) {
setAge(event.target.value as number);
}

function handleClose() {
setOpen(false);
}

function handleOpen() {
setOpen(true);
}

return (
<form autoComplete="off">
<Button className={classes.button} onClick={handleOpen}>
Open the select
</Button>
<FormControl className={classes.formControl}>
<InputLabel htmlFor="demo-controlled-open-select">Age</InputLabel>
<Select
open={open}
onClose={handleClose}
onOpen={handleOpen}
value={age}
onChange={handleChange}
inputProps={{
name: 'age',
id: 'demo-controlled-open-select',
}}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</form>
);
}

export default ControlledOpenSelect;
110 changes: 110 additions & 0 deletions docs/src/pages/demos/selects/CustomizedSelects.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import React from 'react';
import { makeStyles, withStyles } from '@material-ui/styles';
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import FormControl from '@material-ui/core/FormControl';
import Select from '@material-ui/core/Select';
import NativeSelect from '@material-ui/core/NativeSelect';
import InputBase from '@material-ui/core/InputBase';
import { Theme } from '@material-ui/core/styles';

const BootstrapInput = withStyles((theme: Theme) => ({
root: {
'label + &': {
marginTop: theme.spacing(3),
},
},
input: {
borderRadius: 4,
position: 'relative',
backgroundColor: theme.palette.background.paper,
border: '1px solid #ced4da',
fontSize: 16,
width: 'auto',
padding: '10px 26px 10px 12px',
transition: theme.transitions.create(['border-color', 'box-shadow']),
// Use the system font instead of the default Roboto font.
fontFamily: [
'-apple-system',
'BlinkMacSystemFont',
'"Segoe UI"',
'Roboto',
'"Helvetica Neue"',
'Arial',
'sans-serif',
'"Apple Color Emoji"',
'"Segoe UI Emoji"',
'"Segoe UI Symbol"',
].join(','),
'&:focus': {
borderRadius: 4,
borderColor: '#80bdff',
boxShadow: '0 0 0 0.2rem rgba(0,123,255,.25)',
},
},
}))(InputBase);

const useStyles = makeStyles((theme: Theme) => ({
root: {
display: 'flex',
flexWrap: 'wrap',
},
margin: {
margin: theme.spacing(1),
},
bootstrapFormLabel: {
fontSize: 18,
},
}));

function CustomizedSelects() {
const classes = useStyles();
const [age, setAge] = React.useState('');
const handleChange = (event: React.ChangeEvent<{ value: unknown }>) => {
setAge(event.target.value as string);
};
return (
<form className={classes.root} autoComplete="off">
<FormControl className={classes.margin}>
<InputLabel htmlFor="age-customized-select" className={classes.bootstrapFormLabel}>
Age
</InputLabel>
<BootstrapInput />
</FormControl>
<FormControl className={classes.margin}>
<InputLabel htmlFor="age-customized-select" className={classes.bootstrapFormLabel}>
Age
</InputLabel>
<Select
value={age}
onChange={handleChange}
input={<BootstrapInput name="age" id="age-customized-select" />}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
<FormControl className={classes.margin}>
<InputLabel htmlFor="age-customized-native-simple" className={classes.bootstrapFormLabel}>
Age
</InputLabel>
<NativeSelect
value={age}
onChange={handleChange}
input={<BootstrapInput name="age" id="age-customized-native-simple" />}
>
<option value="" />
<option value={10}>Ten</option>
<option value={20}>Twenty</option>
<option value={30}>Thirty</option>
</NativeSelect>
</FormControl>
</form>
);
}

export default CustomizedSelects;
97 changes: 97 additions & 0 deletions docs/src/pages/demos/selects/DialogSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React from 'react';
import { makeStyles, Theme } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogTitle from '@material-ui/core/DialogTitle';
import InputLabel from '@material-ui/core/InputLabel';
import Input from '@material-ui/core/Input';
import MenuItem from '@material-ui/core/MenuItem';
import FormControl from '@material-ui/core/FormControl';
import Select from '@material-ui/core/Select';

const useStyles = makeStyles((theme: Theme) => ({
container: {
display: 'flex',
flexWrap: 'wrap',
},
formControl: {
margin: theme.spacing(1),
minWidth: 120,
},
}));

function DialogSelect() {
const classes = useStyles();
const [state, setState] = React.useState({
open: false,
age: '',
});

const handleChange = (name: keyof typeof state) => (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a preference, but the state type could be broken into its own interface, referenced in the useState call above, and then used here as well!

Copy link
Contributor Author

@cahilfoley cahilfoley Apr 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's totally fair! I usually tend to use type inference when it will be handled correctly, especially for state hooks as there could be quite a few and it can get a bit tedious to write an interface for each if they are simple; that's just a preference too though - if you think it would be better to explicitly declare the interfaces in the examples then I'm happy to change it 👌

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see! That makes sense to me!

event: React.ChangeEvent<{ value: unknown }>,
) => {
setState({ ...state, [name]: Number(event.target.value) });
};

function handleClickOpen() {
setState({ ...state, open: true });
}

function handleClose() {
setState({ ...state, open: false });
}

return (
<div>
<Button onClick={handleClickOpen}>Open select dialog</Button>
<Dialog disableBackdropClick disableEscapeKeyDown open={state.open} onClose={handleClose}>
<DialogTitle>Fill the form</DialogTitle>
<DialogContent>
<form className={classes.container}>
<FormControl className={classes.formControl}>
<InputLabel htmlFor="age-native-simple">Age</InputLabel>
<Select
native
value={state.age}
onChange={handleChange('age')}
input={<Input id="age-native-simple" />}
>
<option value="" />
<option value={10}>Ten</option>
<option value={20}>Twenty</option>
<option value={30}>Thirty</option>
</Select>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel htmlFor="age-simple">Age</InputLabel>
<Select
value={state.age}
onChange={handleChange('age')}
input={<Input id="age-simple" />}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</form>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} color="primary">
Cancel
</Button>
<Button onClick={handleClose} color="primary">
Ok
</Button>
</DialogActions>
</Dialog>
</div>
);
}

export default DialogSelect;
Loading