React Material UI: Outlined text field shows line through label - reactjs

I'm using MUI 5 and React and I have this issue that the outlined text field shows line through the label as per the screenshot
I have no idea how to fix it.
My fields looks like this
<FormControl fullWidth variant="outlined">
<InputLabel shrink id={labelId}>
{label}
</InputLabel>
<Controller
as={
<Select
displayEmpty
name={name}
labelId={labelId}
id={name}
label={label}
>
<MenuItem key={`no${name}`} value="">
{intl.formatMessage({
defaultMessage: 'No proxy number',
})}
</MenuItem>
{items.map(pn => (
<MenuItem key={pn.id} value={pn.id}>
<ListItemIcon>
<img
src={pn?.country?.flagIconUrl}
alt={pn.countryCode}
width="20px"
height="15px"
/>
</ListItemIcon>
{pn.value}
</MenuItem>
))}
</Select>
}
name={name}
control={control}
/>
<FormHelperText>{helperText}</FormHelperText>
</FormControl>
Then the above is used as a function called SelectFormInput to make the specific fields
<Grid item xs={6}>
<SelectFormInput
control={control}
labelId="proxyNumber"
name="proxyNumber"
items={proxyNumbers}
label={intl.formatMessage({
defaultMessage: 'Proxy phone Number',
})}
helperText={intl.formatMessage({
defaultMessage: 'Optional. Phone number used by site users',
})}
/>
</Grid>
<Grid item xs={6}>
<SelectFormInput
control={control}
labelId="inboundProxyNumber"
name="inboundProxyNumber"
items={inboundProxyNumbers}
label={intl.formatMessage({
defaultMessage: 'Inbound Proxy Number',
})}
helperText={intl.formatMessage({
defaultMessage: 'Optional. Phone number seen by candidate',
})}
/>
</Grid>
I was unable to find any solution on the net for my specific situation.

I found a solution that helped my specific situation.
I had to add this
input={<OutlinedInput notched label={label} />}
Inside my
<Select
displayEmpty
name={name}
labelId={labelId}
id={name}
input={<OutlinedInput notched label={label} />} />
And so the label UI has been fixed

There is a <fieldset/> tag within the FormControl, and the <legend/> inside of it is making the white block possible.
https://github.com/mui/material-ui/blob/de11911f2e3b15b9fe07ce2625a3ce1cc593093c/packages/mui-material/src/OutlinedInput/OutlinedInput.js#L142
https://github.com/mui/material-ui/blob/de11911f2e3b15b9fe07ce2625a3ce1cc593093c/packages/mui-material/src/OutlinedInput/NotchedOutline.js#L79
I am not sure in your case (<Select/>), but if you are trying to use raw input with the outlined style, you have to give label prop to the <OutlinedInput/>.
<FormControl fullWidth>
<InputLabel>Phone</InputLabel>
<OutlinedInput label="Phone" /> // without label="...", you get the line-through
</FormControl>

you can also try add a background color to InputLabel, on createTheme, this works for me:
import { createTheme } from '#material-ui/core';
const theme = createTheme({
overrides: {
MuiInputLabel: {
root: {
backgroundColor: '#ffffff',
paddingLeft: '4px',
paddingRight: '4px'
}
}
}
});
export default theme;

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.

How can I change the way of selecting in a checkbox?

I'm using react and I have a checkbox created with Autocomplete where I select items. It
is the same as that provided by material:
The problem is that the function "OnChange" runs only if I select the square.
I would like it to work also by selecting the row. How can I do it? Here's my code:
<AutoComplete
multiple
id="checkboxes-tags-demo"
options={props.roles}
// disableCloseOnSelect
// getOptionLabel={(options) => `${options}`}
renderOption={(options, { selected }) => (
<React.Fragment>
<Checkbox
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 20 }}
value={options}
checked={selected}
onChange={updateNewRoles}
/>
{options}
</React.Fragment>
)}
style={{ width: 500 }}
renderInput={(params) => (
<TextField
{...params}
variant="outlined"
label=""
placeholder="Available Roles"
/>
)}
/>
<button type="submit" onClick={onSubmitChecked}>
Save
</button>
This is a photo of the example provided by material. The functions are performed only by clicking the icon and not the line:

Why does AccordionSummary background change to grey when clicking inside TextField in Material-UI?

I am using Material-UI's Accordion and inside AccordionSummary I have a <TextField /> (which is actually controlled by Formik and formik-material-ui) and the background of AccordionSummary turns grey when clicking inside the field only. I don't want it to do this and it doesn't appear to be anything configured by the Accordion API, unless I am missing something. How can I stop it from behaving this way?
I've recreated the issue on Codesandbox.
Here's the full code from the sandbox:
import React from "react";
import { Formik, Field, Form, ErrorMessage } from "formik";
import { TextField, CheckboxWithLabel, Select } from "formik-material-ui";
import Grid from "#material-ui/core/Grid";
import Box from "#material-ui/core/Box";
import FormControl from "#material-ui/core/FormControl";
import MenuItem from "#material-ui/core/MenuItem";
import Button from "#material-ui/core/Button";
import Accordion from "#material-ui/core/Accordion";
import AccordionDetails from "#material-ui/core/AccordionDetails";
import AccordionSummary from "#material-ui/core/AccordionSummary";
export default function App() {
return (
<div className="App">
<Formik>
<Form>
<Accordion>
<AccordionSummary>
<FormControl fullWidth>
<Field
component={TextField}
name="itemName"
placeholder="What do you want to buy?"
variant="outlined"
/>
</FormControl>
</AccordionSummary>
<AccordionDetails>
<Grid container>
<Grid item xs={2}>
<Box pt={2}>
<FormControl fullWidth>
<Field
component={TextField}
name="quantity"
label="Qty"
type="number"
variant="outlined"
size="small"
/>
</FormControl>
</Box>
</Grid>
<Grid item xs={2}>
<Box pt={2} pl={1}>
<FormControl fullWidth>
<Field
component={TextField}
name="volume"
label="Vol"
type="number"
variant="outlined"
size="small"
/>
</FormControl>
</Box>
</Grid>
<Grid item xs={2}>
<Box pt={2} pl={1}>
<FormControl label="Type" size="small" fullWidth>
<Field
component={Select}
name="volumeType"
as="select"
variant="outlined"
>
<MenuItem value="g">grams</MenuItem>
<MenuItem value="kg">kg</MenuItem>
<MenuItem value="ml">ml</MenuItem>
<MenuItem value="cl">cl</MenuItem>
<MenuItem value="litre">litre</MenuItem>
<MenuItem value="pint">pint</MenuItem>
<MenuItem value="pack">pack</MenuItem>
</Field>
</FormControl>
</Box>
</Grid>
<Grid item xs={4}>
<Box pt={2} pl={1}>
<FormControl fullWidth>
<Field
component={TextField}
name="brandName"
label="Brand"
variant="outlined"
size="small"
/>
</FormControl>
</Box>
</Grid>
<Grid item xs={2}>
<Box pt={2} pl={1}>
<Button
type="submit"
variant="contained"
color="primary"
disableElevation
fullWidth
>
Add
</Button>
</Box>
</Grid>
</Grid>
</AccordionDetails>
</Accordion>
</Form>
</Formik>
</div>
);
}
What you are seeing is the focused styling for AccordionSummary. You can observe this in the Accordion demos as well by clicking on an accordion and then using the Tab key to move to the next AccordionSummary. This is there for accessibility reasons so that the user can tell where focus is within the Accordion when navigating with the keyboard.
You can override this with the following:
import MuiAccordionSummary from "#material-ui/core/AccordionSummary";
import { withStyles } from "#material-ui/core/styles";
const AccordionSummary = withStyles({
root: {
"&.Mui-focused": {
backgroundColor: "inherit"
}
}
})(MuiAccordionSummary);

Material UI OutlinedInput label is invisible

We are using OutlinedInput from Material UI, but text labels are not rendered. How to fix this?
import { Grid, OutlinedInput } from '#material-ui/core';
<Grid container>
<Grid item xs={12}>
<OutlinedInput
label="invisible label"
placeholder="HELLO, STACKOVERFLOW!"
value={value}
onChange={(e) => handleValueChange(e.target.value)}
fullWidth
/>
</Grid>
</Grid>
instead of expected "invisible label" text, an empty space is rendered (top left corner):
Like #Daniel L mentioned, you have to use the InputLabel component within the FormControl component, but in addition to his answer - I had to add a label attribute on my OutlinedInput component so that the outline on the input would not overlap with my label.
Code without the label attribute:
<FormControl sx={{ m: 1, width: '25ch' }} variant="outlined">
<InputLabel htmlFor='display-name'>Display Name</InputLabel>
<OutlinedInput
id="display-name"
value={displayName}
onChange={(e) => handleInputChange(e)}
aria-describedby="base-name-helper-text"
inputProps={{
'aria-label': 'weight',
}}
/>
</FormControl>
Code WITH the label attribute:
<FormControl sx={{ m: 1, width: '25ch' }} variant="outlined">
<InputLabel htmlFor='display-name'>Display Name</InputLabel>
<OutlinedInput
id="display-name"
value={displayName}
label='Display Name'
onChange={(e) => handleInputChange(e)}
aria-describedby="base-name-helper-text"
inputProps={{
'aria-label': 'weight',
}}
/>
</FormControl>
I don't think this component is meant to be used on its own. In the MUI docs, it is primarily used as augmentation for other components such as TextField
<TextField id="outlined-basic" label="Outlined" variant="outlined" />
If you inspect the styles in dev tools, it looks like the CSS property visibility: hidden is causing this issue. In fact, if you remove that style, you will see that the label works.
However, if you have already built the majority of your app with this component and you need to show that label, just override it with MUI's styling solutions such as makeStyles. In addition, use notched prop to allocate space for it
const useStyles = makeStyles({
customInputLabel: {
"& legend": {
visibility: "visible"
}
}
});
export default function App() {
const classes = useStyles();
return (
<div className="App">
<Grid container>
<Grid item xs={12}>
<OutlinedInput
classes={{ notchedOutline: classes.customInputLabel }}
label="visible label"
placeholder="HELLO, STACKOVERFLOW!"
fullWidth
notched
/>
</Grid>
</Grid>
</div>
);
}
I had the same issue and I wrapped OutlinedInput into the FormControl element and attached InputLabe component as a label and that fixed my issue.
The quick answer to this is basically wrapping the component under a FormControl and adding an InputLabel on top of the OutlinedInput component.
Based on your code, it should look like this:
<Grid container>
<Grid item xs={12}>
<FormControl>
<InputLabel htmlFor="outlined-adornment">Some text</InputLabel>
<OutlinedInput
id="outlined-adornment"
placeholder="HELLO, STACKOVERFLOW!"
value={value}
onChange={(e) => handleValueChange(e.target.value)}
fullWidth
/>
</FormControl>
</Grid>
</Grid>

How to add padding between label and control on FormControlLabel

I'm trying to have an inline form, where the label is left to the control which doesn't seem to be default usage of various form components.
So far this does the trick:
<Grid container spacing={0}>
<Grid item xs={12}>
<FormControlLabel
label="ID"
disabled
value="42a5936e-9856-42d4-b540-104fd79bcf36"
labelPlacement="start"
control={
<TextField fullWidth name="ID" />
}
/>
</Grid>
</Grid>
But there is no space at all between the label and the control.
Here's what it looks like
I assume some padding-right has to be added to the label, but I'm not sure where I would put that using these components.
Add style to the props of TextField:
<Grid container spacing={0}>
<Grid item xs={12}>
<FormControlLabel
label="ID"
disabled
value="42a5936e-9856-42d4-b540-104fd79bcf36"
labelPlacement="start"
control={
<TextField
fullWidth
name="ID"
style={{ paddingLeft: '20px' }}
/>
}
/>
</Grid>
</Grid>
Alternatively, TextField takes a className prop for you to add classes to the components and style those classes.
To customize the Textfield input zone padding:
Use MUI nesting selector of className MuiInputBase-root
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles(theme => ({
root: {
"& .MuiInputBase-root": {
paddingLeft: 10
}
}
}));
const classes = useStyles();
control={<TextField fullWidth name="ID" className={classes.root} />}
For inline style
Would this work for you?
<TextField
value="42a5936e-9856-42d4-b540-104fd79bcf36"
fullWidth
InputProps={{
startAdornment: (<InputAdornment position="start">ID</InputAdornment>)
}}
/>

Resources