Achieving the perfect button using a combination of material-ui and styled-components

Utilizing the ToggleButton and ToggleButtonGroup components from material-ui, starting with material-ui's gatsby template. To prevent common material-ui errors with production builds, I am attempting to incorporate styled-components as well.

The following react code is having trouble targeting the material ui base button correctly.

  • What is the correct way to achieve this using styled-components?
  • Am I overlooking any best practices?

(I understand that material ui may have specific guidelines on layout, but suppose I wanted to customize the hover or text color of the base element).

// Also imports React, gatsby packages etc

import ToggleButton from '@material-ui/lab/ToggleButton';
import ToggleButtonGroup from '@material-ui/lab/ToggleButtonGroup';
import styled from 'styled-components';

const StyledToggleButton = styled(ToggleButton)`
  color: black;
  ${'' /* Not focusing too much on this section */}

  & .MuiButtonBase{
    color: pink;
    border-radius: 10em;
     ${'' /* THIS IS WHERE I WANT TO AFFECT THE BASE BUTTONS! NOT SURE IF .MuiButtonBase IS CORRECT!*/}
  }
`;

Answer №1

Your code contains two issues that need to be addressed:

  • The CSS class MuiButtonBase is being used, but it does not exist. The correct CSS class name is MuiButtonBase-root.
  • You are using a descendant selector to reference the CSS class, but MuiButtonBase-root should be on the root element itself. Therefore, the appropriate syntax would be &.MuiButtonBase-root (without the space after the ampersand). Using .MuiButtonBase-root in this manner only serves to increase specificity to override default styling, which can also be achieved by doubling the generated class name as &&.

An example below demonstrates various methods of specifying styles with equivalent specificity.

import React from "react";
import { makeStyles, StylesProvider } from "@material-ui/core/styles";
import FormatAlignLeftIcon from "@material-ui/icons/FormatAlignLeft";
import FormatAlignCenterIcon from "@material-ui/icons/FormatAlignCenter";
import FormatAlignRightIcon from "@material-ui/icons/FormatAlignRight";
import FormatAlignJustifyIcon from "@material-ui/icons/FormatAlignJustify";
import ToggleButton from "@material-ui/lab/ToggleButton";
import ToggleButtonGroup from "@material-ui/lab/ToggleButtonGroup";
import styled from "styled-components";

const useStyles = makeStyles(theme => ({
  toggleContainer: {
    margin: theme.spacing(2, 0)
  }
}));

const StyledToggleButton1 = styled(ToggleButton)`
  && {
    color: pink;
    border-radius: 10em;
  }
`;
const StyledToggleButton2 = styled(ToggleButton)`
  &.MuiToggleButton-root {
    color: blue;
    border-radius: 1em;
  }
`;
const StyledToggleButton3 = styled(ToggleButton)`
  &.MuiButtonBase-root {
    color: purple;
    border-color: blue;
  }
`;

export default function ToggleButtons() {
  const [alignment, setAlignment] = React.useState("left");

  const handleAlignment = (event, newAlignment) => {
    setAlignment(newAlignment);
  };

  const classes = useStyles();

  return (
    <StylesProvider injectFirst>
      <div className={classes.toggleContainer}>
        <ToggleButtonGroup
          value={alignment}
          exclusive
          onChange={handleAlignment}
          aria-label="text alignment"
        >
          <StyledToggleButton1 value="left" aria-label="left aligned">
            <FormatAlignLeftIcon />
          </StyledToggleButton1>
          <StyledToggleButton2 value="center" aria-label="centered">
            <FormatAlignCenterIcon />
          </StyledToggleButton2>
          <StyledToggleButton3 value="right" aria-label="right aligned">
            <FormatAlignRightIcon />
          </StyledToggleButton3>
          <ToggleButton value="justify" aria-label="justified">
            <FormatAlignJustifyIcon />
          </ToggleButton>
        </ToggleButtonGroup>
      </div>
    </StylesProvider>
  );
}

https://codesandbox.io/s/togglebutton-styled-components-2l6u5?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

Resolving the issue: "How to fix the error "Credentials are not supported if the CORS header 'Access-Control-Allow-Origin' is '*' in React?"

Recently, I encountered some CORS issues while using a third party API in my front-end application. After reaching out to the API maintainers, they lifted the CORS control by adding a * to Access-Control-Allow-Origin, which seemed like the perfect solution ...

What could be causing this jQuery to malfunction?

Having trouble with the functionality of hasclass and this.addclass. if ($('.sidebar-menu-container li').hasClass('current-menu-item')) { $(this).addClass('expanded'); } Check out this CodePen for reference. ...

Customizing the Paper Component Theme in Material-UI React

My React app is designed using the latest Material-UI component library. Throughout my application, I make use of multiple instances of the Paper component. Instead of manually adding margins and padding to each instance separately, I want to apply these s ...

Getting the text value from a table in JavaScript is a straightforward process. By using

I am working with a table displaying available hotel rooms and want to change the text color to green if the room is marked as "available." Is there a way to check the innerHTML of a td element to see if it contains the word "available"? var status = do ...

Challenges with Enzyme setup

I recently started using create-react-app and decided to incorporate testing into my project. Following the instructions on the create-react-app repo, I successfully installed Enzyme. For more information on Enzyme installation, you can check out this link ...

"Utilizing the power of Twitter Bootstrap and Snap.js for

I am currently working on integrating Snap.js by jakiestfu with Twitter Bootstrap. I have managed to make it work to some extent (I can slide the content and open a drawer through a click event). However, I am facing a challenge where the drawer content re ...

React-admin will automatically add the query "_eq" for you

Every time I call the setFilter function in react-admin, it keeps adding the "_eq" operator to my query. Below is my custom filter code: const TestFilter = () => { const { filterValues, showFilter, setFilters, displayedFilters } = useListContext(); ...

Employing the Context API to simulate the functionality of useSelector and useDispatch in redux version 5

I am currently working on a React project that requires me to use React Redux v5, which unfortunately does not include the useDispatch and useSelector hooks. However, I really need these hooks (or something similar) in my application. To work around this ...

Notifications for AngularJS tabs

I need help finding a method to incorporate "tab notification" using AngularJS, in order to show that there are important alerts that require attention. For example: (1) (3) TAB_ONE TAB_TWO TAB_THREE Could you provide any recom ...

What is the best way to implement a transaction fee when a specific function is triggered within my contract?

Consider this scenario: whenever a user successfully performs a contract function that calculates the sum of two numbers, I want to impose a 1% ETH fee that is transferred to a separate account from the contract. Although my current method "works", it is n ...

How can I ensure that my boxes are aligned in a straight line?

I'm having trouble with applying the style="display: inline-block" to each div. Can someone please assist me? https://i.sstatic.net/Gi75l.png Below is my HTML code: <div class="hobby" style="display: inline-block"> <di ...

Passing information from the frontend to the backend in a ReactJS/NodeJS application: A guide on sending

Currently, I am in the process of developing a website and looking to enhance my API functionality. My setup includes a frontend React app and a backend Express Node.js server. In addition, I have a local webserver that contains information on football ma ...

What is the purpose of using square brackets in a CSS style declaration?

I've recently taken over the management of a website and I came across some unfamiliar CSS syntax. Has anyone encountered this type of syntax before? Can someone explain what the square brackets inside a style represent? Thank you, Rob .trigger-tx ...

Problem with accessing state in React 16

In my code snippet below, I am encountering an issue. When the button is clicked and 'streaming' appears on the UI, the console.log within the 'process' function displays false. Can you help me identify what might be causing this discre ...

Setting an object in state based on values entered in a Material UI textfield

I've been trying tirelessly to find the solution, but all my efforts have proved futile. Can someone please assist me? Firstly, here's a functional example: this.state = { module:'', description: '', status: '&apo ...

The Material UI Icon is missing from the location '@mui/icons-material/Send.js'

I am currently utilizing the Material UI library and attempting to import SendIcon through this import statement: import { SendIcon } from "@mui/icons-material/Send.js"; Due to including "type" : "module" in my package.json f ...

Achieve consistent card body heights in Bootstrap 4 with the card group feature

I am working towards achieving a specific layout using Bootstrap 4's card-group feature, as shown in the image below: The goal is to have everything at the same height within each card (including card-header, card-title, and small subtext if present) ...

Different hover effects for Material-UI [v0.x] RaisedButton

Is there a way to customize the hover styling of a Material-UI RaisedButton? It seems that the design guidelines dictate what happens on hover, but is there a method to modify the button's color and background-color specifically for when it is being h ...

Leveraging the power of ReactJS for efficiency in executing multiple API calls concurrently

I'm encountering an issue with the following code snippet: let tmpContributors = [...this.state.contributors]; for (let i = 0; i < 10; i++) {//10 most active contributors due to performance and github limits contributorPropertiesPromises.pus ...

I am looking to include both the type and maxLength attributes in a MUI TextField

<TextField value={ele.mobile} helperText={ferrors[id]?.mobile} name="mobile" classes={{ root: classes.textField }} InputProps={{ clas ...