Focus lost event on View

Is there any event that tells me if the focus has been lost? There is an event on TextInput and screens of drawer, but I need an event for something more basic like View. I see others working around by wrapping the View in a TouchableWithoutFeedback, but this workaround does only work in simple cases. I am creating a form with a date input and a calendar date picker that appears if a button is pressed and the calendar should disappear if the user clicks anywhere else. My form is fairly big and I don’t want to split it up into many small sub-form-steps in the browser (as a workaround to make the workaround with TouchableWithoutFeedback work) because I find it very annoying as a user if there is only one button and one input field on the whole PC screen.

I found the solution by looking at the source code of TimePicker from "react-time-picker".

The concept is to register event listeners on the document.

import * as React from 'react';
import { Text, View, Button } from 'react-native';

export default function App() {
  const [overlayVisible, setOverlayVisible] = React.useState(true);
  const refOverlay = React.useRef<View>(null);
  (['focusin', 'mousedown', 'touchstart'] as const).forEach((value) => {
    document.addEventListener(value, (event) => {
      const ref = refOverlay.current;
      const target = event.target;
      if (!(ref instanceof Node && target instanceof Node)) return;
      if (!ref.contains(target) && overlayVisible) setOverlayVisible(false);
    });
  });
  return (
    <View style={{margin: 50}}>
      <View>
        <Text>this is a text</Text>
      </View>
      <View>
        <Text>this is a text</Text>
      </View>
      <View style={{flexDirection: "row"}}>
        <Button title="show overlay" onPress={() => setOverlayVisible(true)} />
      </View>
      <View ref={refOverlay} style={{ zIndex: 1 }}>
        {overlayVisible ? (
          <View style={{ position: 'absolute', backgroundColor: 'red' }}>
            <Text>overlay</Text>
          </View>
        ) : null}
      </View>
      <View>
        <Text>this is a text</Text>
      </View>
      <View>
        <Text>this is a text</Text>
      </View>
    </View>
  );
}

Screenshot from 2021-07-29 20-14-18

Note that document is probably only existing in react-native-web environment.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.