Tips for applying a custom design to your MUI V5 styled component

How do I customize the style of a button component in MUI V5? I've been trying to combine old methods with the new version, but it's not working as expected.

import { Button } from "@mui/material";
import { styled } from "@mui/material/styles";
import React from "react";

const StyledButton = styled(Button)(({ theme }) => ({
  root: {
    minWidth: 0,
    margin: theme.spacing(0.5),
  },
  secondary: {
    backgroundColor: theme.palette.secondary.light,
      "& .MuiButton-label": {
        color: theme.palette.secondary.main,
      },
  },
  primary: {
    backgroundColor: theme.palette.primary.light,
     "& .MuiButton-label": {
       color: theme.palette.primary.main,
     },
   },
}));

export default function CustomButton(props) {
  const { color, children, onClick } = props;

  return (
    <Button
        className={`${StyledButton["root"]} ${StyledButton[color]}`}
        onClick={onClick}
    >
      {children}
    </Button>
  );
}

Now to use this Button with a "secondary" color:

import CustomButton from "./CustomButton";
import { Close } from "@mui/icons-material";
export default function Header() {
    return (
        <CustomButton color="secondary">
            <Close />
        </CustomButton>  
     
    )
}

Answer №1

If you were trying to update your code from using makeStyles/useStyles to styled, it's important to note that they are quite different. Unlike makeStyles, styled does not generate multiple CSS classes like StyledButton["root"] and StyledButton[color], which will be undefined. Instead, styled generates a single CSS class that is then passed in the className prop to the wrapped component (e.g. Button). With styled, you can use props (like the color prop) to dynamically generate styles within the generated CSS class.

Here is an example that I have provided to help achieve the effect your code was aiming for. The example doesn't utilize MuiButton-label as this class does not exist in version 5 of the library. Additional changes may be necessary when passing the color prop through to the Button.

import Button from "@mui/material/Button";
import { styled } from "@mui/material/styles";

const StyledButton = styled(Button)(({ theme, color }) => ({
  minWidth: 0,
  margin: theme.spacing(0.5),
  backgroundColor: color ? theme.palette[color].light : undefined
}));

export default StyledButton;

https://codesandbox.io/s/styled-button-j7e06?fontsize=14&hidenavigation=1&theme=dark

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

How can I transfer information from Node.js to Vue in an Nuxt.js server-side rendering setup?

I need to find a way to pass Firestore data to Vue files from Node.js (Express) because I have to utilize Firestore's getCollections() method, which cannot be executed on the client side. I have set up nuxt-ssr for deploying Google Cloud Functions an ...

The alignment of inline-block elements is not being maintained on the same line

Here's a question I have about my embedded form. Why does the display property of inline-block make the "submit" and "terms" elements appear higher than the email field? And more importantly, how can I fix this issue? I've attempted to use the t ...

What sets apart the components found in material-ui lab @material-ui/lab/ from those in material-ui core?

Although it may sound like a typical question, I am really impressed by the scalability of Material-UI compared to other React open source frameworks. Question: What is the difference between components in "@material-ui/core" and "@material-ui/lab"? Accor ...

Establishing the folder organization for Express Handlebars

I work with NodeJs, Express, and Handlebars. The main file for my server is named app.js const express = require('express'); const exphbs = require('express-handlebars'); const app = express(); app.engine('handlebars', ex ...

Arrange data in JSON file based on job title (role name) category

My current code successfully outputs data from a JSON file, but I'm looking to enhance it by organizing the output based on the "Role Name". For example, individuals with the role of Associate Editor should have their information displayed in one sect ...

"Retrieve a list of all routes that have been registered in Node.js

I am trying to retrieve a list of all registered routes in my project. Here is the code I have used for this purpose: const app = require("express"); let routers = app._router.stack .filter((r) => r.route) .map((r) => { return { ...

Guide to incorporating HTML within React JSX following the completion of a function that yields an HTML tag

I am currently working on a function that is triggered upon submitting a Form. This function dynamically generates a paragraph based on the response received from an Axios POST request. I am facing some difficulty trying to figure out the best way to inje ...

Guide to accessing a newly opened window from a different domain originating from the current window

Currently working on an Angular project, I am facing a scenario where I have a link on page A that directs users to a different origin page B. The HTML code for the link is shown below: ... <a href="https://another.origin"> PAGE B </a> ... On ...

Conditionally setting the screen size within a function based on an if statement

Is there a way to have an if statement inside this function that checks the screen size and performs a certain action? I'm unsure if I should use CSS media queries or if there's an easier method. toggleSidebarMobile () { let state = this.sta ...

Can an identification be included in a label element?

My inquiry is as follows: <label for="gender" class="error">Choose</label> I am interested in dynamically adding an id attribute to the above line using jQuery or JavaScript, resulting in the following html: <label for="gender" class="err ...

Angular2 (RC5) global variables across the application

I am seeking a solution to create a global variable that can be accessed across different Angular2 components and modules. I initially considered utilizing dependency injection in my `app.module` by setting a class with a property, but with the recent angu ...

When employing UI-Router, custom directives may not function properly within nested views

I was developing an angular application using phonegap, ionic, and angular. I had created a custom directive that registered an event listener for the element to activate iScroll upon loading. Initially, the directive worked perfectly when all the views we ...

React: detect the key pressed when submitting a form

I am currently working with React in combination with Material UI. My goal is to implement a functionality where the form submission only occurs when I click the Submit button, rather than triggering it by pressing enter while focused on a text field. Her ...

Using Angular 5 to access a variable within a component while iterating through a loop

I am currently in the process of transferring code from an AngularJS component to an Angular 5 component. Within my code, I have stored an array of objects in a variable called productlist. In my previous controller, I initialized another empty array nam ...

Infinite loop triggered by jQuery dropdown menu on page resize was causing an issue

I have been working on developing a navigation menu for a website that displays as a horizontal bar on larger screens, but transforms into a jQuery dropdown menu when the window width is less than 980px. During initial page load with a window width below ...

A dynamically-generated dropdown element in the DOM is being duplicated due to JavaScript manipulation

Currently, I am dynamically adding a dropdown element to the page using javascript. The goal is for this dropdown to modify the properties displayed on a map. However, when attempting to add the element after the map loads, I encounter an issue where the d ...

Trigger animation once you've scrolled past a designated point in the document

I created a count-up counter animation using JavaScript, but the issue is that the counter starts animating as soon as I refresh the page regardless of where I am on the page or if the counter is even visible. I would like the counter to only start workin ...

What is the best way to establish a new JavaScript data type that can be accessed using both key and index?

Looking to create a unique datatype or object in JavaScript that allows access by both index and key, as well as having a length property to display the number of items in the datatype. Something along the lines of: MyDataType[0].name="John" MyDataType[0 ...

What is the best way to target the first child element in this scenario?

Is there a way to target only the p tag with id="this" using .root p:first-child selector? Here is the code snippet: Link to CodePen .root p:first-child { background-color: green; } p { margin: 0; } .container { display ...

What is the best way to align NavLink to the right in AppBar?

<AppBar position="static" className={this.props.classes.appBar}> <Toolbar style={{ margin: "0 auto", width: "80%" }} > <Link to="/"> <img src={logo} alt="logo" width="65" height="48" /> </Link> <Nav ...