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

PropTypeDefaultDescription
lengthnumber6Number of code input cells (1-20)
valuestringundefinedControlled value
onChangeText(code: string) => voidundefinedCalled when code changes
onSubmit(code: string) => voidundefinedCalled when code is complete
onClear() => voidundefinedCalled when code is cleared
autoFocusbooleanfalseAuto focus on mount
disabledbooleanfalseDisable input
testIDstring'code-input'Test identifier

Styling Props

PropTypeDescription
cellStyleStyleProp<ViewStyle>Style for individual cells
filledCellStyleStyleProp<ViewStyle>Style for cells with values
focusCellStyleStyleProp<ViewStyle>Style for focused cell
textStyleStyleProp<TextStyle>Style for text inside cells
focusTextStyleStyleProp<TextStyle>Style for focused cell text
cellContainerStyleStyleProp<ViewStyle>Style for container holding all cells
cellWrapperStyleStyleProp<ViewStyle>Style for wrapper around each cell
focusCellWrapperStyleStyleProp<ViewStyle>Style for wrapper around focused cell

Placeholder Props

PropTypeDefaultDescription
placeholderstring''Placeholder text for empty cells
placeholderTextColorstringundefinedColor for placeholder text
placeholderAsDotbooleanfalseRender placeholder as dot
placeholderDotStyleStyleProp<ViewStyle>undefinedStyle for placeholder dot

Security Props

PropTypeDefaultDescription
secureTextEntrybooleanfalseHide entered values
secureViewStyleStyleProp<ViewStyle>undefinedStyle 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

  1. Use appropriate keyboard types - number-pad for numeric codes, default for alphanumeric
  2. Provide clear visual feedback - Use focusCellStyle to indicate active cell
  3. Handle errors gracefully - Clear input on invalid codes
  4. Consider accessibility - Test with screen readers
  5. Use controlled components for complex validation logic
  6. Provide loading states - Disable input during verification
  7. 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 autoFocus conflicts 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