react-native: TextInput cursor not aligned in the centre when value is empty

When using TextInput with textAlign: center, the cursor is in the wrong position when the text is empty. It seems to be aligning with the placeholder. image

React Native version:

System:
    OS: macOS 10.15.2
    CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
    Memory: 185.86 MB / 16.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 12.13.0 - /usr/local/bin/node
    npm: 6.13.4 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    Android SDK:
      API Levels: 23, 25, 27, 28
      Build Tools: 26.0.2, 28.0.1, 28.0.3
      System Images: android-25 | Google Play Intel x86 Atom
  IDEs:
    Android Studio: 3.5 AI-191.8026.42.35.5791312
    Xcode: /undefined - /usr/bin/xcodebuild
  npmPackages:
    react: 16.9.0 => 16.9.0 
    react-native: 0.61.5 => 0.61.5 
  npmGlobalPackages:
    react-native: 0.61.5

Steps To Reproduce

<TextInput placeholder='NAME'  textAlign={'center'}/>

Expected Behaviour

The cursor should be in the middle of text input

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 37
  • Comments: 48 (4 by maintainers)

Most upvoted comments

Im using in the following way and it works:

<TextInput
  style={[
    {
      textAlign: 'center',
      flex: 1,
    },
  ]}
/>

i hope it helps

Still an issue in 0.64.2

Same in 0.63.2

Right, as someone that just hit this bug, just adding a wrapper that centers a TextInput with a dynamic width wasn’t good enough. The caret would still appear at the end of the smaller TextInput when the placeholder was showing, and this approach would also reduce the touchable area (horizontally) that the user can press to focus the TextInput.

I have managed to find a dodgy hackaround that will fix it (or rather make it appear to be fixed).

You do want the wrapper element around your TextInput styled like so:

<View
  style={{
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  }}
>
  {{your text input}}
</View>

Then for your TextInput, you want to change the width depending on whether there is a value or not, so as to trigger a redraw of the element, and a recalculation of the caret position:

<TextInput
  value={inputValue}
  style={{
    flex: 1,
    width: Boolean(inputValue) ? '100%' : '95%',
    textAlign: 'center',
  }}
/>

This will result in the behaviour appearing as you’d expect - the caret remains centered regardless of placeholder text, but the TextInput is still nice and wide to allow for touches at the edges.

Ohh… When will this be fixed ?

+1 Still an issue

As mentioned above, a workaround is:

multiline={true}
numberOfLines={1}

Still an issue

this issue still occurs

I have managed by this:

`<View style={styles.inputWrapper}> <TextInput value={value} onChangeText={val => setValue(val)} placeholder=“Input Placeholder” style={styles.input} /> </View>

// styling inputWrapper: { backgroundColor: colors.grey, width: ‘90%’, //depending on your style borderRadius: 30, marginVertical: 20, justifyContent: ‘center’, alignItems: ‘center’, }, input: { paddingHorizontal: 20, paddingVertical: 10, fontSize: scaleFont(16), } `

@ShivamJoker You either clone my branch

https://github.com/fabriziobertoglio1987/react-native/tree/fix-text-input-cursor-jump

and test it in the RNTester App Read the instructions here https://github.com/facebook/react-native/tree/master/RNTester

Or even better, if you also want to fix this issue in your React Native project. Clone my branch of react native https://github.com/fabriziobertoglio1987/react-native/tree/fix-text-input-cursor-jump

and install in your project that version of react native as explained in the instructions here https://github.com/facebook/react-native/wiki/Building-from-source

otherwise wait for the latest release and support me 😃 Thanks

this works fine you can also use number of line. For I wanted one line text so I used
numberOfLines={1} https://stackoverflow.com/a/67281614/12242668

I was getting this issue only on iOS (RN 0.63.4). For some reason the previous developer had the following: placeholder='email' placeholderColor='transparent' Removing both those lines (obviously didn’t need a placeholder) worked for me. Might be worth trying it without a placeholder to see if it still bugs out.

Thanks for the idea @mrjackwhitaker After commenting placeholder and placeholderTextColor props, the cursor is aligned to center correctly but the issue is there’s no placeholder exist anymore.

This is a workaround if you still need a placeholder with textAlign=‘center’

import {  InteractionManager } from react-native

const inputRef = React.createRef() 

const focusInputWithKeyboard = () => { //  this part is copied from Stackoverflow
    InteractionManager.runAfterInteractions(() => {
      inputRef.current.focus();
    });
  };

<View>
     <TextInput ref={inputRef} value={someValue}  textAlign={'center'}/>
     {!someValue ? 
        <View style={{
                 position: 'absolute',
                  top: 0,
                  bottom: 0,
                  left: 0,
                  right: 0,
                  justifyContent: 'center',
                  alignItems: 'center',
              }}>
             <Text onPress={focusInputWithKeyboard}>{'placeholder'}</Text>
          </View> 
    :  null}
</View>

Hope this help someone.

Still an issue in 0.63.4

+1, still a thing for now.

Same issue in 0.62.2

Thanks @fabriziobertoglio1987 I have tested your changes and it works perfect, hope they merge this soon

Seems to be an issue since 2016 with it being classified as desired behaviour https://github.com/facebook/react-native/issues/10030. Would really like it fixed so it matches with ios and normal web behaviour