Toggle
A two-state button that can be either on or off.
Usage
Installation
Toggle.tsx
1"use client";
2import { cn } from "@/utils/cn";
3import React, { useState } from "react";
4
5type ToggleVariants = "squared" | "squashed" | "";
6
7type ToggleProps = {
8  label?: string;
9  onChange?: (checked: boolean) => void;
10  initialState?: boolean;
11  className?: string;
12  variant?: ToggleVariants;
13} & Omit<React.InputHTMLAttributes<HTMLInputElement>, "type" | "onChange">;
14
15export const Toggle: React.FC<ToggleProps> = ({
16  label,
17  onChange,
18  initialState = false,
19  className = "",
20  variant = "",
21  ...inputProps
22}) => {
23  const [isChecked, setIsChecked] = useState(initialState);
24
25  const handleToggle = () => {
26    
27    setIsChecked((prev) => !prev);
28    onChange && onChange(!isChecked);
29  };
30
31  return (
32    <label className={cn("flex cursor-pointer items-center", className)}>
33      <div className="relative">
34        <input
35          {...inputProps}
36          type="checkbox"
37          className="sr-only"
38          checked={isChecked}
39          onChange={handleToggle}
40        />
41        <div
42          className={cn(
43            "w-10 shadow-inner transition-colors duration-300 ease-in-out",
44            isChecked ? "bg-rose-500" : "bg-rose-200",
45            variant === "squashed" ? "h-4" : "h-6",
46            switchToggleVariant(variant),
47          )}
48        ></div>
49        <div
50          className={cn(
51            "absolute bg-white shadow transition-transform duration-300 ease-in-out",
52            variant === "squashed"
53              ? "-inset-1 -left-1 h-6 w-6"
54              : "inset-y-1 left-1 h-4 w-4",
55            isChecked
56              ? variant === "squashed"
57                ? "translate-x-6 transform"
58                : "translate-x-full transform"
59              : "",
60            variant === "squared" ? "rounded" : "rounded-full",
61          )}
62        ></div>
63      </div>
64      <div
65        className={cn("ml-2 font-geist font-semibold text-rose-100", className)}
66      >
67        {label}
68      </div>
69    </label>
70  );
71};
72
73const switchToggleVariant = (variant: ToggleVariants) => {
74  switch (variant) {
75    case "squared":
76      return "rounded";
77    case "squashed":
78      return "rounded-full";
79    default:
80      return "rounded-full";
81  }
82};Props
The Toggle component accepts the following props:
| Prop | Type | Default | Description | 
|---|---|---|---|
| label | string | - | Optional label for the toggle. | 
| onChange | A function with void return type | - | Function called when the toggle state changes. | 
| initialState | boolean | false | Initial state of the toggle. | 
| className | string | "" | Additional CSS classes for the component. | 
| variant | "squared" "squashed" "" | "" | Visual variant of the toggle. | 
The component also accepts all valid HTML input attributes except type and onChange.
Variant Details
The variant prop affects the appearance of the toggle:
- ""(default): Rounded toggle with standard height
- "squared": Toggle with square corners
- "squashed": Flatter toggle with rounded corners
If no variant is specified, it defaults to the standard rounded appearance.Toggle,