Animated Toggle
smoothui-registry/animated-toggleFreeComponent
Animated toggle switch with morph and icon variants
Install it
npx shadcn@latest add https://www.smoothui.dev/r/animated-toggle.jsonSource
1"use client";23import { cn } from "@/lib/utils";4import { AnimatePresence, motion, useReducedMotion } from "motion/react";5import {6 type KeyboardEvent,7 type ReactNode,8 useCallback,9 useState,10} from "react";1112export interface AnimatedToggleProps {13 /** Controlled checked state */14 checked?: boolean;15 /** Additional CSS classes */16 className?: string;17 /** Default checked state for uncontrolled mode */18 defaultChecked?: boolean;19 /** Whether the toggle is disabled */20 disabled?: boolean;21 /** Icons for on/off states (only used with icon variant) */22 icons?: { on: ReactNode; off: ReactNode };23 /** Accessible label for the toggle */24 label?: string;25 /** Callback when checked state changes */26 onChange?: (checked: boolean) => void;27 /** Size of the toggle */28 size?: "sm" | "md" | "lg";29 /** Visual variant of the toggle */30 variant?: "default" | "morph" | "icon";31}3233const SPRING = {34 bounce: 0.1,35 duration: 0.25,36 type: "spring" as const,37};3839const SIZES = {40 lg: {41 icon: "size-3.5",42 thumb: "size-6",43 thumbTranslate: 24,44 track: "w-[52px] h-7",45 },46 md: {47 icon: "size-3",48 thumb: "size-5",49 thumbTranslate: 20,50 track: "w-11 h-6",51 },52 sm: {53 icon: "size-2.5",54 thumb: "size-4",55 thumbTranslate: 16,56 track: "w-9 h-5",57 },58};5960const AnimatedToggle = ({61 checked: controlledChecked,62 defaultChecked = false,63 onChange,64 variant = "default",65 icons,66 size = "md",67 disabled = false,68 label,69 className,70}: AnimatedToggleProps) => {71 const shouldReduceMotion = useReducedMotion();7273 const [internalChecked, setInternalChecked] = useState(defaultChecked);7475 const isControlled = controlledChecked !== undefined;76 const checked = isControlled ? controlledChecked : internalChecked;7778 const handleToggle = useCallback(() => {79 if (disabled) {80 return;81 }8283 const newValue = !checked;84 if (!isControlled) {85 setInternalChecked(newValue);86 }87 onChange?.(newValue);88 }, [checked, disabled, isControlled, onChange]);8990 const handleKeyDown = useCallback(91 (event: KeyboardEvent<HTMLButtonElement>) => {92 if (event.key === " " || event.key === "Enter") {93 event.preventDefault();94 handleToggle();95 }96 },97 [handleToggle]98 );99100 const sizeConfig = SIZES[size];101102 const getThumbBorderRadius = () => {103 if (variant !== "morph" || shouldReduceMotion) {104 return 9999;105 }106 return checked ? 9999 : 6;107 };108109 const getThumbTransform = () => {110// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from SmoothUI Registry
All 178 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Agent Avataragent-avatar | SmoothUI Registry | Components | Free | no deps | |
| Ai Approvalai-approval | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Artifactai-artifact | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Branchai-branch | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Citationai-citation | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Context Meterai-context-meter | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Conversationai-conversation | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Coreai-core | SmoothUI Registry | Components | Free | 1 dep |
