Tigran Petrosyan
Tigran Petrosyan

Reputation: 570

how to style mui 5 switch to look like a toggle switch

I'm currently working on customizing an MUI version 5 switch to function more like a toggle switch, rather than a simple on/off indicator. I've set it up to display "A" on one side and "B" on the other. You can see what I've done so far here: https://codesandbox.io/p/sandbox/sweitch-xywckp?file=%2Fsrc%2FApp.tsx%3A4%2C58. However, I'm facing a few issues with my current implementation:

My goal is for the toggle switch to be 140px in length, with each side ("A" and "B") taking up 70px. Both labels should always be visible. When "A" is selected, I want its background to be in the primary color with white text, while "B" should have a white background with black text. Toggling the switch should swap these color schemes for the two sides. I'm also trying to hide the switch's thumb completely on hover and click actions. Despite my efforts, I haven't been able to achieve this effect. I've spent quite a bit of time on it but can't seem to resolve these issues. I would really appreciate any guidance or assistance you could provide. Thank you!

import { styled } from "@mui/material/styles";
import Switch, { SwitchProps } from "@mui/material/Switch";

const App = styled(Switch)<SwitchProps>(({ theme }) => ({
  width: "140px",
  height: "42px",
  padding: 0,
  border: "1px solid #C6CBD0",
  borderRadius: "9px",

  "& .MuiSwitch-switchBase": {
    transition: theme.transitions.create(["transform", "background-color"], {
      duration: theme.transitions.duration.shortest,
    }),

    "&.Mui-checked": {
      transform: "translateX(70px)",
    },

    "&.Mui-checked + .MuiSwitch-track": {
      backgroundColor: theme.palette.secondary.main,
      opacity: 1,
      display: "flex",
      alignItems: "center",
      justifyContent: "flex-end",

      "&:before": {
        content: '"B"',
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        fontWeight: 700,
        fontSize: "20px",
        width: "50%",
        color: theme.palette.getContrastText(theme.palette.secondary.main),
      },
    },

    "&.Mui-checked + .MuiSwitch-track.Mui-disabled": {
      backgroundColor: theme.palette.grey[400],
    },
  },

  "& .MuiSwitch-thumb": {
    width: "70px",
    height: "42px",
    opacity: 0,
  },

  "& .MuiSwitch-track": {
    backgroundColor: theme.palette.primary.main,
    opacity: 1,
    display: "flex",
    alignItems: "center",
    justifyContent: "flex-start",

    "&:before": {
      content: "'A'",
      display: "flex",
      alignItems: "center",
      justifyContent: "center",
      fontWeight: 700,
      fontSize: "20px",
      width: "50%",
      color: theme.palette.getContrastText(theme.palette.primary.main),
    },
  },

  "&.Mui-disabled": {
    "& .MuiSwitch-switchBase": {
      backgroundColor: theme.palette.grey[400],
    },
  },
}));

export default App;

enter image description here enter image description here

Upvotes: 0

Views: 61

Answers (0)

Related Questions