MUI textfield label not floating to the top left properly - reactjs

I try to use the MUI in my project, and all the input fields I use don't behave correctly.
it supposed to look like this
but when I use it it will look like this
import Box from '#mui/material/Box'
import TextField from '#mui/material/TextField'
import Autocomplete from '#mui/material/Autocomplete'
<Autocomplete
className="mt-3"
size="small"
id="country-select-demo"
options={arr}
autoHighlight
getOptionLabel={(option) => option.label}
renderOption={(props, option) => (
<Box
component="li"
sx={{ '& > img': { mr: 2, flexShrink: 0 } }}
{...props}
>
{option.label}
</Box>
)}
renderInput={(params) => (
<TextField
{...params}
label="Choose.."
inputProps={{
...params.inputProps,
}}
/>
)}

I just found out that uninstalling the react-bootstrap fix this problem.

Related

React MUI Autocomplete - Customizing renderInput content

I'm using the React MUI Autocomplete component like in the countries example from the official doc.
My goal is to display in bold the country code, as I already did in the renderOption by simply enclosing the option.code value with HTML tags.
import * as React from 'react';
import Box from '#mui/material/Box';
import TextField from '#mui/material/TextField';
import Autocomplete from '#mui/material/Autocomplete';
export default function CountrySelect() {
return (
<Autocomplete
id="country-select-demo"
sx={{ width: 300 }}
options={countries}
autoHighlight
getOptionLabel={(option) => `${option.code} ${option.label}`} // DISPLAY THE CODE
renderOption={(props, option) => (
<Box component="li" sx={{ '& > img': { mr: 2, flexShrink: 0 } }} {...props}>
<img
loading="lazy"
width="20"
src={`https://flagcdn.com/w20/${option.code.toLowerCase()}.png`}
srcSet={`https://flagcdn.com/w40/${option.code.toLowerCase()}.png 2x`}
alt=""
/>
{option.label} (<b>{option.code}</b>) +{option.phone}
</Box>
)}
renderInput={(params) => (
<TextField
{...params}
label="Choose a country"
inputProps={{
...params.inputProps,
autoComplete: 'new-password', // disable autocomplete and autofill
}}
/>
)}
/>
);
}
I cannot find a way to reference the option.code inside the renderInput property, so I cannot figure out how to display the country code in bold also in the renderInput, since the bold is only visible when choosing an option, but not when that option is selected.
Is there a solution for this?
The main problem with this is that MUI Textfields consist of HTML <input/> tags.
Its value can only be of type string which prohibits any direct value styling but you can make use of an startAdornment like so:
...
renderInput={(params) => (
<TextField
{...params}
label="Choose a country"
inputProps={{
...params.inputProps,
autoComplete: "new-password" // disable autocomplete and autofill
}}
InputProps={{
...params.InputProps,
startAdornment: <strong>{params.inputProps.value.split(" ")[0]}</strong>
}}
/>
)}
...
Your next challenge would be to remove the additional country code from the input-value or even better, move to a controlled value approach.

Material ui Autocomplete endInputAdornment custom elements not centered

When setting material ui <Autocomplete /> with variant='filled' The endInputAdornments does not center to the AutoComplete.
Codesandbox with both variants for reference here
<Autocomplete
disablePortal
id="combo-box-demo"
options={top100Films}
sx={{ width: 300, mt: 2 }}
renderInput={(params) => (
<TextField
{...params}
label="Movie"
variant="filled" //With filled it does not center anymore
InputProps={{
...params.InputProps,
endAdornment: (
<React.Fragment>
{params.InputProps.endAdornment}
<IconButton
color="primary"
aria-label="upload picture"
component="span"
>
<PhotoCamera />
</IconButton>
</React.Fragment>
)
}}
/>
I found a github issue where they fixed it for the inputProps internally but I cant seem to find a way to do the same with my own adornment elements.
The only prop that seems relevant is popupIcon but i still want that default feature. I just want to be able to add more IconButtons to the endInputAdornments
You can style the container for the icon by using a <div> instead of <React.Fragment>:
endAdornment: (
<div style={{ marginTop: "-19px" }}>
{params.InputProps.endAdornment}
<IconButton
color="primary"
aria-label="upload picture"
component="div"
>
<PhotoCamera />
</IconButton>
</div>
)
Here's the sandbox link
Why -19px? Because with variant="filled" the container for the text and icon is shifted down by 19px:
The popup icon of Autocomplete is vertically centered because of this styles. You can add your own styles to center the icon next to it by modifying the styles from the source a bit:
<Autocomplete
options={top100Films}
renderInput={(params) => (
<TextField
{...params}
label="Movie"
variant="filled"
InputProps={{
...params.InputProps,
sx: {
// this is necessary if you don't want to input value to be
// placed under the icon at the end
'&&&': { pr: '70px' },
},
endAdornment: (
<React.Fragment>
{params.InputProps.endAdornment}
<IconButton
color="primary"
sx={{
position: 'absolute',
p: 0,
right: 40,
top: 'calc(50% - 12px)', // Center vertically
}}
>
<PhotoCamera />
</IconButton>
</React.Fragment>
),
}}
/>
)}
/>

How can I set the placeholder of Autocomplete in a new line?

I'm using Autocomplete of material-ui and I have the list of the selected values and the placeholder in the same area. I would like to set the placeholder in a new line. I'm able to change the style of placeholder using makeStyles but I didn't find a way to going in a new line.
const useStyles = makeStyles ({
placeholder: {
"& input::placeholder": {
display: "block",
},
})
renderInput={(params) => (
<TextField
/* eslint-disable react/jsx-props-no-spreading */
{...params}
classes={{root: classes.placeholder}}
label="Selected Options"
placeholder="Availables Options"
variant="outlined"
color="primary"
/>
)
You can override the renderTags method, add a wrapper component around all selected tags, and set the wrapper width to 100% to push the placeholder element down like this:
<Autocomplete
multiple
options={top100Films.map((option) => option.title)}
renderTags={(value: string[], getTagProps) => (
<div style={{ width: "100%" }}>
{value.map((option: string, index: number) => (
<Chip
variant="outlined"
label={option}
{...getTagProps({ index })}
/>
))}
</div>
)}
renderInput={(params) => <TextField {...params} />}
/>
Live Demo

material-ui adding search icon in autocomplete component

I am using #material-ui autocomplete for search and I want to add search icon next to autocomplete component
I tried something like this but after changing ---- option fields is not displaying
import TextField from "#material-ui/core/TextField";
import Autocomplete from "#material-ui/lab/Autocomplete";
.
.
.
<Autocomplete
id="combo-box-demo"
options={this.state.results} // .map((option) => option.title_display)
getOptionLabel={(option) => option.title}
style={{ width: 300 }}
onInputChange={this.handleInputChange}
renderInput={(params) => (
<TextField
{...params}
variant="outlined"
InputProps={{
endAdornment: (
<InputAdornment>
<IconButton>
<SearchIcon />
</IconButton>
</InputAdornment>
)
}}
/>
)}
/>
ANd if I just add searchicon it get added below the autocomplete component
<Fragment>
<Autocomplete
id="combo-box-demo"
options={top100Films}
getOptionLabel={(option) => option.title}
style={{ width: 300 }}
renderInput={(params) => <TextField {...params} label="Combo box" variant="outlined" />}
/>
<SearchIcon />
</Fragment>
https://codesandbox.io/s/material-demo-forked-qt99q?file=/demo.js
[this is output][1]
[1]: https://i.stack.imgur.com/JBSvO.png
import React, { useState, useEffect } from 'react';
import { TextField} from '#material-ui/core'
import InputAdornment from '#material-ui/core/InputAdornment';
import Autocomplete from '#material-ui/lab/Autocomplete';
import SearchIcon from '#material-ui/icons/Search';
import { makeStyles, Theme } from "#material-ui/core/styles";
export default function AddBusiness() {
const useStyles = makeStyles((theme: Theme) => ({
margin: {
padding: "10px 5px 5px 5px",
borderRadius: 4,
backgroundColor: theme.palette.common.white,
margin: theme.spacing(0),
border: "1px solid rgb(157, 157, 157)",
width: "100%",
},
}));
const classes = useStyles();
const [cityData, setCityData] = React.useState([]);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/todos')
.then(data => data.json())
.then(res => setCityData(res))
.catch(error => console.log(error))
}, [])
return (
<Autocomplete
id="combo-box-demo"
options={cityData}
getOptionLabel={(option: any) => option.title}
className={classes.margin}
style={{ paddingBottom: '8px' }}
renderInput={(params) => <TextField {...params} label=""
placeholder="Search City"
InputProps={{ ...params.InputProps,
startAdornment: ( <InputAdornment position="start"> <SearchIcon />
</InputAdornment> ),
disableUnderline: true }} />}
/>
)}
You can use display: "flex" for the parent to align its child in the same line.
And also align search icon at the center of the element,
<SearchIcon style={{ cursor: "pointer", padding: "17px" }} />
Hope you are expecting the same use case. Let me know if you are facing any issue.
Sample demo:- https://codesandbox.io/s/material-demo-forked-v17jz?file=/demo.js
This is the way you can customize the popup Icon
<Autocomplete
className={classes.root}
id="combo-box-demo"
options={boards}
getOptionLabel={(option) => option}
forcePopupIcon={true}
popupIcon={<SearchIcon />}
renderInput={(params) => (
<>
<TextField
placeholder="search"
{...params}
label="Combo box"
variant="filled"
/>
</>
)}
/>

Using react material-ui autocomplete with loading and freeSolo props

I have been using material-ui's autocomplete in freeSolo mode. I would like to show a loading text while options are being loaded. It isn't working as expected currently. But loading text is shown when freeSolo is disabled. The same behaviour is seen for no-options text also. Is it possible to show loading and no options text in freeSolo mode?
Ref: https://codesandbox.io/s/material-demo-mqtk8
In the above example, if freeSolo is set as false, loading text and no options text is shown as expected.
Using this prop loadingText can you set your own loading text.
You can see this MaterialUi documentation, here is the link Material UI AutoComlete API
<Autocomplete
freeSolo
id="asynchronous-demo"
style={{ width: 300 }}
open={open}
onOpen={() => {
setOpen(true);
}}
onClose={() => {
setOpen(false);
}}
getOptionSelected={(option, value) => option.name === value.name}
getOptionLabel={(option) => option.name}
options={options}
loading={loading}
loadingText="Your loading text here"
renderInput={(params) => (
<TextField
{...params}
label="Asynchronous"
fullWidth
variant="outlined"
InputProps={{
...params.InputProps,
endAdornment: (
<React.Fragment>
{loading ? (
<CircularProgress color="inherit" size={20} />
) : null}
{params.InputProps.endAdornment}
</React.Fragment>
)
}}
/>
)}
/>

Resources