From 7778f11ece02dab02bb8bd9eea2879e02ba66d5e Mon Sep 17 00:00:00 2001 From: Meksi Abdennour Date: Sat, 23 Sep 2023 21:52:18 +0100 Subject: [PATCH] add onAnimationEnd function --- README.md | 1 + .../xcschemes/SwitchExample.xcscheme | 9 ++- example/src/App.tsx | 16 +++++- package.json | 2 +- src/components/switch.tsx | 57 ++++++++++++------- src/types/index.d.ts | 1 + 6 files changed, 63 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index cea816b..131dc78 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,7 @@ const styles = StyleSheet.create({ | width | number | 100 | | value | boolean | false | | onValueChange | function | undefined | +| onAnimationEnd | function | undefined | | disabled | boolean | false | | activeText | string | ON | | inActiveText | string | OFF | diff --git a/example/ios/SwitchExample.xcodeproj/xcshareddata/xcschemes/SwitchExample.xcscheme b/example/ios/SwitchExample.xcodeproj/xcshareddata/xcschemes/SwitchExample.xcscheme index 982bc57..2a05e6b 100644 --- a/example/ios/SwitchExample.xcodeproj/xcshareddata/xcschemes/SwitchExample.xcscheme +++ b/example/ios/SwitchExample.xcodeproj/xcshareddata/xcschemes/SwitchExample.xcscheme @@ -1,7 +1,7 @@ + version = "1.7"> @@ -22,6 +22,13 @@ + + + @@ -34,7 +42,7 @@ export default function App() { switchBorderRadius={30} switchPaddingLeft={2} switchPaddingRight={2} - circleInActiveColor='#ff5454' + circleInActiveColor="#ff5454" switchStyle={{ paddingVertical: 4 }} /> @@ -76,6 +84,10 @@ export default function App() { /> } + onAnimationEnd={(_value) => { + setTheme(!_value ? 'dark' : 'light'); + console.log('theme is ', !_value ? 'dark' : 'light'); + }} /> diff --git a/package.json b/package.json index 508f566..1ae90b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@meksiabdou/react-native-switch", - "version": "1.0.6", + "version": "1.0.7", "description": "Customisable switch component for React Native", "main": "lib/commonjs/index", "module": "lib/module/index", diff --git a/src/components/switch.tsx b/src/components/switch.tsx index 497cf7b..69935c5 100644 --- a/src/components/switch.tsx +++ b/src/components/switch.tsx @@ -3,17 +3,22 @@ import { StyleSheet, TouchableWithoutFeedback, I18nManager, - View, } from 'react-native'; import Reanimated, { + AnimationCallback, useAnimatedStyle, useSharedValue, withSpring, + runOnJS, } from 'react-native-reanimated'; import type { SwitchProps } from '../types'; -const spring = (_value: any, config: any = { damping: 20, stiffness: 120 }) => - withSpring(_value, config); +const spring = ( + _value: any, + config: any = { damping: 20, stiffness: 120 }, + callback?: AnimationCallback +) => + withSpring(_value, config, callback); const PADDINGHORIZONTAL = 2; @@ -45,6 +50,7 @@ const Switch = (IProps: SwitchProps): JSX.Element => { switchStyle, circleChildrenActive, circleChildrenInActive, + onAnimationEnd, } = IProps; const { isRTL } = I18nManager; @@ -142,7 +148,6 @@ const Switch = (IProps: SwitchProps): JSX.Element => { (defaultCircleSize + (defaultPadding.paddingLeft + defaultPadding.paddingRight))); if (value) { - circleTranslateX.value = spring(size, { damping: 15, stiffness: 120 }); textTranslateXActive.value = spring(0); textTranslateXInActive.value = spring(factory * defaultWidth); if (circleActiveColor) { @@ -153,8 +158,17 @@ const Switch = (IProps: SwitchProps): JSX.Element => { } circleChildrenActiveOpacity.value = spring(1); circleChildrenInActiveOpacity.value = spring(0); + circleTranslateX.value = spring( + size, + { damping: 15, stiffness: 120 }, + (finished?: boolean) => { + 'worklet'; + if (finished && onAnimationEnd) { + runOnJS(onAnimationEnd)(true); + } + } + ); } else { - circleTranslateX.value = spring(0, { damping: 15, stiffness: 120 }); textTranslateXActive.value = spring(-(defaultWidth * factory)); textTranslateXInActive.value = spring(0); if (circleInActiveColor) { @@ -165,6 +179,16 @@ const Switch = (IProps: SwitchProps): JSX.Element => { } circleChildrenActiveOpacity.value = spring(0); circleChildrenInActiveOpacity.value = spring(1); + circleTranslateX.value = spring( + 0, + { damping: 15, stiffness: 120 }, + (finished?: boolean) => { + 'worklet'; + if (finished && onAnimationEnd) { + runOnJS(onAnimationEnd)(false); + } + } + ); } }, [value, defaultWidth, defaultCircleSize, defaultPadding, isRTL]); @@ -176,20 +200,14 @@ const Switch = (IProps: SwitchProps): JSX.Element => { } }, [disabled]); - const Button = (props: any) => { - if (typeof onValueChange === 'function' && !disabled) { - return ( - onValueChange(!value)} - /> - ); - } - return ; - }; - return ( - + ); }; @@ -285,6 +303,7 @@ Switch.defaultProps = { disabled: false, value: false, onValueChange: undefined, + onAnimationEnd: undefined, activeText: 'ON', inActiveText: 'OFF', backgroundActive: '#249c00', diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 840e48b..fb1b9c9 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -5,6 +5,7 @@ export interface SwitchProps { disabled?: boolean; value: boolean; onValueChange?: (value: boolean) => void; + onAnimationEnd?: (value?: boolean) => void; width?: number; activeText?: string; inActiveText?: string;