Creating a grid with the box component and sx prop - reactjs

In material UI v5 supposedly one can create almost anything with the sx prop, on the list is grid unfortunately I am unable to create what should be a simple grid. To illustrate here is what my grid would look like.
My unsuccessful attempts at using the Box component and sx prop look like this
What am I missing here, how can recreate what I have with the Grid component with the Box/sx combo?

Is it that you want ? Live example sandbox ?
<Box sx={{ placeContent: "center", display: "grid" }}>
<Box sx={{ gridRow: "1", gridColumn: "div 1" }}>
<TextField
name="name"
label="Name"
variant="outlined"
type="text"
margin="dense"
/>
</Box>
<Box sx={{ gridRow: "2", gridColumn: "div 1" }}>
<Autocomplete
disablePortal
id="combo-box-demo"
options={top100Films}
renderInput={(params) => <TextField {...params} label="Movie" />}
/>
</Box>
</Box>

Related

How to apply maxWidth to TextField component from mui?

I'm trying to apply maxWidth to the TextField from material-ui but it seems like I can't.
import * as React from "react";
import Box from "#mui/material/Box";
import TextField from "#mui/material/TextField";
export default function BasicTextFields() {
const messages = [
{ id: 1, message: "short message" },
{
id: 2,
message: " It comes with three variants: outlined."
},
{
id: 3,
message:
"The TextField wrapper component is a complete form control including a label, input, and help text."
}
];
return (
<Box
component="form"
sx={{
"& > :not(style)": { m: 1, width: "25ch" }
}}
noValidate
autoComplete="off"
style={{ display: "flex", flexDirection: "column" }}
>
{messages.map((e) => (
<TextField
id="outlined-basic"
key={e.id}
value={e.message}
label="Outlined"
variant="outlined"
multiline={true}
style={{ maxWidth: "350px" }}
/>
))}
</Box>
);
}
Currently, the max-width for TextField seems not applying correctly. If I look at TextField with the inspect, it says 200px
I know I can apply regular width like this.
<TextField
id="outlined-basic"
key={e.id}
value={e.message}
label="Outlined"
variant="outlined"
multiline={true}
style={{ width: "350px" }}
/>
But what I want here is maxWidth.
Ideally, I like to have the width of text input based on the message length which I pass to the value property like this value={e.message}.
So before the width hits 350px, width needs to be kind of auto like the width is depends on the message, but once it hits 350px, it will keep being 350px.
Is that possible with the TextField component?
Attampts
I used InputProps proptery.
{messages.map((e) => (
<TextField
id="outlined-basic"
key={e.id}
value={e.message}
label="Outlined"
variant="outlined"
multiline={true}
InputProps={{
style: { maxWidth: "350px" }
}}
/>
))}
But I got width 200px.
if you wrap in an div?
<div style: { width: "400px" }>
<TextField
id="outlined-basic"
key={e.id}
value={e.message}
label="Outlined"
variant="outlined"
multiline={true}
InputProps={{
style: { maxWidth: "350px" }
}}
/>
</div>

How can I make a component responsive in Material UI?

I am relatively new to material UI and I have designed a text field of type search. I would like it to be responsive. But I am failing to render the textfield in screen sizes with width smaller than 423
<Box
sx={{ flexGrow: 1 }}
m={5} pt={5}
display="flex"
justifyContent="flex-end"
alignItems="flex-end"
>
<Grid item sx={{ flexGrow: 1 }} spacing={{ xs: 1, md: 2,lg:2}} columns={{ xs: 2, sm: 2, md: 12 ,lg: 22}} display="flex"
justifyContent="center"
alignItems="center" marginLeft={8} marginRight={1} mt={4} width='100%'>
<SearchIcon style={{ coSelf: "center", margin: "5px" }} />
<TextField
id="standard-search"
label="Search for a company..."
type="search"
variant="standard"
textAlign="center"
fullWidth
/>
</Grid>
<Button onClick={() => setLight((prev) => !prev)} variant="contained" color="primary" sx={{ height: 40 }}>
<SettingsIcon/>
</Button>
</Box>
Any help is appreciated.
Seems your search component is rendered but hiding behind the Stock Market Charting header as it gets longer in smaller screen sizes. If you have it as a fixed position try changing it to relative position, or remove/reduce the text inside it so it gets shorter for a quick test and might reveal the search component.

MUI textfield label not floating to the top left properly

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.

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>
),
}}
/>
)}
/>

Resources