File size: 1,533 Bytes
cd6f98e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import * as SwitchPrimitive from "@radix-ui/react-switch";
import { clsx } from "clsx";
import React, { useEffect, useState } from "react";

interface SwitchProps {
  value: boolean;
  disabled?: boolean;
  onChange: (checked: boolean) => void;
}

const Switch = ({ value, disabled = false, onChange }: SwitchProps) => {
  const [checked, setChecked] = useState(false);

  // Due to SSR, we should only change the internal state after the initial render
  useEffect(() => {
    setChecked(value);
  }, [value]);

  const handleChange = (checked: boolean) => {
    onChange(checked);
  };

  return (
    <SwitchPrimitive.Root
      className={clsx(
        "group",
        "radix-state-checked:bg-sky-600 radix-state-unchecked:bg-zinc-500",
        "relative inline-flex h-4 w-7 flex-shrink-0 rounded-full border border-transparent transition-colors duration-200 ease-in-out",
        "focus:outline-none focus-visible:ring focus-visible:ring-sky-500 focus-visible:ring-opacity-75",
        disabled ? "cursor-not-allowed opacity-60" : "cursor-pointer "
      )}
      disabled={disabled}
      onCheckedChange={handleChange}
      checked={checked}
    >
      <SwitchPrimitive.Thumb
        className={clsx(
          "group-radix-state-checked:translate-x-3",
          "group-radix-state-unchecked:translate-x-0",
          "pointer-events-none inline-block h-3 w-3 transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out"
        )}
      />
    </SwitchPrimitive.Root>
  );
};

export { Switch };