import React, { useRef, useEffect } from 'react'; import { Pressable, Animated, Text, StyleSheet } from 'react-native'; import { useTheme } from '../../theme/useTheme'; import type { CheckboxProps, CheckboxSize } from './Checkbox.types'; export const Checkbox: React.FC = ({ checked, onCheckedChange, color = 'primary', size = 'md', label, disabled = false, style, labelStyle, }) => { const theme = useTheme(); const animatedValue = useRef(new Animated.Value(checked ? 1 : 0)).current; useEffect(() => { Animated.timing(animatedValue, { toValue: checked ? 1 : 0, duration: 150, useNativeDriver: false, }).start(); }, [checked, animatedValue]); const sizeMap: Record = { sm: { box: 18, check: 10, fontSize: theme.typography.fontSize.sm }, md: { box: 22, check: 13, fontSize: theme.typography.fontSize.md }, lg: { box: 28, check: 16, fontSize: theme.typography.fontSize.lg }, }; const { box, check, fontSize } = sizeMap[size]; const colorValue = theme.colors[color]; const bgColor = animatedValue.interpolate({ inputRange: [0, 1], outputRange: ['transparent', colorValue], }); const borderColor = animatedValue.interpolate({ inputRange: [0, 1], outputRange: [theme.colors.border, colorValue], }); const checkScale = animatedValue.interpolate({ inputRange: [0, 1], outputRange: [0, 1], }); return ( !disabled && onCheckedChange(!checked)} disabled={disabled} accessibilityRole="checkbox" accessibilityState={{ checked, disabled }} accessibilityLabel={label} style={[styles.wrapper, disabled && styles.disabled, style]} > {label && ( {label} )} ); }; const styles = StyleSheet.create({ wrapper: { flexDirection: 'row', alignItems: 'center', }, box: { alignItems: 'center', justifyContent: 'center', }, label: {}, disabled: { opacity: 0.5, }, });