Switch
avenra/liquid-switchFreeComponent
A liquid glass switch.
Install it
npx shadcn@latest add https://docs.avenra.online/r/liquid-switch.jsonSource
1'use client';23import * as React from 'react';4import {5 createLiquidSwitch,6 type LiquidSwitchHandle,7 type LiquidSwitchOptions,8 type LiquidSwitchEventMap,9} from '@avenra/liquid-glass';1011export interface LiquidSwitchProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {12 /** Controlled state */13 checked?: boolean;14 /** Default state for uncontrolled usage */15 defaultChecked?: boolean;16 /** Called when checked state changes */17 onCheckedChange?: (checked: boolean) => void;18 /** Pass-through options for the underlying library */19 options?: LiquidSwitchOptions;20}2122export const LiquidSwitch = React.forwardRef<LiquidSwitchHandle | null, LiquidSwitchProps>(23 ({ checked, defaultChecked = false, onCheckedChange, options, className, ...props }, ref) => {24 const containerRef = React.useRef<HTMLDivElement>(null);25 const instanceRef = React.useRef<LiquidSwitchHandle | null>(null);2627 const isControlled = checked !== undefined;2829 // Initialize component30 React.useEffect(() => {31 if (!containerRef.current) return;32 if (instanceRef.current) return;33 if (containerRef.current.children.length > 0) return;3435 const instance = createLiquidSwitch(containerRef.current, {36 checked: checked ?? defaultChecked,37 ...options,38 });3940 instanceRef.current = instance;4142 const handleChange = (payload: LiquidSwitchEventMap['change']) => {43 onCheckedChange?.(payload.checked);44 };4546 instance.on('change', handleChange);4748 return () => {49 instance.off('change', handleChange);50 instance.destroy();51 instanceRef.current = null;52 };53 }, []);5455 // Sync controlled state56 React.useEffect(() => {57 if (!instanceRef.current || !isControlled) return;58 instanceRef.current.checked = checked!;59 }, [checked, isControlled]);6061 // Expose imperative API62 React.useImperativeHandle(ref, () => instanceRef.current!, []);6364 return <div ref={containerRef} className={className} {...props} />;65 },66);6768LiquidSwitch.displayName = 'LiquidSwitch';
