react-native tTextInput start in capitalisation but can be turned off

146 Views Asked by At

I want to create a TextInput that starts with capitalisation on but then if its turned off by the user it stays off.

the autoCapitilisation prop offers 'characters' but then it keeps going on again after each new character even if the user has turned it off, if I choose 'words' then it automatically leave capitalisation after the first character :(

1

There are 1 best solutions below

0
On

You could switch the autoCapitalization prop based on the events of the keyboard, the correct way would be to listen for the Shift key, but it seems that key is not supported in the onKeyPress listener. So in this solution, I check if the character entered is in the lowercase letters range and then switch the autoCapitalization to none and set it to characters whenever the keyboard is shown.

import React from "react";
import { SafeAreaView, StyleSheet, TextInput, Keyboard } from "react-native";

const AutoCapitalizeTextInput = () => {
  const [text, onChangeText] = React.useState("Useless Text");
  const [autoCapitalize, setAutoCapitalize] = React.useState("characters");
  const onKeyPress = (event) => {
    const key = event.nativeEvent.key;
    if(/[a-z]/.test(key) && key.length === 1) {
      setAutoCapitalize("sentences");
    }
  }

  const _keyboardDidShow = () => setAutoCapitalize("characters");

  React.useEffect(() => {
    Keyboard.addListener("keyboardDidShow", _keyboardDidShow);

    // cleanup function
    return () => {
      Keyboard.removeListener("keyboardDidShow", _keyboardDidShow);
    };
  }, []);

  return (
    <SafeAreaView>
      <TextInput
        onKeyPress={onKeyPress}
        style={styles.input}
        onChangeText={onChangeText}
        value={text}
        autoCapitalize={autoCapitalize}
      />
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  ...
});

export default AutoCapitalizeTextInput;

https://snack.expo.io/@diedu89/textinput-autocapitalize

Note: I tested this on an android device, and it worked. It doesn't work in the iOS emulator on snack.expo, not sure if it is because of the emulator or a react-native bug.