Is it possible to apply inherited styles while using createStyles?

Here is a createStyles statement in my code:

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    menuOpen: {
      zIndex: 1,
      width: 200,
      height: '100%',
      position: 'fixed',
      top: 48,
      transition: 'left .1s',
      marginRight: theme.spacing(2),
      left: 0,
      background: '#3f51b5',
      '& div:first-element': {
        marginTop: 100
      }
    },
    menuClose: {
      zIndex: 1,
      width: 200,
      height: '100%',
      position: 'fixed',
      top: 48,
      transition: 'left .1s',
      marginRight: theme.spacing(2),
      left: -200,
      background: '#3f51b5',
      '& div:first-element': {
        marginTop: 100
      }
    },
  }),
);

I'm toggling between these to open or close a menu using a useState variable. Both styles share common attributes. How can I create a menu style that both can inherit from?

Edit: It seems like the transition is not working as expected. Could it be because React is reloading those DOM elements? I attempted adding transitions in both the menuClose and menuOpen styles, but the menu does not transition properly.

Following @doglozano's answer, I modified my createStyles function with the following:

// I also tried placing the transition in a div wrapper
// but it seems like that element is getting overridden as well
toolBar: {
  '& div': {
    transition: 'left .1s'
  }
},
menu: {
  zIndex: 1,
  width: 200,
  height: '100%',
  position: 'fixed',
  top: 48,
  transition: 'left .1s',
  marginRight: theme.spacing(2),
  left: -200,
  background: '#3f51b5',
  '& div:first-element': {
    marginTop: 100
  }
},
menuOpen: {
  left: 0,
  transition: 'left .1s',
},
menuClose: {
  left: -200,
  transition: 'left .1s',
},

When the menu is closed:

.makeStyles-menuClose-7 {
    left: -200px;
    transition: left .1s;
}
.makeStyles-menu-5 {
    top: 48px;
    left: -200px;
    width: 200px;
    height: 100%;
    z-index: 1;
    position: fixed;
    background: #3f51b5;
    transition: left .1s;
    margin-right: 16px;
}
.makeStyles-toolBar-4 {
    transition: left .1s;
}

When the menu is open:

.makeStyles-menuOpen-6 {
    left: 0;
    transition: left .1s;
}
.makeStyles-menu-5 {
    top: 48px;
    left: -200px;
    width: 200px;
    height: 100%;
    z-index: 1;
    position: fixed;
    background: #3f51b5;
    transition: left .1s;
    margin-right: 16px;
}
.makeStyles-toolBar-4 {
    transition: left .1s;
}

Edit 2: Here is my Sandbox link.

Any suggestions?

Answer №1

To create a clean and organized code structure, consider defining a base class containing all common attributes, while having specific attributes assigned to the menuOpen and menuClose classes. Utilize a library like classnames or clsx to consistently apply the base class and conditionally add either menuOpen or menuClose based on the state.

Here is an example implementation:


import clsx from 'clsx';

...

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    menu: {
      zIndex: 1,
      width: 200,
      height: '100%',
      position: 'fixed',
      top: 48,
      transition: 'left .1s',
      marginRight: theme.spacing(2),
      background: '#3f51b5',
      '& div:first-element': {
        marginTop: 100
      }
    }
    menuOpen: {
      left: 0,
    },
    menuClose: {
      left: -200,
    },
  }),
);

...

const YourStyledCommponent = ({ classes }) => {

   const [isOpen, setOpen] = useState(false);

   return (
      <SomeMuiComponent 
         className={clsx(classes.menu, {
            [classes.menuOpen]: isOpen,
            [classes.menuClose]: !isOpen,
         })}
      />
   );
}

You could also consider setting the base menu style as the close state, eliminating the need for an additional style:


import clsx from "clsx";

...

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    menu: {
      zIndex: 1,
      width: 200,
      height: '100%',
      position: 'fixed',
      top: 48,
      transition: 'left .1s',
      marginRight: theme.spacing(2),
      background: '#3f51b5',
      left: -200,
      '& div:first-element': {
        marginTop: 100
      }
    }
    menuOpen: {
      left: 0,
    },
  }),
);

...

const YourStyledCommponent = ({ classes }) => {

   const [isOpen, setOpen] = useState(false);

   return (
      <SomeMuiComponent 
         className={clsx(classes.menu, {
            [classes.menuOpen]: isOpen,
         })}
      />
   );
}

UPDATE: It was pointed out in the comments by @Ryan Cogswell that clsx is the recommended library for Material UI >= v4.0, as it is already integrated within the framework 😁.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Looking to add a glowing effect to a div when hovered using jQuery

Seeking assistance to add a glow effect to a div when hovered using jQuery. Below is the code snippet: HTML <div class="tablerow"> <div class="image"> <img src="1.jpg"> </div> <div class="info"> ...

Implementing a Searchable Autocomplete Feature within a Popover Component

Having an issue saving the search query state. https://i.stack.imgur.com/HPfhD.png https://i.stack.imgur.com/HbdYo.png The problem arises when the popover is focused, the searchString starts with undefined (shown as the second undefined value in the ima ...

Storing a single array from a nested array into the state of a React component

As a new enthusiast in the world of React, I could really use some guidance. Currently, I have an array stored in a state variable called projects 0:{id: 1, title: "Business Web", category: "Web Design", deleted_at: "0000-00-00 00:00:00"} 1:{id: 2, title ...

"Unresolvable Promise: Stripe's Payment Intent Creation Always Hits a Dead End

After signing up for my Stripe account, I decided to take a shot at integrating it with Node.js. Following the simple steps, I installed the necessary package and gave payment Intents a test run using my test key: const Stripe = require('stripe') ...

React and Axios: Overcoming CORS Policy to Connect with Java/SpringBoot REST Backend Service

As a first-time user of Axios to connect to my Java/SpringBoot Rest GET service on localhost:8080, I am using React and node.js. My goal is to successfully retrieve the REST data but encountered the following error: Failed to compile src\App.js Lin ...

Ensuring the model accurately reflects the input's value attribute in AngularJS

I am in the process of creating a set of image "radio buttons" where only one can be selected per group. However, as a newcomer to Angular, I'm facing difficulties in maintaining the value and using it as my ng-model. Additionally, I am looking for a ...

Mastering the Art of Harnessing External Templates in Meteor Mantra

I have been diving into the Mantra style guide () in order to integrate it with meteor. What confuses me is determining the "right" approach for using external templates with meteor and mantra. Specifically, I'm unsure about handling CSS and JS files. ...

I am unsure of how the rendering logic works for 'checked: {}', but I have observed that it does function properly. If I remove it, the color appears to become lighter

const CustomCheckbox = withStyles({ root: { color: orange[500], '&$checked': { color: orange[700], }, }, checked: {}, })(props => <Checkbox color="default" {...props} />); For more detailed code, check out th ...

AdBlock causing image display issue in Firefox with bootstrap and Wordpress

My Wordpress + Bootstrap code is not displaying images in Firefox, despite working fine in other browsers. I tried disabling ad-block as suggested on SO, but it didn't help. I'm stuck. Here's the HTML snippet: <div class="navbar-collap ...

Utilizing asset URLs in style binding with Vite: A comprehensive guide

Is anyone else experiencing issues with displaying a background image from the assets folder? I am currently using an image tag and it appears properly, but when I attempt to use the background-image style, I receive a 404 error. I am utilizing Vue 3 with ...

Material design Snackbar notification smoothly glides onto the screen

https://i.stack.imgur.com/yJDVj.png Hello there! I am currently working on a fun project using React and Material-ui. However, I'm facing an issue when the snack bar or react-toastify pops up. It doesn't stay on the screen (RED: scroll up/dow ...

Exploring the World of Card Components in ReactJS

Error: Encountered an Error: TypeError - Unable to read property 'card' of undefined. Removing the content className={classes.card} resolves the issue. However, without classes, Const Styles cannot be utilized. import React from 'r ...

Enhancing Blog Navigation with PicoCMS Pagination

After successfully setting up PicoCMS on my website, everything seems to be working well except for the blog pages. I am having issues with the "Older Posts" button not functioning as expected. Unfortunately, I couldn't find any information in the the ...

Tips for making a Google Map API Element fit perfectly in a Bootstrap column below a heading

I've spent countless hours trying to solve this on my own, scouring the internet for answers with no luck. I'm hoping someone here can spare a few moments to help me out. Much appreciated! I'm attempting to make the Google Maps API element ...

Failed to transmit information from React application to Node server

I'm having trouble creating a search function where I can retrieve a variable from the search field and display the matching results. However, I keep encountering an error stating that the variable is undefined when I try to console.log it in the node ...

There were no visible outputs displayed within the table's tbody section

import React from 'react'; export default class HelloWorld extends React.Component { public render(): JSX.Element { let elements = [{"id":1,"isActive":true,"object":"Communication","previ ...

guide on utilizing rulenames as references in a subcomponent within jss

Currently, I am working with the Material-UI library and utilizing its support for CSS styling with JSS. However, I am facing difficulty in accessing rule names from a different component within my project. In the code snippet below, you can see that MyCom ...

Error: Empty reference found in Popover

Struggling to set autofocus on an input element when opening a popover. Check out the sandbox here: https://codesandbox.io/s/green-bash-x6bj4?file=/src/App.js The issue I'm facing is that the current property is always null on ref. Is this a situatio ...

What is a way to include a ":hover" effect in Elm without relying on signals?

I'm looking to apply a :hover style to an element using Elm's HTML library. I've considered using Signals and Sets to manage selected nodes, but it feels like overkill for such a simple task. Another option is adding an external stylesheet, ...

modifying the paragraph format in dropzone-material-ui

What is the best way to customize the style of the material-ui-dropzone component using makeStyles? Here is my current useStyles: const useStyles = makeStyles(theme => ({ DropzoneArea: { fontWeight: 10, margin:0, ...