Can't horizontally align Material-UI Autocomplete & Material-UI FormControl - reactjs

Can't horizontally align Material-UI Autocomplete & Material-UI FormControl. I don't know what happened. When I import or write code for autocomplete then I got stuck into this. I need horizontally align the way FormControl and the Button is.
codesandbox: https://codesandbox.io/s/laughing-fast-fenv9?file=/src/Account.js:2364-2370
import React, { Component } from "react";
import {
Container, Grid, TextField,
FormControl, InputLabel, Select,
MenuItem, Button } from "#material-ui/core";
import { withStyles } from "#material-ui/core/styles";
import Autocomplete from "#material-ui/lab/Autocomplete";
import { createRef } from "react";
const styles = (theme) => ({
mR: {
marginRight: theme.spacing(3)
},
formControl: {
minWidth: 180,
marginRight: theme.spacing(3)
}
});
class Account extends Component {
constructor() {
super();
this.state = {
labelWidth: 0
};
this.handleChange = this.handleChange.bind(this);
this.inputLabel = createRef();
}
componentDidMount() {
this.setState({ labelWidth: this.inputLabel.current.offsetWidth });
}
handleChange = (event) => this.setState({ age: event.target.value });
render() {
const { classes } = this.props;
const top100Films = [
{ title: "The Shawshank Redemption", year: 1994 },
{ title: "The Godfather", year: 1972 }
];
const { age, labelWidth } = this.state;
return (
<React.Fragment>
<Container>
<Grid container spacing={2}>
<Grid item xs={12} sm={12} md={12} lg={12} xl={12}>
<Autocomplete
options={top100Films}
getOptionLabel={(option) => option.title}
style={{ maxWidth: 180 }}
renderInput={(params) => (
<TextField
{...params}
label="Account Name"
variant="outlined"
/>
)}
color="primary"
size="small"
autoFocus
/>
<FormControl
className={classes.formControl}
variant="outlined"
size="small"
>
<InputLabel ref={this.inputLabel}>Age</InputLabel>
<Select value={age} labelWidth={labelWidth}>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
<Button variant="contained" color="primary">
Submit
</Button>
</Grid>
</Grid>
</Container>
</React.Fragment>
);
}
}
export default withStyles(styles, { withTheme: true })(Account);

You can wrap Autocomplete , Formcontrol , Button with :
<Grid item xs={4} sm={4} md={4} lg={4} xl={4}>
// Code
</Grid>
This will divide it into 3 columns. (12 grid layout).
Also please correct the lablewidth code. Select box will overflow in small screen case.

You should wrap the each of them using the <Grid item xs>...</Grid>
return (
<React.Fragment>
<Container>
<Grid container spacing={2}>
<Grid item xs>
<Autocomplete
options={top100Films}
getOptionLabel={(option) => option.title}
style={{ maxWidth: 180 }}
renderInput={(params) => (
<TextField
{...params}
label="Account Name"
variant="outlined"
/>
)}
color="primary"
size="small"
autoFocus
/>
</Grid>
<Grid item xs>
<FormControl
className={classes.formControl}
variant="outlined"
size="small"
>
<InputLabel ref={this.inputLabel}>Age</InputLabel>
<Select value={age} labelWidth={labelWidth}>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid item xs>
<Button variant="contained" color="primary">
Submit
</Button>
</Grid>
</Grid>
</Container>
</React.Fragment>

Related

Required property from React hook form does not validate on textfields

I'm currently using React-hook-form to manage my textfields and that includes validation.
The problem right now is that the required property does not work well, because it does not show the little helpertext under the inputfield when it is empty.
Here is there a snippet of the UI, it only shows a few of the inputfields to save you the
unnecessary JSX code
This is how i have done it:
import { FragmentType, useFragment } from '#gql/fragment-masking';
import { graphql } from '#gql/gql';
import { Gender } from '#gql/graphql';
import {
Button,
Card,
CardContent,
Grid,
MenuItem,
TextField,
TextFieldProps,
Typography,
} from '#mui/material';
import { AdapterDayjs } from '#mui/x-date-pickers/AdapterDayjs';
import { DesktopDatePicker } from '#mui/x-date-pickers/DesktopDatePicker';
import { LocalizationProvider } from '#mui/x-date-pickers/LocalizationProvider';
import dayjs, { Dayjs } from 'dayjs';
import { useTranslation } from 'next-i18next';
import React, { useCallback, useState } from 'react';
import { useForm } from 'react-hook-form';
type Inputs = {
firstName: string;
lastName: string;
birthdate: string;
street: string;
postalcode: string;
city: string;
country: string;
gender: string;
email: string;
leveloftrust: string;
lastsignedin: string;
};
export const PatientInfoFragment = graphql(/* GraphQL */ `
fragment PatientInfo on Patient {
addresses {
city
lines
postalCode
}
birthDate
email
gender
id
name {
firstName
lastName
}
status {
lastSignInAt
levelOfTrust
}
}
`);
interface PatientInfoProps {
patient: FragmentType<typeof PatientInfoFragment>;
}
export function PatientInfo(props: PatientInfoProps) {
const patient = useFragment(PatientInfoFragment, props.patient);
const [value, setValue] = React.useState<Dayjs | null>(
dayjs(patient.birthDate)
);
const genderValueArray = Object.values(Gender);
const [disabled, setDisabled] = useState(true);
const { register, handleSubmit } = useForm<Inputs>({
defaultValues: {
firstName: patient.name?.firstName ?? '',
lastName: patient.name?.lastName ?? '',
birthdate: patient.birthDate ?? '',
country: '',
gender: patient.gender,
email: patient.email ?? '',
leveloftrust: patient.status?.levelOfTrust,
lastsignedin: patient.status?.lastSignInAt,
postalcode: patient.addresses[0]?.postalCode ?? '',
city: patient.addresses[0]?.city ?? '',
street: patient.addresses[0]?.lines[0] ?? '',
},
shouldUseNativeValidation: true,
});
const handleChange = React.useCallback(
(newValue: Dayjs | null) => setValue(newValue),
[]
);
const { t } = useTranslation();
const handleEditClick = useCallback(() => setDisabled(!disabled), [disabled]);
const renderInputField = React.useCallback(
(params: JSX.IntrinsicAttributes & TextFieldProps) => {
return <TextField {...params} />;
},
[]
);
const onSubmit = (data: any) => console.log(data);
return (
<Card>
<CardContent>
<form onSubmit={handleSubmit(onSubmit)}>
<Grid container direction="row" justifyContent="space-between">
<Grid item>
<Typography gutterBottom variant="h5" component="div">
{t('patient.info.title', 'Personal Information')}
</Typography>
</Grid>
<Grid item>
<Grid container justifyContent="space-between" sx={{ m: 1 }}>
{!disabled && (
<Button
onClick={handleEditClick}
size="large"
variant="outlined">
Cancel
</Button>
)}
<Button
onClick={handleEditClick}
size="large"
type="submit"
variant="contained">
{!disabled
? t('patient.setToComplete', 'Set to complete')
: t('patient.edit', 'Edit')}
</Button>
</Grid>
</Grid>
</Grid>
<Grid container direction="row">
<Grid
container
sx={{ margin: 1 }}
rowSpacing={3}
spacing={{ md: 4 }}>
<Grid item>
<TextField
{...register('firstName', { required: 'Field needs to be filled out' })}
label="Name"
name="firstName"
id="component-outlined"
disabled={disabled}
/>
</Grid>
<Grid item>
<TextField
{...register('lastName', {
required: 'Field needs to be filled out',
})}
label="lastname"
name="lastName"
id="component-outlined"
disabled={disabled}
/>
</Grid>
<Grid item sx={{ width: '274.67px' }}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DesktopDatePicker
{...register('birthdate', {
required: 'Field needs to be filled out',
})}
label="Birthdate"
inputFormat="MM/DD/YYYY"
value={value}
onChange={handleChange}
renderInput={renderInputField}
disabled={disabled}
/>
</LocalizationProvider>
</Grid>
</Grid>
<Grid
container
sx={{ margin: 1 }}
rowSpacing={3}
spacing={{ md: 4 }}>
<Grid item>
<TextField
{...register('street')}
id="component-outlined"
label="Street"
name="street"
disabled={disabled}
/>
</Grid>
<Grid item>
<TextField
{...register('postalcode')}
id="component-outlined"
label="Postal code"
name="postalCode"
disabled={disabled}
/>
</Grid>
<Grid item>
<TextField
{...register('city')}
id="component-outlined"
label="City"
name="city"
disabled={disabled}
/>
</Grid>
</Grid>
<Grid
container
sx={{ margin: 1 }}
rowSpacing={3}
spacing={{ md: 4 }}>
<Grid item>
<TextField
{...register('country')}
id="component-outlined"
label="Country"
name="country"
disabled={disabled}
/>
</Grid>
<Grid item>
<TextField
sx={{ width: '242.67px' }}
id="outlined-select-gender"
select
{...register('gender')}
label="Gender"
disabled={disabled}
value={patient.gender}>
{genderValueArray.map(option => (
<MenuItem key={option} value={option}>
{option}
</MenuItem>
))}
</TextField>
</Grid>
<Grid item>
<TextField
{...register('email')}
id="component-outlined"
label="Email"
name="email"
disabled
/>
</Grid>
</Grid>
<Grid
container
sx={{ margin: 1 }}
rowSpacing={3}
spacing={{ md: 4 }}>
<Grid item>
<TextField
{...register('leveloftrust')}
id="component-outlined"
label="Level of trust"
name="leveloftrust"
disabled
/>
</Grid>
<Grid item>
<TextField
{...register('lastsignedin')}
id="component-outlined"
label="Last signed in"
name="lastsignedin"
disabled
/>
</Grid>
</Grid>
</Grid>
</form>
</CardContent>
</Card>
);
}
If you're using React Hook Form with MUI Textfield, you'll need to use the Controller component wrapper from react-hook-form for your MUI Textfield components.
View Integrating with UI Libraries
For example, you would grab the Input component from MUI's Core library instead:
import Input from "#material-ui/core/Input";
Then in your form you'd wrap it using Controller like:
<Controller
name="firstName"
control={control}
render={({ field }) => <Input {...field} />}
/>
Then MUI Input has has error boolean and helperText string as available properties on the Input component. For example using Formik (but any form library would work with MUI):
<TextField
id="password"
name="password"
label="Password"
type="password"
value={formik.values.password}
onChange={formik.handleChange}
error={!!formik.errors.password && formik.touched.password}
helperText={formik.touched.password && formik.errors.password}
required
/>
Otherwise, reviewing their documentation on how to Handle Errors, it appears with no library they have you handle error output manually using the errors object from formState. You'd destructure that data like:
const { register, formState: { errors }, handleSubmit } = useForm();
Finally, they link a very handy CodeSandbox which uses a #hookform/error-message library that can wrap regular HTML inputs. If you want to stick with MUI, I'd go with the helperText and error properties.

React Hook Form is not submitting

I'm new with react form, I'm using Material UI and Controller Component, and I'm sending a React Hook form request but not getting any response, form's (HTML form tag) onSubmit event is occurring but handleSubmit is not working I have one more form like that it is working perfectly fine but I don't know why it's not working, can anybody please help me with that
import { Button, useTheme, Grid, TextField, Typography } from '#mui/material';
import WSSelectBox from 'components/common/WSSelect';
import React, { FC } from 'react';
import { Controller, FormProvider, useForm } from 'react-hook-form';
import { isMobile } from 'utils/mediaqueries';
import CheckBoxButton from '../CheckBoxButton';
import { formTypes } from './utils';
import { yupResolver } from '#hookform/resolvers/yup';
import * as yup from 'yup';
import { FormPropTypes } from './type';
const schema = yup
.object()
.shape({
name: yup.string().required(),
residentialCountry: yup.number().required(),
initiator: yup.string().required(),
program: yup.string().required(),
list: yup.string().required(),
})
.required();
const Entities: FC<FormPropTypes> = ({
handleClick,
selectedType,
handleSearch,
}) => {
const theme = useTheme();
const methods = useForm({
resolver: yupResolver(schema),
});
const { handleSubmit, control } = methods;
const onSubmit = (data) => {
// Backend is not done yet
console.log('DataData', data);
};
return (
<FormProvider {...methods}>
<form
onSubmit={(e) => {
e.preventDefault();
console.log('skdjskd', 'Line no 44');
handleSubmit(onSubmit);
}}
>
<Grid container spacing={'16px'}>
{formTypes.map((type) => (
<Grid item xs={6} sm={'auto'} md={'auto'} key={type}>
<CheckBoxButton
key={type}
name={'type'}
value={type}
handleClick={handleClick}
active={type == selectedType ? true : false}
/>
</Grid>
))}
</Grid>
<Grid container pt={4} columnSpacing="20px" rowSpacing={'16px'}>
<Grid item xs={12} sm={12} md={6}>
<Controller
name="name"
render={({
// eslint-disable-next-line #typescript-eslint/no-unused-vars
field: { value, ...otherFieldProps },
fieldState,
}) => (
<TextField
fullWidth
id="sanctions-form-name"
label="Name"
variant="outlined"
helperText={
<p
style={{
position: 'relative',
left: -13,
fontSize: 12,
}}
>
Try to enter the full name or part of it. It is possible
to use original language or the Latin alphabet.
</p>
}
required
error={!!fieldState.error}
{...otherFieldProps}
/>
)}
/>
</Grid>
<Grid item xs={12} sm={6} md={3}>
<WSSelectBox
id="sanctions-form-residential-country"
label="Residential country"
name={'residentialCountry'}
data={['Ten', 'Twenty']}
handleSelect={() => {}}
type={'text'}
control={control}
/>
</Grid>
<Grid item xs={12} sm={6} md={3}>
<WSSelectBox
data={['Ten', 'Twenty']}
handleSelect={() => {}}
id="sanctions-form-initiator"
name={'initiator'}
label="Initiator"
type="text"
control={control}
/>
</Grid>
<Grid item xs={12} sm={6} md={6}>
<WSSelectBox
id="sanctions-form-program"
label="Program"
data={['Ten', 'Twenty']}
handleSelect={() => {}}
type="text"
name={'program'}
control={control}
/>
</Grid>
<Grid item xs={12} sm={6} md={6}>
<WSSelectBox
id="sanctions-form-list"
label="List"
data={['Ten', 'Twenty']}
handleSelect={() => {}}
type={'text'}
name={'list'}
control={control}
/>
</Grid>
</Grid>
<Grid
container
pt={{ xs: '20px', md: '30px' }}
rowSpacing="10px"
alignItems="center"
sx={{
[isMobile(theme)]: {
textAlign: 'center',
},
}}
justifyContent="left"
>
<Grid item xs={6} sm={'auto'}>
<Button
variant="contained"
color="primary"
sx={{
minWidth: '200px',
['#media (max-width:460px)']: {
minWidth: '120px',
},
}}
type="submit"
>
Search
</Button>
</Grid>
<Grid item xs={6} sm={'auto'}>
<Button
sx={{
minWidth: '200px',
color: '#3883FA',
['#media (max-width:460px)']: {
minWidth: '120px',
},
}}
type="submit"
>
Reset
</Button>
</Grid>
</Grid>
</form>
<Typography
variant="body2"
sx={{ fontSize: 17, color: '#121E3D', marginTop: '20px' }}
>
Use filters to start your search.
</Typography>
</FormProvider>
);
};
export default Entities;
SELECT BOX
import { TextField, MenuItem, styled, Select } from '#mui/material';
import { Controller, useForm } from 'react-hook-form';
export type SelectBoxProps = {
label: string;
id: string;
data: Array<string>;
handleSelect: VoidFunction;
type: string;
Control: () => {};
};
const SelectBox = styled(TextField)`
& .MuiOutlinedInput-root:focus {
&.Mui-focused fieldset {
border-bottom: none !important;
}
}
`;
const WSSelectBox = ({
label,
id,
data,
handleSelect,
name,
type,
control,
}) => {
return (
<>
<Controller
name={name}
render={({ field }) => (
<SelectBox
defaultValue=""
fullWidth
autoComplete="off"
id={id}
type={type}
label={label}
variant="outlined"
required
select
{...field}
>
{data.map((opt) => (
<MenuItem key={opt} value={opt}>
{opt}
</MenuItem>
))}
</SelectBox>
)}
control={control}
/>
</>
);
};
export default WSSelectBox;

Can't access FormData using sign-up form from Material-UI example templates

I'm new to react and fiddling around with Material-UI. I'm trying to use DataPicker and then access the form data with the new FormData() - even though it seems to use TextField, values for start and end are not present. I've used this SignUp form for the beginning.
How do I get them?
App.js
import * as React from 'react';
import Avatar from '#mui/material/Avatar';
import Button from '#mui/material/Button';
import CssBaseline from '#mui/material/CssBaseline';
import TextField from '#mui/material/TextField';
import Link from '#mui/material/Link';
import Grid from '#mui/material/Grid';
import Box from '#mui/material/Box';
import EventAvailableIcon from '#mui/icons-material/EventAvailable';
import Typography from '#mui/material/Typography';
import Container from '#mui/material/Container';
import { createTheme, ThemeProvider } from '#mui/material/styles';
import MyDataPicker from './MyDataPicker';
const theme = createTheme();
export default function SignUp() {
const handleSubmit = (event) => {
event.preventDefault();
const data = new FormData(event.currentTarget);
// eslint-disable-next-line no-console
console.log(data);
// Display the key/value pairs
for (var pair of data.entries()) {
console.log(pair[0] + ': ' + pair[1]);
}
};
return (
<ThemeProvider theme={theme}>
<Container component="main" maxWidth="xs">
<CssBaseline />
<Box
sx={{
marginTop: 8,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<Avatar sx={{ m: 1, bgcolor: 'primary.main' }}>
<EventAvailableIcon />
</Avatar>
<Typography component="h1" variant="h5">
Make Calendar link
</Typography>
<Box component="form" noValidate onSubmit={handleSubmit} sx={{ mt: 3 }}>
<Grid container spacing={2}>
<Grid item xs={12}>
<MyDataPicker
name="start"
label="Start date"
date={null}
/>
</Grid>
<Grid item xs={12}>
<MyDataPicker
name="end"
label="End date"
date={null}
/>
</Grid>
<Grid item xs={12}>
<TextField
required
fullWidth
name="timezone"
label="Timezone"
defaultValue="Europe/Prague"
helperText="See: https://www.php.net/manual/en/timezones.php"
/>
</Grid>
<Grid item xs={12}>
<TextField
required
fullWidth
name="title"
label="Title"
/>
</Grid>
<Grid item xs={12}>
<TextField
multiline
required
fullWidth
name="description"
label="Description"
rows={4}
/>
</Grid>
<Grid item xs={12}>
<TextField
fullWidth
name="location"
label="Location"
/>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
sx={{ mt: 3, mb: 2 }}
>
Generate links
</Button>
</Box>
</Box>
</Container>
</ThemeProvider>
);
}
MyDataPicker.js
import * as React from 'react';
import Stack from '#mui/material/Stack';
import TextField from '#mui/material/TextField';
import AdapterDateFns from '#mui/lab/AdapterDateFns';
import LocalizationProvider from '#mui/lab/LocalizationProvider';
//https://mui.com/api/date-time-picker/
import DateTimePicker from '#mui/lab/DateTimePicker';
export default function MaterialUIPickers(props) {
const [value, setValue] = React.useState(props.date);
console.log(props);
const handleChange = (newValue) => {
setValue(newValue);
console.log(props);
};
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<Stack spacing={3}>
<DateTimePicker
label={props.label}
value={value}
onChange={handleChange}
renderInput={(props) => <TextField {...props} />}
clearable
cleartext="Clear"
/>
</Stack>
</LocalizationProvider>
);
}
You have 2 params with the same name props inside MaterialUIPickers:
export default function MaterialUIPickers(props /* ---------------> props 1 */) {
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<Stack spacing={3}>
<DateTimePicker
{...}
renderInput={(props /* ---------------> props 2 */) => {
return (
<TextField {...props} />
);
}}
clearable
cleartext="Clear"
/>
</Stack>
</LocalizationProvider>
);
}
Because props 1 is from the outer scope, it will be overridden by props 2, which prevents you from passing the name attribute down to the input element, that's why the form can't find the field value. The fix is pretty simple, rename one of the props to differentiate between the 2 of them:
renderInput={(params) => {
return (
<TextField
{...params}
{...props} // put props after to let it overrides the name here
inputProps={{
...params.inputProps,
...props.inputProps
}}
InputProps={{
...params.InputProps,
...props.InputProps
}}
/>
);
}}

how to preview the selected image upload React js

Have created a button called image upload, need to view the selected image when selected
<GridItem xs={6}>
<FormControl className={classes.formControl}>
<input
accept="image/*"
className={classes.input}
style={{ display: 'none' }}
id="raised-button-file"
multiple
type="file"
/>
<label htmlFor="raised-button-file">
<Button
variant="raised"
component="span"
className={classes.button}
>
Upload Image
</Button>
</label>
</FormControl>
</GridItem>
you can set the file object URL in the state during the onChange and use it in an img tag like this,
const [file, setFile] = useState(undefined);
const handleChange = (event) => {
setFile(URL.createObjectURL(event.target.files[0]));
}
use this handleChange method in input onChange event,
<GridItem xs={6}>
<FormControl className={classes.formControl}>
<input
accept="image/*"
className={classes.input}
style={{ display: 'none' }}
id="raised-button-file"
multiple
type="file"
onChange={handleChange}
/>
{/* preview of file */}
{ file && <img src={this.state.file}/>}
<label htmlFor="raised-button-file">
<Button
variant="raised"
component="span"
className={classes.button}
>
Upload Image
</Button>
</label>
</FormControl>
</GridItem>
also if you want to allow the user to crop the image selected there is this library react-image-crop. I use it and it works pretty good for me.
before select
select image
Typescript
import { Grid, IconButton, makeStyles, Tooltip } from '#material-ui/core'
import { PhotoCamera, Publish } from "#material-ui/icons"
import React, { useState } from 'react'
import { useDispatch } from 'react-redux'
import { IRequestState } from '../../assets/interfaces'
const FILE = 'ImageUpload.tsx'
const useStyles = makeStyles((theme) => ({
root: {
'& > *': {
margin: theme.spacing(1),
},
}, right: {
float: "right"
}, w100: {
width: "100%"
}, input: {
display: "none",
},
faceImage: {
color: theme.palette.primary.light,
}, success: {
color: theme.palette.success.main
}
}))
interface IImageUploadProps {
Submit(event: React.MouseEvent<HTMLButtonElement>): void
}
type IImageUploadState = IRequestState & {
imageFile?: any
}
export default function ImageUpload(props: IImageUploadProps) {
const classes = useStyles()
const dispatch = useDispatch()
const initState: IImageUploadState = { inited: false, requesting: false }
const [values, setState] = useState<IImageUploadState>(initState)
const handleCapture = ({ target }: any) => {
if (target && target.files && target.files.length)
setState({ ...values, imageFile: target.files[0] })
}
return (
<>
<Grid
container
direction="row"
justify="space-evenly"
alignItems="center"
spacing={2}
>
<Grid item sm={6} md={3}>
<Grid
justify="center"
alignItems="center"
container
>
<Grid item>
<input
accept="image/jpeg"
className={classes.input}
id="faceImage"
type="file"
onChange={handleCapture}
/>
<Tooltip title="select image">
<label htmlFor="faceImage">
<IconButton
className={classes.faceImage}
color="primary"
aria-label="upload picture"
component="span"
>
<PhotoCamera fontSize="large" />
</IconButton>
</label>
</Tooltip>
</Grid>
</Grid>
</Grid>
<Grid item sm={6} md={3}>
<img className={classes.w100} hidden={!values.imageFile} src={values.imageFile && URL.createObjectURL(values.imageFile)} alt="Logo" />
</Grid>
<Grid item sm={6} md={3}>
<Grid
justify="center"
alignItems="center"
container
>
<Grid item>
<Tooltip title="upload image">
<IconButton
className={classes.success}
aria-label="upload"
onClick={props.Submit}
edge="end"
disabled={!values.imageFile}
>
<Publish />
</IconButton>
</Tooltip>
</Grid>
</Grid>
</Grid>
</Grid>
</>
)
}

Material UI Grid - Textfield is being resized once an item is selected in Select element

I am using Material UI to build a simple UI. Textfield size (set to fullWidth) is getting smaller when I select one from Select element.
I reduced the code to minimum which can reproduce the weird action.
function ImportDialog(props) {
const [state, setState] = useState({
id: "",
color: ""
});
const handleChange = name => event => {
setState({ ...state, [name]: event.target.value });
};
const inputLabel = React.useRef(null);
const [labelWidth, setLabelWidth] = React.useState(0);
useEffect(() => {
setLabelWidth(inputLabel.current.offsetWidth);
}, []);
return (
<div style={{ width: "40vw", height: "50vh", margin: "25vh auto" }}>
<Grid container spacing={2}>
<Grid item md={6}>
<Grid container direction="column">
<Grid item>
<TextField
label="ID"
margin="dense"
variant="outlined"
fullWidth
value={state.id}
onChange={handleChange("id")}
/>
</Grid>
<Grid item>
<FormControl
variant="outlined"
margin="dense"
fullWidth
>
<InputLabel ref={inputLabel} htmlFor="outlined-age-simple">
Color
</InputLabel>
<Select
value={state.color}
onChange={handleChange("color")}
labelWidth={labelWidth}
inputProps={{
name: "color",
id: "outlined-age-simple"
}}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={1}>Sup1</MenuItem>
</Select>
</FormControl>
</Grid>
</Grid>
</Grid>
</Grid>
</div>
);
}
export default withStyles(styles)(ImportDialog);
When I move focus to textfield after choosing one from the Select element, it gets smaller.
Please try the codesandbox in bigger window size.
https://codesandbox.io/s/material-demo-59siu
This is the url of codesandbox.

Resources