Adjust the Material UI Select component to accommodate the length of the label

Is there a way to automatically adjust the size of Material-UI's Select input based on the label?

In the official demo, minWidth is added to the formControl element. However, I have multiple inputs and do not want to set fixed sizes for each one. When I remove the minWidth field, the label gets compressed as shown in the demo linked below. I am aiming for a result where the label and required star fit perfectly inside the Select element.

https://codesandbox.io/s/material-demo-forked-x4m3x

Answer №1

To achieve the desired layout, you can specify the min-width of the InputLabel to be equal to the width of its content by setting it to max-content.

Then, during rendering, calculate the offsetWidth of the InputLabel and apply this value as the minimum width for the FormControl.

const SimpleSelect = () => {
  const classes = useStyles();
  const [age, setAge] = React.useState("");
  const [labelWidth, setLabelWidth] = React.useState();
  const labelRef = React.useRef();

  const handleChange = (event) => {
    setAge(event.target.value);
  };

  React.useEffect(() => {
    setLabelWidth(`${labelRef.current.offsetWidth + 24}px`);
  }, [labelRef]);

  return (
    <div>
      <FormControl
        required
        className={classes.formControl}
        style={{
          minWidth: labelWidth
        }}
      >
        <InputLabel
          id="demo-simple-select-required-label"
          style={{ minWidth: "max-content" }}
          ref={labelRef}
        >
          The label
        </InputLabel>
        <Select
          value={age}
          onChange={handleChange}
          className={classes.selectEmpty}
        >
          <MenuItem value="">
            <em>None</em>
          </MenuItem>
          <MenuItem value={10}>An option</MenuItem>
        </Select>
      </FormControl>
    </div>
  );
};

Check out this demo on CodeSandbox

Additionally, remember that the FormControl component has a fullWidth prop which, when set to true, will make the component expand to fill its container's width entirely.

Answer №2

After taking inspiration from bertdida's solution, I decided to implement the following approach. Instead of using Select, adjusting the width of the select element itself proved to be the most effective.

export default function CustomWidthSelect( props ) {
    const [labelWidth, setLabelWidth] = React.useState();
    const labelRef = React.createRef();

    React.useEffect(() => {
        setLabelWidth(`${labelRef.current.offsetWidth + 24}px`); // 24 for caret icon
    }, [labelRef]);

    return (
        <FormControl
            required={props.required}>
            <InputLabel ref={labelRef}>{props.label}</InputLabel>
            <Select
                style={{
                    minWidth: labelWidth
                }}
                value={props.value}
                multiple={props.multiple}
                input={props.input}
                onChange={props.onChange}
                renderValue={props.renderValue}
            >
                {props.children}
            </Select>
        </FormControl>
    );
}

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

Sometimes, the browser may fail to recognize a jQuery click event when a CSS3 transform is applied

There is an issue where click events are sometimes not triggered when an element contains another element being animated with CSS transitions. To see an example of this problem, check out the test case at http://codepen.io/anon/pen/gbosy In my layout, I ...

Next.js - the next development environment fails to show the latest code modifications

Recently, I've been going through some tutorials and despite spending considerable time searching for a solution, I'm still unable to figure out why changes I make to a specific component (navbar) are not showing up in the development server. I& ...

The header, main content, and footer sections expand to occupy the entire page

I am in need of HTML structure that looks like the following: <header></header> <div id='main'></div> <footer></footer> I want all elements to be positioned relatively. The header and footer will have fixed h ...

Troubleshooting the non-responsive behavior of Bootstrap's hidden-sm-down

Why are the two images within the <div> with hidden-sm-down still visible on my laptop when I resize the page? I need them to be hidden on small devices for a different menu layout. <div class="row"> <div class="col-m ...

The origin of the image must be constantly changing

Is there a way to dynamically load an image src with React? I attempted the following: const country = this.state.countryCode; <img src="https://www.countryflags.io/"+country+"/shiny/64.png"/> However, I encountered the following error: P ...

Discovering the proper way to infer type for tss-react withParams and create

Greetings to everyone and a huge thank you in advance for your generous help. I have a desire to utilize the tss-react library for styling, particularly because I will be implementing Material UI components. As I delve into some documentation, the latest A ...

Limiting the Material-UI text field of number type to accept only positive integers

Struggling to find a way to limit an MUI text field of type='number' to only accept positive numbers This is the TextField I am using: <TextField name={name} type={props.type || 'text'} label={props.label} helperText ...

What is the process for incorporating a button to the left of the search field?

Is it possible to enhance the search field by adding a button to make it more user-friendly? Below is the code I have been using: <div id="search"> <div class="container"> <h1>Search U.K. house price data</h1> <form c ...

Display or conceal a division underneath a dropdown menu based on selections retrieved from a SQL Server database

Presented here is my JavaScript code. function appendItemforPurchaseOrder() { debugger var rowNumber = parseInt($(".itemmapContainer").attr("data-rownumber")); rowNumber = isNaN(rowNumber) ? 1 : rowNumber + 1; var addNewItemDetailHtml = ...

React Final Form clears form fields and validation, while keeping submitSucceeded status intact

Utilizing React Final Form to showcase a form and manage form submission, I am facing an issue where I want all the form fields to clear upon successful submission while displaying a submit success message tied to the submitSucceeded FormState property. H ...

Changes are being made to the state, but the updates are not showing up in the user interface of my photo feed

Welcome everyone, I'm currently immersed in learning react and have developed several apps using react, such as a hotel website (using react and contentful cms), an e-commerce website (using react, contentful cms, paypal), githubfinder app, todos app, ...

When utilizing Apollo query in conjunction with next.js getServerSideProps, the document is found to be undefined

How can I utilize getServerSideProps with apollo and next.js to fetch a query each time this component is rendered? export async function getServerSideProps(context) { const { data } = await client.query({ query: GET_AUTHED_USER }) return { ...

Tips on saving an image in MongoDB

Is there a way to store an image in MongoDB with the following scenario? I have a product schema where I need to include another field for images. How can I manually upload and associate images with products using methods like Product.create or Product. ...

Adding JQuery to a running webpage using the DOM and Opera browser add-ons

I'm currently working on an Opera Extension and I have a question. Is there a way to use the includes folder in order to directly inject jQuery into the live HTML of a webpage? For example, can I change the background color of the DOM to black? If ...

Unable to locate module '.next/server/font-manifest.json'

I'm encountering a frustrating issue while attempting to deploy my nextjs app with server rendering. The app was created using Azure Pipelines and then uploaded to a production server that runs on a Linux operating system. Below is the configuration ...

Require execution of function prior to rendering component

const DisplayProduct = () => { const parameters = useParams(); const [product, setProduct] = useState(); const serverHost = "http://localhost:5000"; useEffect(() => { if (parameters.id) { fetchProduct() ...

What are some ways I can efficiently load large background images on my website, either through lazy loading or pre

Just dipping my toes into the world of javascript. I'm currently tackling the challenge of lazy loading some large background images on my website. My goal is to have a "loading" gif displayed while the image is being loaded, similar to how it works ...

Attention: There was a prop type failure. The `game` prop type is not valid; it should be a function, typically from React.PropTypes

import React, { PropTypes } from 'react'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; // import UI components import GameList from '../components/game/GameList'; // import act ...

The lengthy email exceeds its limits

https://i.sstatic.net/juD2P.png https://i.sstatic.net/WQo8o.png Take a look at this code snippet: <div className='mt-[3vh] flex h-1/3 min-h-fit w-[80%] min-w-[300px] flex-col content-center items-center justify-center rounded-2xl bg-white shadow ...

Building an easy-to-use jQuery task list

I'm currently working on a basic to-do list in Javascript, but I've encountered an issue. When I check the checkbox, the style of the adjacent text doesn't change as expected. Instead, it's the heading text that is affected by the chang ...