Is there a way for me to customize the appearance of the Material UI switch component when it is in the checked

I am seeking to customize the color of the switch component based on its checked and unchecked state. By default, it displays in red. My goal is to have the "ball knob" appear yellow when the switch is checked and grey when it is not. This styling must be implemented using createMuiTheme and ThemeProvider as I cannot apply classes directly to the component in this particular project.

I have attempted to replicate the customization of the purple knob example provided by Material-UI here: https://codesandbox.io/s/x8bz8 Source: https://material-ui.com/components/switches/

Despite managing to set the colors for the track in both states, as well as the color of the ball when unchecked, I have hit a roadblock with changing the color of the ball when it is checked (it reverts back to red). Can anyone offer assistance in applying the desired color style to the ball when checked?

I have created a CodeSandbox where I have been experimenting: https://codesandbox.io/s/material-demo-b6153

 const theme = createMuiTheme({
    overrides: {
      MuiSwitch: {
        switchBase: {
          color: "#ccc", // this works
          "&$checked": { // this doesn't work
            color: "#f2ff00"
          }
        },
        track: { // this works
          opacity: 0.2,
          backgroundColor: "#fff",
          "$checked$checked + &": {
            opacity: 0.7,
            backgroundColor: "#fff"
          }
        }
      }
    }
  });

  return (
    <ThemeProvider theme={theme}>
      <FormGroup>
        <FormControlLabel
          control={
            <Switch
              checked={state.checkedA}
              onChange={handleChange}
              name="checkedA"
            />
          }
          label="Custom color"
        />
      </FormGroup>
    </ThemeProvider>
  );

I also attempted:

checked: {
  "& + $bar": {
    opacity: 1.0,
    backgroundColor: "rgb(129, 171, 134)" // Light green, aka #74d77f
  }
},

This was suggested in response to a similar question found here: How do I properly use theme overrides for the MUISwitch "bar" color when checked? However, it does not seem to be working, possibly due to version differences or discrepancies in styles when used within createMuiTheme.

Answer №1

The default setting for the Switch component now uses the secondary color.

To change the color of the thumb, modify the colorSecondary CSS class. Below are the default styles for this class:

 /* Styles applied to the internal SwitchBase component's root element if `color="secondary"`. */
  colorSecondary: {
    '&$checked': {
      color: theme.palette.secondary.main,
      '&:hover': {
        backgroundColor: fade(theme.palette.secondary.main, theme.palette.action.hoverOpacity),
        '@media (hover: none)': {
          backgroundColor: 'transparent',
        },
      },
    },
    '&$disabled': {
      color: theme.palette.type === 'light' ? theme.palette.grey[400] : theme.palette.grey[800],
    },
    '&$checked + $track': {
      backgroundColor: theme.palette.secondary.main,
    },
    '&$disabled + $track': {
      backgroundColor:
        theme.palette.type === 'light' ? theme.palette.common.black : theme.palette.common.white,
    },
  }, 

You can customize the checked color in your theme using the following code snippet (which changes both the thumb and track colors):

const theme = createMuiTheme({
   overrides: {
     MuiSwitch: {
       switchBase: {
         // Controls default (unchecked) color for the thumb
         color: "#ccc"
       },
       colorSecondary: {
         "&$checked": {
           // Controls checked color for the thumb
           color: "#f2ff00"
         }
       },
       track: {
         // Controls default (unchecked) color for the track
         opacity: 0.2,
         backgroundColor: "#fff",
         "$checked$checked + &": {
           // Controls checked color for the track
           opacity: 0.7,
           backgroundColor: "#fff"
         }
       }
     }
   }
}); 

https://codesandbox.io/s/customize-switch-via-theme-0wr0j?fontsize=14&hidenavigation=1&theme=dark


Updates for MUI v5

In version 5, the structure of the object passed to createTheme has changed. Also, the default color is now primary instead of secondary, so you need to override the colorPrimary styles rather than colorSecondary.

Here is the equivalent code for MUI v5:

import React from "react";
import FormGroup from "@mui/material/FormGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import Switch from "@mui/material/Switch";
import { createTheme, ThemeProvider } from "@mui/material/styles";

export default function CustomizedSwitches() {
  const [state, setState] = React.useState({
    checkedA: true
  });

  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setState({ ...state, [event.target.name]: event.target.checked });
  };

  const theme = createTheme({
    components: {
      MuiSwitch: {
        styleOverrides: {
          switchBase: {
            // Controls default (unchecked) color for the thumb
            color: "#ccc"
          },
          colorPrimary: {
            "&.Mui-checked": {
              // Controls checked color for the thumb
              color: "#f2ff00"
            }
          },
          track: {
            // Controls default (unchecked) color for the track
            opacity: 0.2,
            backgroundColor: "#fff",
            ".Mui-checked.Mui-checked + &": {
              // Controls checked color for the track
              opacity: 0.7,
              backgroundColor: "#fff"
            }
          }
        }
      }
    }
  });

  return (
    <ThemeProvider theme={theme}>
      <FormGroup>
        <FormControlLabel
          control={
            <Switch
              checked={state.checkedA}
              onChange={handleChange}
              name="checkedA"
            />
          }
          label="Custom color"
        />
      </FormGroup>
    </ThemeProvider>
  );
} 

https://codesandbox.io/s/customize-switch-via-theme-1z09hu?fontsize=14&hidenavigation=1&theme=dark

Answer №2

give this a try

const customStyles = makeStyles((theme) => ({  
    toggle_track: {
        backgroundColor: "#f50057",
    },
    toggle_base: {
        color: "#f50057",
        "&.Mui-disabled": {
            color: "#e886a9"
        },
        "&.Mui-checked": {
            color: "#95cc97"
        },
        "&.Mui-checked + .MuiSwitch-track": {
            backgroundColor: "#4CAF50",
        }
    },
    toggle_primary: {
        "&.Mui-checked": {
            color: "#4CAF50",
        },
        "&.Mui-checked + .MuiSwitch-track": {
            backgroundColor: "#4CAF50",
        },
    },
}));

<Toggle
  classes={{
    track: customStyles.toggle_track,
    base: customStyles.toggle_base,
    primaryColor: customStyles.toggle_primary,
  }}
  color={!disabled ? "primary" : "default"}
  checked={value}
  onChange={updateValue}
  name="<your_name>"
  disabled={isDisabled}
/>

Answer №3

Response for MUI version 5

const lightTheme = createTheme({
  components: {
    MuiSwitch: {
      styleOverrides: {
        switchBase: {
          color: "#E60060",
          "&.Mui-checked": {
            color: "#16DF97"
          }
        },
      },
    },
  },
}

Alternatively

<Switch
 name="mySwitch"
 checked={isChecked}
 onChange={handleChange}
 sx={{
  "&.MuiSwitch-root .MuiSwitch-switchBase": {
    color: "red"
  },

  "&.MuiSwitch-root .Mui-checked": {
   color: "green"
  }
 }}
/>

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

React's useState is causing the NextJS Button to inexplicably click on its own

As I develop a commenting system using Next.js and Firebase, an issue arises where the button triggers itself and sends the content of the textboxes to Firestore whenever the page loads or the user interacts with the textbox. This results in repetitive en ...

What could be causing the footer to not show up at the bottom of the page?

I've encountered an issue with my code where the footer appears to be stuck at the bottom of the h2_c div instead of the bottom of the .content div where it should be. I have tried using positioning but it hasn't resolved the problem. Thank You. ...

Integrating dynamic transition effects using Jquery Mobile for <div> elements

Just a friendly reminder, I must admit that my knowledge of Javascript is quite limited. I received a script from Padilicious to implement swipe navigation on my Jquery Mobile Site. It involves adding functions to a div tag like this: <div data-ro ...

Contrasting the use of jQuery versus AJAX for updating static page text

While I haven't fully grasped the concept of AJAX yet, my understanding is that it can be beneficial for updating specific parts of a webpage. Does using AJAX only make sense when you require server interaction? I am looking to replace text on a webp ...

Implementing a Div response within the actionPerformed method

I've spent hours working on this javascript/ajax code trying to get it to add a div response that was echoed by a php script. Any assistance with this would be greatly appreciated. <form id="form1" name="form1" method="post" enctype="multipart/for ...

Unable to retrieve Google Maps route on Android device

After discovering the route between two latitude and longitude values on Google Maps using "Get Directions," everything appears accurately. However, when attempting to use the same directions in an Android mobile application, only the destination marker ...

The transformation of href to data-href is now complete

Recently, I encountered an unusual issue in my Next JS application. I included Google Fonts using the code snippet below: <link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@300;400;500&family=Source+Serif+Pro:wght@300;400;500& ...

The pre tag does not have any effect when added after the onload event

I have been experimenting with a jQuery plugin for drawing arrows, detailed in this article. When using the plugin, this code is transformed: <pre class="arrows-and-boxes"> (Src) > (Target) </pre> into this format: Src --> Target The is ...

Setting up Express routes in a separate file from the main one: a step-by-step

My goal is to organize my routes separately from the main app.js file using the following file structure. I attempted to create a api/user/ post API but encountered a 404 error. Any suggestions on how to resolve this issue with the given file structure? . ...

Leveraging Selenium to dismiss a browser pop-up

While scraping data from Investing.com, I encountered a pop-up on the website. Despite searching for a clickable button within the elements, I couldn't locate anything suitable. On the element page, all I could find related to the 'X' to cl ...

Can we implement a variety of site designs based on the size of the window?

Utilizing media queries allows us to modify the CSS for various screen sizes. My inquiry is: can we switch to a completely different page layout (or View in MVC) when the window size, specifically when the width is less than 500? Assuming that the control ...

increase the selected date in an Angular datepicker by 10 days

I have a datepicker value in the following format: `Fri Mar 01 2021 00:00:00 GMT+0530 (India Standard Time)` My goal is to add 60 days to this date. After performing the addition, the updated value appears as: `Fri Apr 29 2021 00:00:00 GMT+0530 (India St ...

Enhance your website's user experience with jQuery by implementing smooth scrolling alongside

I have a fixed header at the top of my page. When it scrolls, I want to ensure that it does not cover or hide any of my content, especially the top portion of the section. // This code enables smooth scrolling (source: css-tricks) $('a[href*="#"]:no ...

Steps to insert an image into my source code when it is selected

One of the challenges I'm facing is trying to update the display of images in my src when a user selects a new image from my file input field. Initially, I set my img src in my React app like this: src={"http://localhost:3000/" + this.props.file}, whe ...

Encountering unexpected behavior with the .data() method

I'm encountering an issue with my code <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv= ...

Creating a replica of a Parse Server object

I've been struggling to clone Parse objects without affecting the original ones. Despite trying various methods like Parse.Object.clone() and converting to JSON, I haven't found a working solution. I came across some recommendations online but no ...

"Can you provide guidance on displaying a form for a specific element based on its unique ID

I am trying to display the edit form when clicking on a specific image, but it is currently showing for all tasks. I need help in figuring out how to make it show only for one task. I attempted to use useState to change the boolean value "active" to show ...

What is the reason that PHP has the ability to set Cookies but Local Storage does not?

Let's take a step back to the era of cookies, not too far back since they are considered old but still quite relevant. PHP allows you to set and read them even though they are a client-side technology; however, JavaScript can also be used completely o ...

Guide to comparing 2 arrays and determining the quantity of identical elements

If an AJAX call returns 2 arrays upon successful execution, the arrays will be different each time but may contain some common elements. For instance: array1 = [x, y, z, a] array2 = [x, y, y, y, x, z, y, z, z] The goal is to determine how many times eac ...

Nodemon failing to trigger auto-refresh

My journey with learning node.js using nodemon has hit a roadblock. Despite following tutorials and installing everything exactly as shown, I'm facing an issue. Whenever I enter 'nodemon index.js' in the terminal, it hosts properly but any c ...