Hi im try to place my code Breakpoints but in output show me error
import { makeStyles } from "#material-ui/styles";
const useStyle = makeStyles((theme)=>({
LogoLg:{
display:'none',
[theme.breakpoints.up('sm')]:{
display:'block'
}
}
}))
export default useStyle;
In the following stress test, you can update the theme color and the background-color property live:
const useStyles = makeStyles((theme) => ({
root: (props) => ({
backgroundColor: props.backgroundColor,
color: theme.color,
}),
}));
Using the theme context
Starting from v5, MUI no longer uses JSS as its default styling solution. If you still want to use the utilities exported by #mui/styles and they depend on the theme, you will need to provide the theme as part of the context. For this, you can use the ThemeProvider component available in #mui/styles, or, if you are already using #mui/material, you should use the one exported from #mui/material/styles so that the same theme is available for components from '#mui/material'.
import { makeStyles } from '#mui/styles';
import { createTheme, ThemeProvider } from '#mui/material/styles';
const theme = createTheme();
const useStyles = makeStyles((theme) => ({
root: {
color: theme.palette.primary.main,
}
}));
const App = (props) => {
const classes = useStyles();
return <ThemeProvider theme={theme}><div {...props} className={classes.root}></ThemeProvider>;
}
Related
I have an older external component library which is still in the process of being migrated from MUI v4 to v5.
One of these components which is still using v4 needs to be used in a brand new codebase, which is set up for v5.
The problem is, this external component completely loses all of its styles when I attempt to use it in the newer codebase.
I would like to avoid having to install and set up MUI v4 o this new codebase. Did I miss something in the setup to be able to use components that are still on MUI v4?
Here is a rough sketch of my setup:
Older component from an external library
import { Grid, Button, makeStyles } from '#material-ui/core'
const useStyles = makeStyles((theme) => ({
gridRoot: {
// a bunch of styles
},
buttonRoot: {
// more styles
}
}))
const SomeOldComponent = () => {
const classes = useStyles()
return (
<Grid classes={{ root: classes.gridRoot }}>
I am an old component from an external library. I still use MUI v4.
<Button classes={{ root: classes.buttonRoot }}>Some button</Button>
</Grid>
)
}
export default SomeOldComponent
New codebase
import React from "react"
import { ThemeProvider } from "#mui/material/styles"
import { StylesProvider, createGenerateClassName } from '#mui/styles'
import { createTheme } from "./myTheme"
const classNameOpts = {
productionPrefix: '',
disableGlobal: true,
seed: 'mySeed',
}
const generateClassName = createGenerateClassName(classNameOpts)
export const ApplicationWrapper = ({ children }) => (
<StylesProvider generateClassName={generateClassName}>
<ThemeProvider theme={createTheme()}>{children}</ThemeProvider>
</StylesProvider>
)
export default ApplicationWrapper
Usage of the older component in the new codebase
The issue I have here is that in SomeOldComponent, none of its styles set in useStyles are being applied.
import { Grid, Button } from '#mui/material'
import SomeOldComponent from 'external-library'
const MyComponent = () => {
return (
<Grid>
I am a new component in a new MUI v5 only codebase
<SomeOldComponent/>
<Button>Do something!</Button>
</Grid>
)
}
export default MyComponent
I'm studying MUI, and in the course, the instructor asks me to style just one component and not the entire theme.
For that, it uses the makeStyles function and spreads the theme.mixins.toolbar. The problem is when I do this, I have the following error:
TypeError: Cannot read properties of undefined (reading 'toolbar')
This course is apparently in version 4, and I am using version 5. Despite this, my code appears to follow the changes that the documentations asks for. So what could be causing this error?
app.js
import "./App.css";
import Header from "./components/ui/Header";
import { ThemeProvider } from "#material-ui/core/styles";
import theme from "./components/ui/Theme";
function App() {
return (
<ThemeProvider theme={theme}>
<Header />
</ThemeProvider>
);
}
export default App;
Theme.js
import { createTheme } from "#material-ui/core/styles";
const arcBlue = "#0B72B9";
const arcOrange = "#FFBA60";
export default createTheme({
typography: {
h3: {
fontWeight: 100,
},
},
palette: {
common: {
blue: `${arcBlue}`,
orange: `${arcOrange}`,
},
primary: {
main: `${arcBlue}`,
},
secondary: {
main: `${arcOrange}`,
},
},
});
header/index.jsx
import React from "react";
import AppBar from "#mui/material/AppBar";
import Toolbar from "#mui/material/Toolbar";
import useScrollTrigger from "#mui/material/useScrollTrigger";
import Typography from "#mui/material/Typography";
import { makeStyles } from "#material-ui/styles";
function ElevationScroll(props) {
const { children, window } = props;
const trigger = useScrollTrigger({
disableHysteresis: true,
threshold: 0,
target: window ? window() : undefined,
});
return React.cloneElement(children, {
elevation: trigger ? 10 : 0,
});
}
const useStyles = makeStyles((theme) => ({
toolbarMargin: { ...theme.mixins.toolbar },
}));
function Header() {
const classes = useStyles();
return (
<React.Fragment>
<ElevationScroll>
<AppBar color="primary">
<Toolbar>
<Typography variant="h3" component="h3">
Nome de teste
</Typography>
</Toolbar>
</AppBar>
</ElevationScroll>
<div className={classes.toolBarMargin} />
</React.Fragment>
);
}
export default Header;
Since you're using v5, change your ThemeProvider, createTheme and makeStyles import path from:
import { ThemeProvider, createTheme, makeStyles } from "#material-ui/core/styles";
To:
import { ThemeProvider, createTheme } from "#mui/material/styles";
import { makeStyles } from "#mui/styles";
#material-ui/core is v4 package and #mui/material is the v5 equivalent. The API from the 2 versions are not compatible. In v5, makeStyles is also moved to a legacy package called #mui/styles, if you are using MUI v5 in a new project, you should switch completely to styled/sx API as recommended by the MUI team.
Related answers
Difference between #mui/material/styles and #mui/styles?
Cannot use palette colors from MUI theme
MUI createTheme is not properly passing theme to MUI components
I created a project on CodeSandbox and it doesn't seem the problem in code.
I guess you need to check the version of package you installed in package.json file.
Here is the link to the CodeSandbox project and you can see the console.log message on console tab.
https://codesandbox.io/s/check-makestyle-eq67m?file=/src/components/ui/Header/index.js
I faced similar issue with Can not read properties of undefined, reading refs thrown by makeStyles. In my case it was mui v5 and the issue occurred after upgrading to React 18.
In my case it turned out I had some legacy makeStyles(()=>createStyles) wrapped in a manner:
const useStyles = (minWidth: number) =>
makeStyles((theme: Theme) => ...
I had to change it to:
const useStyles =
makeStyles((theme: Theme) => ...
Perhaps it will be useful for somebody else facing the issue.
Solution
Install #mui/styles
npm install #mui/styles
Change
import { ThemeProvider, createTheme } from "#material-ui/core/styles";
To
import { ThemeProvider, createTheme } from "#mui/material/styles";
And
import { makeStyles } from "#material-ui/styles";
To
import { makeStyles } from "#mui/styles";
And
<div className={classes.toolBarMargin} />
To
<div className={classes.toolbarMargin} />
I would like to create an external stylesheet using the MaterialUI 'makeStyles' and 'createStyles' like you can in React Native however, I don't know how to do it.
export const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
display: 'flex'
},
content: {
flexGrow: 1,
padding: theme.spacing(3),
}
}),
);
So this would be called 'globalStyle.tsx' and then in any other file I can import it then do something like styles.root, etc. I've done it before in React Native but as said previously, I'm stuck on how to proceed.
React Native way: https://reactnative.dev/docs/stylesheet
First you should import the makeStyles like:
import { makeStyles } from "#material-ui/core/styles";
and then you can use it with something like this:
export const useStyles = makeStyles((theme) => ({
container: {
width: "100%",
},
}));
I am trying to pass an argument back to my component library that is imported in a parent app as a dependency, but I am not entirely sure how to achieve this and I was hoping somebody could tell me what am I doing wrong. The idea is that on customer login we will determine which brand are they with and switch the theme that should be used going forward (I added a simplified example rendering a SpecialComponent)
Currently I have a Theme object in my component library that returns a Theme component wrapped in ThemeProvider. This was working fine until I tried to expand the concept of the theme object and add a concept of a brand.
Here is my Theme.js:
import React from 'react';
import PropTypes from 'prop-types';
import { ThemeProvider } from 'styled-components';
export const theme = config => {
const Theme = (props) => (
<ThemeProvider theme={config}>
{props.children}
</ThemeProvider>
);
Theme.propTypes = {
children: PropTypes.node.isRequired
};
return Theme;
};
const LightThemes = {
Adidas: {
name: 'Light',
variant: 'white',
background: 'red',
color: 'green',
textColor: 'white'
},
Nike: {
name: 'Light',
variant: 'red',
background: 'black',
color: 'yellow',
textColor: 'black'
}
};
const Light = ({ brand }) => theme(LightThemes[brand]);
const Theme = {
Light
};
export default Theme;
And here is how I am calling it within my app:
import React from 'react';
import {
SpecialComponent,
Theme
} from '#my-component-library';
const App = () => (
<Theme.Light brand={'Adidas'}>
<SpecialComponent />
</Theme.Light>
);
export default App;
As you can see I am trying to pass the string of Adidas to <Theme.Light> however this doesn't work and I get an error back saying Warning: Functions are not valid as a React child..
Before I added the concept of a brand in, my Theme.js looked like this and it was working fine:
import React from 'react';
import PropTypes from 'prop-types';
import { ThemeProvider } from 'styled-components';
export const theme = config => {
const Theme = (props) => (
<ThemeProvider theme={config}>
{props.children}
</ThemeProvider>
);
Theme.propTypes = {
children: PropTypes.node.isRequired
};
return Theme;
};
const LightThemes = {
name: 'Light',
variant: 'white',
background: 'red',
color: 'green',
textColor: 'white'
};
const Light = theme(LightThemes);
const Theme = {
Light
};
export default Theme;
I believe this is because previously I had a HOC and now that became a function that returns a component, so I can't use it in the same way that I used in the past. I am struggling to understand how to do this though.
Well, it's right there in the error. Theme.Light is a function, not a component, meaning that the way to make it work is with Theme.Light({ brand: 'BrandName' }).
This might help:
const lightCmp = Theme.Light({ brand: 'Adidas' });
const App = () => (
<lightCmp>
<SpecialComponent />
</lightCmp>
);
EDIT:
The reason it worked before is because to Light you are assigning the return of theme() which is a component, in your new version you need to instantiate the function first. Basically, you're doing the same thing with an extra step.
Another solution could be to have a hook useTheme({ brand }) that returns a HoC component.
I am doing something fundamentally wrong leveraging Redux and Material UI V1, and I am looking for help. I have not been able to successfully style the width of my Card component at 75 pixels.
How are we suppose to pass custom styles to our components leveraging withStyles and connect? I have been following an example here in Material UI's docs on the Paper component but have not been able to style my UI successfully. Below are code snippets of my presentational and container component:
Container:
import compose from 'recompose/compose';
import { connect } from 'react-redux';
import { withStyles } from 'material-ui/styles';
import Home from '../components/Home';
import * as homeActions from '../modules/home';
const styles = theme => ({
root: theme.mixins.gutters({
width: 75,
}),
});
const mapStateToProps = (state, ownProps = {}) => {
return {
props: {
classes: styles,
welcomeMessage: state.home.message || ''
}
};
};
const mapDispatchToProps = (dispatch, ownProps = {}) => {
dispatch(homeActions.loadPage());
return {
};
};
export default compose(
withStyles(styles),
connect(mapStateToProps, mapDispatchToProps)
)(Home)
Presentational:
import Card, { CardActions, CardContent, CardMedia } from 'material-ui/Card';
import Button from 'material-ui/Button';
import PropTypes from 'prop-types';
import React from 'react';
import ReactDOM from 'react-dom';
import Typography from 'material-ui/Typography';
import photo from './party.png';
const Component = ({props}) => {
return (
<div>
<Card classes={{
root: props.classes.card
}}>
This is Paper
</Card>
</div>
);
}
Component.propTypes = {
props: PropTypes.object.isRequired
};
export default Component;
EDIT:
I have also leveraged this SO post to see how the Redux and Material UI API for styling have been combined.
Also, I did not explicit state this but according to Material UI, all Paper props are valid for Card props in case you were wondering why I cited Paper documentation.
I also replaced code snippets where previously there were directly links to my project.
I think it is acceptable for your presentational component to express its own style.
Export your presentational component using withStyles:
import Card from 'material-ui/Card';
import { withStyles } from 'material-ui/styles';
import PropTypes from 'prop-types';
import React from 'react';
const styles = theme => ({
root: theme.mixins.gutters({
width: 75,
}),
});
const Component = ({ classes }) => {
return (
<div>
<Card className={classes.root}>This is Paper</Card>
</div>
);
};
Component.propTypes = {
classes: PropTypes.shape({
root: PropTypes.string,
}).isRequired,
};
export default withStyles(styles)(Component);
Then, in your container, you simply connect the presentational component's default export:
export default connect(mapStateToProps, mapDispatchToProps)(Home)