@@ -3,16 +3,15 @@ import {
33 Text ,
44 View ,
55 Image ,
6- Easing ,
76 Animated ,
87 StyleProp ,
98 ViewStyle ,
109 TextStyle ,
11- TouchableOpacity ,
10+ Pressable ,
1211 ImageSourcePropType ,
1312 TouchableWithoutFeedbackProps ,
1413} from "react-native" ;
15- import styles , { _textStyle , _iconContainer } from "./BouncyCheckbox.style" ;
14+ import styles , { _textStyle } from "./BouncyCheckbox.style" ;
1615
1716type CustomStyleProp = StyleProp < ViewStyle > | Array < StyleProp < ViewStyle > > ;
1817type CustomTextStyleProp = StyleProp < TextStyle > | Array < StyleProp < TextStyle > > ;
@@ -24,20 +23,27 @@ type BaseTouchableProps = Pick<
2423export interface IBouncyCheckboxProps extends BaseTouchableProps {
2524 size ?: number ;
2625 text ?: string ;
27- iconStyle ?: any ;
2826 fillColor ?: string ;
2927 isChecked ?: boolean ;
3028 unfillColor ?: string ;
3129 disableText ?: boolean ;
32- ImageComponent ?: any ;
3330 bounceEffect ?: number ;
3431 bounceFriction ?: number ;
3532 useNativeDriver ?: boolean ;
3633 disableBuiltInState ?: boolean ;
34+ ImageComponent ?: any ;
3735 TouchableComponent ?: any ;
36+ bounceEffectIn ?: number ;
37+ bounceEffectOut ?: number ;
38+ bounceVelocityIn ?: number ;
39+ bounceVelocityOut ?: number ;
40+ bouncinessIn ?: number ;
41+ bouncinessOut ?: number ;
3842 iconComponent ?: React . ReactNode ;
3943 textComponent ?: React . ReactNode ;
40- style ?: StyleProp < ViewStyle > ;
44+ iconStyle ?: CustomStyleProp ;
45+ innerIconStyle ?: CustomStyleProp ;
46+ style ?: CustomStyleProp ;
4147 textStyle ?: CustomTextStyleProp ;
4248 iconImageStyle ?: CustomStyleProp ;
4349 textContainerStyle ?: CustomStyleProp ;
@@ -48,6 +54,7 @@ export interface IBouncyCheckboxProps extends BaseTouchableProps {
4854interface IState {
4955 checked : boolean ;
5056 springValue : Animated . Value ;
57+ bounceValue : Animated . Value ;
5158}
5259
5360const defaultCheckImage = require ( "./check.png" ) ;
@@ -58,44 +65,26 @@ class BouncyCheckbox extends React.Component<IBouncyCheckboxProps, IState> {
5865 this . state = {
5966 checked : false ,
6067 springValue : new Animated . Value ( 1 ) ,
68+ bounceValue : new Animated . Value ( 1 ) ,
6169 } ;
6270 }
6371
6472 componentDidMount ( ) {
6573 this . setState ( { checked : this . props . isChecked || false } ) ;
6674 }
6775
68- onPress = ( ) => {
69- const {
70- disableBuiltInState = false ,
71- useNativeDriver = true ,
72- bounceEffect = 1 ,
73- bounceFriction = 3 ,
74- } = this . props ;
75- const { checked, springValue } = this . state ;
76- if ( ! disableBuiltInState ) {
77- this . setState ( { checked : ! checked } , ( ) => {
78- springValue . setValue ( 0.7 ) ;
79- Animated . spring ( springValue , {
80- toValue : bounceEffect ,
81- friction : bounceFriction ,
82- useNativeDriver,
83- } ) . start ( ) ;
84- this . props . onPress && this . props . onPress ( this . state . checked ) ;
85- } ) ;
86- } else {
87- springValue . setValue ( 0.7 ) ;
88- Animated . spring ( springValue , {
89- toValue : bounceEffect ,
90- friction : bounceFriction ,
91- useNativeDriver,
92- } ) . start ( ) ;
93- this . props . onPress && this . props . onPress ( this . state . checked ) ;
94- }
76+ bounceEffect = ( value : number , velocity : number , bounciness : number ) => {
77+ const { useNativeDriver = true } = this . props ;
78+ Animated . spring ( this . state . bounceValue , {
79+ toValue : value ,
80+ velocity,
81+ bounciness,
82+ useNativeDriver,
83+ } ) . start ( ) ;
9584 } ;
9685
9786 renderCheckIcon = ( ) => {
98- const { checked, springValue } = this . state ;
87+ const { checked } = this . state ;
9988 const {
10089 size = 25 ,
10190 iconStyle,
@@ -106,25 +95,30 @@ class BouncyCheckbox extends React.Component<IBouncyCheckboxProps, IState> {
10695 unfillColor = "transparent" ,
10796 disableBuiltInState,
10897 isChecked,
98+ innerIconStyle,
10999 checkIconImageSource = defaultCheckImage ,
110100 } = this . props ;
111101
112102 const checkStatus = disableBuiltInState ? isChecked ! : checked ;
113103 return (
114104 < Animated . View
115105 style = { [
116- { transform : [ { scale : springValue } ] } ,
117- _iconContainer ( size , checkStatus , fillColor , unfillColor ) ,
106+ { transform : [ { scale : this . state . bounceValue } ] } ,
107+ styles . iconContainer ( size , checkStatus , fillColor , unfillColor ) ,
118108 iconStyle ,
119109 ] }
120110 >
121- { iconComponent ||
122- ( checkStatus && (
123- < ImageComponent
124- source = { checkIconImageSource }
125- style = { [ styles . iconImageStyle , iconImageStyle ] }
126- />
127- ) ) }
111+ < View
112+ style = { [ styles . innerIconContainer ( size , fillColor ) , innerIconStyle ] }
113+ >
114+ { iconComponent ||
115+ ( checkStatus && (
116+ < ImageComponent
117+ source = { checkIconImageSource }
118+ style = { [ styles . iconImageStyle , iconImageStyle ] }
119+ />
120+ ) ) }
121+ </ View >
128122 </ Animated . View >
129123 ) ;
130124 } ;
@@ -158,13 +152,40 @@ class BouncyCheckbox extends React.Component<IBouncyCheckboxProps, IState> {
158152 ) ;
159153 } ;
160154
155+ handleCheck = ( ) => {
156+ const { disableBuiltInState = false } = this . props ;
157+ const { checked } = this . state ;
158+ if ( ! disableBuiltInState ) {
159+ this . setState ( { checked : ! checked } , ( ) => {
160+ this . props . onPress && this . props . onPress ( this . state . checked ) ;
161+ } ) ;
162+ } else {
163+ this . props . onPress && this . props . onPress ( this . state . checked ) ;
164+ }
165+ } ;
166+
161167 render ( ) {
162- const { style, TouchableComponent = TouchableOpacity } = this . props ;
168+ const {
169+ style,
170+ bounceEffectIn = 0.9 ,
171+ bounceEffectOut = 1 ,
172+ bounceVelocityIn = 0.1 ,
173+ bounceVelocityOut = 0.4 ,
174+ bouncinessIn = 20 ,
175+ bouncinessOut = 20 ,
176+ TouchableComponent = Pressable ,
177+ } = this . props ;
163178 return (
164179 < TouchableComponent
165180 { ...this . props }
166181 style = { [ styles . container , style ] }
167- onPress = { this . onPress . bind ( this , Easing . bounce ) }
182+ onPressIn = { ( ) => {
183+ this . bounceEffect ( bounceEffectIn , bounceVelocityIn , bouncinessIn ) ;
184+ } }
185+ onPressOut = { ( ) => {
186+ this . bounceEffect ( bounceEffectOut , bounceVelocityOut , bouncinessOut ) ;
187+ this . handleCheck ( ) ;
188+ } }
168189 >
169190 { this . renderCheckIcon ( ) }
170191 { this . renderCheckboxText ( ) }
0 commit comments