Stopping horizontal scrolling in Material-UI Autocomplete/Popper: A troubleshooting guide

I am currently working on incorporating the Material-UI Autocomplete component, and my goal is to have each option label show an icon along with some text. The challenge I'm facing is that I only want the popper element to be the width of the text input, with any overflowing text displaying ellipsis. In my renderOption method, if I use

<Typography noWrap>"Text"</Typography>
, it successfully adds an ellipsis to the text. However, when I try to include this in a Grid or Flex box along with the icon, the Popper component ends up having horizontal scroll. Is there a way to ensure that the Popper viewport stays constrained to the Autocomplete width so that the text in the renderOption method wraps properly?

import React from 'react';
import InputAdornment from '@material-ui/core/InputAdornment';
import TextField from '@material-ui/core/TextField';
import SearchIcon from '@material-ui/icons/Search';
import PersonIcon from '@material-ui/icons/Person';
import GraphicEqIcon from '@material-ui/icons/GraphicEq';
import { Grid } from '@material-ui/core';
import { Autocomplete } from '@material-ui/lab';
import Typography from '@material-ui/core/Typography';

function SearchBarDisplay({ options = [], onChange, onSelectValue, value = '' }) {
    function getOptionLabel(option) {
        if (option.name) {
            return option.name;
        } else if (option.username) {
            return option.username;
        } else if (option.type === 'advanced') {
            return option.value;
        } else {
            return null;
        }
    }

    function renderOption(name, username, type) {
        if (name) {
            return (
                <Grid container alignItems="center" spacing={1} wrap={'nowrap'}>
                    <GraphicEqIcon />
                    <Grid item>
                        <Typography noWrap>{name}</Typography>
                    </Grid>
                </Grid>
            );
        } else if (username) {
            return (
                <Grid container alignItems="center" spacing={1} wrap={'nowrap'}>
                    <PersonIcon />
                    <Grid item>
                        <Typography noWrap>{username}</Typography>
                    </Grid>
                </Grid>
            );
        } else if (type === 'advanced') {
            return (
                <Grid container alignItems="center" spacing={1}>
                    <SearchIcon />
                    <Grid item>
                        <Typography
                            noWrap={true}
                            color="textSecondary">{`See more results for "${value}"`}</Typography>
                    </Grid>
                </Grid>
            );
        } else {
            return null;
        }
    }

    return (
        <Autocomplete
            id="autocomplete"
            options={options}
            getOptionSelected={(option, value) => option._id === value._id}
            getOptionLabel={(option) => getOptionLabel(option)}
            onChange={(event, value) => {
                onSelectValue(value);
            }}
            onInputChange={(event, value) => onChange(value)}
            renderOption={({ name, username, type }) => renderOption(name, username, type)}
            renderInput={(params) => (
                <TextField
                    {...params}
                    placeholder="Search for podcasts or users"
                    margin="normal"
                    variant="outlined"
                    InputProps={{
                        ...params.InputProps,
                        startAdornment: (
                            <>
                                <InputAdornment position="start">
                                    <SearchIcon />
                                </InputAdornment>
                            </>
                        )
                    }}
                />
            )}
        />
    );
}

export default SearchBarDisplay;

Answer №1

If you want each option label to display as a single line with ellipsis (...) instead of multiple lines, you can achieve this by modifying the renderOption property in your code like below:

<Autocomplete
...
getOptionLabel={(option: any) => `${option.label} (${option.code})`}
renderOption={(option) => (
        <React.Fragment>
          <div style={{ textOverflow: 'ellipsis', overflow: "hidden", whiteSpace: "nowrap" }}>
            {option.label} ({option.code})
          </div>
        </React.Fragment>
      )}
...
/>

You can view an example using a list of countries on CodeSandbox that I have prepared: https://codesandbox.io/s/autocomplete-with-ellipsis-i8hnw

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

Embed a static label inside an input field that remains constant even while text is inputted, without using a placeholder. Crafted using HTML,

Take a look at the screenshot below - what you see on the left side is my current setup, while on the right side is the desired outcome achieved without any plugins or HTML5 attributes The left side scenario occurs when I have 2 input fields - one with th ...

Building a flexible table in React JS based on specific keys: a complete guide

I'm currently working on developing a dynamic table component using React JS. The component at the moment has a fixed header with the most common result keys. Some results contain additional information such as phone numbers and degrees. I'm loo ...

Personalizing Bulma in Next.js

I am currently working on customizing the default yellow colors in Bulma for my Next.js project. In an effort to make these changes, I have created a global Sass file where I am adjusting the default $yellow and $warning color variables. However, when I i ...

Running MERN on Heroku may result in unexpected errors

Currently, my project utilizes the MERN stack - incorporating NodeJS(Express), ReactJS, and mLab for the database, with webpack managing resources. Initially, I started with just ReactJS, but eventually added a backend for API functionality. Deploying so ...

Two divs with floated attributes and equal heights

My unique HTML is below: <div class="container"> <div class="box"> <div class="float"> <img src='http://media-cdn.tripadvisor.com/media/photo-s/03/9b/2f/db/miami-beach.jpg' /> </div> ...

Running a Django server continuously

I am working on a Django-React Project where I have integrated the React project build file into my Django setup to run both projects simultaneously. Everything runs smoothly when I use the following command: python manage.py runserver 0.0.0.0:8000 on my ...

Testing Material UI v5 components that utilize sx props using @testing-library/react

When using React Testing Library, the sx props of Material UI components are not applied during rendering. For instance, I set properties to hide an element at specific breakpoints. <> <AppBar data-testid="mobile" ... sx={ ...

Unable to modify the .top attribute style in elements within an arraylist using JavaScript

I need to align multiple images in DIVs on the same line by setting their Top value to match the first image in the array. Here is the code I am struggling with: (addBorder function is called when divs are clicked) <div class="DRAGGABLE ui-widget-cont ...

What causes an error in react-intl's defineMessages function when passing in an object reference as an argument?

I am currently navigating my way through the react-intl library developed by Yahoo! for internationalization and I have encountered a peculiar issue. My objective is to store the base string (in English) in JSON files located outside the components so that ...

The jQuery toggleClass() function is not being applied successfully to content that is dynamically generated from

I've created an awesome collection of CSS-generated cards containing icons and text with a cool animation that expands upon tapping to reveal more icons and options. I carefully crafted the list to look and behave exactly how I wanted it to. But now, ...

I need to fix the width of my background image in the URL - what's the best way to do

<div style="background-image:url('19.jpg');height:40px;position:fixed;width:1274px">hello </div> I'm trying to keep this div tag in a fixed position, but I also need to set a width for it. It seems like the background image is c ...

How to verify the parent nodes in a jstree

I have implemented a two state jstree. However, I am encountering an issue where it is not possible to select any other node in relation to a node. My goal is that when I click on a specific node, all of its parent nodes should also be checked. Any assist ...

Creating a minimalist metro-inspired menu using HTML and CSS

After researching online for a few days, I've just started learning HTML/CSS and my skills are currently at about a 6 out of 100. I have this code that functions as a blogger HTML widget, but I want to customize it further. Here is the code snippet: ...

The CSS Media Query won't be effective for a precise 767

I have created an HTML file that changes the background color based on the browser width. When the width is 769, the background color is set to white. At 768, it changes to green. However, when the width is 767, I expected it to become red but it still rem ...

Having difficulties with Cypress test for dragging and dropping an element within the same area

I am experimenting with the drag and drop feature using a plugin called 4teamwork/cypress-drag-drop. I have a scenario where there are three elements stacked on top of each other. The task is to select the first element and move it under the last element i ...

Struggle with Firefox: Table-cell with Relative Positioning Not Acting as Parent

Upon investigation, I have come across a unique layout issue that seems to only affect Firefox. It appears that elements with display:table-cell; do not act as the positional parent for descendants with position:absolute;. It is surprising to discover th ...

Ways to ensure that v-model does not become "true" or "false" in an input checkbox using Vue

I am currently working on a filter popup that includes a list of checkboxes. By default, some items should be selected and others not selected. I have connected these checkboxes to an object array using v-model. My issue is that when I deselect and select ...

React and Express failing to display content

After relocating my React frontend folder to my collaborator's Express backend folder, here is our updated file structure. https://i.stack.imgur.com/i77XJ.png This code snippet represents app.js which is responsible for rendering the website. const ...

CSS styling not appearing on HTML button

I'm attempting to create a login page similar to Instagram using HTML and CSS. However, I'm having trouble styling the button to match Instagram's login page. The button <input type="submit" class="sub-btn"> The CS ...

Cannot use Axios instance in Next.js due to error stating 'Localstorage is not defined'

I am currently working on a React app and have created an Axios component that I would like to reuse: import axios from 'axios' import dynamic from 'next/dynamic' const baseUrl = 'http://127.0.0.1:8000/' const axiosInstan ...