Setting the minimum and maximum width of the MenuItem (popover) in Material-UI based on the width of the select component

I need the popover width to always match the width of the select component, regardless of the length of the text in the menu items. Setting autoWidth to either true or false is not providing a solution.

Below is the code for the select component:

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import OutlinedInput from '@material-ui/core/OutlinedInput';
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';

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

function SimpleSelect() {
  const classes = useStyles();
  const [values, setValues] = React.useState({
    age: '',
  });

  const inputLabel = React.useRef(null);
  const [labelWidth, setLabelWidth] = React.useState(0);
  React.useEffect(() => {
    setLabelWidth(inputLabel.current.offsetWidth);
  }, []);

  function handleChange(event) {
    setValues(oldValues => ({
      ...oldValues,
      [event.target.name]: event.target.value,
    }));
  }

  return (
    <form className={classes.root} autoComplete="off">
      <FormControl variant="outlined" className={classes.formControl}>
        <InputLabel ref={inputLabel} htmlFor="outlined-age-simple">
          Age
        </InputLabel>
        <Select
          value={values.age}
          onChange={handleChange}
          input={<OutlinedInput labelWidth={labelWidth} name="age" id="outlined-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>
  );
}

export default SimpleSelect;

What is the best way to achieve this alignment?

Answer №1

To ensure consistency in width between the menu items and form control, set an explicit width for both elements.

Here is some sample code to illustrate this:

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import InputLabel from "@material-ui/core/InputLabel";
import MuiMenuItem from "@material-ui/core/MenuItem";
import FormControl from "@material-ui/core/FormControl";
import Select from "@material-ui/core/Select";

const selectWidth = 150;

const useStyles = makeStyles(theme => ({
  root: {
    display: "flex",
    flexWrap: "wrap"
  },
  formControl: {
    margin: theme.spacing(1),
    width: selectWidth
  },
  selectEmpty: {
    marginTop: theme.spacing(2)
  }
}));

const useMenuItemStyles = makeStyles(theme => ({
  menuItem: {
    width: selectWidth
  }
}));

function MenuItem(props) {
  const classes = useMenuItemStyles(props);
  return <MuiMenuItem className={classes.menuItem} {...props} />;
}

function SimpleSelect() {
  const classes = useStyles();
  const [values, setValues] = React.useState({
    age: ""
  });

  function handleChange(event) {
    setValues(oldValues => ({
      ...oldValues,
      [event.target.name]: event.target.value
    }));
  }

  return (
    <form className={classes.root} autoComplete="off">
      <FormControl className={classes.formControl}>
        <InputLabel htmlFor="age-simple">Age</InputLabel>
        <Select
          value={values.age}
          onChange={handleChange}
          inputProps={{
            name: "age",
            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>
  );
}

export default SimpleSelect;

https://codesandbox.io/s/material-demo-y6tmn?fontsize=14

If you require the width of the Select to be dynamic based on the widest menu item, a more intricate solution would be needed.

Answer №2

The default setting for menus is to have automatic width and height, adjusting itself based on the child ListItems within it.

const customStyles = makeStyles((theme: Theme) =>
createStyles({
    listItem:{
        maxWidth:150,
        minWidth:100,
        padding: theme.spacing(2)
    }
}),

);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Preventing Users from Accessing NodeJS Express Routes: A Guide

Currently, I am working on a React application where I am utilizing Express to handle database queries and other functions. When trying to retrieve data for a specific user through the express routes like so: app.get("/u/:id", function(req, res) { ...

Deletion of ::before and ::after pseudo-elements upon addition of the class is-sticky

One issue I'm facing is that when the class is-sticky is applied to my menu, the ::before and ::after pseudo-elements on my logo become unnecessary. As I am not very proficient in JQuery, I have been unable to resolve this by searching online. The HT ...

Creating a MUI Datagrid with Individual Row-Controlled Checkboxes

One method of integrating Checkbox or TextField is by utilizing renderCell, which successfully displays the Checkboxes: https://i.stack.imgur.com/IyNRC.png However, I am unsure about how to individually control the Checkbox/TextField for each row. For in ...

Design a PHP tool for generating custom CSS frameworks

After attempting to create a CSS frame generator similar to this one, I stumbled upon a solution that works well with one exception. PHP Code: <?php function print_css($parentTag, $prefix, &$dup_checker) { if ($parentTag->nodeName == &apos ...

Strange activities observed during the management of state in react hooks, where the splice() function ends up eliminating the

My current setup involves maintaining a state to handle the addition of new JSX elements: const [display, setDisplay] = useState<IDisplay>({ BookingFormDropDown: [], } ); I have a function in onClick() which adds an elem ...

What is the best way to dynamically display a React Form using Next.js?

As a novice in web development, I am currently tackling a small project using next js. The task at hand involves creating a registration form for restaurants with numerous input fields, prompting me to consider splitting the form into two separate pages. O ...

What is the best way to effectively carry out a partial update using ReactJS?

During a recent job interview, the recruiter discussed the importance of handling partial updates and managing application size. As an example, he presented a Single Page Application (SPA) with a size of 8MB, which he deemed less than ideal. He emphasize ...

Steps for removing the label associated with an input field in an HTML form

I attempted to use JQuery and JavaScript in order to modify the CSS of a label to make it greyed out, but unfortunately I have not been able to achieve this. The label is positioned next to a checkbox, and although I am able to disable the checkbox, I hav ...

The Type {children: Element; } is distinct and does not share any properties with type IntrinsicAttributes

I am encountering an issue in my React application where I am unable to nest components within other components. The error is occurring in both the Header component and the Search component. Specifically, I am receiving the following error in the Header co ...

Detection of TextField blur event in Material UI

Is there a way to detect when the user leaves or focuses away from a field in Material UI TextField? I am looking for two events - one for entering and one for leaving the field. I know that we can use onFocus to handle entering the field, but is there an ...

What is the best way to display a div in Chrome without allowing any user interactions?

I currently have a <div> placed on top of my webpage that follows the mouse cursor. Occasionally, users are able to move the mouse quickly enough to enter the tracking <div>. Additionally, this <div> sometimes prevents users from clicking ...

I am experiencing an issue with mydaterangepicker and primeng where it is not displaying properly in the table header. Can anyone assist me with this

I am attempting to integrate mydaterangepicker () with primeng turbotable (since primeng calendar does not meet the requirements), but I am having trouble with its display. Could you please assist me with some CSS code or suggest an alternative solution? ...

Could not locate module: Issue: Unable to resolve './Firebase'

I'm a beginner with React and I've been working on setting up Firebase in my React application. import firebase from 'firebase/compat/app'; import 'firebase/compat/auth'; import 'firebase/compat/firestore'; var fire ...

Stopping the infinite refresh issue in your React webpack application

Every time I modify the TS file, Webpack keeps refreshing the page without stopping. The console message reads: "@ebpack 5.66.0 compiled successfully" I've searched online and experimented with various plugins, but none of them seem to solve the issu ...

React input with outlined phone number design

Hey there! I'm new to learning React, so this question might be easy for some, but any help is greatly appreciated. Right now, I'm working on a project using Material UI and I need to create an outlined phone number input with a flag and label th ...

Display a loading spinner at the bottom of a React-Native ListView

Trying to find a method to attach an activity indicator at the bottom of a ListView when the user has scrolled to the end and the app is fetching additional data from a server. I attempted adding the indicator after the ListView element, but it appears c ...

Transfer ERC20 tokens along with an Ethereum transaction

Is there a way to specify the ETH value for a transaction when using the "useContractWrite" hook? I need to send both ETH and ERC20 tokens. I am having trouble with nesting elements, asynchronous calls... I'm not sure how to handle this in wagmi. Any ...

Ways to disable HTML loading prior to CSS loading

After downloading a site template, I observed that the HTML is loaded first before the CSS. Is there a way to disable this? I am looking to create a preloader for the website. ...

CSS3 family tree tutorial: Incorporating a wife into the design

I came across a fascinating tutorial about creating a family tree using CSS3 only. However, I'm struggling to understand how to depict a marriage. To explain further: What the code currently accomplishes is this: what i aim to include is this: Alth ...

Launching the date/time selection tool through code in the Material UI framework

I'm currently working on a project that involves React and Material Design. I decided to utilize Material UI for its sleek Dat- and Time Pickers components. In my application, I have to set Start and End Times and Dates in a specific order. To stream ...