I have just started learning Material UI in react js.
When it comes to custom styling, I encounter an issue where everything seems to be logically correct but the styling doesn't apply.
There is a button in Create.js component which I'm trying to change its style with the help of import { makeStyles } from "#material-ui/styles"
These are the dependencies installed in package.json:
"dependencies": {
"#emotion/react": "^11.4.1",
"#emotion/styled": "^11.3.0",
"#material-ui/styles": "^4.11.4",
"#mui/icons-material": "^5.0.1",
"#mui/material": "^5.0.2",
Here is Create.js component:
import React from "react";
import Typography from "#mui/material/Typography";
import { Button, Container } from "#mui/material";
import KeyboardArrowRightIcon from "#mui/icons-material/KeyboardArrowRight";
import { makeStyles } from "#material-ui/styles";
const useStyle = makeStyles({
btn: {
fontSize: 60,
backgroundColor: "red",
},
});
export default function Create() {
const classes = useStyle();
return (
<Container>
<Typography
variant="h6"
color="textSecondary"
align="center"
gutterBottom
>
Create a New Note
</Typography>
<Button
className={classes.btn}
onClick={() => console.log("you clicked me")}
type="submit"
color="secondary"
variant="contained"
endIcon={<KeyboardArrowRightIcon />}
>
Submit
</Button>
</Container>
);
}
This is what I see when I inspect the element:
DevTools keeps ignoring this style
The code is so far good. One difference I observed in documentation and the provided code is the import of makeStyles. Try importing makesStyles from #mui/styles. For reference have a look at documentation.
Also MUI is now compatible with plain css for minor tweaks like these. Please refer here
As far as the issue of browser ignoring styles is concerned a workaround can be using important keyword in custom styles but that is not a recommended and inefficient way.
Related
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.
I was trying to upgrate material v5(from v4). As per documentation , it is recommended to use
Styled or sx API but I wanted to use makeStyles approach as in v4. Even though it is deprecated in v5 but can be used(as per documentation). But I am unable to get theme variable inside makeStyles callback function causing cann't access property of undefined(eg. theme.breakpoints.between...)
import makeStyles from '#mui/styles/makeStyles';
const useStyles = makeStyles((theme) => ({
// here theme variable is undefined
appBar: {
backgroundColor: "white",
height: "60px",
padding: "0px 5em",
[theme.breakpoints.between("xs", 'lg')]: {
padding: "0px",
},
},
.......
Here is my index.js
import { ThemeProvider, StyledEngineProvider } from "#mui/material/styles";
import theme from "./theme/theme"
ReactDOM.render(
<React.StrictMode>
<StyledEngineProvider injectFirst>
<ThemeProvider theme={theme}>
<CssBaseline />
<App />
</ThemeProvider>
</StyledEngineProvider>
</React.StrictMode>,
document.getElementById("root")
);
theme.js
import { createTheme, responsiveFontSizes, adaptV4Theme } from "#mui/material/styles";
import baseTheme from "./baseTheme";
let theme = createTheme(adaptV4Theme(baseTheme));
theme = responsiveFontSizes(theme);
export default theme;
Also I noticed, StyledEngineProvider is not being property imported(followed this)
package.json
"#emotion/react": "^11.5.0",
"#emotion/styled": "^11.3.0",
"#fortawesome/fontawesome-svg-core": "^1.2.32",
"#fortawesome/free-solid-svg-icons": "^5.15.1",
"#fortawesome/react-fontawesome": "^0.1.13",
"#mui/icons-material": "^5.1.0",
"#mui/lab": "^5.0.0-alpha.54",
"#mui/material": "^5.1.0",
"#mui/styles": "^5.1.0",
Do I have to install additional package to make it working?
Okay, just had this problem. The makeStyles and styled uses a different context to get theme. In order for your makeStyles to access the theme you need import { ThemeProvider } from '#mui/styles'. But to use styled(), you need import { ThemeProvider } from '#mui/material'.
And if you use both styled() AND makeStyles for migration, you need to have BOTH of those theme providers....
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!
I'm integrating Material-UI (v4.4.3) into a React (v16.9.2) TypeScript (v3.6.3) website. Using the sample AppBar component example https://material-ui.com/components/app-bar/ and the TypeScript Guide https://material-ui.com/guides/typescript/#typescript I have the following functional component.
However, I'm getting a TS error for useStyles() on this line
const classes = useStyles();
(TS): Expected one argument, but got 0.
import * as React from 'react';
import { createStyles, Theme, makeStyles } from '#material-ui/core/styles';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import Button from '#material-ui/core/Button';
import IconButton from '#material-ui/core/IconButton';
import MenuIcon from '#material-ui/icons/Menu';
const useStyles = makeStyles(({ spacing }: Theme) =>
createStyles({
root: {
flexGrow: 1,
},
menuButton: {
marginRight: spacing(2),
},
title: {
flexGrow: 1,
},
}),
);
export default function ButtonAppBar() {
const classes = useStyles();
return (
<div className={classes.root}>
<AppBar position="static">
<Toolbar>
<IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu">
<MenuIcon />
</IconButton>
<Typography variant="h6" className={classes.title}>
MSC
</Typography>
<Button color="inherit">Login</Button>
)}
</Toolbar>
</AppBar>
</div>
);
}
I want to use the default theme. Am I missing something?
Try to pass an empty object:
const classes = useStyles({});
try using components from :
import AppBar from "#material-ui/core/AppBar"
import XXX from "#material-ui/core/xxx"
XXX = other components
notes my dependencies are:
dependencies : "#material-ui/core": "^4.9.14"
devDependencies : "#types/material-ui": "^0.21.7"
don't forgot to import #types/material-ui devDependencies in your project.
I am working on a material-ui package in react.js. I just want to open a drawer and close when I click anywhere on the screen.
my code is just like
import React, {Component} from 'react';
import Drawer from 'material-ui/Drawer';
import MenuItem from 'material-ui/MenuItem';
import AppBar from 'material-ui/AppBar';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
export default class extends React.Component {
constructor() {
super();
this.state = {
open: false,
};
}
handleToggle() {
this.setState({
open: !this.state.open
});
}
render() {
const styles = {
container: {
textAlign: 'center',
paddingTop: 200,
},
};
return (
<MuiThemeProvider>
<div>
<AppBar
title="Title"
iconClassNameRight="muidocs-icon-navigation-expand-more"
onTouchTap={(e) => this.handleClick()}
/>
<Drawer open={this.state.open}>
<MenuItem>Menu Item</MenuItem>
<MenuItem>Menu Item 2</MenuItem>
</Drawer>
</div>
</MuiThemeProvider>
);
}
}
and my Package.json file is like
"dependencies": {
"express": "^4.15.2",
"material-ui": "latest",
"next": "^2.1.1",
"next-routes": "^1.0.24",
"prop-types": "^15.5.6",
"react": "^15.4.0",
"react-dom": "^15.5.4",
"react-redux": "^5.0.4",
"react-tap-event-plugin": "^2.0.1"
"redux": "^3.6.0"
}
Actually, i am using next.js with react-redux.
please suggest the best solution for this problem.
Thank You
If you want to open the drawer by clicking anywhere on the screen you can some sort of onClick event that calls your handleToggle function. If you want to Drawer to open when clicking on the actual Drawer you might need to add the onRequestChange prop to the Drawer.
Also, I wanted to point out that it's best practice to use a function in setState in this case instead of an object. It's not best practice to rely on this.state to calculate the next value because setState is an asynchronous function, so this.state.open might not be what you expect it to be. There's a good post you can read more about this approach here.
handleToggle() {
this.setState(function(prevState, props){
return {open: !prevState.open}
});
}
you need to use theses properties on the Drawer
<Drawer
docked={false}
width={200}
open={this.state.open}
onRequestChange={(open) => this.setState({open})}
>
and for Warning: Unknown prop onTouchTap. this mean you not set the Provider. read this topic for usage of Material-UI
http://www.material-ui.com/#/get-started/usage
Thank you for your answer #Mohamed Bionthman and #Turnipdabeets.
I tried to solve this problem with your suggestions but i cann't solve it.
This code is working for me.
Here i find one solution
add into current code.
import injectTapEventPlugin from 'react-tap-event-plugin';
try {
injectTapEventPlugin()
}
catch(e) {
//Don't do anything
}