How do I write makeStyles()
so that it allows me to use both theme variables and props?
I've tried this:
const useStyles = makeStyles(theme => ({ appbar: props => ({ boxShadow: "none", background: "transparent", marginTop: theme.spacing(2), marginBottom: theme.spacing(2), color: theme.palette.getContrastText(props) }), }));
And called it in the component with:
const classes = useStyles(backgroundColor);
Where backgroundColor
is a prop on the component with type CSSProperties["backgroundColor"]
But I'm getting the error:
TypeError: Cannot read property 'rules' of undefined at RuleList.onUpdate (C:\Users\...\node_modules\jss\dist\jss.cjs.js:944:14) at RuleList.update (C:\Users\...\node_modules\jss\dist\jss.cjs.js:923:12) at StyleSheet.update (C:\Users\...\node_modules\jss\dist\jss.cjs.js:1178:39) at attach (C:\Users\...\node_modules\@material-ui\styles\makeStyles\makeStyles.js:141:18) at C:\Users\...\node_modules\@material-ui\styles\makeStyles\makeStyles.js:262:7 at useSynchronousEffect (C:\Users\...\node_modules\@material-ui\styles\makeStyles\makeStyles.js:207:14) at C:\Users\...\node_modules\@material-ui\styles\makeStyles\makeStyles.js:254:5 at Layout (C:\Users\...\.next\server\static\development\pages\index.js:1698:17) at processChild (C:\Users\...\node_modules\react-dom\cjs\react-dom-server.node.development.js:2888:14) at resolve (C:\Users\...\node_modules\react-dom\cjs\react-dom-server.node.development.js:2812:5) at ReactDOMServerRenderer.render (C:\Users\...\node_modules\react-dom\cjs\react-dom-server.node.development.js:3202:22) at ReactDOMServerRenderer.read (C:\Users\...\node_modules\react-dom\cjs\react-dom-server.node.development.js:3161:29) at renderToString (C:\Users\...\node_modules\react-dom\cjs\react-dom-server.node.development.js:3646:27) at render (C:\Users\...\node_modules\next-server\dist\server\render.js:86:16) at renderPage (C:\Users\...\node_modules\next-server\dist\server\render.js:211:20) at ctx.renderPage (C:\Users\...\.next\server\static\development\pages\_document.js:2404:22) 100 | handleSignUpClick, 101 | backgroundColor 102 | }) => { > 103 | const classes = useStyles(backgroundColor); 104 | return ( 105 | <AppBar className={classes.appbar}> 106 | <Container maxWidth="lg">
edit: I'm using version 4.0.0-beta.1 of material core and styles
So, this is how to use 'theme' and 'props' in makeStyles. import { Theme } from '@material-ui/core'; import { makeStyles } from '@material-ui/styles'; import { CustomStyleProps } from './example-components. interfaces.
Theme provider If you wish to customize the theme, you need to use the ThemeProvider component in order to inject a theme into your application. However, this is optional; MUI components come with a default theme.
It is deprecated in v5. It depends on JSS as a styling solution, which is not used in the @mui/material anymore.
Tested with:
"@material-ui/core": "^4.0.0-beta.1", "@material-ui/styles": "^4.0.0-rc.0",
my-component.js
import React from 'react'; import { makeStyles } from '@material-ui/styles'; import { useStyles } from './my-component.styles.js'; const myComponent = (props) => { const styleProps = { width: '100px', height: '100px' }; const classes = useStyles(styleProps); return ( <div className={classes.mySelector}></div> // with 100px and height 100px will be applied ) }
my-component.styles.js
export const useStyles = makeStyles(theme => ({ mySelector: props => ({ display: 'block', width: props.width, height: props.height, }), }));
my-component.ts
import React, { FC } from 'react'; import { makeStyles } from '@material-ui/styles'; import { useStyles } from './my-component.styles.ts'; import { MyComponentProps, StylesProps } from './my-component.interfaces.ts'; const myComponent: FC<MyComponentProps> = (props) => { const styleProps: StylesProps = { width: '100px', height: '100px' }; const classes = useStyles(styleProps); return ( <div className={classes.mySelector}></div> // with 100px and height 100px will be applied ) }
my-component.interfaces.ts
export interface StyleProps { width: string; height: string; } export interface MyComponentProps { }
my-component.styles.ts
import { Theme } from '@material-ui/core'; import { makeStyles } from '@material-ui/styles'; import { StyleProps } from './my-components.interfaces.ts'; export const useStyles = makeStyles<Theme, StyleProps>((theme: Theme) => ({ mySelector: props => ({ // props = { width: string; height: string } display: 'block', width: props.width, height: props.height, }), }));
Update
Re-tested with
"@material-ui/core": "^4.12.X"
You need to pass an object to useStyles
rather than a string.
So instead of:
const classes = useStyles(backgroundColor);
you should have:
const classes = useStyles(props);
or
const classes = useStyles({backgroundColor});
Then you can get at backgroundColor using:
color: theme.palette.getContrastText(props.backgroundColor)
.
Here's a working example: https://codesandbox.io/s/o7xryjnmly
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With