hunk.code_window: {
     "url": "exp://expo.io/@expo-home-dev/exponent-home-dev-3ff98f15eef6933f343f1e2d4e0557db53c1c748"
   }
  
hunk.labels: keep replace keep
hunk.after_edit:   "url": "exp://expo.io/@expo-home-dev/exponent-home-dev-0c7b8f265f35e338ac984e1510a19363c74a4ac0"
  
hunk.file_path: dev-home-config.json
hunk.type: replace
file: /**
   * Copyright (c) 2015-present, Facebook, Inc.
   * All rights reserved.
   *
   * This source code is licensed under the BSD-style license found in the
   * LICENSE file in the root directory of this source tree. An additional grant
   * of patent rights can be found in the PATENTS file in the same directory.
   *
   * @providesModule KeyboardAvoidingView
   * @flow
   */
  'use strict';
  
  const createReactClass = require('create-react-class');
  const Keyboard = require('./Keyboard');
  const LayoutAnimation = require('../../LayoutAnimation/LayoutAnimation');
  const Platform = require('../../Utilities/Platform');
  const PropTypes = require('prop-types');
  const React = require('react');
  /* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error
   * found when Flow v0.54 was deployed. To see the error delete this comment and
   * run Flow. */
  const TimerMixin = require('react-timer-mixin');
  const View = require('../View/View');
  const ViewPropTypes = require('../View/ViewPropTypes');
  
  import type EmitterSubscription from '../../vendor/emitter/EmitterSubscription';
  import type {ViewLayout, ViewLayoutEvent} from '../View/ViewPropTypes';
  
  type ScreenRect = {
    screenX: number,
    screenY: number,
    width: number,
    height: number,
  };
  type KeyboardChangeEvent = {
    startCoordinates?: ScreenRect,
    endCoordinates: ScreenRect,
    duration?: number,
    easing?: string,
  };
  
  const viewRef = 'VIEW';
  
  /**
   * This is a component to solve the common problem of views that need to move out of the way of the virtual keyboard.
   * It can automatically adjust either its height, position or bottom padding based on the position of the keyboard.
   */
  const KeyboardAvoidingView = createReactClass({
    displayName: 'KeyboardAvoidingView',
    mixins: [TimerMixin],
  
    propTypes: {
      ...ViewPropTypes,
      /**
       * Specify how the `KeyboardAvoidingView` will react to the presence of
       * the keyboard. It can adjust the height, position or bottom padding of the view
       */
      behavior: PropTypes.oneOf(['height', 'position', 'padding']),
  
      /**
       * The style of the content container(View) when behavior is 'position'.
       */
      contentContainerStyle: ViewPropTypes.style,
  
      /**
       * This is the distance between the top of the user screen and the react native view,
       * may be non-zero in some use cases. The default value is 0.
       */
      keyboardVerticalOffset: PropTypes.number.isRequired,
    },
  
    getDefaultProps() {
      return {
        keyboardVerticalOffset: 0,
      };
    },
  
    getInitialState() {
      return {
        bottom: 0,
      };
    },
  
    subscriptions: ([]: Array<EmitterSubscription>),
    frame: (null: ?ViewLayout),
  
    _relativeKeyboardHeight(keyboardFrame: ScreenRect): number {
      const frame = this.frame;
      if (!frame || !keyboardFrame) {
        return 0;
      }
  
      const keyboardY = keyboardFrame.screenY - this.props.keyboardVerticalOffset;
  
      // Calculate the displacement needed for the view such that it
      // no longer overlaps with the keyboard
      return Math.max(frame.y + frame.height - keyboardY, 0);
    },
  
    _onKeyboardChange(event: ?KeyboardChangeEvent) {
      if (!event) {
        this.setState({bottom: 0});
        return;
      }
  
      const {duration, easing, endCoordinates} = event;
      const height = this._relativeKeyboardHeight(endCoordinates);
  
      if (this.state.bottom === height) {
        return;
      }
  
      if (duration && easing) {
        LayoutAnimation.configureNext({
          duration: duration,
          update: {
            duration: duration,
            type: LayoutAnimation.Types[easing] || 'keyboard',
          },
        });
      }
      this.setState({bottom: height});
    },
  
    _onLayout(event: ViewLayoutEvent) {
      this.frame = event.nativeEvent.layout;
    },
  
    componentWillUpdate(nextProps: Object, nextState: Object, nextContext?: Object): void {
      if (nextState.bottom === this.state.bottom &&
          this.props.behavior === 'height' &&
          nextProps.behavior === 'height') {
        // If the component rerenders without an internal state change, e.g.
        // triggered by parent component re-rendering, no need for bottom to change.
        nextState.bottom = 0;
      }
    },
  
    componentWillMount() {
      if (Platform.OS === 'ios') {
        this.subscriptions = [
          Keyboard.addListener('keyboardWillChangeFrame', this._onKeyboardChange),
        ];
      } else {
        this.subscriptions = [
          Keyboard.addListener('keyboardDidHide', this._onKeyboardChange),
          Keyboard.addListener('keyboardDidShow', this._onKeyboardChange),
        ];
      }
    },
  
    componentWillUnmount() {
      this.subscriptions.forEach((sub) => sub.remove());
    },
  
    render(): React.Element<any> {
      // $FlowFixMe(>=0.41.0)
      const {behavior, children, style, ...props} = this.props;
  
      switch (behavior) {
        case 'height':
          let heightStyle;
          if (this.frame) {
            // Note that we only apply a height change when there is keyboard present,
            // i.e. this.state.bottom is greater than 0. If we remove that condition,
            // this.frame.height will never go back to its original value.
            // When height changes, we need to disable flex.
            heightStyle = {height: this.frame.height - this.state.bottom, flex: 0};
          }
          return (
            <View ref={viewRef} style={[style, heightStyle]} onLayout={this._onLayout} {...props}>
              {children}
            </View>
          );
  
        case 'position':
          const positionStyle = {bottom: this.state.bottom};
          const { contentContainerStyle } = this.props;
  
          return (
            <View ref={viewRef} style={style} onLayout={this._onLayout} {...props}>
              <View style={[contentContainerStyle, positionStyle]}>
                {children}
              </View>
            </View>
          );
  
        case 'padding':
          const paddingStyle = {paddingBottom: this.state.bottom};
          return (
            <View ref={viewRef} style={[style, paddingStyle]} onLayout={this._onLayout} {...props}>
              {children}
            </View>
          );
  
        default:
          return (
            <View ref={viewRef} onLayout={this._onLayout} style={style} {...props}>
              {children}
            </View>
          );
      }
    },
  });
  
  module.exports = KeyboardAvoidingView;
  