diff --git a/src/components/common/mdy-switch.scss b/src/components/common/mdy-switch.scss new file mode 100644 index 0000000000..db1a215f03 --- /dev/null +++ b/src/components/common/mdy-switch.scss @@ -0,0 +1,15 @@ +.MDYSwitch-container { + position: relative; + + .MDYSwitch-CircularProgress { + position: absolute; + top: 8px; + left: 8px; + z-index: 1; + + &.checked { + right: 8px; + left: unset; + } + } +} diff --git a/src/components/common/mdy-switch.tsx b/src/components/common/mdy-switch.tsx index 27d91591c7..98103bcf19 100644 --- a/src/components/common/mdy-switch.tsx +++ b/src/components/common/mdy-switch.tsx @@ -1,64 +1,89 @@ import { styled } from "@mui/material/styles"; import Switch, { SwitchProps } from "@mui/material/Switch"; +import CircularProgress from "@mui/material/CircularProgress"; +import "./mdy-switch.scss"; -const MDYSwitch = styled((props: SwitchProps) => )( - ({ theme, checked }) => ({ - height: "32px", - padding: 0, - margin: 0, +interface MDYSwitchProps extends SwitchProps { + loading?: boolean; +} + +const MDYSwitch = styled((props: MDYSwitchProps) => { + const { loading = false, checked, disabled, ...nativeProps } = props; + + return ( +
+ {loading && ( + + )} + +
+ ); +})(({ theme, checked, loading, disabled }) => ({ + height: "32px", + padding: 0, + margin: 0, + borderRadius: 24, + opacity: loading || disabled ? 0.5 : 1, + "& .MuiSwitch-track": { borderRadius: 24, - "& .MuiSwitch-track": { - borderRadius: 24, - opacity: checked - ? "1 !important" - : theme.palette.mode === "dark" - ? "0.3 !important" - : "0.7 !important", - backgroundColor: checked - ? theme.palette.primary.main - : theme.palette.mode === "dark" - ? theme.palette.grey.A700 - : theme.palette.grey.A200, - "&::before": { - content: '""', - border: `solid 2px ${theme.palette.grey.A700}`, - width: "100%", - height: "100%", - opacity: checked ? 0 : 1, - position: "absolute", - borderRadius: "inherit", - boxSizing: "border-box", - transitionProperty: "opacity, background-color", - transitionTimingFunction: "linear", - transitionDuration: "67ms", - }, + opacity: checked + ? "1 !important" + : theme.palette.mode === "dark" + ? "0.3 !important" + : "0.7 !important", + backgroundColor: checked + ? theme.palette.primary.main + : theme.palette.mode === "dark" + ? theme.palette.grey.A700 + : theme.palette.grey.A200, + "&::before": { + content: '""', + border: `solid 2px ${theme.palette.grey.A700}`, + width: "100%", + height: "100%", + opacity: checked ? 0 : 1, + position: "absolute", + borderRadius: "inherit", + boxSizing: "border-box", + transitionProperty: "opacity, background-color", + transitionTimingFunction: "linear", + transitionDuration: "67ms", }, - "& .MuiSwitch-switchBase": { - padding: "6px 9px 6px 6px", + }, + "& .MuiSwitch-switchBase": { + padding: "6px 9px 6px 6px", + }, + "& .MuiSwitch-thumb": { + boxShadow: "none", + width: loading ? 24 : 16, + height: loading ? 24 : 16, + margin: loading ? -2 : 3, + color: checked + ? theme.palette.getContrastText(theme.palette.primary.main) + : theme.palette.mode === "dark" + ? theme.palette.grey.A200 + : theme.palette.grey.A700, + opacity: checked ? 1 : 0.7, + }, + "& .Mui-checked": { + "&.MuiSwitch-switchBase": { + padding: "6px 9px 6px 12px", }, "& .MuiSwitch-thumb": { - boxShadow: "none", - width: 16, - height: 16, - margin: 3, - color: checked - ? theme.palette.getContrastText(theme.palette.primary.main) - : theme.palette.mode === "dark" - ? theme.palette.grey.A200 - : theme.palette.grey.A700, - opacity: checked ? 1 : 0.7, - }, - "& .Mui-checked": { - "&.MuiSwitch-switchBase": { - padding: "6px 9px 6px 12px", - }, - "& .MuiSwitch-thumb": { - width: 24, - height: 24, - margin: -2, - }, + width: 24, + height: 24, + margin: -2, }, - }), -); + }, +})); export default MDYSwitch;