CodeInput Component
A highly customizable and accessible code input component for React Native, perfect for OTP (One-Time Password), PIN, and verification code inputs.
Features
- 🎯 Flexible Length - Support for 1-20 digit codes
- 🎨 Highly Customizable - Extensive styling options for every element
- ♿ Accessible - Full screen reader support and ARIA labels
- 🎮 Controlled/Uncontrolled - Works with both patterns
- 🔒 Secure Input - Built-in secure text entry mode
- 📱 Mobile Optimized - Proper keyboard handling and auto-focus
- 🎪 Multiple Placeholders - Text, dots, or custom placeholders
- 🎯 TypeScript Ready - Full type safety and IntelliSense support
Installation
💻Bash
npm install rn-base-component
# or
yarn add rn-base-component
Basic Usage
⚛️TSX
import React from 'react'
import { CodeInput } from 'rn-base-component'
export default function App() {
return (
console.log('Code entered:', code)}
autoFocus
/>
)
}
Advanced Usage
Controlled Component
⚛️TSX
import React, { useState } from 'react'
import { CodeInput } from 'rn-base-component'
export default function ControlledExample() {
const [code, setCode] = useState('')
const [loading, setLoading] = useState(false)
const handleSubmit = async (enteredCode: string) => {
setLoading(true)
try {
await verifyCode(enteredCode)
} catch (error) {
setCode('') // Clear on error
} finally {
setLoading(false)
}
}
return (
)
}
With Ref Control
⚛️TSX
import React, { useRef } from 'react'
import { CodeInput, CodeInputRef } from 'rn-base-component'
export default function RefExample() {
const codeInputRef = useRef(null)
const handleClear = () => {
codeInputRef.current?.clear()
codeInputRef.current?.focus()
}
return (
<>
{
if (code !== '1234') {
codeInputRef.current?.clear()
}
}}
/>
>
)
}
Styling Examples
Custom Cell Styling
⚛️TSX
const styles = StyleSheet.create({
cell: {
borderWidth: 2,
borderColor: '#e0e0e0',
borderRadius: 8,
backgroundColor: '#f9f9f9',
},
filledCell: {
borderColor: '#007AFF',
backgroundColor: '#ffffff',
},
focusCell: {
borderColor: '#007AFF',
borderWidth: 2,
backgroundColor: '#ffffff',
shadowColor: '#007AFF',
shadowOffset: { width: 0, height: 0 },
shadowOpacity: 0.3,
shadowRadius: 4,
elevation: 4,
},
cellText: {
fontSize: 20,
fontWeight: 'bold',
color: '#333',
},
})
Dot Placeholder Style
⚛️TSX
const styles = StyleSheet.create({
placeholderDot: {
width: 8,
height: 8,
backgroundColor: '#ccc',
borderRadius: 4,
},
secureView: {
width: 12,
height: 12,
backgroundColor: '#333',
borderRadius: 6,
},
})
API Reference
Core Props
| Prop | Type | Default | Description |
|---|---|---|---|
length | number | 6 | Number of code input cells (1-20) |
value | string | undefined | Controlled value |
onChangeText | (code: string) => void | undefined | Called when code changes |
onSubmit | (code: string) => void | undefined | Called when code is complete |
onClear | () => void | undefined | Called when code is cleared |
autoFocus | boolean | false | Auto focus on mount |
disabled | boolean | false | Disable input |
testID | string | 'code-input' | Test identifier |
Styling Props
| Prop | Type | Description |
|---|---|---|
cellStyle | StyleProp<ViewStyle> | Style for individual cells |
filledCellStyle | StyleProp<ViewStyle> | Style for cells with values |
focusCellStyle | StyleProp<ViewStyle> | Style for focused cell |
textStyle | StyleProp<TextStyle> | Style for text inside cells |
focusTextStyle | StyleProp<TextStyle> | Style for focused cell text |
cellContainerStyle | StyleProp<ViewStyle> | Style for container holding all cells |
cellWrapperStyle | StyleProp<ViewStyle> | Style for wrapper around each cell |
focusCellWrapperStyle | StyleProp<ViewStyle> | Style for wrapper around focused cell |
Placeholder Props
| Prop | Type | Default | Description |
|---|---|---|---|
placeholder | string | '' | Placeholder text for empty cells |
placeholderTextColor | string | undefined | Color for placeholder text |
placeholderAsDot | boolean | false | Render placeholder as dot |
placeholderDotStyle | StyleProp<ViewStyle> | undefined | Style for placeholder dot |
Security Props
| Prop | Type | Default | Description |
|---|---|---|---|
secureTextEntry | boolean | false | Hide entered values |
secureViewStyle | StyleProp<ViewStyle> | undefined | Style for secure dots |
Ref Methods
⚛️TSX
interface CodeInputRef {
focus: () => void // Focus the input
blur: () => void // Blur the input
clear: () => void // Clear the code
getValue: () => string // Get current value
setValue: (value: string) => void // Set value programmatically
}
Common Use Cases
OTP Verification
⚛️TSX
const styles = StyleSheet.create({
otpCell: {
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 8,
},
otpFocusCell: {
borderColor: '#007AFF',
},
})
PIN Entry
⚛️TSX
const styles = StyleSheet.create({
pinCell: {
backgroundColor: '#f0f0f0',
borderRadius: 12,
borderWidth: 0,
},
})
Verification Code
⚛️TSX
const styles = StyleSheet.create({
verificationCell: {
borderBottomWidth: 2,
borderBottomColor: '#ddd',
borderRadius: 0,
backgroundColor: 'transparent',
},
verificationFocusCell: {
borderBottomColor: '#007AFF',
},
})
Accessibility
The component is fully accessible with:
- Screen reader support with descriptive labels
- Proper ARIA attributes for each cell
- Keyboard navigation support
- Focus management with clear focus indicators
- Status announcements for completion state
Accessibility Labels
- Input: "Code input with X digits"
- Cells: "Code input cell X of Y, contains Z" or "empty"
- Container: "Code input cells, X of Y filled"
Best Practices
- Use appropriate keyboard types -
number-padfor numeric codes,defaultfor alphanumeric - Provide clear visual feedback - Use
focusCellStyleto indicate active cell - Handle errors gracefully - Clear input on invalid codes
- Consider accessibility - Test with screen readers
- Use controlled components for complex validation logic
- Provide loading states - Disable input during verification
- Auto-focus appropriately - Only when it makes sense in your UX flow
Security Note
For sensitive data like PINs, always use secureTextEntry={true} to hide the entered values from screen recordings and shoulder surfing.
Troubleshooting
Common Issues
Input not focusing on cell press
- Ensure the component is not disabled
- Check if
autoFocusconflicts with your navigation
Styling not applying
- Verify you're using the correct style prop for the element
- Check theme integration if using styled-components
Accessibility issues
- Test with screen readers enabled
- Ensure proper labeling for your use case
Performance with many cells
- Consider using fewer cells (max 20 supported)
- Optimize custom render functions