MaterialUI v5 -> How to style Autocomplete options - reactjs

I'm trying to apply some basic styles to the options inside the Autocomplete component from MUI v5. I'm just trying to change the background color on hover, and based on whether or not it is selected. I've tried 2 approaches based on the documentation, using a theme, and applying the sx prop to Autocomplete.
Using Theme almost has me there, code below:
import { createTheme, ThemeProvider } from '#mui/material/styles';
const theme = createTheme({
components: {
MuiAutocomplete: {
styleOverrides: {
option: {
'&[aria-selected="true"]': {
backgroundColor: '#e3abed',
},
'&:hover': {
backgroundColor: '#9c27b0',
},
backgroundColor: '#fff',
},
},
},
},
})
I have the ThemeProvider wrapped around my entire app
and the component:
<Autocomplete
options={['1', '2', '3']}
renderInput={(params) => <TextField {...params} label="Priority" />}
onChange={(_e, val) => setPriority(val)}
/>
So, this almost works. However the [aria-selected="true"] styling is only being applied when I am also hovering over another option in the dropdown. Otherwise it's the default grey that comes with the component and I don't understand why.
The second path I have tried is to use the sx prop on the Autocomplete component. In the docs it says you can target child components by their class name: https://mui.com/material-ui/customization/how-to-customize/#overriding-styles-with-class-names
Here is my component:
<Autocomplete
options={['1', '2', '3']}
renderInput={(params) => <TextField {...params} label="Priority" />}
onChange={(_e, val) => setPriority(val)}
sx={{
'& .MuiAutocomplete-option': {
backgroundColor: '#000',
},
'& .Mui-focused': {
backgroundColor: 'red',
},
}}
open
/>
That doesn't appear to be having any effect. I've been working on this for almost 2 hours and can't seem to get to the finish line here. Any help would be greatly appreciated.

I had the same problem; turns out I just needed to explore the Autocomplete API docs' Props section a bit further. There are several customization possibilities if you don't want to deal with global theme customization:
The PaperComponent prop allows customization of "[t]he component used to render the body of the popup." Note that simply using sx on Autocomplete does not work here because (as #bnays-mhz pointed out) the PopperComponent that the PaperComponent is nested in lives outside the main DOM tree (for z-index/modal UX purposes).
The renderGroup prop allows overriding the rendering of option group headers.
The renderOption prop allows overriding the rendering of individual options.

function CustomPaper({ children }) {
return (
<Paper
sx={{
"& .MuiAutocomplete-listbox": {
"& .MuiAutocomplete-option[aria-selected='true']": {
bgcolor: "purple",
"&.Mui-focused": {
bgcolor: "purple",
}
}
},
"& .MuiAutocomplete-listbox .MuiAutocomplete-option.Mui-focused": {
bgcolor: "red",
}
}}
>
{children}
</Paper>
);
}
Following up on Lars' answer, here's an example using a custom Paper component. Just pass in the custom Paper component name to the PaperComponent prop on Autocomplete <Autocomplete PaperComponent={CustomPaper} {...blahBlahOtherProps} />. This way is nice if you don't want to override the theme for all Autocomplete components.

You can override Autocomplete options css by targeting class
'.MuiAutocomplete-popper'
You will have to apply css globally because this node is created outside the root element in DOM.

I too faced this issue and found a solution.
You Can try this to set the css for options, single option and while hovered (focused) in the Autocomplete using 'sx' prop
Easy Way to customize your AutoComplete component which can be used in Mui V5
<Autocomplete
limitTags={1}
disablePortal
id="simple-search"
value={select.region}
onChange={handleChange("region")}
options={region}
sx={{
width: { sm: "100%", md: 340 },
"& + .MuiAutocomplete-popper .MuiAutocomplete-option":
{
backgroundColor: "#363636",
},
"& + .MuiAutocomplete-popper .MuiAutocomplete-option[aria-selected='true']":
{
backgroundColor: "#4396e6",
},
"& + .MuiAutocomplete-popper .MuiAutocomplete-option[aria-selected ='true'] .Mui-focused":
{
backgroundColor: "#3878b4",
},
}}
disableCloseOnSelect
multiple
renderInput={(params) => (
<TextField {...params} label="Region" color="info" />
)}
/>

Related

Material UI V5 Theming Customization

How can i override this css of material ui ? i want to change de color to : white, becouse when i try to write on my TextField the color is black
If you want just the text color to be white
You can add sx prop for the TextField.
<TextField
variant="outlined"
sx={{
'& .MuiInputBase-input': {
color: 'white',
},
}}
/>
If you want to customize the default MUI theme
Import createTheme and ThemeProvider.
import { createTheme, ThemeProvider } from '#mui/material/styles';
Override theme.
(You can go to https://mui.com/customization/default-theme/ and find exactly what to override.)
const theme = createTheme({
palette: {
common: {
white: '#FFFAFA'
},
}
})
Wrap Your Components or the TextField with ThemeProvider.
<ThemeProvider theme={theme} >
<TextField
variant="outlined"
sx={{
'& .MuiInputBase-input': {
color: 'white',
},
}}
/>
</ThemeProvider>
The color 'white' in the TextField will be the white color that you customized.
You can also define a color palette for the application.
Refer mui.com/customization/theming for more details.
Here is a youtube Tutorial for this
https://www.youtube.com/watch?v=xIIJfmDnvPE&ab_channel=TheNetNinja
If your custom style is overridden by Material UI you can just add !important; after each one of your custom styles.
You can the sx on the props of the object:
<TextField id="outlined-basic" sx={{background:'red'}} label="Outlined" variant="outlined" />
follow the link to see the props of sx: https://mui.com/system/the-sx-prop/
See the docs for overriding nested component styles.
For TextField that would be:
<TextField
variant="outlined"
sx={{
'& .MuiInputBase-input': {
color: 'white',
},
}}
/>)

How to pass custom props to Material-UI component using makeStyles/withStyles?

How can I pass a custom props to MUI component? Let's say I want pass customProps='red' which changes the background color of a component?
In my case I need to add a different background color for a button and I want to add something like this:
<SubmitButton
variant={"outlined"}
customBackground={'red'} // this prop
>
Submit
</SubmitButton>
Should I use makeStyles?
Here's the codesandbox.
In your styles defined with withStyles
root: {
backgroundColor: (props) => props.customBackground
{...}
},
Then in the component created by withStyles HOC:
<SubmitButton customBackground="red"
If you want to set a group of style properties, you can pass a callback that returns a style object instead of a value (docs):
root: ({ mode }) => ({
...(mode === "dark" && {
backgroundColor: "black",
color: "lightgray",
"&:hover": {
backgroundColor: "darkblue"
}
}),
...(mode === "light" && {
backgroundColor: "white",
color: "black",
"&:hover": {
backgroundColor: "lightblue"
}
}),
})
Then pass the prop in your custom component to apply dynamic styles:
<SubmitButton mode="light">light</SubmitButton>
<SubmitButton mode="dark">dark</SubmitButton>
Should I use makeStyles?
makeStyles and withStyles are the same except that makeStyles returns a hook which cannot be used in a class component. If you use functional component, you should use makeStyles because it's more pluggable (easier to add or remove styles).

material UI - How can I change the font size of the label in FormControlLabel

How can I change the font size of the label inside the FormControlLabel?
I am using it with React for Front End JS
<FormGroup row>
<FormControlLabel
control={
<Checkbox onClick={() => onClick('rdOption4')} />
      }
label="All Date"
/>
</FormGroup>
FormControlLabel's label prop accepts a node, so you can pass in a Typography element and style it the same way you style the rest of the text in your app.
eg.
<FormControlLabel
label={<Typography variant="body2" color="textSecondary">Foo</Typography>}
/>
I know that this is not beautiful way but I can change font size for specific label like this.
<FormControlLabel
label={<span style={{ fontSize: '2rem' }}>{label}</span>}
/>
Do it using themes:
import { createMuiTheme } from '#material-ui/core';
export const theme = createMuiTheme({
overrides: {
MuiFormControlLabel: {
label: {
fontSize: '0.875rem',
}
}
}
});
Themes Documentation
See how style overrides work at the component level:
https://material-ui.com/customization/components/#overriding-styles-with-global-class-names
You have to override the default css like this:
First make a style object with the property you want to customize. Make sure to use withStyles method to export your component
Then in your component, use the classes prop to pass your new css
Code example:
const styles = {
label: {
fontSize: '20px',
},
};
.
.
.
<FormControlLabel
classes={{
label: classes.label, // Pass your override css here
}}
control={
<Checkbox
checked={this.state.checked}
onChange={this.handleChange}
name="checked"
color="primary"
/>
}
label="This option is correct"
/>
.
.
.
.
export default withStyles(styles)('YOUR_COMPONENT');
According to the official Material-UI documentation, you can override the the component styles. So in your case:
Create your custom styles e.g.
const useStyles = makeStyles(() => ({
label: {
fontSize: '0.8em'
}
}));
Apply it to the FormControlLabel
<FormControlLabel
classes={{ label: classes.label }}
[...]
</FormControlLabel>
You can set the style through componentsProps on FormControlLabel, e.g.:
<FormControlLabel
componentsProps={{ typography: { variant: 'subtitle2' } }}
control={<Switch />}
label='my toggle'
/>
You can also modify the style of individual form control labels by using the sx prop and CSS global classes.
https://mui.com/material-ui/api/form-control-label/
<FormControlLabel
sx={{ '& .MuiFormControlLabel-label': { fontSize: '50px' } }}
control={<Checkbox onClick={() => onClick('rdOption4')} />}
label="All Date"
/>
Since you're using React with ES5, and I can imagine that you're using the CDN version.
So you can override the default value of the font size of the label in FormControlLabel by using createMuiTheme like this:
var theme = MaterialUI.createMuiTheme({
overrides: {
MuiFormControlLabel: {
label: {
fontSize: 'new value here'
}
}
}
});
ReactDOM.render(
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>,
document.querySelector('#root'),
);
Here is an example https://github.com/mui-org/material-ui/tree/master/examples/cdn
Please note according to the official doc:
You can start using Material-UI with minimal Front-end infrastructure, which is great for prototyping.
Two Universal Module Definition (UMD) files are provided:
one for development: https://unpkg.com/#material-ui/core#latest/umd/material-ui.development.js
one for production: https://unpkg.com/#material-ui/core#latest/umd/material-ui.production.min.js
You can follow this CDN example to quickly get started.
⚠️ Using this approach in production is discouraged though - the client has to download the entire library, regardless of which components are actually used, affecting performance and bandwidth utilization.
⚠️ The UMD links are using the latest tag to point to the latest version of the library. This pointer is unstable, it shifts as we release new versions. You should consider pointing to a specific version, such as v4.4.0.
I found this here: https://kevinyckim33.medium.com/withstyles-material-ui-override-d8f772341390
Wrap FormControlLabel with StyledFormControlLabel and use that in your code instead like so:
import FormControlLabel from '#material-ui/core/FormControlLabel'
import { withStyles } from '#material-ui/core/styles'
export const StyledFormControlLabel = withStyles({
root: {
color: 'red',
},
label: {
textTransform: 'capitalize',
},
})(FormControlLabel)
const useStyle = makeStyles(style => ({
fontSize: {
"& span:last-child": {
fontSize:10
}
}
}));
<FormControlLabel
className={classes.fontSize}
control={<Checkbox style={{ color: blueColor['300'] }} />}
label="Econom"
/>

How to change the hover color of Material-UI table?

I am using React and Material UI for my web application. I want to change the hover color of table row but cannot do that.
Sample code:
x={
hover:{
color:'green'
}
}
<TableRow
hover
key={lead.id} className={classes.row}
classes={{
hover:x.hover
}}
onClick={() => {}}
>
I've got this solution so far. Maybe there are other approaches to override css of tableRow but this one works like a charm:
const styles = theme => ({
tableRow: {
"&:hover": {
backgroundColor: "blue !important"
}
}
});
<TableRow hover
key={lead.id} className={classes.tableRow}
onClick={() => {}}>
Feel free to ask any question.
tableRow: {
hover: {
"&$hover:hover": {
backgroundColor: '#49bb7b',
},
},
}
<TableRow className={classes.tableRow} key={n.id} hover onClick={event => this.handleClick(event)}>Text</TableRow>
The implementation of the TableRow component and the customizing components page show that you need to override two classes, root.hover:hover and .hover to change the hover color.
const useStyles = makeStyles((theme) => ({
/* Styles applied to the root element. */
root: {
// Default root styles
color: 'inherit',
display: 'table-row',
verticalAlign: 'middle',
// We disable the focus ring for mouse, touch and keyboard users.
outline: 0,
'&$hover:hover': {
// Set hover color
backgroundColor: theme.palette.action.hover,
},
},
/* Pseudo-class applied to the root element if `hover={true}`. */
hover: {},
}));
Then in your component, you can apply the styles to the classes prop.
const HelloWorld = () => {
const classes = useStyles();
return (
<TableRow classes={classes}><TableCell></TableCell></TableRow>
);
};
You can maintain dependency on the Material UI hover prop by using
hover: {
'&:hover': {
backgroundColor: 'green !important',
},
},
just put hover in the TableRow, but not the header Tablerow
<StyledTableRow hover key={row.name}>
#material-ui/core/TableRow has built in code to deal with hover, it worked for me.
This is a trivial task in MUI v5. See the docs here:
<Table
sx={{
"& .MuiTableRow-root:hover": {
backgroundColor: "primary.light"
}
}}
>
Live Demo
Just in case, if you are using the component overrides and want to do a style override you have to target the root and not the hover rule. I spent quite a while trying to get the pseudo :hover to work on that but it wouldn't ever work.
Here's what I have.
MuiTableRow: {
styleOverrides: {
// Even though there is a hover rule we have to override it here. Don't ask.
root: {
'&.MuiTableRow-hover:hover': {
backgroundColor: 'blue',
},
},
},
},
Use this is you want to override the component at the theme level vs styled overrides, sx or useStyles.
If you're using withstyles you can just override it in the root element like so:
An example of how to do it is here: https://codesandbox.io/s/7249117670

How to change Material UI tab button width

Is there a way of changing the button's min-width property that's rendered inside a <Tab /> in Material UI?
There doesn't seem to be a property that allows that or I cannot find it.
And since I'm new to React, I'm not quite sure what's the proper way of overriding the property.
I've never used this library before, but according to the docs you can use the classes prop to add any custom styles.
In react we usually use the className property to add or overwrite styles for components, according to the material-ui docs, you can use classes which receives an object with the styles you need.
First you need to create the styles:
const styles = theme => ({
root: {
flexGrow: 1,
marginTop: theme.spacing.unit * 3,
backgroundColor: theme.palette.background.paper,
},
tabRoot: {
minWidth: 10,
},
});
The in the tab you use the classes prop like this:
<Tab label="X" classes={{ root: classes.tabRoot }} />
Here's an example: https://codesandbox.io/s/l52rw252rm
You can use classes prop to apply width to Tab component.
const style = {
root: {
minWidth: 500
}
}
<Tab classes={style.root} />
Check here for more details.
OR
You can also use inline-style like below
const style = {
minWidth: 500
}
<Tab style={style} />
OR
If you feel inline-styles are lil difficult then customize your components using muitheme. check here for more details.
See if you can override it by using withStyles HOC.
const styles = {
tab: {
width: 140px
}
}
export const MyTab = (props) => {
return (
<Tab className={props.classes.tab} label="Item One" />
);
}
export default withStyles(styles)(MyTab);
Please check this doc regarding overriding classes

Resources