Animated Code Verification/ Authentication 2

Published in UI
September 12, 2022
1 min read
Animated Code Verification/ Authentication 2

Introduction

An UI module for user-side pincode verification.

Component features:

  • 🔮 Simple and tiny 1.55 KB. Easy to use;

  • 🚮 Clearing part of the code by clicking on the cell;

  • 🍎 Support “fast paste SMS-code” on iOS. And custom code paste for Android;

  • ⚡ TextInput ref support;

  • 🛠 Highly customizable. Can be used as masked TextInput;

  • 🤓 Readable

    Props

    NameTypeDescriptionDefault
    descriptionTextStringA description textPlease enter pincode for entry
    spaceColorColorColor of line under digit#FF0000
    closeButtonColorColorColor of X - close button#FF0000
    onEnteredPincodeFunctionA function that returns entered code-
    onCloseViewFunctionOn press close button, will be useful to close view-
    onPressTouchIdFunctionTouch Id is not available, but you can make it by yourself-
    withTouchIdBooleanIf you do not neet touch id, you can set it to falseTRUE

Installation

npm i react-native-code-verification --save --force

Example

import {Animated, Image, SafeAreaView, Text, View} from 'react-native';
import React, {useState} from 'react';
import {
CodeField,
Cursor,
useBlurOnFulfill,
useClearByFocusCell,
} from 'react-native-confirmation-code-field';
import styles, {
ACTIVE_CELL_BG_COLOR,
CELL_BORDER_RADIUS,
CELL_SIZE,
DEFAULT_CELL_BG_COLOR,
NOT_EMPTY_CELL_BG_COLOR,
} from './styles';
const {Value, Text: AnimatedText} = Animated;
const CELL_COUNT = 4;
const source = {
uri:
'https://user-images.githubusercontent.com/4661784/56352614-4631a680-61d8-11e9-880d-86ecb053413d.png',
};
const animationsColor = [...new Array(CELL_COUNT)].map(() => new Value(0));
const animationsScale = [...new Array(CELL_COUNT)].map(() => new Value(1));
const animateCell = ({hasValue, index, isFocused}) => {
Animated.parallel([
Animated.timing(animationsColor[index], {
useNativeDriver: false,
toValue: isFocused ? 1 : 0,
duration: 250,
}),
Animated.spring(animationsScale[index], {
useNativeDriver: false,
toValue: hasValue ? 0 : 1,
duration: hasValue ? 300 : 250,
}),
]).start();
};
const AnimatedExample = () => {
const [value, setValue] = useState('');
const ref = useBlurOnFulfill({value, cellCount: CELL_COUNT});
const [props, getCellOnLayoutHandler] = useClearByFocusCell({
value,
setValue,
});
const renderCell = ({index, symbol, isFocused}) => {
const hasValue = Boolean(symbol);
const animatedCellStyle = {
backgroundColor: hasValue
? animationsScale[index].interpolate({
inputRange: [0, 1],
outputRange: [NOT_EMPTY_CELL_BG_COLOR, ACTIVE_CELL_BG_COLOR],
})
: animationsColor[index].interpolate({
inputRange: [0, 1],
outputRange: [DEFAULT_CELL_BG_COLOR, ACTIVE_CELL_BG_COLOR],
}),
borderRadius: animationsScale[index].interpolate({
inputRange: [0, 1],
outputRange: [CELL_SIZE, CELL_BORDER_RADIUS],
}),
transform: [
{
scale: animationsScale[index].interpolate({
inputRange: [0, 1],
outputRange: [0.2, 1],
}),
},
],
};
// Run animation on next event loop tik
// Because we need first return new style prop and then animate this value
setTimeout(() => {
animateCell({hasValue, index, isFocused});
}, 0);
return (
<AnimatedText
key={index}
style={[styles.cell, animatedCellStyle]}
onLayout={getCellOnLayoutHandler(index)}>
{symbol || (isFocused ? <Cursor /> : null)}
</AnimatedText>
);
};
return (
<SafeAreaView style={styles.root}>
<Text style={styles.title}>Verification</Text>
<Image style={styles.icon} source={source} />
<Text style={styles.subTitle}>
Please enter the verification code{'\n'}
we send to your email address
</Text>
<CodeField
ref={ref}
{...props}
value={value}
onChangeText={setValue}
cellCount={CELL_COUNT}
rootStyle={styles.codeFiledRoot}
keyboardType="number-pad"
textContentType="oneTimeCode"
renderCell={renderCell}
/>
<View style={styles.nextButton}>
<Text style={styles.nextButtonText}>Verify</Text>
</View>
</SafeAreaView>
);
};
export default AnimatedExample;

Tutorial

Coming Soon…

Style File(styles.js)

import {StyleSheet, Platform} from 'react-native';
export const CELL_SIZE = 55;
export const CELL_BORDER_RADIUS = 8;
export const DEFAULT_CELL_BG_COLOR = '#fff';
export const NOT_EMPTY_CELL_BG_COLOR = '#3557b7';
export const ACTIVE_CELL_BG_COLOR = '#f7fafe';
const styles = StyleSheet.create({
codeFiledRoot: {
height: CELL_SIZE,
marginTop: 30,
paddingHorizontal: 20,
justifyContent: 'center',
},
cell: {
marginHorizontal: 8,
height: CELL_SIZE,
width: CELL_SIZE,
lineHeight: CELL_SIZE - 5,
fontSize: 30,
textAlign: 'center',
borderRadius: CELL_BORDER_RADIUS,
color: '#3759b8',
backgroundColor: '#fff',
// IOS
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 1,
},
shadowOpacity: 0.22,
shadowRadius: 2.22,
// Android
elevation: 3,
},
// =======================
root: {
minHeight: 800,
padding: 20,
},
title: {
paddingTop: 50,
color: '#000',
fontSize: 25,
fontWeight: '700',
textAlign: 'center',
paddingBottom: 40,
},
icon: {
width: 217 / 2.4,
height: 158 / 2.4,
marginLeft: 'auto',
marginRight: 'auto',
},
subTitle: {
paddingTop: 30,
color: '#000',
textAlign: 'center',
},
nextButton: {
marginTop: 30,
borderRadius: 60,
height: 60,
backgroundColor: '#3557b7',
justifyContent: 'center',
minWidth: 300,
marginBottom: 100,
},
nextButtonText: {
textAlign: 'center',
fontSize: 20,
color: '#fff',
fontWeight: '700',
},
});
export default styles;

Share


Awesome React Native
© 2026, All Rights Reserved.

Social Media