Escaga Seen
Escaga Seen

Reputation: 151

MUI <Autocomplete/> input label different from search option

On this demo : https://codesandbox.io/s/oxvsfy?file=/demo.js I can search for a country with it's name (Spain, France, etc). But when I click, I want that the value that stays on the TextField to be the phone number of the country.

Is it possible to achieve? Thank you.

Upvotes: 2

Views: 993

Answers (2)

codmitu
codmitu

Reputation: 709

i have something like this, might need to install extra dependencies for styles

 import { StyledButton, StyledListbox, StyledOption } from '../../styles/Autocomplete.styles';

 const [value, setValue] = useState("US")
 return (
    <CustomSelect value={value} onChange={(newValue) => setValue(newValue)}>
        {countries.map((c, i) => (
            <StyledOption key={i} value={c.code}>
                <img loading="lazy"
                    width="20"
                    src={`https://flagcdn.com/w20/${c.code}.png`}
                    srcSet={`https://flagcdn.com/w40/${c.code}.png 2x`}
                    alt={`Flag of ${c.label}`} />
                {c.label} {c.phone}
            </StyledOption>
        ))}
    </CustomSelect>
)

 const StyledPopper = styled(PopperUnstyled)`
     z-index: 1;
 `;

 const CustomSelect = forwardRef(function CustomSelect(
     props: SelectUnstyledProps,
     ref: React.ForwardedRef,
 ) {
      const components: SelectUnstyledProps['components'] = {
      Root: StyledButton,
      Listbox: StyledListbox,
      Popper: StyledPopper,
      ...props.components,
   };

   return <SelectUnstyled {...props} ref={ref} components={components} />;
});

styles in Autocomplete.styles.js

import styled from "styled-components"
import OptionUnstyled, { optionUnstyledClasses } from '@mui/base/OptionUnstyled';
import {selectUnstyledClasses} from '@mui/base/SelectUnstyled';

export const StyledButton = styled('button')(() => `
   font-family: IBM Plex Sans, sans-serif;
   font-size: 0.875rem;
   box-sizing: border-box;
   min-height: calc(1.5em + 22px);
   width: 200px;
   background: '#fff';
   border: 1px solid grey;
   border-radius: 4px;
   margin: 0.5em;
   padding: 10px;
   text-align: left;
   line-height: 1.5;
   color: grey;
&.MuiSelectUnstyled-popper {
    background: white;
}
&:hover {
  background: #e4e4e4;
  border-color:  grey;
}

&.${selectUnstyledClasses.focusVisible} {
  outline: 3px solid blue;
}

&.${selectUnstyledClasses.expanded} {
  &::after {
    content: '▴';
  }
}

&::after {
  content: '▾';
  float: right;
}

& img {
  margin-right: 10px;
}
`);

export const StyledListbox = styled('ul')(() => `
    font-family: IBM Plex Sans, sans-serif;
    font-size: 0.875rem;
    box-sizing: border-box;
    border-radius: 4px;
    margin: 0;
    width: 200px;
    max-height: 400px;
    background: '#fff';
    color: grey;
    overflow: auto;
    outline: 0px;
    border: 1px solid lightgray;
`);
export const StyledOption = styled(OptionUnstyled)(() => `
   list-style: none;
   padding: 8px;
   cursor: default;
   background: #fff;

&:last-of-type {
  border-bottom: none;
}

&.${optionUnstyledClasses.selected} {
  background-color: #e7e7ff;
  color: blue;
}

&.${optionUnstyledClasses.highlighted} {
  background-color: #e4e4e4;
  color:  grey;
}

&.${optionUnstyledClasses.highlighted}.${optionUnstyledClasses.selected} {
  background-color: #e7e7ff;
  color: blue;
}

&.${optionUnstyledClasses.disabled} {
  color: grey;
}

&:hover:not(.${optionUnstyledClasses.disabled}) {
  background-color: #e4e4e4;
  color:  grey;
}

& img {
  margin-right: 10px;
}
`);

Upvotes: 0

Clay Banks
Clay Banks

Reputation: 4581

To do that, you'll need to convert the AutoComplete into a controlled component, and utilize the inputValue attribute

import React, { useState } from 'react';
import Autocomplete from '@mui/material/Autocomplete';

export default function CountrySelect() {
  const [inputValue, setInputValue] = React.useState('');
  const handleChange = e => {
    const text = e.currentTarget.innerText
    setInputValue(text.substring(text.indexOf('+'), text.length))
  }
  return (
    <Autocomplete
      options={countries}
      onChange={handleChange}
      inputValue={inputValue}
      renderInput={(params) => (
        <TextField
          {...params}
        />
      )}
    />
  );
}

Upvotes: 2

Related Questions