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

The React Hook useEffect is missing a dependency: 'handleLogout'. Make sure to either add it to the dependency array or remove it from the useEffect hook

import { useState, useEffect } from "react"; import LoginModal from "./LoginModal"; import { NavLink, useLocation, useNavigate } from "react-router-dom"; import { useDispatch } from "react-redux"; import { userLogout ...

The hydration error in next js is causing this code to malfunction

Why am I encountering a hydration error with this code in NextJS? The Items variable is an array of ReactNode's. Any suggestions for an alternative approach? I've searched extensively for information but haven't found anything related to Nex ...

The Next JS build process is failing to generate certain paths

Issue with Anime Database App Deployment A problem arose when I developed an anime database app using Nextjs and deployed it on Vercel. Although the build was successful and the initial page rendered properly, only a few dynamic routes displayed correctly ...

Adding a <span> element within an <h1> tag in WordPress

I am attempting to create this layout in Wordpress using the code <h1>This is my <span>title</span></h1>, but I am unsure how to incorporate a <span> tag within the <?php the_title(); ?> function. After consulting the c ...

Issue encountered while accessing theme properties in a ReactJs component with Typescript

I am trying to pass the color of a theme to a component in my TypeScript project (as a beginner). However, I have encountered an error that I am struggling to resolve. The specific error message reads: 'Parameter 'props' implicitly has an ...

Apply a unique CSS class to the first two elements, then skip the following two elements, and continue this pattern using ngFor in Angular and flex styling

Here is a code snippet that displays a list of products using *ngFor in Angular: <div class="container-products"> <div class="item-product" *ngFor="let product of ['product A', 'product B', 'prod ...

IE6 disrupts stored layouts

I've encountered a strange issue with my design in IE6. It loads perfectly at first, but after reloading it a couple of times, everything suddenly collapses. The strange part is that when I upload an updated version, it fixes the issue, only to break ...

Editing the dimensions of the input in Bootstrap 4

Is there a way to adjust the width of the input and select elements? I want the input element to take up more space while the select element occupies less space. <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel=" ...

Height of Parent Div minus Margin Top equal to 100%

I am working on a layout that requires three divs with different heights and header sizes to be positioned 100% from the top of their parent, while taking into account the height of the headers. I could use jQuery to achieve this, but since it's a res ...

The slider thumb is not showing up properly on Microsoft Edge

Hey there! I'm experiencing an issue with the range slider's thumb display in Microsoft Edge. It appears to be positioned inside the track rather than outside as intended. Take a look at this snapshot for clarification: https://i.stack.imgur.co ...

Tips for handling function component state in NextJS

How can I access a state variable of component 1 in component 2, given that they are "brothers" components? There is only one state variable. My project utilizes nextjs with styled-components and typescript, along with an atomic design structure. I want ...

Customizing Your Keyboard Design with CSS

I need assistance in creating a compact and dynamic keyboard layout with characters only, but I have hit a roadblock. Here is the link to my current progress: http://jsfiddle.net/45zDd The design is almost complete, however, the second and third rows req ...

When using React Final Form, the onBlur event can sometimes hinder the

What is the reason that validation does not work when an onBlur event is added, as shown in the example below? <Field name="firstName" validate={required}> {({ input, meta }) => ( <div> <label>First Name</label& ...

Tips for Removing Column Heading in Material-UI v5 DataGrid Using React and TypeScript

In my React Typescript project using MUI datagrid, I needed to remove a column header that was no longer necessary. Instead of having a datagrid with the column header, I wanted to create one without it. This is the result I was aiming for: https://i.stack ...

Navigating through props outside a class component in React

I'm struggling to grasp how I can access props that are defined outside of a React class component. In the code snippet below, all props are clearly outlined except for this.props.checkboxArray, which is currently throwing an error "cannot read prope ...

Playground Themed Central Menu Features

Check out the theme live preview here: I've been experimenting with different combinations of text-align: center; and margin: 0 auto; but I'm struggling to align the menu elements to the center of the page. Any assistance would be highly apprec ...

CSS: Achieving Full Container Width Text with Respect to Another Container's Height

Hello, I am facing a very specific issue that I can't seem to resolve: I have two containers (ion-card) and I want them to always be the same height. I was able to achieve this by following the solution provided here: https://i.sstatic.net/he8O7.png ...

Ways to retrieve arrow information in JavaScript?

I'm currently retrieving tabular data in Arrow format from an API where the response content-type is application/vnd.apache.arrow.stream. Within my React code, I am attempting to parse this response. However, I'm uncertain if this approach is the ...

Choose a label that will consistently appear over the component, even if a value has already been selected

Utilizing Material UI v5 with emotion, I am in need of the component label to consistently cover the select, regardless of whether any values have been selected. Upon reviewing their documentation and conducting a Google search, it appears there is no str ...

I am currently working on a website that offers different themes, and I am attempting to update the iframe to reflect the selected theme on the site

I'm feeling lost on how to accomplish this task. Despite my efforts, I have been unable to find a solution so far. Perhaps utilizing javascript might be the key here, yet I am uncertain about integrating it into the existing script that I use for modi ...