I'm using React
and Material UI
to make a web application. I'm using Select
to build a multi-select component. It's working OK. See the code that follows.
export const AvailableStations = () => {
const [personName, setPersonName] = React.useState([]);
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>
<Box textAlign='center'>
<FormControl sx={{ m: 0}}>
<InputLabel m={1} shrink htmlFor="select-multiple-native">
Native
</InputLabel>
<Select sx={{minWidth: 170, maxWidth: 170}}
multiple
native
value={personName}
// @ts-ignore Typings are not considering `native`
onChange={handleChangeMultiple}
label="Native"
inputProps={{
id: 'select-multiple-native',
}}
>
{names.map((name) => (
<option key={name} value={name}>
{name}
</option>
))}
</Select>
</FormControl>
</Box>
</div>
);
}
The problem is that the Select
content is overlapping the InputLabel
. See the image that follows.
Can anyone help me to include a separation between them?
CodePudding user response:
You can fix this by adjusting the padding-top on the select with some additions to the sx
prop:
<Select
sx={{
minWidth: 170,
maxWidth: 170,
pt: 1,
"& .MuiNativeSelect-select": { pt: "8.5px" }
}}
multiple
native
This adds one spacing unit of padding-top to the root element of the Select
. The next element within that has a default padding-top of 16.5px:
After adding 8px (one spacing unit) of padding-top on the outer element to avoid the option text overlapping with the label, that default padding-top needs to be reduced by 8px (16.5px - 8px = 8.5px
) in order to avoid causing the space above the first option to be bigger than the default.
Here's a full working example:
import * as React from "react";
import InputLabel from "@mui/material/InputLabel";
import FormControl from "@mui/material/FormControl";
import Select from "@mui/material/Select";
const names = [
"Oliver Hansen",
"Van Henry",
"April Tucker",
"Ralph Hubbard",
"Omar Alexander",
"Carlos Abbott",
"Miriam Wagner",
"Bradley Wilkerson",
"Virginia Andrews",
"Kelly Snyder"
];
export default function MultipleSelectNative() {
const [personName, setPersonName] = React.useState<string[]>([]);
const handleChangeMultiple = (
event: React.ChangeEvent<HTMLSelectElement>
) => {
const { options } = event.target;
const value: string[] = [];
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 sx={{ m: 1, minWidth: 120, maxWidth: 300 }}>
<InputLabel shrink htmlFor="select-multiple-native">
Native
</InputLabel>
<Select
sx={{
minWidth: 170,
maxWidth: 170,
pt: 1,
"& .MuiNativeSelect-select": { pt: "8.5px" }
}}
multiple
native
value={personName}
// @ts-ignore Typings are not considering `native`
onChange={handleChangeMultiple}
label="Native"
inputProps={{
id: "select-multiple-native"
}}
>
{names.map((name) => (
<option key={name} value={name}>
{name}
</option>
))}
</Select>
</FormControl>
</div>
);
}