React + MotionInputs

Toggle switch

An on/off switch whose knob springs across, with a color and size you can set to match your design.

Settings

36px

Code

import { useState } from "react";
import { motion } from "framer-motion";

interface ToggleSwitchProps {
  color?: string;
  size?: number;
  checked?: boolean;
  defaultChecked?: boolean;
  onCheckedChange?: (checked: boolean) => void;
  label?: string;
}

export default function ToggleSwitch({
  color = "#0071e3",
  size = 36,
  checked,
  defaultChecked = true,
  onCheckedChange,
  label = "Turn on",
}: ToggleSwitchProps) {
  const [internal, setInternal] = useState(defaultChecked);
  const on = checked ?? internal;

  const toggle = () => {
    if (checked === undefined) setInternal(!on);
    onCheckedChange?.(!on);
  };

  return (
    <button
      type="button"
      role="switch"
      aria-checked={on}
      aria-label={label}
      onClick={toggle}
      className="flex shrink-0 items-center rounded-full p-1 transition-colors"
      style={{
        width: size * 1.85,
        height: size,
        backgroundColor: on ? color : "oklch(0.3 0.012 260)",
      }}
    >
      <motion.span
        className="rounded-full bg-white shadow"
        style={{ width: size - 8, height: size - 8 }}
        animate={{ x: on ? size * 0.85 : 0 }}
        transition={{ type: "spring", stiffness: 500, damping: 30 }}
      />
    </button>
  );
}

Prompt for AI

Paste it into ChatGPT, Claude or Cursor and it will adapt the block to your project with these settings, even if you don’t use React.

More in Inputs

Where to use it

Use a toggle for settings that take effect straight away: dark mode, email notifications, “Show prices with VAT” in a B2B shop or availability in a booking dashboard. The springy knob lands with a satisfying little snap. If you searched for an animated toggle switch in React, this is a clean starting point.

A toggle should never need a “Save” button after it; if the change only applies later, a checkbox is more honest. Put a label next to it that says what “on” means, and check that the off color has enough contrast on your background.