All files / app/components CustomColorSwitch.tsx

100% Statements 24/24
100% Branches 22/22
100% Functions 10/10
100% Lines 23/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 1104x 4x 4x 4x 4x   4x               18x         91x 91x                           91x   91x         91x     91x             4x                             91x   91x   91x 26x     91x 65x                               91x 26x     65x                            
import { Switch, SwitchProps } from "@material-ui/core";
import classNames from "classnames";
import { useEffect, useState } from "react";
import { theme } from "theme";
import makeStyles from "utils/makeStyles";
 
import CircularProgress from "./CircularProgress";
 
interface SwitchStyleProps {
  checked: boolean;
  color: string;
  size: SwitchProps["size"];
}
 
const useStyles = makeStyles(({ palette, shadows }) => ({
  circle: {
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    width: (props: SwitchStyleProps) => (props.size === "medium" ? 20 : 16),
    height: (props: SwitchStyleProps) => (props.size === "medium" ? 20 : 16),
    borderRadius: "50%",
    backgroundColor: palette.grey[600],
    boxShadow: shadows[1],
  },
  active: {
    backgroundColor: palette.grey[600],
  },
  switchBase: {
    color: palette.grey[600],
    "& + .MuiSwitch-track": {
      backgroundColor: palette.grey[200],
    },
    "&.Mui-checked": {
      color: (props: { color: string }) => props.color,
      "& + .MuiSwitch-track": {
        backgroundColor: (props: { color: string }) => props.color,
      },
    },
    "&.Mui-disabled": {
      color: (props: { checked: boolean; color: string }) =>
        props.checked ? props.color : palette.grey[600],
      "& + .MuiSwitch-track": {
        backgroundColor: (props: { checked: boolean; color: string }) =>
          props.checked ? props.color : palette.grey[200],
        opacity: 0.4,
      },
    },
  },
}));
 
export default function CustomColorSwitch({
  checked,
  onClick,
  size = "medium",
  status,
  isLoading = false,
  color = theme.palette.secondary.main,
}: {
  checked: boolean;
  onClick: SwitchProps["onClick"];
  size?: SwitchProps["size"];
  status?: string;
  isLoading?: boolean;
  color?: string;
}) {
  const classes = useStyles({ checked, color, size });
 
  const [isMounted, setIsMounted] = useState(false);
 
  useEffect(() => {
    setIsMounted(true);
  }, []);
 
  const Icon = () => (
    <div
      className={classNames(classes.circle, {
        [classes.active]: checked && !isLoading,
      })}
      style={{ backgroundColor: checked ? color : undefined }}
    >
      {isLoading && (
        <CircularProgress
          size={size === "medium" ? 14 : 12}
          style={{ color: "white" }}
          thickness={6}
        />
      )}
    </div>
  );
 
  if (!isMounted) {
    return null;
  }
 
  return (
    <Switch
      classes={{
        switchBase: classes.switchBase,
      }}
      checked={checked}
      checkedIcon={<Icon />}
      disabled={isLoading || status === "loading"}
      icon={<Icon />}
      onClick={onClick}
      size={size}
    />
  );
}