Highlight the currently selected TextInput in React Native

76 Views Asked by At

I'd like to highlight the currently selected TextInput by changing the borderColor. I'm aware of the onFocus and onBlur properties, however, I can't figure out how to actually change the borderColor.

const MainScreen = () => {
   const [pelletWeight, setPelletWeight] = React.useState('');
   onFocus = () => {
        console.log("Text is focused")
    }
    
    onBlur = () => {
        console.log("Text is blurred")
    }
    return (
        <View style={styles.root}>
                            
            <TextInput 
            style = {styles.container}
            keyboardType='numeric'
            placeholder="Pellet weight (grains)"
            onChangeText={setPelletWeight}
            value={pelletWeight}
            
            onFocus={onFocus}
            onBlur={onBlur}
            />
    )
}

Any help would be much appreciated, thank you!

1

There are 1 best solutions below

3
PhantomSpooks On

First you need a piece of state to keep track of whether the input is focused or not. Lets called it isFocused. Use onBlur and onFocus to set its values. Now you create your focused textinput style. It will be added to the style only when isFocused is true:

 const [pelletWeight, setPelletWeight] = React.useState('');
  const [isFocused, setIsFocused] = React.useState(false);
  onFocus = () => {
    setIsFocused(true);
  };

  onBlur = () => {
    setIsFocused(false);
  };
  return (
    <View style={styles.root}>
      <Text style={[styles.baseText]}>Pellet Weight (grains)</Text>

      <TextInput
        style={[styles.container, isFocused && styles.focusedInput]}
        keyboardType="numeric"
        placeholder="Pellet weight (grains)"
        onChangeText={setPelletWeight}
        value={pelletWeight}
        onFocus={onFocus}
        onBlur={onBlur}
      />
    </View>
  );
}

Demo

Now if you wanted to take things a step further, instead of the border width, border color, and background color instantly changing, you could use react native reanimated to make the transition happen smoothly:

  const [pelletWeight, setPelletWeight] = React.useState('');
  const [isFocused, setIsFocused] = React.useState(false);
  const anim = useSharedValue(0);
  onFocus = () => {
    setIsFocused(true);
  };

  onBlur = () => {
    setIsFocused(false);
  };
  const animStyle = useAnimatedStyle(() => {
    return {
      borderWidth: anim.value,
      backgroundColor: interpolateColor(
        anim.value,
        [0, 1],
        ['transparent', 'lightblue']
      ),
      borderColor: interpolateColor(
        anim.value,
        [0, 1],
        ['transparent', 'blue']
      ),
    };
  });
  React.useEffect(() => {
    anim.value = withTiming(isFocused? 1 : 0)
  }, [isFocused,anim]);
  return (
    <View style={styles.root}>
      <Text style={[styles.baseText]}>Pellet Weight (grains)</Text>

      <AnimatedTextInput
        style={[styles.container, styles.focusedInput,animStyle]}
        keyboardType="numeric"
        placeholder="Pellet weight (grains)"
        onChangeText={setPelletWeight}
        value={pelletWeight}
        onFocus={onFocus}
        onBlur={onBlur}
      />
    </View>
  );

Demo