React Material-UI styling active menu items - reactjs

I'm trying to figure out how to apply css styles to :active and :hover states of a Material-UI Menu.
The docs say,
selectedMenuItemStyle | object | | Override the inline-styles of selected menu items.
But applying,
<Menu selectedMenuItemStyle={{ color: 'red'}}>
<MenuItem
style={ menuItemStyles }
primaryText={ pages.dashboard.title.toUpperCase() }
containerElement={<NavLink to={ `${pages.dashboard.slug}` } />} />
</Menu>
has no effect when I click on <MenuItem>
I've also tried React-Router's activeStyle and activeClassName which have no effect because Material-UI overrides them.
Anyone know how to apply :active and :hover correctly?

Have a look there : material-ui
Every component provides a className property. Those properties are always applied to the root element.
Note that CSS properties defined inline are given priority over those defined in a CSS class. You need to use !important to take precedence over the inline style.
try to add !important on your custom style to override material-ui like
.test-class:hover {
color: red !important
}

Related

How to style Material UI Dialog with Tailwind?

Material UI Dialog is a portaled component. The way I understood it and saw it in action is that it renders its markup outside the React's root element.
It renders itself before the </body> tag.
Now I have encountered a problem because of this.
When user chooses the dark mode, I set a dark class on top-level element, one beneath the root element.
And on all components I can use dark variant to apply styles, like dark:bg-zinc-700.
But when I apply it the <Dialog /> component, it won't affect its style, though I can see that the class exists in the output.
<Dialog
PaperProps={{
className="dark:bg-zinc-700"
}}
How should I solve this problem? I know I can use sx to apply style. But that means I need to lose consistency and I also don't know how to translate Tailwind to sx. Thus I prefer to keep using Tailwind.
I solve this problem with this Link
MuiDialog: {
defaultProps: {
container: rootElement,
},
},
Check this
#HosseinFallah Looking back at your post I think this won't work because tailwind and material ui handle dark modes differently. However, you can target Material UI css without using sx. You can use the Dialog API classes in your css and apply tailwind colors on them like this in your global css:
.MuiDialog-paperScrollBody {
background-color: theme(colors.dark) !important;
}
Where dark is the custom dark color you've set in your tailwind.config.js
To add to the answer you can also set this for your whole app by wrapping it with the Mui's StyledEngineProvider. This way tailwind will be prioritized when injecting styling.
In your index.tsx
import { StyledEngineProvider } from '#mui/material';
const container: any = document.getElementById('root');
const root = createRoot(container);
root.render(
<Provider store={store}>
<React.StrictMode>
<StyledEngineProvider injectFirst>
<App />
</StyledEngineProvider>
</React.StrictMode>
</Provider>
);
Then this will be possible without needing to specify !important
<Dialog
PaperProps={{
className="dark:bg-zinc-700"
}}
Did you set the "important" property in the Tailwind config (tailwind.config.js) by chance?
If you set it to something like "#root" then it will only match the elements inside the #root element which is bypassed when MUI uses React Portals.
You could change it to something like "#tw" and then set your body's ID to "tw" so it will always match since Portals are always children of the body element.
if you completely interoperate to tailwindcss, see: https://mui.com/material-ui/guides/interoperability/#tailwind-css
i think this mistake occure in tailwindcss.config.js.
by adding another id to wrap dialog container and asign it to "important" property will solve this problem
You can increase the specificity of the TailwindCSS by using !important selector.
You can find more here https://tailwindcss.com/docs/functions-and-directives

Material UI - Overriding styles using Root & using ClassName

I'm new to material UI. While learning, I came to know out that styles of a material UI can be overridden with the rule name of the classes.
If I have an element - MenuItem where I just need to change the default styling of the text (such as fontFamily, fontWeight, fontSize)
According to the documentation available here https://material-ui.com/api/menu-item/ I used makeStyles hook and have overridden some properties of the root element of Menu-Item
Sample code
const useStyles = makeStyles((theme) => ({
menuItem: {
fontFamily: "Raleway",
}
}));
JSX code: <MenuItem onClick={handleClose} component={Link} to="/services" classes={{root: classes.menuItem}}>Services</MenuItem>
In one more tutorial, I found another way of overriding - with className like
const useStyles = makeStyles((theme) => ({
menuItem: {
fontFamily: "Raleway",
}
}));
JSX code: <MenuItem onClick={handleClose} component={Link} to="/services" className={classes.menuItem}>Services</MenuItem>
My question lies in this part className={classes.menuItem} and classes={{root: classes.menuItem}}
On using root -> I see the css properties getting added to the root element but on using className={classes.menuItem} I see a new class is added to the DOM. But Is there any difference with respect to the behaviour of the app between these 2 methods or is it just another way of doing it?
Thanks
From what I can tell having worked with Material UI, the difference is with what you're trying to do.
className={classes.menuItem} and classes={{root: classes.menuItem}} will both get you the results that you're expecting, as you've already discovered.
The distinctions are important when you start building custom themes, because Material UI allows you to apply classes to the components as a whole, meaning potentially comprised of other components, or pass along styles to the root elements if you need a higher specificity.
For example, consider the Stepper component.
classes={{root: classes.menuItem}} will override the root in the component, applying your styles.
className={classes.menuItem} will add an additional class to the component, leaving the underlying styles intact.

How can I access to change styles of inner items of a component in react and material ui?

How can I access to inner css classes of children of a component and add or change styles to/of them? like I want to change and customize material ui stepper steps circle font size and color and so on.
How can I write css classes like bellow:
.stepper circle {
font-size:18px;
}
or
.stepper .text {
font-size:18px;
}
thanks.
Thanks to #spakmad's answer, but that's not exactly what I meant, maybe my question was not clear enough. I meant how to write above mentioned CSSs in material ui object style classes format(classes injected with withStyle HOC).
I found my solution:
stepper:{
'& circle':{
fontSize: '18px'
}
}
and
stepper: {
'& .text': {
fontSize: '18px'
}
}
The very straightforward way to do it without having to worry about classes is by using the material-ui style prop. Like so,
<Stepper style={{ fontSize: '18px' }} />
This applies a style to the root element, which I assume to be a div or container of sorts, although it probably varies by the component.
More specifically, and what you probably want to do is use material-ui classes prop. That is, since you know exactly what classes you want to override, you can do so as follows,
<Stepper classes={{ text: { fontSize: '18px' }}} />
I use text here as a classname because in the question, .text appears to reference and already existing class. Since you're trying to increase the size of the font in this svg that comes with the Stepper. You'll need to get the class name applied to the svg and override it. In this case, one of its classnames is MuiSvgIcon-root-184 so you would expect to be able to do,
<Stepper classes={{ MuiSvgIcon-root-184: { fontSize: '18px' }}} />
This classname however is generated by material-ui dynamically based on the layout resulting from props and could be different across all renders.
TLDR
So, trusty className component and writing some css and component JSX as follows.
<Stepper className={'customStepper'} />
.customStepper svg: {
font-size: '18px !important',
}
You need to include !important to make sure this style is respected. Material UI by default puts its styles last in the document so they're normally overwriting anything else, but the !important spec should override the override.

how custom margin react-loading in react js

i want custom style like margin-left, height, widht in react-loading.
i'm only can custom color, but custom margin doesn't work.
<Loading type ='spinningBubbles' color='#0088CF' />
Best wishes! Wish for replying.
You add custom styles using the style prop on DOM element components.
<div style={{ margin: '100px' }}>
<Loading type ='spinningBubbles' color='#0088CF' />
</div>
if you have access to change the loading component you could pass the style (or just the margin value) through to the underlying DOM elements as a prop.
If you have a lot of custom styling to do, there is a great library called Radium for making it easier.

How to inline style child DOM element React?

Let imagine I import library react-select or any other that I don't have direct access to its component and jsx. Is it possible to pass your own style to child DOM element like drop down menus from other library. Like your can with normal css div div div{... here you will style only children}. I am using Radium.
In my case I want to change the z-index of Select Select--single is-searchable class and style drop down menu.
Radium provide so called Style component that allows you to style such components that you imported from other libraries Link: https://github.com/FormidableLabs/radium/tree/master/docs/api#style-component.
Example:
<Style
scopeSelector=".scoping-class"
rules={{
color: 'blue',
span: {
fontFamily: 'Lucida Console, Monaco, monospace'
}
}}
/>

Resources