--- title: Liquid Glass Switch description: A premium 3D liquid glass toggle switch featuring multi-stage crystal lens refraction, spring sliding knob animations, top curved glare highlights, and active liquid color glow channels. Supports multiple color variants, responsive size presets, icons inside the knob, and full keyboard accessibility. --- ## Installation CLI Manual ```bash npx lightswind@latest add liquid-glass-switch ``` Copy and paste the following code into your project. ```tsx "use client"; import React, { useState, useEffect } from "react"; import { cn } from "@/components/lib/utils"; import { motion, HTMLMotionProps } from "framer-motion"; import { Check, X } from "lucide-react"; export interface LiquidGlassSwitchProps extends Omit, "onChange" | "size"> { checked?: boolean; defaultChecked?: boolean; onChange?: (checked: boolean) => void; variant?: "emerald" | "primary" | "cyan" | "purple" | "glass"; size?: "sm" | "md" | "lg"; disabled?: boolean; label?: string; iconChecked?: React.ReactNode; iconUnchecked?: React.ReactNode; className?: string; } export const LiquidGlassSwitch = React.forwardRef< HTMLButtonElement, LiquidGlassSwitchProps >( ( { checked, defaultChecked = false, onChange, variant = "emerald", size = "md", disabled = false, label, iconChecked, iconUnchecked, className, ...props }, ref ) => { const [isOn, setIsOn] = useState(checked !== undefined ? checked : defaultChecked); useEffect(() => { if (checked !== undefined) { setIsOn(checked); } }, [checked]); const toggle = () => { if (disabled) return; const next = !isOn; if (checked === undefined) { setIsOn(next); } onChange?.(next); }; // Sizing presets — compact professional const trackSizeClasses = { sm: "w-11 h-6 p-[3px] rounded-full", md: "w-14 h-8 p-1 rounded-full", lg: "w-[4.5rem] h-10 p-1.5 rounded-full", }; const knobSizeClasses = { sm: "w-[18px] h-[18px] text-[9px]", md: "w-6 h-6 text-xs", lg: "w-7 h-7 text-sm", }; const travelDistances = { sm: 20, md: 24, lg: 30, }; // Variant track backgrounds when ACTIVE (ON) const activeTrackVariants = { emerald: cn( "bg-gradient-to-r from-emerald-400/90 via-teal-500/85 to-emerald-600/90", "border-white/80 dark:border-white/40", "shadow-[0_12px_25px_-4px_rgba(16,185,129,0.55),inset_0_2px_1.5px_0px_rgba(255,255,255,0.9),inset_0_-3px_6px_0px_rgba(5,80,50,0.4)]" ), primary: cn( "bg-gradient-to-r from-[#ff6a3d]/90 via-[#ee3e26]/85 to-[#c31e14]/90", "border-white/80 dark:border-white/40", "shadow-[0_12px_25px_-4px_rgba(238,62,38,0.6),inset_0_2px_1.5px_0px_rgba(255,255,255,0.9),inset_0_-3px_6px_0px_rgba(130,15,0,0.4)]" ), cyan: cn( "bg-gradient-to-r from-cyan-400/90 via-blue-500/85 to-indigo-600/90", "border-white/80 dark:border-white/40", "shadow-[0_12px_25px_-4px_rgba(0,114,255,0.5),inset_0_2px_1.5px_0px_rgba(255,255,255,0.9),inset_0_-3px_6px_0px_rgba(0,40,130,0.4)]" ), purple: cn( "bg-gradient-to-r from-purple-400/90 via-fuchsia-500/85 to-pink-600/90", "border-white/80 dark:border-white/40", "shadow-[0_12px_25px_-4px_rgba(168,85,247,0.5),inset_0_2px_1.5px_0px_rgba(255,255,255,0.9),inset_0_-3px_6px_0px_rgba(90,15,120,0.4)]" ), glass: cn( "bg-gradient-to-b from-white/60 via-white/35 to-white/20 dark:from-white/30 dark:via-white/15 dark:to-white/5", "border-white/90 dark:border-white/40", "shadow-[0_14px_30px_-6px_rgba(15,23,42,0.25),inset_0_2px_1.5px_0px_rgba(255,255,255,0.95)]" ), }; // Inactive track style (OFF) const inactiveTrackClass = cn( "bg-gradient-to-b from-slate-900/25 via-slate-900/15 to-slate-900/10 dark:from-white/20 dark:via-white/10 dark:to-white/5", "border-slate-900/20 dark:border-white/25", "shadow-[0_10px_22px_-5px_rgba(15,23,42,0.2),inset_0_2px_1px_0px_rgba(255,255,255,0.6),inset_0_-3px_6px_0px_rgba(0,0,0,0.15)]" ); // Knob content helper const renderKnobContent = () => { if (isOn) { if (iconChecked) return iconChecked; return ; } if (iconUnchecked) return iconUnchecked; if (iconChecked) { return {iconChecked}; } return ; }; return (
{/* Top glossy curved glare reflection - full width, pill radius */} {/* Bottom internal refraction ring - full width, pill radius */} {/* Sliding Liquid Glass Knob - Theme Adaptive */} {/* Top dome reflection inside knob */} {/* Icon inside knob */} {renderKnobContent()} {/* Optional Label */} {label && ( {label} )}
); } ); LiquidGlassSwitch.displayName = "LiquidGlassSwitch"; export default LiquidGlassSwitch; ```
## Usage ```tsx import { LiquidGlassSwitch } from "@/components/lightswind/liquid-glass-switch" ``` ```tsx import { useState } from "react"; import { LiquidGlassSwitch } from "@/components/lightswind/liquid-glass-switch"; import { Sparkles } from "lucide-react"; export function Demo() { const [enabled, setEnabled] = useState(true); return ( } /> ); } ```