veza/apps/web/src/components/ui/switch.tsx

101 lines
2.6 KiB
TypeScript
Raw Normal View History

2025-12-13 02:34:34 +00:00
import * as React from 'react';
import { cn } from '@/lib/utils';
/**
* SwitchProps - Propriétés du composant Switch
*
* @interface SwitchProps
* @extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'>
*/
export interface SwitchProps
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {
/**
* État checked du switch
*
* @example
* ```tsx
* <Switch checked={isEnabled} onCheckedChange={setIsEnabled} />
* ```
*/
checked?: boolean;
/**
* Fonction appelée lorsque l'état checked change
*
* @param {boolean} checked - Nouvel état checked
*
* @example
* ```tsx
* <Switch onCheckedChange={(checked) => console.log('Switch:', checked)} />
* ```
*/
onCheckedChange?: (checked: boolean) => void;
}
/**
* Switch - Composant d'interrupteur avec design system Kodo
*
* Composant d'interrupteur (toggle) pour activer/désactiver une option.
* Utilise le design system Kodo avec une animation de transition fluide.
*
* @example
* ```tsx
* // Switch simple
* <Switch />
*
* // Switch contrôlé
* <Switch
* checked={isEnabled}
* onCheckedChange={setIsEnabled}
* />
*
* // Switch désactivé
* <Switch disabled />
* ```
*
* @component
* @param {SwitchProps} props - Propriétés du composant
* @returns {JSX.Element} Élément label contenant un switch stylisé
*/
const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
({ className, checked, onCheckedChange, disabled, ...props }, ref) => {
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (onCheckedChange) {
onCheckedChange(e.target.checked);
}
};
return (
<label
className={cn(
'peer inline-flex h-[24px] w-[44px] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors',
'focus-within:outline-none focus-within:ring-2 focus-within:ring-kodo-cyan focus-within:ring-offset-2 focus-within:ring-offset-kodo-void',
'disabled:cursor-not-allowed disabled:opacity-50',
checked ? 'bg-kodo-cyan' : 'bg-kodo-steel',
className,
)}
>
<input
ref={ref}
type="checkbox"
className="sr-only"
checked={checked}
onChange={handleChange}
disabled={disabled}
{...props}
/>
<span
className={cn(
'pointer-events-none block h-5 w-5 rounded-full bg-white shadow-lg ring-0 transition-transform',
checked ? 'translate-x-5' : 'translate-x-0',
)}
/>
</label>
);
},
);
Switch.displayName = 'Switch';
2025-12-13 02:34:34 +00:00
export { Switch };