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,