react-native-advanced-checkbox
Version:
A customizable, animated checkbox component for React Native with group support, haptic feedback, and accessibility features, compatible with React Native 0.72.0 and above.
163 lines • 7.14 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importStar(require("react"));
const react_native_1 = require("react-native");
const AnimatedView = react_native_1.Animated.createAnimatedComponent(react_native_1.View);
const AnimatedText = react_native_1.Animated.createAnimatedComponent(react_native_1.Text);
const AdvancedCheckbox = ({ value = false, onValueChange, checkedImage, uncheckedImage, size = 24, label, labelPosition = 'right', labelStyle, containerStyle, checkedColor = '#007AFF', checkBoxStyle, uncheckedColor = '#ccc', disabled = false, animationType = 'bounce', checkMarkContent, testID, accessibilityLabel, accessibilityHint, }) => {
const isChecked = typeof value === 'boolean' ? value : false;
const scaleAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(1)).current;
const fadeAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(1)).current;
const rotateAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
(0, react_1.useEffect)(() => {
const animations = [];
if (animationType === 'bounce') {
animations.push(react_native_1.Animated.timing(scaleAnim, {
toValue: 0.85,
duration: 100,
useNativeDriver: true,
}), react_native_1.Animated.timing(scaleAnim, {
toValue: 1,
duration: 100,
useNativeDriver: true,
}));
}
else if (animationType === 'fade') {
animations.push(react_native_1.Animated.timing(fadeAnim, {
toValue: isChecked ? 1 : 0.5,
duration: 200,
useNativeDriver: true,
}));
}
else if (animationType === 'rotate') {
animations.push(react_native_1.Animated.timing(rotateAnim, {
toValue: isChecked ? 1 : 0,
duration: 200,
useNativeDriver: true,
}));
}
react_native_1.Animated.sequence([
...animations,
react_native_1.Animated.timing(fadeAnim, {
toValue: isChecked ? 1 : 0.7,
duration: 200,
useNativeDriver: true,
}),
]).start();
}, [isChecked, scaleAnim, fadeAnim, rotateAnim, animationType]);
const handlePress = (0, react_1.useCallback)(() => {
console.log('Checkbox clicked, value:', value, 'isChecked:', isChecked);
if (!disabled && onValueChange) {
// In group context, value is a string; otherwise toggle boolean
onValueChange(typeof value === 'string' ? value : !isChecked);
}
}, [disabled, isChecked, onValueChange, value]);
const renderCheckbox = () => {
if (checkedImage && isChecked) {
return <react_native_1.Image source={checkedImage} style={{ width: size, height: size }}/>;
}
if (uncheckedImage && !isChecked) {
return <react_native_1.Image source={uncheckedImage} style={{ width: size, height: size }}/>;
}
const rotateInterpolate = rotateAnim.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '90deg'],
});
return (<AnimatedView style={[
styles.checkbox,
checkBoxStyle,
{
width: size,
height: size,
borderColor: isChecked ? checkedColor : uncheckedColor,
backgroundColor: isChecked ? checkedColor : 'transparent',
transform: [
{ scale: animationType === 'bounce' ? scaleAnim : 1 },
{ rotate: animationType === 'rotate' ? rotateInterpolate : '0deg' },
],
opacity: fadeAnim,
},
]} testID={testID ? `${testID}-checkbox` : undefined}>
{isChecked && (checkMarkContent ? (<react_native_1.Animated.View style={{ opacity: fadeAnim }}>
{checkMarkContent}
</react_native_1.Animated.View>) : (<AnimatedText style={[
styles.checkMark,
{ fontSize: size * 0.6, opacity: fadeAnim },
]}>
✓
</AnimatedText>))}
</AnimatedView>);
};
const content = (<>
{labelPosition === 'left' && label && (<react_native_1.Text style={[styles.label, labelStyle]} testID={testID ? `${testID}-label-left` : undefined}>
{label}
</react_native_1.Text>)}
{renderCheckbox()}
{labelPosition === 'right' && label && (<react_native_1.Text style={[styles.label, labelStyle]} testID={testID ? `${testID}-label-right` : undefined}>
{label}
</react_native_1.Text>)}
</>);
return (<react_native_1.Pressable onPress={handlePress} disabled={disabled} style={[
styles.container,
containerStyle,
{ opacity: disabled ? 0.5 : 1 },
]} accessibilityLabel={accessibilityLabel} accessibilityHint={accessibilityHint || `Toggles checkbox to ${isChecked ? 'off' : 'on'}`} testID={testID}>
{content}
</react_native_1.Pressable>);
};
const styles = react_native_1.StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
marginVertical: 8,
},
checkbox: {
borderWidth: 1.5,
borderRadius: 4,
alignItems: 'center',
justifyContent: 'center',
},
checkMark: {
color: '#fff',
fontWeight: 'bold',
},
label: {
fontSize: 16,
marginHorizontal: 8,
},
});
exports.default = AdvancedCheckbox;
//# sourceMappingURL=AdvancedCheckbox.js.map
;