Some elements not responding to the costum theme in materialUI - reactjs

So when I apply a custom theme in materialUI (specifically changing the font) some of the components change the font and some don't and I don't know why. Basically, all the imported components that use the <Typography> component don't get the applied theme if they are nested inside other materialUI components or not.
import classes from "./App.module.css";
import Form from "./components/Form";
import Text from "./components/Text";
import { createTheme, ThemeProvider } from "#material-ui/core";
const theme = createTheme({
typography: {
fontFamily: "Grey Qo",
fontSize: 25,
},
});
function App() {
return (
<div className={classes.wrapper}>
<ThemeProvider theme={theme}>
<Text></Text>
<Form></Form>
</ThemeProvider>
</div>
);
}
export default App;
enter image description here
In the picture you can see the form font and the top button change becuase they dont use the <Typography> component but the rest stay the same
Here is also an example of the React <Text> component which is imported
import { Typography } from "#mui/material";
import { makeStyles } from "#material-ui/styles";
import React from "react";
import classes from "./Text.module.css";
const useStyles = makeStyles({
text: {
color: "#f0f0f0",
},
});
export default function Text() {
const uiClasses = useStyles();
return (
<div className={classes.wrapper}>
<Typography variant="h4" className={uiClasses.text}>
Learn code by watching others
</Typography>
<Typography className={uiClasses.text}>
See how expirienced developers solve problems in real-time. Watching
scripted tutorilas is great, but understanding how developers thinks is
invalubale
</Typography>
</div>
);
}
This font is used to make the problem more obvious, hope someone can help. tnx in advanced

Maybe because you imported Text.module.css or the other css files are overriding the font family that is set by material theme, you can inspect elements to the one that does not apply the correct font to know exactly where is the style come from.
One more important thing is when using material there's a jss implementation that is the makeStyles you're using, it would be awesome and good enough for you to work with. so you don't have to use css module anymore. Hope my hint can help you!

Related

makeStyles in Material-ui need to use so many ( !important <= css code ) to style mui components

I'm now trying to create a website using material-ui with react.
I needed to add my own style to mui components. For this purpose, I used the makeStyle from '#mui',
But
The problem is that if I want to make changes to the material components, I have to use the ( !important ) with each stage.
so here is simple example:
App.js
import { makeStyles } from "#mui/styles";
import { Button } from "#mui/material";
const useStyles = makeStyles({
btn: {
backgroundColor: "red !important",
},
});
function App() {
const classes = useStyles();
return (
<>
<Button variant="contained" className={classes.btn}>
Click me
</Button>
</>
);
}
export default App;
if i want to change the <Button> background i must use !important with css code .
so What do I have to do now ???
versions:
"#mui/material": "^5.4.4",
"#mui/styles": "^5.5.1",
If you are starting new app, new MaterialUI version recommend not to use useStyles but use styled-components or EmotionJS.
Anyways if you want to use useStyles try to wrap your app in <StylesProvider injectFirst></StylesProvider> from mui. It should inject your styles first and !important shouldnt be needed.

How to access MUI 5 theme variables in deep functional component?

The MUI 5 docs on Theming have a section on "Accessing the theme in a component". However, it's really just one sentence that links to the legacy style docs.
Here's the example they give in those legacy docs:
import { useTheme } from '#mui/styles';
function DeepChild() {
const theme = useTheme();
return <span>{`spacing ${theme.spacing}`}</span>;
}
Which is pretty much exactly what I want to do — I want to be able to access the theme color palette down in some deep functional component. However, my component complains
Module not found: Error: Can't resolve '#mui/styles' in...
Digging a little further, it seems they're rather strongly trying to discourage people from using this legacy Styles technique, and the MUI 5 way to do this is with "system design tokens", which I guess should Just Work. But, they're not.
I have my whole app wrapped in ThemeProvider:
import React from 'react';
import { CssBaseline } from '#mui/material';
import { ThemeProvider } from '#mui/material/styles';
import theme from './theme';
import Foo from './foo';
const App = () => {
return (
<Fragment>
<ThemeProvider theme={theme}>
<CssBaseline enableColorScheme />
<Foo />
</ThemeProvider>
</Fragment>
);
};
export default App;
And then in foo.js:
import React from 'react';
import { Box } from '#mui/material';
export const Foo = () => {
return (
<Box
sx={{
background: 'repeating-linear-gradient(-45deg, '
+ ' theme.palette.error.light, theme.palette.error.light 25px,'
+ ' theme.palette.error.dark 25px, theme.palette.error.dark 50px'
+ ')',
}}
>
<span>Test</span>
</Box>
);
};
I initially started with just error.light and error.dark. When that didn't work, I expanded it all to palette.error.light, etc..., and then ultimately to theme.palette.error.light, etc....
It seems no matter what I try, it's not accessing those theme variables, and is instead just passing through the text.
So, back to the question: how am I supposed to access MUI 5 theme variables in nested functional components?
Replace
import { useTheme } from '#mui/styles';
with
import { useTheme } from '#mui/material/styles';
#mui/styles is used for legacy, you can add it using yarn add or npm install, but first give a shot to what I mentioned above.

Use style functions for material-ui components besides Box

I'm just starting with Material UI. Thanks for bearing with me.
I know you can use things like <Box mx={2}> out-of-the-box (ha). So if I wanted to put a margin around, say, a TextField, I could wrap it in a box.
Is there a simple way to set up my app's theme so that any component can use those style function props? (m, p, display, etc)
So that I could to <TextField mx={2}/> without having to wrap it in a Box.
The docs imply that you can do this:
(the example uses ThemeProvider from styled-components but I'm assuming that MUI's ThemeProvider works the same way???)
import React from 'react'
import { ThemeProvider } from 'styled-components'
const theme = {
spacing: 4,
palette: {
primary: '#007bff',
},
};
export default function App() {
return (
<ThemeProvider theme={theme}>
{/* children */}
</ThemeProvider>
)
}
I've tried this but it crashes from the TextField's my prop:
import { createMuiTheme, TextField, ThemeProvider } from '#material-ui/core';
// Greatly simplified version of my component
const App = () => <TextField my={2}/>
let theme = createMuiTheme({})
export default () =>
<ThemeProvider theme={ theme }>
<App/>
</ThemeProvider>;
I can do something like this and it works:
function App() {
const Input = styled(TextField)(compose(spacing))
return <Input my={3}/>
}
But then I'd have to compose my components every time I want to do use the style functions.
The docs are showing how the theme can parameterize the Box features (e.g. such that a spacing unit is 4px instead of 8px) -- the theme doesn't do anything to enable those features.
Material-UI is intending to support #material-ui/system features on core components in v5, but that is still months away.
Your main options are doing something like you showed in your example (though you should move const Input = styled(TextField)(compose(spacing)) to the top-level rather than doing this within render of App). You could put this in a separate file and import this component instead of TextField whenever you want to use those features. For instance:
MyTextField.js
import TextField from "#material-ui/core/TextField";
import { styled } from "#material-ui/core/styles";
import { compose, spacing } from "#material-ui/system";
export default styled(TextField)(compose(spacing));
App.js
import React from "react";
import TextField from "./MyTextField";
export default function App() {
return (
<div className="App">
<TextField variant="outlined" label="Material-UI system demo" />
</div>
);
}
Another option is to use Box with the clone prop and wrap the component you want to style. For instance:
import React from "react";
import TextField from "#material-ui/core/TextField";
import Box from "#material-ui/core/Box";
export default function App() {
return (
<div className="App">
<Box my={3} clone>
<TextField variant="outlined" label="Box demo" />
</Box>
</div>
);
}
You can also use the component prop of Box:
import React from "react";
import TextField from "#material-ui/core/TextField";
import Box from "#material-ui/core/Box";
export default function App() {
return (
<div className="App">
<Box my={3} component={TextField} variant="outlined" label="Box demo" />
</div>
);
}
Related answers:
Material-UI Grid does not hide whe use Display
Dynamic icon size in Material-UI
Box vs className vs style for vertical spacing in Material UI
Reusable component using theme-based Box features
Using Material-UI Box Component with the Drawer Compoment
How to use override Button using Box component in Material-UI?

Where does FilledInput inherit backgroundColor property in Mui?

I was working on Filled Inputs in form of TextFields as well as FilledInput. I need a solution to make the background color of all the FilledInputs, currently, I am using makeStyle and adding class names to each component, which seems redundant.
Can someone give a better workaround, like changing some property in the theme?
From the FilledInput API docs we can learn that:
The MuiFilledInput name can be used for providing default props or
style overrides at the theme level.
And from this this guide in overriding MUI CSS globally we can learn to use overrides key of the theme to potentially change every single style injected by Material-UI into the DOM
Sample Code:
import React from "react";
import { createMuiTheme, ThemeProvider } from "#material-ui/core/styles";
import FilledInput from "#material-ui/core/FilledInput";
const theme = createMuiTheme({
overrides: {
// Style sheet name
MuiFilledInput: {
// Name of the rule
root: {
backgroundColor: "orange"
}
}
}
});
function OverridesCss() {
return (
<ThemeProvider theme={theme}>
<FilledInput placeholder="sample placeholder" />
</ThemeProvider>
);
}
export default OverridesCss;

How to overwrite styles with classes and css modules?

Focused, checked classes seems to not work properly.
I need to always use !important or use jss styles provided by material-ui.
For example:
https://codesandbox.io/s/css-modules-nvy8s?file=/src/CssModulesButton.js
CssModulesButton.module.css
.checkboxtest {
color: blue;
}
.checkboxtestworking {
color: blue !important;
}
CssModulesButton.js
import React from "react";
// webpack, parcel or else will inject the CSS into the page
import styles from "./CssModulesButton.module.css";
import Checkbox from "#material-ui/core/Checkbox/Checkbox";
export default function CssModulesButton() {
return (
<div>
<Checkbox classes={{ checked: styles.checkboxtest }}>testasd</Checkbox>
<Checkbox classes={{ checked: styles.checkboxtestworking }}>
testasd
</Checkbox>
</div>
);
}
index.js
import React from "react";
import { render } from "react-dom";
import { StylesProvider } from "#material-ui/core/styles";
import CssModulesButton from "./CssModulesButton";
import CssBaseline from "#material-ui/core/CssBaseline";
const App = () => <CssModulesButton />;
render(<App />, document.querySelector("#root"));
I cant overwrite Checkbox color in any other way than using !important.
The problem persists when using classes={{focused:styles.focused}} and many others.
Is there a way to simply overwrite components with classes without !important? Sometimes even !important doesnt work
inb4 im using injectFirst
You mentioned injectFirst in your question, though your sandbox example wasn't using it. You should use it since this will make sure that the CSS from your CSS modules is inserted after the Material-UI CSS in the <head> element. When specificity is the same, the styles that occur later will win over earlier styles.
The default styles for the checkbox colors are as follows:
colorSecondary: {
'&$checked': {
color: theme.palette.secondary.main,
'&:hover': {
backgroundColor: fade(theme.palette.secondary.main, theme.palette.action.hoverOpacity),
// Reset on touch devices, it doesn't add specificity
'#media (hover: none)': {
backgroundColor: 'transparent',
},
},
},
'&$disabled': {
color: theme.palette.action.disabled,
},
},
Below is the corresponding CSS generated by JSS:
.MuiCheckbox-colorSecondary.Mui-checked {
color: #f50057;
}
.MuiCheckbox-colorSecondary.Mui-disabled {
color: rgba(0, 0, 0, 0.26);
}
.MuiCheckbox-colorSecondary.Mui-checked:hover {
background-color: rgba(245, 0, 87, 0.04);
}
#media (hover: none) {
.MuiCheckbox-colorSecondary.Mui-checked:hover {
background-color: transparent;
}
}
The important aspect to notice is that the checked style is done via two classes. In order to override these styles you need that same degree of specificity or greater.
Below is a full working example overriding the checked color of the checkbox:
index.js (important part here is <StylesProvider injectFirst>)
import React from "react";
import { render } from "react-dom";
import { StylesProvider } from "#material-ui/core/styles";
import CssModulesButton from "./CssModulesButton";
const App = () => (
<StylesProvider injectFirst>
<CssModulesButton />
</StylesProvider>
);
render(<App />, document.querySelector("#root"));
CssModulesButton.module.css
Uses two classes in the style declaration -- the checkboxtest CSS module class and Mui-checked (the global class which Material-UI adds for the checked state)
.checkboxtest:global(.Mui-checked) {
color: blue;
}
CssModulesButton.js
import React from "react";
import styles from "./CssModulesButton.module.css";
import Checkbox from "#material-ui/core/Checkbox";
export default function CssModulesButton() {
return (
<div>
<Checkbox className={styles.checkboxtest} />
</div>
);
}
Follow-up question from the comments:
Could you explain why can't I use classes? Shouldn't classes={{checked:styles.AnyClass}} overwrite the styles successfully? I understand why it doesn't, but what is the purpose of classes then?
You can use the classes prop, but there isn't any compelling reason to do so in this case. The following will also work, so long as the declaration for the styles is the same (using two CSS classes) so that you have the appropriate degree of specificity:
<Checkbox classes={{ checked: styles.checkboxtest }} />
As far as the second part of your question ("what is the purpose of classes then?"), there are two main reasons to use the classes prop. Some of the CSS classes for the classes prop get applied to different elements within the component, and some only get applied when the component is in a particular state, or when certain props have been used on the component. In this case, you are trying to target these styles for a particular state of the component. In v3 of Material-UI, you would have needed to use the classes prop to provide a class name that would only be applied for the checked state, but in v4 Material-UI switched to using global class names for these states (more details here: https://material-ui.com/customization/components/#pseudo-classes) such as Mui-checked. This makes it easier to target these states via a single generated class (a big driver of this change was to make it easier to customize Material-UI components using styled-components).

Resources