npx expo install react-native-reanimated @expo/vector-icons react-native-safe-area-context color
src/├── components/checkbox.tsx # Our checkbox component├── constants/index.ts # Colors and data configuration├── hooks/useCuisines.ts # State management logic└── App.tsx # Main layout and composition
export const ACTIVE_COLOR = '#EF8E52';export const INACTIVE_COLOR = '#B3B1B4';
import { useCallback, useState } from 'react';const Cuisines = new Array(20).fill('Italian').map((cuisine, i) => ({id: i,name: cuisine,selected: false,}));export const useCuisines = () => {const [cuisines, setCuisines] = useState(Cuisines);const toggleCuisine = useCallback((id: number) => {setCuisines((prevCuisines) => {return prevCuisines.map((cuisine) => {if (cuisine.id === id) {return { ...cuisine, selected: !cuisine.selected };}return cuisine;});});}, []);return { cuisines, toggleCuisine };};
import { StyleSheet, View, Text, TouchableOpacity } from 'react-native';import { AntDesign } from '@expo/vector-icons';import { ACTIVE_COLOR, INACTIVE_COLOR } from '../constants';type CheckboxProps = {label: string;checked: boolean;onPress: () => void;};export const Checkbox: React.FC<CheckboxProps> = ({label,checked,onPress,}) => {return (<TouchableOpacitystyle={[styles.container,{backgroundColor: checked ? 'rgba(239, 142, 82, 0.1)' : 'transparent',borderColor: checked ? ACTIVE_COLOR : INACTIVE_COLOR,},]}onPress={onPress}><Textstyle={[styles.label,{ color: checked ? ACTIVE_COLOR : INACTIVE_COLOR },]}>{label}</Text>{checked && (<View style={styles.iconContainer}><AntDesign name="checkcircle" size={20} color={ACTIVE_COLOR} /></View>)}</TouchableOpacity>);};const styles = StyleSheet.create({container: {paddingVertical: 12,paddingHorizontal: 20,borderWidth: 1,borderRadius: 32,flexDirection: 'row',alignItems: 'center',justifyContent: 'center',},label: {fontSize: 18,fontFamily: 'SF-Pro-Rounded-Bold',},iconContainer: {marginLeft: 8,justifyContent: 'center',alignItems: 'center',height: 20,width: 20,},});
import { StyleSheet } from 'react-native';import Color from 'color';import { AntDesign } from '@expo/vector-icons';import Animated, {FadeIn,FadeOut,LinearTransition,useAnimatedStyle,withTiming,} from 'react-native-reanimated';import { ACTIVE_COLOR, INACTIVE_COLOR } from '../constants';type CheckboxProps = {label: string;checked: boolean;onPress: () => void;};const TimingConfig = {duration: 150,};export const Checkbox: React.FC<CheckboxProps> = ({label,checked,onPress,}) => {const fadedActiveColor = Color(ACTIVE_COLOR).alpha(0.1).toString();const rContainerStyle = useAnimatedStyle(() => {return {backgroundColor: withTiming(checked ? fadedActiveColor : 'transparent',TimingConfig),borderColor: withTiming(checked ? ACTIVE_COLOR : INACTIVE_COLOR,TimingConfig),paddingLeft: 20,paddingRight: !checked ? 20 : 14,};}, [checked]);const rTextStyle = useAnimatedStyle(() => {return {color: withTiming(checked ? ACTIVE_COLOR : INACTIVE_COLOR, TimingConfig),};}, [checked]);return (<Animated.Viewlayout={LinearTransition.springify().mass(0.8)}style={[styles.container, rContainerStyle]}onTouchEnd={onPress}><Animated.Text style={[styles.label, rTextStyle]}>{label}</Animated.Text>{checked && (<Animated.Viewentering={FadeIn.duration(350)}exiting={FadeOut}style={styles.iconContainer}><AntDesign name="checkcircle" size={20} color={ACTIVE_COLOR} /></Animated.View>)}</Animated.View>);};const styles = StyleSheet.create({container: {paddingVertical: 12,borderWidth: 1,borderRadius: 32,flexDirection: 'row',alignItems: 'center',justifyContent: 'center',},label: {fontSize: 18,fontFamily: 'SF-Pro-Rounded-Bold',},iconContainer: {marginLeft: 8,justifyContent: 'center',alignItems: 'center',height: 20,width: 20,},});
layout={LinearTransition.springify().mass(0.8)}
<Animated.Viewentering={FadeIn.duration(350)}exiting={FadeOut}>
const rContainerStyle = useAnimatedStyle(() => ({backgroundColor: withTiming(checked ? fadedActiveColor : 'transparent'),borderColor: withTiming(checked ? ACTIVE_COLOR : INACTIVE_COLOR),paddingRight: !checked ? 20 : 14,}));
Every week I send out a newsletter sharing new things about React Native animations.