UNPKG

react-native-keypad-component

Version:
253 lines (193 loc) 8.69 kB
# react-native-keypad-component A customizable and animated keypad component for React Native applications, perfect for PIN entry, passcode screens, and secure input scenarios. Watch demo video here: [Demo Video](https://res.cloudinary.com/dwdsjbetu/image/upload/v1753799731/ScreenRecording2025-07-29at15.15.12-ezgif.com-video-to-gif-converter_1_pzx9iw.gif) ![Keypad Demo](https://res.cloudinary.com/dwdsjbetu/image/upload/v1753799731/ScreenRecording2025-07-29at15.15.12-ezgif.com-video-to-gif-converter_1_pzx9iw.gif) ## Features - ✨ Smooth animations with React Native Reanimated - 🎨 Customizable themes (light/dark) - 🔧 Highly configurable styling - 🎯 TypeScript support - 📏 Adjustable PIN length - 🚫 Built-in error handling with shake animation ## Installation ### npm ```sh npm install react-native-keypad-component ``` ### yarn ```sh yarn add react-native-keypad-component ``` ### bun ```sh bun add react-native-keypad-component ``` ### Expo ```sh npx expo install react-native-keypad-component ``` ### Peer Dependencies This package requires the following peer dependencies: ```sh yarn add react-native-reanimated yarn add react-native-gesture-handler ``` Make sure to follow the [React Native Reanimated installation guide](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started/) for proper setup. ### CLI Tool For quick scaffolding, you can also use the [React Native Keypad Component CLI](https://github.com/Elue-dev/rn-keypad-cli) to add the source code directly to your project. This makes it even easier than it already is to customize the component to fit your exact needs. ```sh npx rn-keypad-cli@latest ``` ## Basic Usage ```js import React from 'react'; import Keypad from 'react-native-keypad-component'; export default function App() { const handlePinEntered = (pin) => { console.log('PIN entered:', pin); // Handle PIN validation here }; return <Keypad onPinEntered={handlePinEntered} pinLength={4} />; } ``` ## Advanced Usage ```js import React, { useState } from 'react'; import { View, Text } from 'react-native'; import Keypad from 'react-native-keypad-component'; export default function SecureScreen() { const [hasError, setHasError] = useState(false); const handlePinEntered = (pin) => { // your PIN validation logic here if (pin === '1234') { setHasError(false); // Navigate to secure area } else { setHasError(true); setTimeout(() => setHasError(false), 3000); } }; const renderFaceIdIcon = () => <Text style={{ fontSize: 24 }}>👆</Text>; const renderErrorMessage = () => ( <Text style={{ color: 'red', marginBottom: 10 }}> Incorrect PIN. Please try again. </Text> ); return ( <View style={{ flex: 1, justifyContent: 'center', padding: 20 }}> <Keypad onPinEntered={handlePinEntered} onPinErrored={hasError} errorMessageComponent={renderErrorMessage} pinLength={6} theme="dark" usesFaceId={true} renderFaceIdIcon={renderFaceIdIcon} keypadRadius={12} gridGap={15} dotColor="#007AFF" keypadColor="#2C2C2E" textColor="#FFFFFF" /> </View> ); } ``` ## Props | Prop | Type | Required | Default | Description | | ------------------------------- | ----------------------- | -------- | ----------- | --------------------------------------------------- | | `onPinEntered` | `(pin: string) => void` | ✅ | - | Callback function called when PIN entry is complete | | `onPinErrored` | `boolean` | ❌ | `false` | Triggers error state and shake animation | | `errorMessageComponent` | `() => ReactNode` | ❌ | `undefined` | Custom component to display error messages | | `pinLength` | `number` | ❌ | `4` | Number of digits in the PIN | | `style` | `ViewStyle` | ❌ | `undefined` | Custom styles for the main container | | `buttonStyle` | `ViewStyle` | ❌ | `undefined` | Custom styles for keypad buttons | | `buttonTextStyle` | `TextStyle` | ❌ | `undefined` | Custom styles for button text | | `keypadTextSize` | `number` | ❌ | `24` | Font size for keypad button text | | `disableKeypadBackground` | `boolean` | ❌ | `false` | Removes background color from buttons | | `usesFaceId` | `boolean` | ❌ | `false` | Enables Face ID/Touch ID button | | `keypadRadius` | `number` | ❌ | `30` | Border radius for kaypad buttons and dots | | `theme` | `'light' \| 'dark'` | ❌ | `'light'` | Overall theme of the keypad | | `keypadColor` | `string` | ❌ | `'#f2f2f7'` | Button background color | | `textColor` | `string` | ❌ | `'#000000'` | Text color of keypad | | `dotColor` | `string` | ❌ | `'#000000'` | Filled dot color | | `emptyDotColor` | `string` | ❌ | `'#d1d1d6'` | Empty dot color | | `dotWidth` | `number` | ❌ | `16` | Width of PIN dot | | `dotHeight` | `number` | ❌ | `16` | Height of PIN dot | | `gridGap` | `number` | ❌ | `10` | Gap between keypad buttons | | `renderFaceIdIcon` | `() => ReactNode` | ❌ | `undefined` | Custom Face ID/Touch ID icon component | | `applyBackgroundToFaceIdButton` | `boolean` | ❌ | `true` | Applies button background to Face ID button | ## Theming The keypad supports both light and dark themes out of the box. You can customize colors for each theme: ## Animations The keypad includes several built-in animations: - **Dot Animation**: Dots scale when PIN digits are entered/removed - **Shake Animation**: Triggered when `onPinErrored` is true - **Error Message**: Smooth zoom in/out transitions - **Layout Transitions**: Smooth transitions when error messages appear/disappear ## Error Handling To display errors and trigger the shake animation: ```js const [hasError, setHasError] = useState(false); const handlePinEntered = (pin) => { if (isValidPin(pin)) { setHasError(false); // Handle success } else { setHasError(true); // Clear error after some time setTimeout(() => setHasError(false), 3000); } }; <Keypad onPinEntered={handlePinEntered} onPinErrored={hasError} errorMessageComponent={() => ( <Text style={{ color: 'red' }}>Invalid PIN</Text> )} />; ``` ## Biometric Authentication Enable Face ID or Touch ID button: ```js const renderFaceIdIcon = () => ( <Icon name="face-id" size={24} color="#007AFF" /> ); <Keypad usesFaceId={true} renderFaceIdIcon={renderFaceIdIcon} applyBackgroundToFaceIdButton={true} onPinEntered={handlePinEntered} />; ``` ## Customization Examples ### Minimal Keypad ```js <Keypad onPinEntered={handlePin} disableKeypadBackground={true} pinLength={6} emptyDotColor="transparent" style={{ backgroundColor: 'transparent' }} /> ``` ### Colorful Keypad ```js // Example usage with dark mode support import { useTheme } from 'your-theme-provider'; // Replace with your theme hook const isDarkMode = useTheme(); <Keypad onPinEntered={handlePin} theme={isDarkMode ? 'dark' : 'light'} keypadColor={isDarkMode ? '#FF6B6B' : '#FDD835'} textColor={isDarkMode ? '#FFFFFF' : '#000000'} activeDotColor={isDarkMode ? '#4ECDC4' : '#1976D2'} emptyDotColor={isDarkMode ? '#95A5A6' : '#BDBDBD'} keypadRadius={20} gridGap={20} />; ``` ## Contributing See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow. ## License MIT