Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use 'theme' and 'props' in makeStyles?

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

like image 812
Jake Avatar asked May 13 '19 11:05

Jake


People also ask

How do you use props in makeStyles?

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.

How do you use themes in MUI?

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.

Is makeStyles deprecated?

It is deprecated in v5. It depends on JSS as a styling solution, which is not used in the @mui/material anymore.


2 Answers

Tested with:

"@material-ui/core": "^4.0.0-beta.1", "@material-ui/styles": "^4.0.0-rc.0", 

JavaScript example:

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,     }), })); 

TypeScript example:

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" 
like image 192
Roman Mahotskyi Avatar answered Oct 20 '22 10:10

Roman Mahotskyi


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

like image 36
Ryan Cogswell Avatar answered Oct 20 '22 09:10

Ryan Cogswell