Skip to content

Commit

Permalink
feat: better example and synthetic checkbox controllering example
Browse files Browse the repository at this point in the history
  • Loading branch information
WrathChaos committed Apr 6, 2024
1 parent 6b7f71a commit 97633e5
Show file tree
Hide file tree
Showing 9 changed files with 325 additions and 243 deletions.
403 changes: 232 additions & 171 deletions example/App.tsx

Large diffs are not rendered by default.

88 changes: 17 additions & 71 deletions example/lib/BouncyCheckbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,72 +5,15 @@ import React, {
useEffect,
useImperativeHandle,
} from 'react';
import {
View,
Text,
Image,
Animated,
StyleProp,
ViewStyle,
Pressable,
PressableProps,
TextStyle,
ImageStyle,
ImageSourcePropType,
} from 'react-native';
import {View, Text, Image, Animated, Pressable} from 'react-native';
import useBounceAnimation from './hooks/useBounceAnimation';
import useStateWIthCallback from './helpers/useStateWIthCallback';
import useStateWithCallback from './helpers/useStateWithCallback';
import styles from './BouncyCheckbox.style';

const AnimationValues = {
BounceIn: 0.9,
BounceOut: 1,
VelocityIn: 0.1,
VelocityOut: 0.4,
BouncinessIn: 20,
BouncinessOut: 20,
};

type BasePressableProps = Pick<
PressableProps,
Exclude<keyof PressableProps, 'onPress' | 'onLongPress'>
>;

export interface BouncyCheckboxProps extends BasePressableProps {
size?: number;
text?: string;
testID?: string;
fillColor?: string;
isChecked?: boolean;
unFillColor?: string;
disableText?: boolean;
bounceEffect?: number;
bounceFriction?: number;
useNativeDriver?: boolean;
bounceEffectIn?: number;
bounceEffectOut?: number;
bounceVelocityIn?: number;
bounceVelocityOut?: number;
bouncinessIn?: number;
bouncinessOut?: number;
ImageComponent?: any;
TouchableComponent?: any;
iconComponent?: React.ReactNode;
textComponent?: React.ReactNode;
iconStyle?: StyleProp<ViewStyle>;
innerIconStyle?: StyleProp<ViewStyle>;
style?: StyleProp<ViewStyle>;
textStyle?: StyleProp<TextStyle>;
iconImageStyle?: StyleProp<ImageStyle>;
textContainerStyle?: StyleProp<ViewStyle>;
checkIconImageSource?: ImageSourcePropType;
onPress?: (checked: boolean) => void;
onLongPress?: (checked: boolean) => void;
}

export interface BouncyCheckboxHandle {
onCheckboxPress: () => void;
}
import {
AnimationValues,
BouncyCheckboxHandle,
BouncyCheckboxProps,
} from './BouncyCheckbox.type';

const BouncyCheckbox: React.ForwardRefRenderFunction<
BouncyCheckboxHandle,
Expand All @@ -81,7 +24,6 @@ const BouncyCheckbox: React.ForwardRefRenderFunction<
iconStyle,
iconComponent,
iconImageStyle,
isChecked,
innerIconStyle,
text,
textComponent,
Expand All @@ -95,6 +37,7 @@ const BouncyCheckbox: React.ForwardRefRenderFunction<
ImageComponent = Image,
unFillColor = 'transparent',
disableText = false,
isChecked = undefined,
checkIconImageSource = require('./check.png'),
bounceEffectIn = AnimationValues.BounceIn,
bounceEffectOut = AnimationValues.BounceOut,
Expand All @@ -106,7 +49,7 @@ const BouncyCheckbox: React.ForwardRefRenderFunction<
...rest
} = props;

const [checked, setChecked] = useStateWIthCallback(isChecked || false);
const [checked, setChecked] = useStateWithCallback(isChecked || false);

const {bounceAnimation, syntheticBounceAnimation, bounceValue} =
useBounceAnimation();
Expand Down Expand Up @@ -136,16 +79,19 @@ const BouncyCheckbox: React.ForwardRefRenderFunction<
syntheticBounceAnimation,
]);

useImperativeHandle(ref, () => ({onCheckboxPress}), [onCheckboxPress]);

const handleLongPress = () => {
const onCheckboxLongPress = useCallback(() => {
if (!onLongPress) {
return;
}
setChecked(!checked, newCheckedValue => {
onLongPress && onLongPress(newCheckedValue);
});
};
}, [checked, onLongPress, setChecked]);

useImperativeHandle(ref, () => ({onCheckboxPress, onCheckboxLongPress}), [
onCheckboxPress,
onCheckboxLongPress,
]);

const renderCheckIcon = () => {
const scaleAnimation = {transform: [{scale: bounceValue}]};
Expand Down Expand Up @@ -193,7 +139,7 @@ const BouncyCheckbox: React.ForwardRefRenderFunction<
bounceAnimation(bounceEffectOut, bounceVelocityOut, bouncinessOut);
}}
onPress={onCheckboxPress}
onLongPress={handleLongPress}
onLongPress={onCheckboxLongPress}
{...rest}>
{renderCheckIcon()}
{renderCheckboxText()}
Expand Down
60 changes: 60 additions & 0 deletions example/lib/BouncyCheckbox.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {
ImageSourcePropType,
ImageStyle,
PressableProps,
StyleProp,
TextStyle,
ViewStyle,
} from 'react-native';
import React from 'react';

export const AnimationValues = {
BounceIn: 0.9,
BounceOut: 1,
VelocityIn: 0.1,
VelocityOut: 0.4,
BouncinessIn: 20,
BouncinessOut: 20,
};

export type BasePressableProps = Pick<
PressableProps,
Exclude<keyof PressableProps, 'onPress' | 'onLongPress'>
>;

export interface BouncyCheckboxProps extends BasePressableProps {
size?: number;
text?: string;
testID?: string;
fillColor?: string;
isChecked?: boolean;
unFillColor?: string;
disableText?: boolean;
bounceEffect?: number;
bounceFriction?: number;
useNativeDriver?: boolean;
bounceEffectIn?: number;
bounceEffectOut?: number;
bounceVelocityIn?: number;
bounceVelocityOut?: number;
bouncinessIn?: number;
bouncinessOut?: number;
ImageComponent?: any;
TouchableComponent?: any;
iconComponent?: React.ReactNode;
textComponent?: React.ReactNode;
iconStyle?: StyleProp<ViewStyle>;
innerIconStyle?: StyleProp<ViewStyle>;
style?: StyleProp<ViewStyle>;
textStyle?: StyleProp<TextStyle>;
iconImageStyle?: StyleProp<ImageStyle>;
textContainerStyle?: StyleProp<ViewStyle>;
checkIconImageSource?: ImageSourcePropType;
onPress?: (checked: boolean) => void;
onLongPress?: (checked: boolean) => void;
}

export interface BouncyCheckboxHandle {
onCheckboxPress: () => void;
onCheckboxLongPress: () => void;
}
File renamed without changes.
2 changes: 1 addition & 1 deletion example/lib/hooks/useBounceAnimation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {Animated} from 'react-native';
import {useState} from 'react';

const useBounceAnimation = () => {
const [bounceValue, setBounceValue] = useState(new Animated.Value(1));
const [bounceValue] = useState(new Animated.Value(1));

const bounceAnimation = (
value: number,
Expand Down
3 changes: 3 additions & 0 deletions example/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export {default} from './BouncyCheckbox';
export * from './BouncyCheckbox';
export * from './BouncyCheckbox.type';
6 changes: 6 additions & 0 deletions example/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"lint": "eslint . --ext .js,.jsx,.ts,.tsx"
},
"dependencies": {
"@freakycoder/react-native-bounceable": "^1.0.3",
"react": "18.1.0",
"react-native": "0.70.10",
"react-native-apple-header": "^1.0.1",
Expand Down
5 changes: 5 additions & 0 deletions example/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1193,6 +1193,11 @@
minimatch "^3.0.4"
strip-json-comments "^3.1.1"

"@freakycoder/react-native-bounceable@^1.0.3":
version "1.0.3"
resolved "https://registry.npmjs.org/@freakycoder/react-native-bounceable/-/react-native-bounceable-1.0.3.tgz"
integrity sha512-+iMq2tnqxCwFjitbPUz9nZ+VfJ8OU9waIlDJAAsoq1229QEwCmERCNy5zVtDsz75q3i4FLXX/n7fimdMzmP21A==

"@freakycoder/react-native-helpers@>= 2.1.0":
version "2.3.0"
resolved "https://registry.npmjs.org/@freakycoder/react-native-helpers/-/react-native-helpers-2.3.0.tgz"
Expand Down

0 comments on commit 97633e5

Please sign in to comment.