In this tutorial, we will create toggle switch using react material ui (mui 5). We will see mui 5 switch component, switch sizes, switch with color example with react material UI 5.
Install & Setup Vite + React + Typescript + MUI 5
React Material UI 5 Toggle Switch Example
1. react mui 5 simple toggle switch component with default check, disabled and disabled checked.
import { Switch } from "@mui/material";
const label = { inputProps: { "aria-label": "Switch demo" } };
export default function App() {
return (
<>
<Switch {...label} defaultChecked />
<Switch {...label} />
<Switch {...label} disabled defaultChecked />
<Switch {...label} disabled />
</>
);
}
2. react mui 5 switch component with Label FormControlLabel component.
import FormGroup from '@mui/material/FormGroup';
import FormControlLabel from '@mui/material/FormControlLabel';
import Switch from '@mui/material/Switch';
export default function SwitchLabels() {
return (
<FormGroup>
<FormControlLabel control={<Switch defaultChecked />} label="Label" />
<FormControlLabel disabled control={<Switch />} label="Disabled" />
</FormGroup>
);
}
3. react mui 5 switch component with sizes.
import { Switch } from "@mui/material";
const label = { inputProps: { "aria-label": "Size switch demo" } };
export default function App() {
return (
<>
<Switch {...label} defaultChecked size="small" />
<Switch {...label} defaultChecked />
</>
);
}
4. react mui 5 switch component with colors.
import { alpha, styled } from '@mui/material/styles';
import { pink } from '@mui/material/colors';
import Switch from '@mui/material/Switch';
const PinkSwitch = styled(Switch)(({ theme }) => ({
'& .MuiSwitch-switchBase.Mui-checked': {
color: pink[600],
'&:hover': {
backgroundColor: alpha(pink[600], theme.palette.action.hoverOpacity),
},
},
'& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track': {
backgroundColor: pink[600],
},
}));
const label = { inputProps: { 'aria-label': 'Color switch demo' } };
export default function ColorSwitches() {
return (
<div>
<Switch {...label} defaultChecked />
<Switch {...label} defaultChecked color="secondary" />
<Switch {...label} defaultChecked color="warning" />
<Switch {...label} defaultChecked color="default" />
<PinkSwitch {...label} defaultChecked />
</div>
);
}
5. You can control the switch with the checked and onChange props:
import * as React from 'react';
import Switch from '@mui/material/Switch';
export default function ControlledSwitches() {
const [checked, setChecked] = React.useState(true);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setChecked(event.target.checked);
};
return (
<Switch
checked={checked}
onChange={handleChange}
inputProps={{ 'aria-label': 'controlled' }}
/>
);
}
6. react mui 5 customizing switch component.
import * as React from "react";
import { styled } from "@mui/material/styles";
import FormGroup from "@mui/material/FormGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import Switch, { SwitchProps } from "@mui/material/Switch";
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
const MaterialUISwitch = styled(Switch)(({ theme }) => ({
width: 62,
height: 34,
padding: 7,
"& .MuiSwitch-switchBase": {
margin: 1,
padding: 0,
transform: "translateX(6px)",
"&.Mui-checked": {
color: "#fff",
transform: "translateX(22px)",
"& .MuiSwitch-thumb:before": {
backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 20 20"><path fill="${encodeURIComponent(
"#fff"
)}" d="M4.2 2.5l-.7 1.8-1.8.7 1.8.7.7 1.8.6-1.8L6.7 5l-1.9-.7-.6-1.8zm15 8.3a6.7 6.7 0 11-6.6-6.6 5.8 5.8 0 006.6 6.6z"/></svg>')`,
},
"& + .MuiSwitch-track": {
opacity: 1,
backgroundColor: theme.palette.mode === "dark" ? "#8796A5" : "#aab4be",
},
},
},
"& .MuiSwitch-thumb": {
backgroundColor: theme.palette.mode === "dark" ? "#003892" : "#001e3c",
width: 32,
height: 32,
"&:before": {
content: "''",
position: "absolute",
width: "100%",
height: "100%",
left: 0,
top: 0,
backgroundRepeat: "no-repeat",
backgroundPosition: "center",
backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 20 20"><path fill="${encodeURIComponent(
"#fff"
)}" d="M9.305 1.667V3.75h1.389V1.667h-1.39zm-4.707 1.95l-.982.982L5.09 6.072l.982-.982-1.473-1.473zm10.802 0L13.927 5.09l.982.982 1.473-1.473-.982-.982zM10 5.139a4.872 4.872 0 00-4.862 4.86A4.872 4.872 0 0010 14.862 4.872 4.872 0 0014.86 10 4.872 4.872 0 0010 5.139zm0 1.389A3.462 3.462 0 0113.471 10a3.462 3.462 0 01-3.473 3.472A3.462 3.462 0 016.527 10 3.462 3.462 0 0110 6.528zM1.665 9.305v1.39h2.083v-1.39H1.666zm14.583 0v1.39h2.084v-1.39h-2.084zM5.09 13.928L3.616 15.4l.982.982 1.473-1.473-.982-.982zm9.82 0l-.982.982 1.473 1.473.982-.982-1.473-1.473zM9.305 16.25v2.083h1.389V16.25h-1.39z"/></svg>')`,
},
},
"& .MuiSwitch-track": {
opacity: 1,
backgroundColor: theme.palette.mode === "dark" ? "#8796A5" : "#aab4be",
borderRadius: 20 / 2,
},
}));
const Android12Switch = styled(Switch)(({ theme }) => ({
padding: 8,
"& .MuiSwitch-track": {
borderRadius: 22 / 2,
"&:before, &:after": {
content: '""',
position: "absolute",
top: "50%",
transform: "translateY(-50%)",
width: 16,
height: 16,
},
"&:before": {
backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 24 24"><path fill="${encodeURIComponent(
theme.palette.getContrastText(theme.palette.primary.main)
)}" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"/></svg>')`,
left: 12,
},
"&:after": {
backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 24 24"><path fill="${encodeURIComponent(
theme.palette.getContrastText(theme.palette.primary.main)
)}" d="M19,13H5V11H19V13Z" /></svg>')`,
right: 12,
},
},
"& .MuiSwitch-thumb": {
boxShadow: "none",
width: 16,
height: 16,
margin: 2,
},
}));
const IOSSwitch = styled((props: SwitchProps) => (
<Switch focusVisibleClassName=".Mui-focusVisible" disableRipple {...props} />
))(({ theme }) => ({
width: 42,
height: 26,
padding: 0,
"& .MuiSwitch-switchBase": {
padding: 0,
margin: 2,
transitionDuration: "300ms",
"&.Mui-checked": {
transform: "translateX(16px)",
color: "#fff",
"& + .MuiSwitch-track": {
backgroundColor: theme.palette.mode === "dark" ? "#2ECA45" : "#65C466",
opacity: 1,
border: 0,
},
"&.Mui-disabled + .MuiSwitch-track": {
opacity: 0.5,
},
},
"&.Mui-focusVisible .MuiSwitch-thumb": {
color: "#33cf4d",
border: "6px solid #fff",
},
"&.Mui-disabled .MuiSwitch-thumb": {
color:
theme.palette.mode === "light"
? theme.palette.grey[100]
: theme.palette.grey[600],
},
"&.Mui-disabled + .MuiSwitch-track": {
opacity: theme.palette.mode === "light" ? 0.7 : 0.3,
},
},
"& .MuiSwitch-thumb": {
boxSizing: "border-box",
width: 22,
height: 22,
},
"& .MuiSwitch-track": {
borderRadius: 26 / 2,
backgroundColor: theme.palette.mode === "light" ? "#E9E9EA" : "#39393D",
opacity: 1,
transition: theme.transitions.create(["background-color"], {
duration: 500,
}),
},
}));
const AntSwitch = styled(Switch)(({ theme }) => ({
width: 28,
height: 16,
padding: 0,
display: "flex",
"&:active": {
"& .MuiSwitch-thumb": {
width: 15,
},
"& .MuiSwitch-switchBase.Mui-checked": {
transform: "translateX(9px)",
},
},
"& .MuiSwitch-switchBase": {
padding: 2,
"&.Mui-checked": {
transform: "translateX(12px)",
color: "#fff",
"& + .MuiSwitch-track": {
opacity: 1,
backgroundColor: theme.palette.mode === "dark" ? "#177ddc" : "#1890ff",
},
},
},
"& .MuiSwitch-thumb": {
boxShadow: "0 2px 4px 0 rgb(0 35 11 / 20%)",
width: 12,
height: 12,
borderRadius: 6,
transition: theme.transitions.create(["width"], {
duration: 200,
}),
},
"& .MuiSwitch-track": {
borderRadius: 16 / 2,
opacity: 1,
backgroundColor:
theme.palette.mode === "dark"
? "rgba(255,255,255,.35)"
: "rgba(0,0,0,.25)",
boxSizing: "border-box",
},
}));
export default function CustomizedSwitches() {
return (
<FormGroup>
<FormControlLabel
control={<MaterialUISwitch sx={{ m: 1 }} defaultChecked />}
label="MUI switch"
/>
<FormControlLabel
control={<Android12Switch defaultChecked />}
label="Android 12"
/>
<FormControlLabel
control={<IOSSwitch sx={{ m: 1 }} defaultChecked />}
label="iOS style"
/>
<Stack direction="row" spacing={1} alignItems="center">
<Typography>Off</Typography>
<AntSwitch defaultChecked inputProps={{ "aria-label": "ant design" }} />
<Typography>On</Typography>
</Stack>
</FormGroup>
);
}