As per the demo, the label for a MUI outlined select input should sit on top of the top border of the select box.
However, in my application, the z-index of the label seems to be placing it behind the top border and thus it looks like a line is cutting through the label.
I have pretty much taken the code exactly from the documentation, and as far as I know, do not have any styles conflicting with this input element. I have compared the styles in the debugger to what I have and what is present in the documentation, and I do not see any of my first party CSS files causing a different style to be set on the element.
Any idea what might be going wrong here?
Here is the source code:
<FormControl variant='outlined' style={{ width: '100%' }} margin={'1'}>
<InputLabel id='test-select-label'>Label</InputLabel>
<Select
labelId='test-select-label'
id='test-select'
value={'test1'}
onChange={e => setTest(e.target.value)}
size='small'
>
<MenuItem key={1} value={'test'} >Test 1</MenuItem>
<MenuItem key={2} value={'test2'} >Test 2</MenuItem>
</Select>
</FormControl>
Solution 1: Use TextField
This is what TextField is for. It uses FormControl and InputLabel internally and make sure they work well together. You can tell TextField to render select instead input by overriding the select props:
<TextField
value={value}
onChange={(e) => setValue(e.target.value)}
select // tell TextField to render select
label="Label"
>
<MenuItem key={1} value="test">
Test 1
</MenuItem>
<MenuItem key={2} value="test2">
Test 2
</MenuItem>
</TextField>
For more detail about how TextField works, see this answer.
Solution 2: Use Select
If you decide to use Select, you need to write more code to do the same amount of work:
Pass the label text as InputLabel children
<InputLabel id="test-select-label">Label</InputLabel>
This label text will be rendered on the screen as the Select label when put inside FormControl and next to the Select component.
Pass the label text to the label props of the Select component
This label text is hidden and used to override and remove the part of the border-top where the real label is occupied when the Select label is shrinked.
<Select labelId="test-select-label" label="Label">
Putting it together we'll have something like below, note that with this approach we need to set the label in 2 different places which is not very DRY, so I'd prefer the first approach.
<FormControl>
<InputLabel id="test-select-label">Label</InputLabel>
<Select
value={value}
onChange={(e) => setValue(e.target.value)}
labelId="test-select-label"
label="Label"
>
<MenuItem key={1} value="test">
Test 1
</MenuItem>
<MenuItem key={2} value="test2">
Test 2
</MenuItem>
</Select>
</FormControl>
Live Demo
If you add the label property to your select component your problem should disappear.
...
<Select
value={value}
onChange={(e) => setValue(e.target.value)}
label="Label" // add this
>
<MenuItem key={1} value="test">
Test 1
</MenuItem>
<MenuItem key={2} value="test2">
Test 2
</MenuItem>
</Select>
...
Here is a live demo where you can see the difference:
Try this method, it worked for me.
JSX:
<TextField select variant={"outlined"} style={{width: "100%"}} label="Label">
<MenuItem key={1} value="test">
Test 1
</MenuItem>
<MenuItem key={2} value="test2">
Test 2
</MenuItem>
</TextField>
CSS:
.MuiSelect-outlined.MuiSelect-outlined, .MuiSelect-outlined.MuiSelect-outlined:active, .MuiSelect-outlined.MuiSelect-outlined:focus {
background-color: transparent;
text-align: left;
font-family: sans-serif !important;
font-size: 14px !important;
font-weight: 400 !important;
}
I had a similar issue when I tried to set padding on the FormControl component. I had the proper id and label, but it was still an issue. CSS is not my strong suit, but I noticed that if I could replicate the layout I wanted using margin on the FormControl component, the label aligned appropriately. See image with padding instead of margin:
Related
I have a multi-select MUI element, and when I select multiple items on a small screen, the elements make the parent larger, so you would have to scroll to the right to view everything.
How can I fixe this?
<Box
display={"flex"}
flexDirection={"column"}
rowGap={3}
sx={{
mb: 1,
px: 2,
}}
>
<FormControl>
<InputLabel id="simple-select-label">
Job completed by
</InputLabel>
<Select
label="Job completed by"
name="employeeID"
multiple={true}
id="simple-select"
sx={{
}}
required
value={values.employeeID}
onChange={(e) => {
setValues({
...values,
employeeID: e.target.value,
})
}}
>
{employeesLists?.map((employee) => (
<MenuItem value={employee.id} key={employee.id}>
{employee.firstName} {employee.lastName}
</MenuItem>
))}
</Select>
</FormControl>
</Box>
To fix this, I had to use the override nested component strategy: https://mui.com/material-ui/customization/how-to-customize/#1-one-off-customization
I added this to fix the problem, to override the default styles. It can be placed on <Select>.
sx={{
'& #simple-select': {
whiteSpace: 'normal',
},
}}
``
This is a little bit weird situation. I have 2 divs in a FormControl and my input label for Select completely fine. However, when I style it in flexDirection: 'row' The label is outboxed as you can see in below picture.
Edit: It works fine when I comment out justifyContent.
When it is ok.
When it is in flexDirection: row
Below is my code
const useStyles = makeStyles((theme) => ({
submitForm: {
display: 'flex',
flexDirection: 'row',
margin: theme.spacing(1),
justifyContent: 'space-evenly'
},
bacsInputs: {
minWidth: '200px'
}
}))
const DemoInventory = () => {
const bacsInfoInputs = () => {
return(
<>
<p><b>Enter BACS information below and click SAVE</b></p>
<FormControl variant="outlined" className={classes.submitForm}>
<div>
<InputLabel clasName={classes.submitForm} id="demo-simple-select-outlined-label">Select BACS Unit</InputLabel>
<Select
labelId="demo-simple-select-outlined-label"
id="demo-simple-select-outlined"
value={bacsUnit}
onChange={onChangeInput}
label="BACS Unit"
className={classes.bacsInputs}
>
<MenuItem value={'Product-1'}>Product-1</MenuItem>
<MenuItem value={'Product-2'}>Product-2</MenuItem>
<MenuItem value={'Product-3'}>Product-3</MenuItem>
<MenuItem value={'Product-4'}>Product-4</MenuItem>
<MenuItem value={'Product-5'}>Product-5</MenuItem>
<MenuItem value={'Product-6'}>Product-6</MenuItem>
<MenuItem value={'Product-7'}>Product-7</MenuItem>
</Select>
<p>Serial number input</p>
<p>Part number input</p>
<p>Location input</p>
<p>description input</p>
</div>
<div>
<p>deployment input</p>
<p>ship Date input</p>
<p>Expected return date input</p>
</div>
<p>Save Button</p>
</FormControl>
</>
)
}
}
return (
<Fragment>
{bacsInfoInputs()}
</Fragment>
)
it is because you've provided a class classes.submitForm to the FormControl element which is changing its default style and thus you're getting a different style in the selectbox.
FormControl elements are used for wrapping the input elements only to get extra control and features, so don't put any other elements other than input elements inside this element. So put only the Select and InputLabel elements only in this case for better result.
I am implementing Material UI `Select' for which values are coming from backend. Below is my code
<FormControl variant="outlined" className={classes.formControl}>
<InputLabel ref={inputLabel} id="demo-simple-select-outlined-label" htmlFor="outlined-Name">
Name
</InputLabel>
<Select
value={Name}
onChange={handleChange}
labelWidth={labelWidth}
inputProps={{
name: 'Name',
id: 'outlined-Name',
}}
>
<MenuItem value="1" className={classes.menuItm}>All</MenuItem>
{
NameArr.data.map(Name => (
<MenuItem value={Name.name} className={classes.menuItm}>{Name.name}</MenuItem>
))
}
</Select>
</FormControl>
The problem with below code is that variant="outlined" is not getting applied. I am not able to see the outline/border which should be there as per the demo here https://codesandbox.io/s/material-demo-9jyoj
What's wrong in my code?
You need to update #material-ui/core package.
In the current version (4.9.1) outlined is passed properly to the <FormControl> children.
For me personally an update from 4.1.0 to 4.9.1 fixed this issue.
you should apply outline variant to select like so :
<FormControl className={classes.formControl}>
<InputLabel ref={inputLabel} id="demo-simple-select-outlined-label" htmlFor="outlined-Name">
Name
</InputLabel>
<Select
value={Name}
variant="outlined" {/* -------------> here is what you looking for */}
onChange={handleChange}
labelWidth={labelWidth}
inputProps={{
name: 'Name',
id: 'outlined-Name',
}}
>
{NameArr.data.map(Name => (
<MenuItem value={Name.name} className={classes.menuItm}>{Name.name}}
</MenuItem>
)}
</Select>
</FormControl>
I am using the Select component of material ui. I want to customise the dropdown menu with a top arrow. I have overriden menuStyle using pseudo element before. However, the arrow appears on the screen even before clicking on the dropdown. This is because the class is used in select element as well. I want to target dropdown menu by checking for the siblings.
<Select
value={this.state.date}
onChange={this.handleChange}
displayEmpty
name='date'
autoWidth={false}
className={classes.selectWithArrow}
classes={{
icon: classes.icon,
selectMenu: classes.menuStyle,
select: classes.select,
}}
renderValue={value => this.state.date}
root={classes.root}
input={
<Input
name='date'
id="label-placeholder"
classes={{
root: classes.root,
}}
/>
}
MenuProps={{ classes: { paper: classes.menuStyle } }}
>
<MenuItem value={1}>One</MenuItem>
<MenuItem value={2}>Two</MenuItem>
<MenuItem value={3}>Three</MenuItem>
</Select>
I want to target siblings something like this -
const styles = theme => ({
'.menuStyle.selectMenu': {
'&::before': {
},
}
});
Is there any way? Any leads will be highly appreciated.
I'm using Meteor + ReactJS and I'm pulling Material-UI via node modules.
<RadioButtonGroup name="shipSpeed" defaultSelected="not_light">
<RadioButton value="light" label="Simple" style={styles.radioButton} />
<RadioButton value="not_light" label="Selected by default" style={styles.radioButton} />
<RadioButton value="ludicrous" label="Disabled" disabled={true} style={styles.radioButton} />
</RadioButtonGroup>
Here is what it renders.
But it won't change values like it's supposed to do on click. It just stays static.
Check the below example. You have to pass valueSelected and onChange props to RadioButtonGroup to get the values of RadioButton. In onChange function set the selected value in state and pass that state to valueSelected that’s all. As simple as that.
<RadioButtonGroup
valueSelected={this.state.cranRadio}
onChange={this.handleCRAN}
style={{ display: "flex", flexWrap: "wrap", justifyContent: "space-between" }}
name="coin"
defaultSelected="not_light"
>
<RadioButton
value="Yes"
label="Yes"
inputStyle={styles.inputStyle}
style={{ width: "auto" }}
labelStyle={{ marginLeft: "-10px" }}
/>
<RadioButton
value="No"
label="No"
style={{ width: "auto" }}
inputStyle={styles.inputStyle}
labelStyle={{ marginLeft: "-10px" }}
/>
</RadioButtonGroup>;
I maybe having similar issue with Checkbox.
If i provide a handler, then the checkbox is not showing 'tick' when checked. Without handler, the check shows with ripple effect.
import mui from 'material-ui';
import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();
...
<mui.Checkbox
label="Employed"
name="Employed"
labelPosition="left"
style={fstyles.checkbox}
onCheck={props.cb}
/>
If I dont provide the onCheck, then the check shows.. should the handler return some value? currently it sets my top level component's state . I tried returning true, but did not help.