React Native Swipe Button Component
npm install rn-swipe-button --save
import SwipeButton from 'rn-swipe-button';
const renderSwipeButton = () => (<SwipeButton />)
Component properties
containerStyles: PropTypes.object,
containerPadding: PropTypes.number,
disable: PropTypes.bool,
disableResetOnTap: PropTypes.bool,
disabledRailBackgroundColor: PropTypes.string,
disabledThumbIconBackgroundColor: PropTypes.string,
disabledThumbIconBorderColor: PropTypes.string,
enableReverseSwipe: PropTypes.bool,
forceReset: PropTypes.func, // RNSwipeButton will call this function by passing a "reset" function as argument. Calling "reset" will reset the swipe thumb.
height: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]),
onSwipeFail: PropTypes.func,
onSwipeStart: PropTypes.func,
onSwipeSuccess: PropTypes.func,
railBackgroundColor: PropTypes.string,
railBorderColor: PropTypes.string,
railBorderWidth: PropTypes.number,
railFillBackgroundColor: PropTypes.string,
railFillBorderColor: PropTypes.string,
railFillBorderWidth: PropTypes.number,
railStyles: PropTypes.object,
resetAfterSuccessAnimDelay: PropTypes.number, // This is delay before resetting the button after successful swipe When shouldResetAfterSuccess = true
resetAfterSuccessAnimDuration: PropTypes.number,
shouldResetAfterSuccess: PropTypes.bool, // If set to true, buttun resets automatically after swipe success with default delay of 1000ms
swipeSuccessThreshold: PropTypes.number, // Ex: 70. Swipping 70% will be considered as successful swipe
thumbIconBackgroundColor: PropTypes.string,
thumbIconBorderColor: PropTypes.string,
thumbIconBorderWidth: PropTypes.number,
thumbIconComponent: PropTypes.oneOfType([
PropTypes.element,
PropTypes.node,
PropTypes.func,
]), Pass any react component to replace swipable thumb icon
thumbIconImageSource: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]),
thumbIconStyles: PropTypes.object,
thumbIconWidth: PropTypes.number,
title: PropTypes.oneOfType([
PropTypes.node,
PropTypes.string,
]),
titleColor: PropTypes.string,
titleFontSize: PropTypes.number,
titleMaxFontScale: PropTypes.number, // Ex: 2. will limit font size increasing to 200% when user increases font size in device properties
titleStyles: PropTypes.object,
titleMargin: PropTypes.number,
RightEndTemplate: PropTypes.node,
LeftEndTemplate: PropTypes.node,
width: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]),
Code for above screenshots
import React, {useState} from 'react';
import {SafeAreaView, View, Text, StatusBar, Button} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import thumbIcon from './assets/thumbIcon.png';
import arrowRight from './assets/arrow-right.png';
import styles from './styles';
import SwipeButton from 'rn-swipe-button';
const App: () => React$Node = () => {
const [disableCBButton, setDisableCBButton] = useState(false)
const defaultStatusMessage = 'swipe status appears here';
const [swipeStatusMessage, setSwipeStatusMessage] = useState(
defaultStatusMessage,
);
setInterval(() => setSwipeStatusMessage(defaultStatusMessage), 5000);
const updateSwipeStatusMessage = (message) => setSwipeStatusMessage(message);
const renderSubHeading = (heading) => (
<Text style={styles.subHeading}>{heading}</Text>
);
let forceResetLastButton = null;
const CheckoutButton = () => {
return(
<View style={{width: 100, height: 30, backgroundColor: '#C70039', borderRadius: 5, justifyContent: 'center', alignItems: 'center'}}>
<Text style={{color: '#ffffff'}}>Checkout</Text>
</View>
);
}
return (
<>
<StatusBar barStyle="dark-content" />
<SafeAreaView>
<View style={styles.container}>
<Text style={styles.title}>React Native Swipe Button</Text>
<Text style={styles.swipeStatus}>{swipeStatusMessage}</Text>
{renderSubHeading('Disabled')}
<SwipeButton thumbIconImageSource={arrowRight} disabled />
{renderSubHeading('Swipe status callbacks')}
<SwipeButton
containerStyles={{borderRadius: 5}}
height={30}
onSwipeFail={() => updateSwipeStatusMessage('Incomplete swipe!')}
onSwipeStart={() => updateSwipeStatusMessage('Swipe started!')}
onSwipeSuccess={() =>
updateSwipeStatusMessage('Submitted successfully!')
}
railBackgroundColor="#31a57c"
railStyles={{borderRadius: 5}}
thumbIconComponent={CheckoutButton}
thumbIconImageSource={arrowRight}
thumbIconStyles={{borderRadius: 5}}
thumbIconWidth={100}
title="Submit order"
/>
{renderSubHeading('Reverse swipe enabled')}
<SwipeButton
enableReverseSwipe
onSwipeSuccess={() => updateSwipeStatusMessage('Slide success!')}
railBackgroundColor="#a493d6"
thumbIconBackgroundColor="#FFFFFF"
title="Slide to unlock"
/>
{renderSubHeading('Set a component as thumb icon & use forceReset')}
<SwipeButton
disableResetOnTap
forceReset={ reset => {
forceResetLastButton = reset
}}
railBackgroundColor="#9fc7e8"
railStyles={{
backgroundColor: '#44000088',
borderColor: '#880000FF',
}}
thumbIconBackgroundColor="#FFFFFF"
title="Slide to unlock"
/>
<View style={{ alignItems: 'center', marginBottom: 5 }}>
<Button onPress={() => forceResetLastButton && forceResetLastButton()} title="Force reset" />
</View>
{renderSubHeading('Set .png image as thumb icon')}
<SwipeButton thumbIconImageSource={thumbIcon} railBackgroundColor="#cfb0dd"/>
{renderSubHeading('Set height & reset after successful swipe')}
<SwipeButton height={25} shouldResetAfterSuccess={true} resetAfterSuccessAnimDelay={1000} />
{renderSubHeading('Set height and width')}
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<SwipeButton height={35} width={200} title="Swipe" disabled={disableCBButton} />
<View style={{ marginLeft: 15, width: 150, height: 32 }}><Button onPress={() => setDisableCBButton(!disableCBButton)} title="Toggle disable" /></View>
</View>
</View>
</SafeAreaView>
</>
);
};
Note
- In accessibility mode this component works like a regular button (double tap to activate)
- We are supporting RTL out of the box. For RTL layouts, swipe button works by default as right to left swipe.
Tech Stack
- Node
- Yarn
- JavaScript
- TypeScript
- ReactNative
Running example app
git clone https://github.com/UdaySravanK/RNSwipeButton.git
cd RNSwipeButton/examples/RNSwipeButtonDemo
yarn
To run on an android emulator
yarn android
Make sure of
- Android Studio is configured
- Global paths set correctly for Android SDK i.e ANDROID_HOME, tools, platform-tools
- Java8 is installed
- At least one emulator is ready
To run on an ios simulator
yarn ios
Make sure of
- xcode is configured
- cocoapods installed
- If seeing issues then run
pod deintegrate & pod install
- If seeing issues with fonts
- Open ios workspace project in xcode
- Select RNSwipeButtonDemo
- Go to Build phases
- Open 'Copy Bundle Resources' and delete all .ttf files