今天要講解的是 Select 組件,官網文件連結在這裡。
其實跟原生 html 裡的 select tag 一樣,只不過換了皮膚,以下是預設的設定:
// 這裡要把它撐開不然預設值很扁
const useStyles = makeStyles({
formControl: {
margin: 8,
minWidth: 120,
},
selectEmpty: {
marginTop: 16,
},
});
export default function SimpleSelect() {
const classes = useStyles();
const [age, setAge] = React.useState('');
const handleChange = (event) => {
setAge(event.target.value);
};
return (
<div>
<FormControl className={classes.formControl}>
<InputLabel id="demo-simple-select-label">Age</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={age}
onChange={handleChange}
>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel id="demo-simple-select-helper-label">Age</InputLabel>
<Select
labelId="demo-simple-select-helper-label"
id="demo-simple-select-helper"
value={age}
onChange={handleChange}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>Some important helper text</FormHelperText>
</FormControl>
<FormControl className={classes.formControl}>
<Select
value={age}
onChange={handleChange}
displayEmpty
className={classes.selectEmpty}
inputProps={{ 'aria-label': 'Without label' }}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>Without label</FormHelperText>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel shrink id="demo-simple-select-placeholder-label-label">
Age
</InputLabel>
<Select
labelId="demo-simple-select-placeholder-label-label"
id="demo-simple-select-placeholder-label"
value={age}
onChange={handleChange}
displayEmpty
className={classes.selectEmpty}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>Label + placeholder</FormHelperText>
</FormControl>
<FormControl className={classes.formControl} disabled>
<InputLabel id="demo-simple-select-disabled-label">Name</InputLabel>
<Select
labelId="demo-simple-select-disabled-label"
id="demo-simple-select-disabled"
value={age}
onChange={handleChange}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>Disabled</FormHelperText>
</FormControl>
<FormControl className={classes.formControl} error>
<InputLabel id="demo-simple-select-error-label">Name</InputLabel>
<Select
labelId="demo-simple-select-error-label"
id="demo-simple-select-error"
value={age}
onChange={handleChange}
renderValue={(value) => (`⚠️ - ${value}`)}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>Error</FormHelperText>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel id="demo-simple-select-readonly-label">Name</InputLabel>
<Select
labelId="demo-simple-select-readonly-label"
id="demo-simple-select-readonly"
value={age}
onChange={handleChange}
inputProps={{ readOnly: true }}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>Read only</FormHelperText>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel id="demo-simple-select-autowidth-label">Age</InputLabel>
<Select
labelId="demo-simple-select-autowidth-label"
id="demo-simple-select-autowidth"
value={age}
onChange={handleChange}
autoWidth
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>Auto width</FormHelperText>
</FormControl>
<FormControl className={classes.formControl}>
<Select
value={age}
onChange={handleChange}
displayEmpty
className={classes.selectEmpty}
inputProps={{ 'aria-label': 'Without label' }}
>
<MenuItem value="" disabled>
Placeholder
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>Placeholder</FormHelperText>
</FormControl>
<FormControl required className={classes.formControl}>
<InputLabel id="demo-simple-select-required-label">Age</InputLabel>
<Select
labelId="demo-simple-select-required-label"
id="demo-simple-select-required"
value={age}
onChange={handleChange}
className={classes.selectEmpty}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>Required</FormHelperText>
</FormControl>
<FormControl variant="outlined" className={classes.formControl}>
<InputLabel id="demo-simple-select-outlined-label">Age</InputLabel>
<Select
labelId="demo-simple-select-outlined-label"
id="demo-simple-select-outlined"
value={age}
onChange={handleChange}
label="Age"
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
<FormControl variant="filled" className={classes.formControl}>
<InputLabel id="demo-simple-select-filled-label">Age</InputLabel>
<Select
labelId="demo-simple-select-filled-label"
id="demo-simple-select-filled"
value={age}
onChange={handleChange}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</div>
);
}
Select 組件可以與原生 select 元素互換,如果要應用一些進階功能,如組合框、多選、自動完成、異步或自訂創建,請前往Autocompelete,它是“react-select”和“downshift”套件的改進版。
export default function NativeSelects() {
const classes = useStyles();
const [state, setState] = React.useState({
age: '',
name: 'hai',
});
const handleChange = (event) => {
const name = event.target.name;
setState({
...state,
[name]: event.target.value,
});
};
return (
<div>
<FormControl className={classes.formControl}>
<InputLabel htmlFor="age-native-simple">Age</InputLabel>
<Select
native
value={state.age}
onChange={handleChange}
inputProps={{
name: 'age',
id: 'age-native-simple',
}}
>
<option aria-label="None" 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-native-helper">Age</InputLabel>
<NativeSelect
value={state.age}
onChange={handleChange}
inputProps={{
name: 'age',
id: 'age-native-helper',
}}
>
<option aria-label="None" value="" />
<option value={10}>Ten</option>
<option value={20}>Twenty</option>
<option value={30}>Thirty</option>
</NativeSelect>
<FormHelperText>Some important helper text</FormHelperText>
</FormControl>
<FormControl className={classes.formControl}>
<NativeSelect
value={state.age}
onChange={handleChange}
name="age"
className={classes.selectEmpty}
inputProps={{ 'aria-label': 'age' }}
>
<option value="">None</option>
<option value={10}>Ten</option>
<option value={20}>Twenty</option>
<option value={30}>Thirty</option>
</NativeSelect>
<FormHelperText>With visually hidden label</FormHelperText>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel shrink htmlFor="age-native-label-placeholder">
Age
</InputLabel>
<NativeSelect
value={state.age}
onChange={handleChange}
inputProps={{
name: 'age',
id: 'age-native-label-placeholder',
}}
>
<option value="">None</option>
<option value={10}>Ten</option>
<option value={20}>Twenty</option>
<option value={30}>Thirty</option>
</NativeSelect>
<FormHelperText>Label + placeholder</FormHelperText>
</FormControl>
<FormControl className={classes.formControl} disabled>
<InputLabel htmlFor="name-native-disabled">Name</InputLabel>
<NativeSelect
value={state.name}
onChange={handleChange}
inputProps={{
name: 'name',
id: 'name-native-disabled',
}}
>
<option value="">None</option>
<optgroup label="Author">
<option value="hai">Hai</option>
</optgroup>
<optgroup label="Contributors">
<option value="olivier">Olivier</option>
<option value="kevin">Kevin</option>
</optgroup>
</NativeSelect>
<FormHelperText>Disabled</FormHelperText>
</FormControl>
<FormControl className={classes.formControl} error>
<InputLabel htmlFor="name-native-error">Name</InputLabel>
<NativeSelect
value={state.name}
onChange={handleChange}
name="name"
inputProps={{
id: 'name-native-error',
}}
>
<optgroup label="Author">
<option value="hai">Hai</option>
</optgroup>
<optgroup label="Contributors">
<option value="olivier">Olivier</option>
<option value="kevin">Kevin</option>
</optgroup>
</NativeSelect>
<FormHelperText>Error</FormHelperText>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel htmlFor="uncontrolled-native">Name</InputLabel>
<NativeSelect
defaultValue={30}
inputProps={{
name: 'name',
id: 'uncontrolled-native',
}}
>
<option value={10}>Ten</option>
<option value={20}>Twenty</option>
<option value={30}>Thirty</option>
</NativeSelect>
<FormHelperText>Uncontrolled</FormHelperText>
</FormControl>
<FormControl className={classes.formControl}>
<NativeSelect
className={classes.selectEmpty}
value={state.age}
name="age"
onChange={handleChange}
inputProps={{ 'aria-label': 'age' }}
>
<option value="" disabled>
Placeholder
</option>
<option value={10}>Ten</option>
<option value={20}>Twenty</option>
<option value={30}>Thirty</option>
</NativeSelect>
<FormHelperText>Placeholder</FormHelperText>
</FormControl>
<FormControl required className={classes.formControl}>
<InputLabel htmlFor="age-native-required">Age</InputLabel>
<Select
native
value={state.age}
onChange={handleChange}
name="age"
inputProps={{
id: 'age-native-required',
}}
>
<option aria-label="None" value="" />
<option value={10}>Ten</option>
<option value={20}>Twenty</option>
<option value={30}>Thirty</option>
</Select>
<FormHelperText>Required</FormHelperText>
</FormControl>
<FormControl variant="outlined" className={classes.formControl}>
<InputLabel htmlFor="outlined-age-native-simple">Age</InputLabel>
<Select
native
value={state.age}
onChange={handleChange}
label="Age"
inputProps={{
name: 'age',
id: 'outlined-age-native-simple',
}}
>
<option aria-label="None" value="" />
<option value={10}>Ten</option>
<option value={20}>Twenty</option>
<option value={30}>Thirty</option>
</Select>
</FormControl>
<FormControl variant="filled" className={classes.formControl}>
<InputLabel htmlFor="filled-age-native-simple">Age</InputLabel>
<Select
native
value={state.age}
onChange={handleChange}
inputProps={{
name: 'age',
id: 'filled-age-native-simple',
}}
>
<option aria-label="None" value="" />
<option value={10}>Ten</option>
<option value={20}>Twenty</option>
<option value={30}>Thirty</option>
</Select>
</FormControl>
</div>
);
}
Select 組件可以處理多個選擇,通過 multiple 屬性啟用,與單選一樣,可以通過 onChange 回調中的 event.target.value 來提取新值。
const useStyles = makeStyles((theme) => ({
formControl: {
margin: theme.spacing(1),
minWidth: 120,
maxWidth: 300,
},
chips: {
display: 'flex',
flexWrap: 'wrap',
},
chip: {
margin: 2,
},
noLabel: {
marginTop: theme.spacing(3),
},
}));
const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250,
},
},
};
const names = [
'Oliver Hansen',
'Van Henry',
'April Tucker',
'Ralph Hubbard',
'Omar Alexander',
'Carlos Abbott',
'Miriam Wagner',
'Bradley Wilkerson',
'Virginia Andrews',
'Kelly Snyder',
];
function getStyles(name, personName, theme) {
return {
fontWeight:
personName.indexOf(name) === -1
? theme.typography.fontWeightRegular
: theme.typography.fontWeightMedium,
};
}
export default function MultipleSelect() {
const classes = useStyles();
const theme = useTheme();
const [personName, setPersonName] = React.useState([]);
const handleChange = (event) => {
setPersonName(event.target.value);
};
const handleChangeMultiple = (event) => {
const { options } = event.target;
const value = [];
for (let i = 0, l = options.length; i < l; i += 1) {
if (options[i].selected) {
value.push(options[i].value);
}
}
setPersonName(value);
};
return (
<div>
<FormControl className={classes.formControl}>
<InputLabel id="demo-mutiple-name-label">Name</InputLabel>
<Select
labelId="demo-mutiple-name-label"
id="demo-mutiple-name"
multiple
value={personName}
onChange={handleChange}
input={<Input />}
MenuProps={MenuProps}
>
{names.map((name) => (
<MenuItem key={name} value={name} style={getStyles(name, personName, theme)}>
{name}
</MenuItem>
))}
</Select>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel id="demo-mutiple-checkbox-label">Tag</InputLabel>
<Select
labelId="demo-mutiple-checkbox-label"
id="demo-mutiple-checkbox"
multiple
value={personName}
onChange={handleChange}
input={<Input />}
renderValue={(selected) => selected.join(', ')}
MenuProps={MenuProps}
>
{names.map((name) => (
<MenuItem key={name} value={name}>
<Checkbox checked={personName.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel id="demo-mutiple-chip-label">Chip</InputLabel>
<Select
labelId="demo-mutiple-chip-label"
id="demo-mutiple-chip"
multiple
value={personName}
onChange={handleChange}
input={<Input id="select-multiple-chip" />}
renderValue={(selected) => (
<div className={classes.chips}>
{selected.map((value) => (
<Chip key={value} label={value} className={classes.chip} />
))}
</div>
)}
MenuProps={MenuProps}
>
{names.map((name) => (
<MenuItem key={name} value={name} style={getStyles(name, personName, theme)}>
{name}
</MenuItem>
))}
</Select>
</FormControl>
<FormControl className={clsx(classes.formControl, classes.noLabel)}>
<Select
multiple
displayEmpty
value={personName}
onChange={handleChange}
input={<Input />}
renderValue={(selected) => {
if (selected.length === 0) {
return <em>Placeholder</em>;
}
return selected.join(', ');
}}
MenuProps={MenuProps}
inputProps={{ 'aria-label': 'Without label' }}
>
<MenuItem disabled value="">
<em>Placeholder</em>
</MenuItem>
{names.map((name) => (
<MenuItem key={name} value={name} style={getStyles(name, personName, theme)}>
{name}
</MenuItem>
))}
</Select>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel shrink htmlFor="select-multiple-native">
Native
</InputLabel>
<Select
multiple
native
value={personName}
onChange={handleChangeMultiple}
inputProps={{
id: 'select-multiple-native',
}}
>
{names.map((name) => (
<option key={name} value={name}>
{name}
</option>
))}
</Select>
</FormControl>
</div>
);
}
以上就是今天的全部內容了,進階用法的部分我們後面會再提到,明天會接著slider的部分對inputs組件做個總結。