Home > Net >  React and Material UI: How to include a space between Select and InputLabel?
React and Material UI: How to include a space between Select and InputLabel?

Time:03-12

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. enter image description here

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:

select padding-top

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>
  );
}

Edit MultipleSelectNative Material Demo (forked)

  • Related