Skip to content

TextInput initial wrong padding/position for text content #4512

@rossparachute

Description

@rossparachute

Hey all,

react-native-paper is great, appreciate all the hard work.

This may not strictly be a bug as I can understand certain layout calculations maybe don't make sense inside a container with display: none.

Regardless, I've found a workaround that might save others some time.

Current behaviour

On initial render the TextInput contents lack the expected padding and positioning.

It affects both Android and iOS.

Expected behaviour

That there is a slight padding on the left/right and the text contents are vertically centre-aligned inside the TextInput.

How to reproduce?

The most reliable way to reproduce the "bug" is when the TextInput is placed inside a that initially has a display style prop set to "none" and then to "flex". The value prop of the TextInput is pre-populated with the value from a useState variable.

However, we have intermittently seen it occur when the inputs are just in a View or ScrollView with no special display prop styles. EDIT: Generally when this has occurred it's when the TextInput components aren't immediately visible on render, i.e - out of visible content of a scroll view but not always.

Changing the contents of the TextInput seems to get the expected padding/text positioning to kick in.

Educated guess is when in a container with display: none the UI layout code can't calculate the required padding etc.

The following snack reproduces the bug:
https://snack.expo.dev/@rossparachute/surprised-red-macaroni-and-cheese

Alternatively, the following code should also do the trick in the event the Snack goes down.

import { useState } from "react"
import { View, Text, TouchableOpacity, SafeAreaView, StyleSheet } from 'react-native'
import { TextInput } from "react-native-paper"

export default function App() {
  const [name, setName] = useState(`Foo`)
  const [isActive, setIsActive] = useState(false)

  const handlePressButton = (e) => {
    setIsActive(!isActive)
  }

  const handleChangeName = (newValue: string) => {
    setName(newValue)
  }

  return (
    <SafeAreaView style={styles.container}>
      <TouchableOpacity style={styles.buttonStyles} onPress={handlePressButton}>
        <Text style={styles.buttonText}>Show Input</Text>
      </TouchableOpacity>

      <View style={{
        display: isActive ? "flex" : "none", // (comment in to see bug)
        // height: isActive ? undefined : 0, // using this instead of display: "none" seems to sort it (comment out to see bug)
      }}>
        <TextInput 
            label="Name"
            value={name}
            onChangeText={handleChangeName}
            style={styles.inputStyles}
            contentStyle={styles.inputContentStyles}
            underlineStyle={styles.underlineStyle}
        />
      </View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  buttonStyles: {
    width: 120,
    height: 44,
    marginBottom: 44,
    alignItems: "center",
    justifyContent: "center",
    backgroundColor: "green",
    borderRadius: 12,
    overflow: "hidden"
  },
  buttonText: {
    fontWeight: 600,
    color: "#ffffff"
  },
  inputStyles: {
    fontSize: 14,
    backgroundColor: "#f4f4f3",
    borderRadius: 12,
    borderTopLeftRadius: 12,
    borderTopRightRadius: 12,
    overflow: "hidden",
  },
  inputContentStyles: {
    backgroundColor: "#ffffff",
  },
  inputUnderlineStyles: {
    height: 0,
    display: "none",
  }
});

package.json

{
  "dependencies": {
    "expo": "^49.0.15",
    "@expo/vector-icons": "^13.0.0",
    "react-native-paper": "^5.7.0",
    "react-native-safe-area-context": "4.6.3"
  }
}

Preview

In Production (Actual Behaviour)
image

In Production (Expected Behaviour, toggled after changing text)
image

Snack (Actual Behaviour)
image

Snack (Expected Behaviour)
image

What have you tried so far?

In production we upgraded to the latest react-native-paper release v5.12.5 to no avail.

Fix/Workaround

Slightly changing the implementation of the "accordion" to have a height of 0 rather than display: none renders the TextInput as expected.

Your Environment

software version
ios 15-18
android 12
react-native 0.72.10
react-native-paper 5.7.0
node 20.11.0
npm 10.2.4
expo sdk 49.0.15

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions