0

I’m building an OTP input component in React Native with four TextInput boxes, but I’m facing an issue where the cursor is not centered inside the box. Instead, it’s aligned to the right side of the box.

Here’s the relevant code I’m using:

<View style={styles.otpContainer}>
  {[...new Array(4)].map((_, index) => (
    <TextInput
      ref={ref => { inputs.current[index] = ref; }}
      style={[styles.otpInput, focusedIndex === index && { borderColor: tertiary }, emptyOtp && { borderColor: '#D00000' }, invalidOtp && { borderColor: '#D00000' }]}
      key={index}
      keyboardType="number-pad"
      maxLength={1}
      selectTextOnFocus
      contextMenuHidden
      testID={`OTPInput-${index}`}
      onChangeText={text => handleChangeText(text, index)}
      onKeyPress={e => handleKeyPress(e, index)}
      placeholder={focusedIndex !== index ? '•' : ''}
      onFocus={() => setFocusedIndex(index)} 
      onBlur={() => setFocusedIndex(-1)} 
    />
  ))}
</View>
otpContainer: {
  flexDirection: 'row',
  alignItems: 'center',
  justifyContent: 'center',
  gap: 8,
  marginTop: 40,
  textAlign: 'center',
},
otpInput: {
  borderWidth: 1,
  borderColor: '#ccc',
  borderRadius: 8,
  paddingHorizontal: 16,
  textAlign: 'center',
  fontSize: 24,
  color: '#000',
  lineHeight: 55,
  width: 55,
  height: 55,
}

The TextInput cursor seems to be slightly off-center, leaning towards the right side. I’ve already ensured that the textAlign: 'center' is set, but it still doesn’t work as expected.

Things I’ve tried:

  • Removing padding and adjusting lineHeight.
  • Ensuring width and height are consistent with fontSize.
  • Adjusting textAlign properties.

Has anyone faced this issue before or have any suggestions for fixing the cursor alignment?

2
  • "slightly off-center, leaning towards the right side" - when you already applied texta-align: center, this most likely means the value of the input field isn't actually empty, but probably a space character ...?
    – C3roe
    Commented yesterday
  • when I remove textAlign: 'center', it aligns to the left instead of the center. How can I fix this and keep the cursor centered?
    – Arijit das
    Commented yesterday

2 Answers 2

1

The paddingHorizontal property in your otpInput style may be causing the cursor to shift. React Native TextInput cursor alignment can also be influenced by fontSize, lineHeight, and any additional padding or margins. Try this:

otpInput: {
  borderWidth: 1,
  borderColor: '#ccc',
  borderRadius: 8,
  textAlign: 'center',
  textAlignVertical: 'center', // Ensure vertical centering
  fontSize: 24,
  color: '#000',
  width: 55,
  height: 55,
  lineHeight: 55, // Match height
  padding: 0, // Avoid conflicting padding
},

1
  • i tried ,it's not centrerd yet
    – Arijit das
    Commented yesterday
0

You can try this code.

import { Text, SafeAreaView, StyleSheet, View, TextInput } from 'react-native';
import React, { useState, useRef } from 'react';

export default function App() {
  const [focusedIndex, setFocusedIndex] = useState(-1);
  const inputs = useRef([]);

  const handleChangeText = (text, index) => {
    if (text && index < 3) {
      inputs.current[index + 1]?.focus();
    }
  };

  const handleKeyPress = (e, index) => {
    if (e.nativeEvent.key === 'Backspace' && index > 0) {
      inputs.current[index - 1]?.focus();
    }
  };

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.otpContainer}>
        {[...new Array(4)].map((_, index) => (
          <TextInput
            ref={(ref) => { inputs.current[index] = ref; }}
            style={[styles.otpInput, focusedIndex === index && { borderColor: 'blue' }]}
            key={index}
            keyboardType="number-pad"
            maxLength={1}
            selectTextOnFocus
            testID={`OTPInput-${index}`}
            onChangeText={(text) => handleChangeText(text, index)}
            onKeyPress={(e) => handleKeyPress(e, index)}
            placeholder={focusedIndex !== index ? '•' : ''}
            onFocus={() => setFocusedIndex(index)}
            onBlur={() => setFocusedIndex(-1)}
          />
        ))}
      </View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: '#ecf0f1',
  },
  otpContainer: {
    flexDirection: 'row',
    justifyContent: 'center',
    textAlign: 'center',
    marginRight: 8,
  },
  otpInput: {
    borderWidth: 1,
    borderColor: '#ccc',
    borderRadius: 8,
    textAlign: 'center',
    fontSize: 24,
    color: '#000',
    width: 56,
    height: 55,
  },
});

New contributor
Anupam Singh Kushwaha is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.