Keyboard.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @format
  8. * @flow strict-local
  9. */
  10. 'use strict';
  11. const LayoutAnimation = require('../../LayoutAnimation/LayoutAnimation');
  12. const NativeEventEmitter = require('../../EventEmitter/NativeEventEmitter');
  13. const dismissKeyboard = require('../../Utilities/dismissKeyboard');
  14. const invariant = require('invariant');
  15. import NativeKeyboardObserver from './NativeKeyboardObserver';
  16. const KeyboardEventEmitter: NativeEventEmitter = new NativeEventEmitter(
  17. NativeKeyboardObserver,
  18. );
  19. export type KeyboardEventName =
  20. | 'keyboardWillShow'
  21. | 'keyboardDidShow'
  22. | 'keyboardWillHide'
  23. | 'keyboardDidHide'
  24. | 'keyboardWillChangeFrame'
  25. | 'keyboardDidChangeFrame';
  26. export type KeyboardEventEasing =
  27. | 'easeIn'
  28. | 'easeInEaseOut'
  29. | 'easeOut'
  30. | 'linear'
  31. | 'keyboard';
  32. export type KeyboardEventCoordinates = $ReadOnly<{|
  33. screenX: number,
  34. screenY: number,
  35. width: number,
  36. height: number,
  37. |}>;
  38. export type KeyboardEvent = AndroidKeyboardEvent | IOSKeyboardEvent;
  39. type BaseKeyboardEvent = {|
  40. duration: number,
  41. easing: KeyboardEventEasing,
  42. endCoordinates: KeyboardEventCoordinates,
  43. |};
  44. export type AndroidKeyboardEvent = $ReadOnly<{|
  45. ...BaseKeyboardEvent,
  46. duration: 0,
  47. easing: 'keyboard',
  48. |}>;
  49. export type IOSKeyboardEvent = $ReadOnly<{|
  50. ...BaseKeyboardEvent,
  51. startCoordinates: KeyboardEventCoordinates,
  52. isEventFromThisApp: boolean,
  53. |}>;
  54. type KeyboardEventListener = (e: KeyboardEvent) => void;
  55. // The following object exists for documentation purposes
  56. // Actual work happens in
  57. // https://github.com/facebook/react-native/blob/master/Libraries/EventEmitter/NativeEventEmitter.js
  58. /**
  59. * `Keyboard` module to control keyboard events.
  60. *
  61. * ### Usage
  62. *
  63. * The Keyboard module allows you to listen for native events and react to them, as
  64. * well as make changes to the keyboard, like dismissing it.
  65. *
  66. *```
  67. * import React, { Component } from 'react';
  68. * import { Keyboard, TextInput } from 'react-native';
  69. *
  70. * class Example extends Component {
  71. * componentWillMount () {
  72. * this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow);
  73. * this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
  74. * }
  75. *
  76. * componentWillUnmount () {
  77. * this.keyboardDidShowListener.remove();
  78. * this.keyboardDidHideListener.remove();
  79. * }
  80. *
  81. * _keyboardDidShow () {
  82. * alert('Keyboard Shown');
  83. * }
  84. *
  85. * _keyboardDidHide () {
  86. * alert('Keyboard Hidden');
  87. * }
  88. *
  89. * render() {
  90. * return (
  91. * <TextInput
  92. * onSubmitEditing={Keyboard.dismiss}
  93. * />
  94. * );
  95. * }
  96. * }
  97. *```
  98. */
  99. const Keyboard = {
  100. /**
  101. * The `addListener` function connects a JavaScript function to an identified native
  102. * keyboard notification event.
  103. *
  104. * This function then returns the reference to the listener.
  105. *
  106. * @param {string} eventName The `nativeEvent` is the string that identifies the event you're listening for. This
  107. *can be any of the following:
  108. *
  109. * - `keyboardWillShow`
  110. * - `keyboardDidShow`
  111. * - `keyboardWillHide`
  112. * - `keyboardDidHide`
  113. * - `keyboardWillChangeFrame`
  114. * - `keyboardDidChangeFrame`
  115. *
  116. * Note that if you set `android:windowSoftInputMode` to `adjustResize` or `adjustNothing`,
  117. * only `keyboardDidShow` and `keyboardDidHide` events will be available on Android.
  118. * `keyboardWillShow` as well as `keyboardWillHide` are generally not available on Android
  119. * since there is no native corresponding event.
  120. *
  121. * @param {function} callback function to be called when the event fires.
  122. */
  123. addListener(eventName: KeyboardEventName, callback: KeyboardEventListener) {
  124. invariant(false, 'Dummy method used for documentation');
  125. },
  126. /**
  127. * Removes a specific listener.
  128. *
  129. * @param {string} eventName The `nativeEvent` is the string that identifies the event you're listening for.
  130. * @param {function} callback function to be called when the event fires.
  131. */
  132. removeListener(
  133. eventName: KeyboardEventName,
  134. callback: KeyboardEventListener,
  135. ) {
  136. invariant(false, 'Dummy method used for documentation');
  137. },
  138. /**
  139. * Removes all listeners for a specific event type.
  140. *
  141. * @param {string} eventType The native event string listeners are watching which will be removed.
  142. */
  143. removeAllListeners(eventName: KeyboardEventName) {
  144. invariant(false, 'Dummy method used for documentation');
  145. },
  146. /**
  147. * Dismisses the active keyboard and removes focus.
  148. */
  149. dismiss() {
  150. invariant(false, 'Dummy method used for documentation');
  151. },
  152. /**
  153. * Useful for syncing TextInput (or other keyboard accessory view) size of
  154. * position changes with keyboard movements.
  155. */
  156. scheduleLayoutAnimation(event: KeyboardEvent) {
  157. invariant(false, 'Dummy method used for documentation');
  158. },
  159. };
  160. // Throw away the dummy object and reassign it to original module
  161. KeyboardEventEmitter.dismiss = dismissKeyboard;
  162. KeyboardEventEmitter.scheduleLayoutAnimation = function(event: KeyboardEvent) {
  163. const {duration, easing} = event;
  164. if (duration != null && duration !== 0) {
  165. LayoutAnimation.configureNext({
  166. duration: duration,
  167. update: {
  168. duration: duration,
  169. type: (easing != null && LayoutAnimation.Types[easing]) || 'keyboard',
  170. },
  171. });
  172. }
  173. };
  174. module.exports = KeyboardEventEmitter;