UNPKG

@futurejj/react-native-checkbox

Version:
128 lines (124 loc) 3.99 kB
"use strict"; import { useEffect, useMemo, useRef } from 'react'; import { Animated, StyleSheet, View, TouchableOpacity, Platform } from 'react-native'; import { animationDuration, defaultCheckedColor, defaultDisabledColor, defaultUncheckedColor } from "./constants.js"; import { getStyles } from "./styles.js"; // Import either Expo or React Native Vector Icons based on availability import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; function loadMaterialIcon() { try { return require('@expo/vector-icons/MaterialCommunityIcons').default; } catch (e) { try { return require('react-native-vector-icons/MaterialCommunityIcons').default; } catch (error) { console.error('No icon library found. Please install either @expo/vector-icons or react-native-vector-icons'); return null; } } } const MaterialCommunityIcon = loadMaterialIcon(); function Checkbox(props) { const { status, disabled = false, onPress, testID, uncheckedColor = defaultUncheckedColor, color = defaultCheckedColor, style, size = 24, ...rest } = props; // Get styles based on size const styles = useMemo(() => getStyles(size), [size]); const { current: scaleAnim } = useRef(new Animated.Value(1)); const isFirstRendering = useRef(true); useEffect(() => { // Do not run animation on very first rendering if (isFirstRendering.current) { isFirstRendering.current = false; return; } const checked = status === 'checked'; Animated.sequence([Animated.timing(scaleAnim, { toValue: 0.85, duration: checked ? animationDuration : 0, useNativeDriver: false }), Animated.timing(scaleAnim, { toValue: 1, duration: checked ? animationDuration : animationDuration * 1.75, useNativeDriver: false })]).start(); }, [status, scaleAnim]); const checked = useMemo(() => status === 'checked', [status]); const indeterminate = useMemo(() => status === 'indeterminate', [status]); const selectionControlColor = useMemo(() => { if (disabled) { return defaultDisabledColor; } if (checked) { return color; } return uncheckedColor; }, [disabled, checked, color, uncheckedColor]); const borderWidth = scaleAnim.interpolate({ inputRange: [0.8, 1], outputRange: [7 * (size / 24), 0] // Scale border animation with size }); const icon = useMemo(() => indeterminate ? 'minus-box' : checked ? 'checkbox-marked' : 'checkbox-blank-outline', [indeterminate, checked]); // Accessibility props based on platform const accessibilityProps = useMemo(() => Platform.OS === 'web' ? { role: 'checkbox', accessibilityState: { checked, disabled } // focusable: !disabled, } : { accessibilityRole: 'checkbox', accessibilityState: { disabled, checked }, accessibilityLiveRegion: 'polite' }, [checked, disabled]); return /*#__PURE__*/_jsx(TouchableOpacity, { ...rest, ...accessibilityProps, onPress: disabled ? undefined : onPress, style: [styles.container, style], testID: testID, activeOpacity: 0.7, children: /*#__PURE__*/_jsxs(Animated.View, { style: { transform: [{ scale: scaleAnim }] }, children: [MaterialCommunityIcon ? /*#__PURE__*/_jsx(MaterialCommunityIcon, { allowFontScaling: false, name: icon, size: size, color: selectionControlColor }) : /*#__PURE__*/_jsx(View, { style: [styles.fallbackIcon, { borderColor: selectionControlColor }] }), /*#__PURE__*/_jsx(View, { style: [StyleSheet.absoluteFill, styles.fillContainer], children: /*#__PURE__*/_jsx(Animated.View, { style: [styles.fill, { borderColor: selectionControlColor }, { borderWidth }] }) })] }) }); } export { Checkbox }; //# sourceMappingURL=index.js.map