react-native-keyboard-controller 1.17.1 → 1.17.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/README.md +24 -23
  2. package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/ThemedReactContext.kt +20 -0
  3. package/android/src/main/java/com/reactnativekeyboardcontroller/listeners/KeyboardAnimationCallback.kt +4 -0
  4. package/ios/KeyboardControllerModule.mm +2 -0
  5. package/ios/views/KeyboardControllerView.mm +18 -0
  6. package/ios/views/KeyboardControllerViewManager.swift +19 -0
  7. package/lib/commonjs/animated.js +23 -7
  8. package/lib/commonjs/animated.js.map +1 -1
  9. package/lib/commonjs/bindings.js +19 -0
  10. package/lib/commonjs/bindings.js.map +1 -1
  11. package/lib/commonjs/components/KeyboardAvoidingView/index.js +14 -4
  12. package/lib/commonjs/components/KeyboardAvoidingView/index.js.map +1 -1
  13. package/lib/commonjs/components/KeyboardAwareScrollView/index.js +54 -36
  14. package/lib/commonjs/components/KeyboardAwareScrollView/index.js.map +1 -1
  15. package/lib/commonjs/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js +17 -1
  16. package/lib/commonjs/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js.map +1 -1
  17. package/lib/commonjs/components/KeyboardStickyView/index.js +13 -0
  18. package/lib/commonjs/components/KeyboardStickyView/index.js.map +1 -1
  19. package/lib/commonjs/components/KeyboardToolbar/index.js +31 -22
  20. package/lib/commonjs/components/KeyboardToolbar/index.js.map +1 -1
  21. package/lib/commonjs/context.js +16 -0
  22. package/lib/commonjs/context.js.map +1 -1
  23. package/lib/commonjs/hooks/index.js +164 -0
  24. package/lib/commonjs/hooks/index.js.map +1 -1
  25. package/lib/commonjs/hooks/useKeyboardState/index.js +21 -0
  26. package/lib/commonjs/hooks/useKeyboardState/index.js.map +1 -1
  27. package/lib/commonjs/hooks/useWindowDimensions/index.js +29 -6
  28. package/lib/commonjs/hooks/useWindowDimensions/index.js.map +1 -1
  29. package/lib/commonjs/internal.js +21 -0
  30. package/lib/commonjs/internal.js.map +1 -1
  31. package/lib/commonjs/module.js +4 -0
  32. package/lib/commonjs/module.js.map +1 -1
  33. package/lib/commonjs/monkey-patch.android.js +0 -5
  34. package/lib/commonjs/monkey-patch.android.js.map +1 -1
  35. package/lib/commonjs/{types.js → types/hooks.js} +1 -1
  36. package/lib/commonjs/types/hooks.js.map +1 -0
  37. package/lib/commonjs/types/index.js +50 -0
  38. package/lib/commonjs/types/index.js.map +1 -0
  39. package/lib/commonjs/types/internal.js +6 -0
  40. package/lib/commonjs/types/internal.js.map +1 -0
  41. package/lib/commonjs/types/module.js +6 -0
  42. package/lib/commonjs/types/module.js.map +1 -0
  43. package/lib/commonjs/types/views.js +6 -0
  44. package/lib/commonjs/types/views.js.map +1 -0
  45. package/lib/commonjs/views/OverKeyboardView/index.js +18 -4
  46. package/lib/commonjs/views/OverKeyboardView/index.js.map +1 -1
  47. package/lib/module/animated.js +23 -7
  48. package/lib/module/animated.js.map +1 -1
  49. package/lib/module/bindings.js +19 -0
  50. package/lib/module/bindings.js.map +1 -1
  51. package/lib/module/components/KeyboardAvoidingView/index.js +14 -4
  52. package/lib/module/components/KeyboardAvoidingView/index.js.map +1 -1
  53. package/lib/module/components/KeyboardAwareScrollView/index.js +56 -38
  54. package/lib/module/components/KeyboardAwareScrollView/index.js.map +1 -1
  55. package/lib/module/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js +17 -1
  56. package/lib/module/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.js.map +1 -1
  57. package/lib/module/components/KeyboardStickyView/index.js +13 -0
  58. package/lib/module/components/KeyboardStickyView/index.js.map +1 -1
  59. package/lib/module/components/KeyboardToolbar/index.js +31 -22
  60. package/lib/module/components/KeyboardToolbar/index.js.map +1 -1
  61. package/lib/module/context.js +16 -0
  62. package/lib/module/context.js.map +1 -1
  63. package/lib/module/hooks/index.js +164 -0
  64. package/lib/module/hooks/index.js.map +1 -1
  65. package/lib/module/hooks/useKeyboardState/index.js +21 -0
  66. package/lib/module/hooks/useKeyboardState/index.js.map +1 -1
  67. package/lib/module/hooks/useWindowDimensions/index.js +28 -1
  68. package/lib/module/hooks/useWindowDimensions/index.js.map +1 -1
  69. package/lib/module/internal.js +21 -0
  70. package/lib/module/internal.js.map +1 -1
  71. package/lib/module/module.js +4 -0
  72. package/lib/module/module.js.map +1 -1
  73. package/lib/module/monkey-patch.android.js +0 -5
  74. package/lib/module/monkey-patch.android.js.map +1 -1
  75. package/lib/module/types/hooks.js +2 -0
  76. package/lib/module/types/hooks.js.map +1 -0
  77. package/lib/module/types/index.js +5 -0
  78. package/lib/module/types/index.js.map +1 -0
  79. package/lib/module/types/internal.js +2 -0
  80. package/lib/module/types/internal.js.map +1 -0
  81. package/lib/module/types/module.js +2 -0
  82. package/lib/module/types/module.js.map +1 -0
  83. package/lib/module/types/views.js +2 -0
  84. package/lib/module/types/views.js.map +1 -0
  85. package/lib/module/views/OverKeyboardView/index.js +18 -4
  86. package/lib/module/views/OverKeyboardView/index.js.map +1 -1
  87. package/lib/typescript/animated.d.ts +20 -6
  88. package/lib/typescript/bindings.d.ts +19 -0
  89. package/lib/typescript/components/KeyboardAvoidingView/index.d.ts +11 -2
  90. package/lib/typescript/components/KeyboardAwareScrollView/index.d.ts +23 -6
  91. package/lib/typescript/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.d.ts +17 -1
  92. package/lib/typescript/components/KeyboardStickyView/index.d.ts +15 -2
  93. package/lib/typescript/components/KeyboardToolbar/index.d.ts +13 -2
  94. package/lib/typescript/context.d.ts +32 -0
  95. package/lib/typescript/hooks/index.d.ts +157 -0
  96. package/lib/typescript/hooks/useKeyboardState/index.d.ts +20 -0
  97. package/lib/typescript/hooks/useWindowDimensions/index.d.ts +2 -1
  98. package/lib/typescript/internal.d.ts +21 -0
  99. package/lib/typescript/module.d.ts +3 -0
  100. package/lib/typescript/{types.d.ts → types/hooks.d.ts} +72 -78
  101. package/lib/typescript/types/index.d.ts +4 -0
  102. package/lib/typescript/types/internal.d.ts +17 -0
  103. package/lib/typescript/types/module.d.ts +91 -0
  104. package/lib/typescript/types/views.d.ts +45 -0
  105. package/lib/typescript/views/OverKeyboardView/index.d.ts +14 -1
  106. package/package.json +2 -1
  107. package/src/animated.tsx +27 -12
  108. package/src/bindings.ts +19 -0
  109. package/src/components/KeyboardAvoidingView/index.tsx +14 -4
  110. package/src/components/KeyboardAwareScrollView/index.tsx +60 -40
  111. package/src/components/KeyboardAwareScrollView/useSmoothKeyboardHandler.ts +17 -1
  112. package/src/components/KeyboardStickyView/index.tsx +14 -1
  113. package/src/components/KeyboardToolbar/index.tsx +31 -19
  114. package/src/context.ts +33 -0
  115. package/src/hooks/index.ts +157 -0
  116. package/src/hooks/useKeyboardState/index.ts +20 -0
  117. package/src/hooks/useWindowDimensions/index.ts +41 -1
  118. package/src/internal.ts +21 -0
  119. package/src/module.ts +3 -0
  120. package/src/monkey-patch.android.ts +3 -6
  121. package/src/{types.ts → types/hooks.ts} +72 -105
  122. package/src/types/index.ts +4 -0
  123. package/src/types/internal.ts +24 -0
  124. package/src/types/module.ts +105 -0
  125. package/src/types/views.ts +46 -0
  126. package/src/views/OverKeyboardView/index.tsx +15 -4
  127. package/lib/commonjs/hooks/useWindowDimensions/index.android.js +0 -34
  128. package/lib/commonjs/hooks/useWindowDimensions/index.android.js.map +0 -1
  129. package/lib/commonjs/types.js.map +0 -1
  130. package/lib/module/hooks/useWindowDimensions/index.android.js +0 -27
  131. package/lib/module/hooks/useWindowDimensions/index.android.js.map +0 -1
  132. package/lib/module/types.js +0 -2
  133. package/lib/module/types.js.map +0 -1
  134. package/lib/typescript/hooks/useWindowDimensions/index.android.d.ts +0 -2
  135. package/src/hooks/useWindowDimensions/index.android.ts +0 -38
@@ -12,6 +12,26 @@ const getLatestState = () => ({
12
12
  isVisible: KeyboardController.isVisible(),
13
13
  });
14
14
 
15
+ /**
16
+ * React Hook that represents the current keyboard state on iOS and Android.
17
+ * It tracks keyboard visibility, height, appearance, type and other properties.
18
+ * This hook subscribes to keyboard events and updates the state reactively.
19
+ *
20
+ * @returns Object {@link KeyboardState|containing} keyboard state information.
21
+ * @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/hooks/keyboard/use-keyboard-state|Documentation} page for more details.
22
+ * @example
23
+ * ```tsx
24
+ * function MyComponent() {
25
+ * const { isVisible, height } = useKeyboardState();
26
+ * return (
27
+ * <View>
28
+ * <Text>Keyboard is {isVisible ? 'visible' : 'hidden'}</Text>
29
+ * <Text>Keyboard height: {height}</Text>
30
+ * </View>
31
+ * );
32
+ * }
33
+ * ```
34
+ */
15
35
  export const useKeyboardState = (): KeyboardState => {
16
36
  const [state, setState] = useState(getLatestState);
17
37
 
@@ -1 +1,41 @@
1
- export { useWindowDimensions } from "react-native";
1
+ import { useEffect, useState } from "react";
2
+ import { Dimensions } from "react-native";
3
+
4
+ import { WindowDimensionsEvents } from "../../bindings";
5
+
6
+ import type { WindowDimensionsEventData } from "../../types";
7
+
8
+ const screen = Dimensions.get("screen");
9
+
10
+ let initialDimensions: WindowDimensionsEventData = {
11
+ width: screen.width,
12
+ height: screen.height,
13
+ };
14
+
15
+ WindowDimensionsEvents.addListener("windowDidResize", (e) => {
16
+ initialDimensions = e;
17
+ });
18
+
19
+ export const useWindowDimensions = () => {
20
+ const [dimensions, setDimensions] = useState(initialDimensions);
21
+
22
+ useEffect(() => {
23
+ const subscription = WindowDimensionsEvents.addListener(
24
+ "windowDidResize",
25
+ (e) => {
26
+ setDimensions(e);
27
+ },
28
+ );
29
+
30
+ // we might have missed an update between reading a value in render and
31
+ // `addListener` in this handler, so we set it here. If there was
32
+ // no change, React will filter out this update as a no-op.
33
+ setDimensions(initialDimensions);
34
+
35
+ return () => {
36
+ subscription.remove();
37
+ };
38
+ }, []);
39
+
40
+ return dimensions;
41
+ };
package/src/internal.ts CHANGED
@@ -7,6 +7,20 @@ import { findNodeHandle } from "./utils/findNodeHandle";
7
7
  type EventHandler = (event: never) => void;
8
8
  type ComponentOrHandle = Parameters<typeof findNodeHandle>[0];
9
9
 
10
+ /**
11
+ * An internal hook that helps to register workletized event handlers.
12
+ *
13
+ * @param map - Map of event handlers and their names.
14
+ * @param viewTagRef - Ref to the view that produces events.
15
+ * @returns A function that registers supplied event handlers.
16
+ * @example
17
+ * ```ts
18
+ * const setKeyboardHandlers = useEventHandlerRegistration<KeyboardHandler>(
19
+ * keyboardEventsMap,
20
+ * viewTagRef,
21
+ * );
22
+ * ```
23
+ */
10
24
  export function useEventHandlerRegistration<
11
25
  H extends Partial<Record<string, EventHandler>>,
12
26
  >(
@@ -68,7 +82,14 @@ export function useEventHandlerRegistration<
68
82
  * and therefore consumes less memory. We can not use a variant from
69
83
  * RN, since this library supports earlier versions of RN.
70
84
  *
85
+ * @param initialValue - Initial value of the animated value (numeric).
86
+ * @param config - Additional {@link Animated.AnimatedConfig|configuration} for the animated value.
87
+ * @returns Properly memoized {@link Animated.Value|Animated} value.
71
88
  * @see https://github.com/facebook/react-native/commit/e22217fe8b9455e32695f88ca835e11442b0a937
89
+ * @example
90
+ * ```ts
91
+ * const progress = useAnimatedValue(0);
92
+ * ```
72
93
  */
73
94
  export function useAnimatedValue(
74
95
  initialValue: number,
package/src/module.ts CHANGED
@@ -47,6 +47,9 @@ const dismiss = async (options?: DismissOptions): Promise<void> => {
47
47
  const isVisible = () => !isClosed;
48
48
  const state = () => lastState;
49
49
 
50
+ /**
51
+ * KeyboardController module. Helps to perform imperative actions/checks with keyboard.
52
+ */
50
53
  export const KeyboardController: KeyboardControllerModule = {
51
54
  setDefaultMode: KeyboardControllerNative.setDefaultMode,
52
55
  setInputMode: KeyboardControllerNative.setInputMode,
@@ -20,12 +20,9 @@ const ModifiedNativeAndroidManager = {
20
20
  setTranslucent: (translucent: boolean): void => {
21
21
  RCTStatusBarManagerCompat.setTranslucent(translucent);
22
22
  },
23
- /**
24
- * - statusBarStyles can be:
25
- * - 'default'
26
- * - 'dark-content'
27
- */
28
- setStyle: (statusBarStyle?: string): void => {
23
+ setStyle: (
24
+ statusBarStyle?: "default" | "dark-content" | "light-content",
25
+ ): void => {
29
26
  RCTStatusBarManagerCompat.setStyle(statusBarStyle);
30
27
  },
31
28
  setHidden: (hidden: boolean): void => {
@@ -1,44 +1,60 @@
1
- import type { PropsWithChildren } from "react";
2
- import type {
3
- EmitterSubscription,
4
- NativeSyntheticEvent,
5
- TextInputProps,
6
- ViewProps,
7
- } from "react-native";
1
+ import type { NativeSyntheticEvent, ViewProps } from "react-native";
8
2
 
9
3
  // DirectEventHandler events declaration
10
4
  export type NativeEvent = {
5
+ /** A value between `0` and `1` indicating keyboard position, where `0` means keyboard is closed and `1` means keyboard is fully visible. */
11
6
  progress: number;
7
+ /** Height of the keyboard. */
12
8
  height: number;
9
+ /** Duration of the keyboard animation. */
13
10
  duration: number;
11
+ /** Tag of the focused `TextInput`. */
14
12
  target: number;
15
13
  };
16
14
  export type FocusedInputLayoutChangedEvent = {
15
+ /** Tag of the focused `TextInput`. */
17
16
  target: number;
17
+ /** Tag of the parent `ScrollView`. */
18
18
  parentScrollViewTarget: number;
19
19
  layout: {
20
+ /** X coordinate of the focused `TextInput`. */
20
21
  x: number;
22
+ /** Y coordinate of the focused `TextInput`. */
21
23
  y: number;
24
+ /** Width of the focused `TextInput`. */
22
25
  width: number;
26
+ /** Height of the focused `TextInput`. */
23
27
  height: number;
28
+ /** X coordinate of the focused `TextInput` relative to the screen. */
24
29
  absoluteX: number;
30
+ /** Y coordinate of the focused `TextInput` relative to the screen. */
25
31
  absoluteY: number;
26
32
  };
27
33
  };
28
34
  export type FocusedInputTextChangedEvent = {
35
+ /** Text that user typed in the focused `TextInput`. */
29
36
  text: string;
30
37
  };
31
38
  export type FocusedInputSelectionChangedEvent = {
39
+ /** Tag of the focused `TextInput`. */
32
40
  target: number;
33
41
  selection: {
42
+ /** Start of the selection. Represents top-left point of rectangle. */
34
43
  start: {
44
+ /** X coordinate of the selection start (relative to the `TextInput`). */
35
45
  x: number;
46
+ /** Y coordinate of the selection start (relative to the `TextInput`). */
36
47
  y: number;
48
+ /** The start of selection. */
37
49
  position: number;
38
50
  };
51
+ /** End of the selection. Represents bottom-right point of rectangle. */
39
52
  end: {
53
+ /** X coordinate of the selection end (relative to the `TextInput`). */
40
54
  x: number;
55
+ /** Y coordinate of the selection end (relative to the `TextInput`). */
41
56
  y: number;
57
+ /** The end of selection. */
42
58
  position: number;
43
59
  };
44
60
  };
@@ -93,104 +109,6 @@ export type KeyboardControllerProps = {
93
109
  enabled?: boolean;
94
110
  } & ViewProps;
95
111
 
96
- export type KeyboardGestureAreaProps = {
97
- interpolator?: "ios" | "linear";
98
- /**
99
- * Whether to allow to show a keyboard from dismissed state by swipe up.
100
- * Default to `false`.
101
- */
102
- showOnSwipeUp?: boolean;
103
- /**
104
- * Whether to allow to control a keyboard by gestures. The strategy how
105
- * it should be controlled is determined by `interpolator` property.
106
- * Defaults to `true`.
107
- */
108
- enableSwipeToDismiss?: boolean;
109
- /**
110
- * Extra distance to the keyboard.
111
- */
112
- offset?: number;
113
- /**
114
- * A corresponding `nativeID` value from the corresponding `TextInput`.
115
- */
116
- textInputNativeID?: string;
117
- } & ViewProps;
118
- export type OverKeyboardViewProps = PropsWithChildren<{
119
- visible: boolean;
120
- }>;
121
-
122
- export type Direction = "next" | "prev" | "current";
123
- export type DismissOptions = {
124
- keepFocus: boolean;
125
- };
126
- export type KeyboardControllerModule = {
127
- // android only
128
- setDefaultMode: () => void;
129
- setInputMode: (mode: number) => void;
130
- // all platforms
131
- dismiss: (options?: DismissOptions) => Promise<void>;
132
- setFocusTo: (direction: Direction) => void;
133
- isVisible: () => boolean;
134
- state: () => KeyboardEventData;
135
- };
136
- export type KeyboardControllerNativeModule = {
137
- // android only
138
- setDefaultMode: () => void;
139
- setInputMode: (mode: number) => void;
140
- // all platforms
141
- dismiss: (keepFocus: boolean) => void;
142
- setFocusTo: (direction: Direction) => void;
143
- // native event module stuff
144
- addListener: (eventName: string) => void;
145
- removeListeners: (count: number) => void;
146
- };
147
-
148
- // Event module declarations
149
- export type KeyboardControllerEvents =
150
- | "keyboardWillShow"
151
- | "keyboardDidShow"
152
- | "keyboardWillHide"
153
- | "keyboardDidHide";
154
- export type KeyboardEventData = {
155
- height: number;
156
- duration: number;
157
- timestamp: number;
158
- target: number;
159
- type: NonNullable<TextInputProps["keyboardType"]>;
160
- appearance: NonNullable<TextInputProps["keyboardAppearance"]>;
161
- };
162
- export type KeyboardState = {
163
- isVisible: boolean;
164
- } & KeyboardEventData;
165
- export type KeyboardEventsModule = {
166
- addListener: (
167
- name: KeyboardControllerEvents,
168
- cb: (e: KeyboardEventData) => void,
169
- ) => EmitterSubscription;
170
- };
171
- export type FocusedInputAvailableEvents = "focusDidSet";
172
- export type FocusedInputEventData = {
173
- current: number;
174
- count: number;
175
- };
176
- export type FocusedInputEventsModule = {
177
- addListener: (
178
- name: FocusedInputAvailableEvents,
179
- cb: (e: FocusedInputEventData) => void,
180
- ) => EmitterSubscription;
181
- };
182
- export type WindowDimensionsAvailableEvents = "windowDidResize";
183
- export type WindowDimensionsEventData = {
184
- width: number;
185
- height: number;
186
- };
187
- export type WindowDimensionsEventsModule = {
188
- addListener: (
189
- name: WindowDimensionsAvailableEvents,
190
- cb: (e: WindowDimensionsEventData) => void,
191
- ) => EmitterSubscription;
192
- };
193
-
194
112
  // reanimated hook declaration
195
113
  export type KeyboardHandlerHook<TContext, Event> = (
196
114
  handlers: {
@@ -232,14 +150,63 @@ export type FocusedInputSelectionHandlerHook<TContext, Event> = (
232
150
  // package types
233
151
  export type Handlers<T> = Record<string, T | undefined>;
234
152
  export type KeyboardHandler = Partial<{
153
+ /**
154
+ * A callback that gets invoked when keyboard starts its movement.
155
+ * The event contains DESTINATION values.
156
+ *
157
+ * @example
158
+ * ```ts
159
+ * onStart: (e) => {
160
+ * "worklet";
161
+ *
162
+ * const willKeyboardAppear = e.progress === 1;
163
+ * }
164
+ * ```
165
+ */
235
166
  onStart: (e: NativeEvent) => void;
167
+ /**
168
+ * A callback that gets involved every frame when keyboard changes its position.
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * onMove: (e) => {
173
+ * "worklet";
174
+ *
175
+ * const keyboardHeight = e.height;
176
+ * }
177
+ */
236
178
  onMove: (e: NativeEvent) => void;
179
+ /**
180
+ * A callback that gets invoked when keyboard finished its movement.
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * onEnd: (e) => {
185
+ * "worklet";
186
+ *
187
+ * const isKeyboardShown = e.progress === 1;
188
+ * }
189
+ * ```
190
+ */
237
191
  onEnd: (e: NativeEvent) => void;
192
+ /**
193
+ * A callback that gets invoked every frame when keyboard changes its position due to interactive dismissal.
194
+ *
195
+ * @example
196
+ * ```ts
197
+ * onInteractive: (e) => {
198
+ * "worklet";
199
+ *
200
+ * const keyboardHeight = e.height;
201
+ * }
202
+ */
238
203
  onInteractive: (e: NativeEvent) => void;
239
204
  }>;
240
205
  export type KeyboardHandlers = Handlers<KeyboardHandler>;
241
206
  export type FocusedInputHandler = Partial<{
207
+ /** A callback that gets invoked every time when the text changes in focused input. */
242
208
  onChangeText: (e: FocusedInputTextChangedEvent) => void;
209
+ /** A callback that gets invoked every time when the selection (cursor) coordinates change in focused input. */
243
210
  onSelectionChange: (e: FocusedInputSelectionChangedEvent) => void;
244
211
  }>;
245
212
  export type FocusedInputHandlers = Handlers<FocusedInputHandler>;
@@ -0,0 +1,4 @@
1
+ export * from "./hooks";
2
+ export * from "./views";
3
+ export * from "./module";
4
+ export * from "./internal";
@@ -0,0 +1,24 @@
1
+ import type { EmitterSubscription } from "react-native";
2
+
3
+ export type FocusedInputAvailableEvents = "focusDidSet";
4
+ export type FocusedInputEventData = {
5
+ current: number;
6
+ count: number;
7
+ };
8
+ export type FocusedInputEventsModule = {
9
+ addListener: (
10
+ name: FocusedInputAvailableEvents,
11
+ cb: (e: FocusedInputEventData) => void,
12
+ ) => EmitterSubscription;
13
+ };
14
+ export type WindowDimensionsAvailableEvents = "windowDidResize";
15
+ export type WindowDimensionsEventData = {
16
+ width: number;
17
+ height: number;
18
+ };
19
+ export type WindowDimensionsEventsModule = {
20
+ addListener: (
21
+ name: WindowDimensionsAvailableEvents,
22
+ cb: (e: WindowDimensionsEventData) => void,
23
+ ) => EmitterSubscription;
24
+ };
@@ -0,0 +1,105 @@
1
+ import type { EmitterSubscription, TextInputProps } from "react-native";
2
+
3
+ // Event module declarations
4
+ export type KeyboardControllerEvents =
5
+ | "keyboardWillShow"
6
+ | "keyboardDidShow"
7
+ | "keyboardWillHide"
8
+ | "keyboardDidHide";
9
+ export type KeyboardEventData = {
10
+ /** Height of the keyboard. */
11
+ height: number;
12
+ /** Duration of the keyboard animation. */
13
+ duration: number;
14
+ /** Timestamp of the last keyboard event. */
15
+ timestamp: number;
16
+ /** Tag of the focused `TextInput`. */
17
+ target: number;
18
+ /** `keyboardType` property from focused `TextInput`. */
19
+ type: NonNullable<TextInputProps["keyboardType"]>;
20
+ /** Keyboard appearance. Can be one of `default`, `dark` or `light`. */
21
+ appearance: NonNullable<TextInputProps["keyboardAppearance"]>;
22
+ };
23
+ /**
24
+ * An object that represent current keyboard state.
25
+ */
26
+ export type KeyboardState = {
27
+ /** Whether the keyboard is currently visible. */
28
+ isVisible: boolean;
29
+ } & KeyboardEventData;
30
+ export type KeyboardEventsModule = {
31
+ /**
32
+ * The `addListener` function connects a JavaScript function to an identified native
33
+ * keyboard notification event.
34
+ *
35
+ * This function then returns the reference to the listener.
36
+ *
37
+ * `name` is the string that identifies the event you're listening for. This
38
+ * can be any of the following:
39
+ *
40
+ * - `keyboardWillShow`;
41
+ * - `keyboardDidShow`;
42
+ * - `keyboardWillHide`;
43
+ * - `keyboardDidHide`.
44
+ */
45
+ addListener: (
46
+ name: KeyboardControllerEvents,
47
+ cb: (e: KeyboardEventData) => void,
48
+ ) => EmitterSubscription;
49
+ };
50
+ export type Direction = "next" | "prev" | "current";
51
+ export type DismissOptions = {
52
+ /**
53
+ * A boolean property indicating whether focus should be kept on the input after dismissing the keyboard. Default is `false`.
54
+ */
55
+ keepFocus: boolean;
56
+ };
57
+ export type KeyboardControllerModule = {
58
+ // android only
59
+ /**
60
+ * Sets default `windowSoftInputMode` (the one that declared in `AndroidManifest.xml`).
61
+ *
62
+ * @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/keyboard-controller#setdefaultmode-|docs} page for more details.
63
+ */
64
+ setDefaultMode: () => void;
65
+ /**
66
+ * Changes `windowSoftInputMode` on Android. @see AndroidSoftInputModes for all possible values and {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/keyboard-controller#setinputmode-|docs} page for more details.
67
+ */
68
+ setInputMode: (mode: number) => void;
69
+ // all platforms
70
+ /**
71
+ * Dismisses the active keyboard. Removes a focus by default, but allows to pass `{keepFocus: true}` to keep focus.
72
+ *
73
+ * @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/keyboard-controller#dismiss|docs} page for more details.
74
+ */
75
+ dismiss: (options?: DismissOptions) => Promise<void>;
76
+ /**
77
+ * Moves focus to the specified direction (`next`, `prev` or `current` to restore a focus).
78
+ *
79
+ * @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/keyboard-controller#setfocusto|docs} page for more details.
80
+ */
81
+ setFocusTo: (direction: Direction) => void;
82
+ /**
83
+ * Whether the keyboard is fully visible.
84
+ *
85
+ * @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/keyboard-controller#isvisible|docs} page for more details.
86
+ */
87
+ isVisible: () => boolean;
88
+ /**
89
+ * Method that returns current keyboard state.
90
+ *
91
+ * @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/keyboard-controller#state|docs} page for more details.
92
+ */
93
+ state: () => KeyboardEventData;
94
+ };
95
+ export type KeyboardControllerNativeModule = {
96
+ // android only
97
+ setDefaultMode: () => void;
98
+ setInputMode: (mode: number) => void;
99
+ // all platforms
100
+ dismiss: (keepFocus: boolean) => void;
101
+ setFocusTo: (direction: Direction) => void;
102
+ // native event module stuff
103
+ addListener: (eventName: string) => void;
104
+ removeListeners: (count: number) => void;
105
+ };
@@ -0,0 +1,46 @@
1
+ import type { PropsWithChildren } from "react";
2
+ import type { ViewProps } from "react-native";
3
+
4
+ export type KeyboardGestureAreaProps = {
5
+ /**
6
+ * Determines how the keyboard position will be controlled:
7
+ * - `ios` - keyboard will be following finger only when finger touches keyboard
8
+ * - `linear` - keyboard will be following finger position linearly.
9
+ *
10
+ * @platform android
11
+ */
12
+ interpolator?: "ios" | "linear";
13
+ /**
14
+ * Whether to allow to show a keyboard from dismissed state by swipe up.
15
+ * Default to `false`.
16
+ *
17
+ * @platform android
18
+ */
19
+ showOnSwipeUp?: boolean;
20
+ /**
21
+ * Whether to allow to control a keyboard by gestures. The strategy how
22
+ * it should be controlled is determined by `interpolator` property.
23
+ * Defaults to `true`.
24
+ *
25
+ * @platform android
26
+ */
27
+ enableSwipeToDismiss?: boolean;
28
+ /**
29
+ * Extra distance to the keyboard.
30
+ */
31
+ offset?: number;
32
+ /**
33
+ * A corresponding `nativeID` value from the associated `TextInput` (a string that links the `KeyboardGestureArea` to one or more `TextInput` components).
34
+ * This is **required on iOS** in order to apply the `offset` when the keyboard is shown. Only the currently focused `TextInput` with a matching `nativeID`
35
+ * will receive offset behavior.
36
+ *
37
+ * @platform ios
38
+ */
39
+ textInputNativeID?: string;
40
+ } & ViewProps;
41
+ export type OverKeyboardViewProps = PropsWithChildren<{
42
+ /**
43
+ * A boolean prop indicating whether the view is visible or not. If it's true then view is shown on the screen. If it's false then view is hidden.
44
+ */
45
+ visible: boolean;
46
+ }>;
@@ -7,10 +7,21 @@ import { useWindowDimensions } from "../../hooks";
7
7
  import type { OverKeyboardViewProps } from "../../types";
8
8
  import type { PropsWithChildren } from "react";
9
9
 
10
- const OverKeyboardView = ({
11
- children,
12
- visible,
13
- }: PropsWithChildren<OverKeyboardViewProps>) => {
10
+ /**
11
+ * A view component that renders its children over the keyboard without closing the keyboard.
12
+ * Acts similar to modal, but doesn't close the keyboard when it's visible.
13
+ *
14
+ * @param props - Component props.
15
+ * @returns A view component that renders over the keyboard.
16
+ * @example
17
+ * ```tsx
18
+ * <OverKeyboardView visible={true}>
19
+ * <Text>This will appear over the keyboard</Text>
20
+ * </OverKeyboardView>
21
+ * ```
22
+ */
23
+ const OverKeyboardView = (props: PropsWithChildren<OverKeyboardViewProps>) => {
24
+ const { children, visible } = props;
14
25
  const { height, width } = useWindowDimensions();
15
26
  const inner = useMemo(() => ({ height, width }), [height, width]);
16
27
  const style = useMemo(
@@ -1,34 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.useWindowDimensions = void 0;
7
- var _react = require("react");
8
- var _bindings = require("../../bindings");
9
- let initialDimensions = {
10
- width: 0,
11
- height: 0
12
- };
13
- _bindings.WindowDimensionsEvents.addListener("windowDidResize", e => {
14
- initialDimensions = e;
15
- });
16
- const useWindowDimensions = () => {
17
- const [dimensions, setDimensions] = (0, _react.useState)(initialDimensions);
18
- (0, _react.useEffect)(() => {
19
- const subscription = _bindings.WindowDimensionsEvents.addListener("windowDidResize", e => {
20
- setDimensions(e);
21
- });
22
-
23
- // we might have missed an update between reading a value in render and
24
- // `addListener` in this handler, so we set it here. If there was
25
- // no change, React will filter out this update as a no-op.
26
- setDimensions(initialDimensions);
27
- return () => {
28
- subscription.remove();
29
- };
30
- }, []);
31
- return dimensions;
32
- };
33
- exports.useWindowDimensions = useWindowDimensions;
34
- //# sourceMappingURL=index.android.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_react","require","_bindings","initialDimensions","width","height","WindowDimensionsEvents","addListener","e","useWindowDimensions","dimensions","setDimensions","useState","useEffect","subscription","remove","exports"],"sources":["index.android.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\n\nimport { WindowDimensionsEvents } from \"../../bindings\";\n\nimport type { WindowDimensionsEventData } from \"../../types\";\n\nlet initialDimensions: WindowDimensionsEventData = {\n width: 0,\n height: 0,\n};\n\nWindowDimensionsEvents.addListener(\"windowDidResize\", (e) => {\n initialDimensions = e;\n});\n\nexport const useWindowDimensions = () => {\n const [dimensions, setDimensions] = useState(initialDimensions);\n\n useEffect(() => {\n const subscription = WindowDimensionsEvents.addListener(\n \"windowDidResize\",\n (e) => {\n setDimensions(e);\n },\n );\n\n // we might have missed an update between reading a value in render and\n // `addListener` in this handler, so we set it here. If there was\n // no change, React will filter out this update as a no-op.\n setDimensions(initialDimensions);\n\n return () => {\n subscription.remove();\n };\n }, []);\n\n return dimensions;\n};\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAEA,IAAAC,SAAA,GAAAD,OAAA;AAIA,IAAIE,iBAA4C,GAAG;EACjDC,KAAK,EAAE,CAAC;EACRC,MAAM,EAAE;AACV,CAAC;AAEDC,gCAAsB,CAACC,WAAW,CAAC,iBAAiB,EAAGC,CAAC,IAAK;EAC3DL,iBAAiB,GAAGK,CAAC;AACvB,CAAC,CAAC;AAEK,MAAMC,mBAAmB,GAAGA,CAAA,KAAM;EACvC,MAAM,CAACC,UAAU,EAAEC,aAAa,CAAC,GAAG,IAAAC,eAAQ,EAACT,iBAAiB,CAAC;EAE/D,IAAAU,gBAAS,EAAC,MAAM;IACd,MAAMC,YAAY,GAAGR,gCAAsB,CAACC,WAAW,CACrD,iBAAiB,EAChBC,CAAC,IAAK;MACLG,aAAa,CAACH,CAAC,CAAC;IAClB,CACF,CAAC;;IAED;IACA;IACA;IACAG,aAAa,CAACR,iBAAiB,CAAC;IAEhC,OAAO,MAAM;MACXW,YAAY,CAACC,MAAM,CAAC,CAAC;IACvB,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,OAAOL,UAAU;AACnB,CAAC;AAACM,OAAA,CAAAP,mBAAA,GAAAA,mBAAA","ignoreList":[]}
@@ -1 +0,0 @@
1
- {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type { PropsWithChildren } from \"react\";\nimport type {\n EmitterSubscription,\n NativeSyntheticEvent,\n TextInputProps,\n ViewProps,\n} from \"react-native\";\n\n// DirectEventHandler events declaration\nexport type NativeEvent = {\n progress: number;\n height: number;\n duration: number;\n target: number;\n};\nexport type FocusedInputLayoutChangedEvent = {\n target: number;\n parentScrollViewTarget: number;\n layout: {\n x: number;\n y: number;\n width: number;\n height: number;\n absoluteX: number;\n absoluteY: number;\n };\n};\nexport type FocusedInputTextChangedEvent = {\n text: string;\n};\nexport type FocusedInputSelectionChangedEvent = {\n target: number;\n selection: {\n start: {\n x: number;\n y: number;\n position: number;\n };\n end: {\n x: number;\n y: number;\n position: number;\n };\n };\n};\nexport type EventWithName<T> = {\n eventName: string;\n} & T;\n\n// native View/Module declarations\nexport type KeyboardControllerProps = {\n //ref prop\n ref?: React.Ref<React.Component<KeyboardControllerProps>>;\n // callback props\n onKeyboardMoveStart?: (\n e: NativeSyntheticEvent<EventWithName<NativeEvent>>,\n ) => void;\n onKeyboardMove?: (\n e: NativeSyntheticEvent<EventWithName<NativeEvent>>,\n ) => void;\n onKeyboardMoveEnd?: (\n e: NativeSyntheticEvent<EventWithName<NativeEvent>>,\n ) => void;\n onKeyboardMoveInteractive?: (\n e: NativeSyntheticEvent<EventWithName<NativeEvent>>,\n ) => void;\n onFocusedInputLayoutChanged?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputLayoutChangedEvent>>,\n ) => void;\n onFocusedInputTextChanged?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputTextChangedEvent>>,\n ) => void;\n onFocusedInputSelectionChanged?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputSelectionChangedEvent>>,\n ) => void;\n // fake props used to activate reanimated bindings\n onKeyboardMoveReanimated?: (\n e: NativeSyntheticEvent<EventWithName<NativeEvent>>,\n ) => void;\n onFocusedInputLayoutChangedReanimated?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputLayoutChangedEvent>>,\n ) => void;\n onFocusedInputTextChangedReanimated?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputTextChangedEvent>>,\n ) => void;\n onFocusedInputSelectionChangedReanimated?: (\n e: NativeSyntheticEvent<EventWithName<FocusedInputSelectionChangedEvent>>,\n ) => void;\n // props\n statusBarTranslucent?: boolean;\n navigationBarTranslucent?: boolean;\n preserveEdgeToEdge?: boolean;\n enabled?: boolean;\n} & ViewProps;\n\nexport type KeyboardGestureAreaProps = {\n interpolator?: \"ios\" | \"linear\";\n /**\n * Whether to allow to show a keyboard from dismissed state by swipe up.\n * Default to `false`.\n */\n showOnSwipeUp?: boolean;\n /**\n * Whether to allow to control a keyboard by gestures. The strategy how\n * it should be controlled is determined by `interpolator` property.\n * Defaults to `true`.\n */\n enableSwipeToDismiss?: boolean;\n /**\n * Extra distance to the keyboard.\n */\n offset?: number;\n /**\n * A corresponding `nativeID` value from the corresponding `TextInput`.\n */\n textInputNativeID?: string;\n} & ViewProps;\nexport type OverKeyboardViewProps = PropsWithChildren<{\n visible: boolean;\n}>;\n\nexport type Direction = \"next\" | \"prev\" | \"current\";\nexport type DismissOptions = {\n keepFocus: boolean;\n};\nexport type KeyboardControllerModule = {\n // android only\n setDefaultMode: () => void;\n setInputMode: (mode: number) => void;\n // all platforms\n dismiss: (options?: DismissOptions) => Promise<void>;\n setFocusTo: (direction: Direction) => void;\n isVisible: () => boolean;\n state: () => KeyboardEventData;\n};\nexport type KeyboardControllerNativeModule = {\n // android only\n setDefaultMode: () => void;\n setInputMode: (mode: number) => void;\n // all platforms\n dismiss: (keepFocus: boolean) => void;\n setFocusTo: (direction: Direction) => void;\n // native event module stuff\n addListener: (eventName: string) => void;\n removeListeners: (count: number) => void;\n};\n\n// Event module declarations\nexport type KeyboardControllerEvents =\n | \"keyboardWillShow\"\n | \"keyboardDidShow\"\n | \"keyboardWillHide\"\n | \"keyboardDidHide\";\nexport type KeyboardEventData = {\n height: number;\n duration: number;\n timestamp: number;\n target: number;\n type: NonNullable<TextInputProps[\"keyboardType\"]>;\n appearance: NonNullable<TextInputProps[\"keyboardAppearance\"]>;\n};\nexport type KeyboardState = {\n isVisible: boolean;\n} & KeyboardEventData;\nexport type KeyboardEventsModule = {\n addListener: (\n name: KeyboardControllerEvents,\n cb: (e: KeyboardEventData) => void,\n ) => EmitterSubscription;\n};\nexport type FocusedInputAvailableEvents = \"focusDidSet\";\nexport type FocusedInputEventData = {\n current: number;\n count: number;\n};\nexport type FocusedInputEventsModule = {\n addListener: (\n name: FocusedInputAvailableEvents,\n cb: (e: FocusedInputEventData) => void,\n ) => EmitterSubscription;\n};\nexport type WindowDimensionsAvailableEvents = \"windowDidResize\";\nexport type WindowDimensionsEventData = {\n width: number;\n height: number;\n};\nexport type WindowDimensionsEventsModule = {\n addListener: (\n name: WindowDimensionsAvailableEvents,\n cb: (e: WindowDimensionsEventData) => void,\n ) => EmitterSubscription;\n};\n\n// reanimated hook declaration\nexport type KeyboardHandlerHook<TContext, Event> = (\n handlers: {\n onKeyboardMoveStart?: (e: NativeEvent, context: TContext) => void;\n onKeyboardMove?: (e: NativeEvent, context: TContext) => void;\n onKeyboardMoveEnd?: (e: NativeEvent, context: TContext) => void;\n onKeyboardMoveInteractive?: (e: NativeEvent, context: TContext) => void;\n },\n dependencies?: unknown[],\n) => (e: NativeSyntheticEvent<Event>) => void;\nexport type FocusedInputLayoutHandlerHook<TContext, Event> = (\n handlers: {\n onFocusedInputLayoutChanged?: (\n e: FocusedInputLayoutChangedEvent,\n context: TContext,\n ) => void;\n },\n dependencies?: unknown[],\n) => (e: NativeSyntheticEvent<Event>) => void;\nexport type FocusedInputTextHandlerHook<TContext, Event> = (\n handlers: {\n onFocusedInputTextChanged?: (\n e: FocusedInputTextChangedEvent,\n context: TContext,\n ) => void;\n },\n dependencies?: unknown[],\n) => (e: NativeSyntheticEvent<Event>) => void;\nexport type FocusedInputSelectionHandlerHook<TContext, Event> = (\n handlers: {\n onFocusedInputSelectionChanged?: (\n e: FocusedInputSelectionChangedEvent,\n context: TContext,\n ) => void;\n },\n dependencies?: unknown[],\n) => (e: NativeSyntheticEvent<Event>) => void;\n\n// package types\nexport type Handlers<T> = Record<string, T | undefined>;\nexport type KeyboardHandler = Partial<{\n onStart: (e: NativeEvent) => void;\n onMove: (e: NativeEvent) => void;\n onEnd: (e: NativeEvent) => void;\n onInteractive: (e: NativeEvent) => void;\n}>;\nexport type KeyboardHandlers = Handlers<KeyboardHandler>;\nexport type FocusedInputHandler = Partial<{\n onChangeText: (e: FocusedInputTextChangedEvent) => void;\n onSelectionChange: (e: FocusedInputSelectionChangedEvent) => void;\n}>;\nexport type FocusedInputHandlers = Handlers<FocusedInputHandler>;\n"],"mappings":"","ignoreList":[]}
@@ -1,27 +0,0 @@
1
- import { useEffect, useState } from "react";
2
- import { WindowDimensionsEvents } from "../../bindings";
3
- let initialDimensions = {
4
- width: 0,
5
- height: 0
6
- };
7
- WindowDimensionsEvents.addListener("windowDidResize", e => {
8
- initialDimensions = e;
9
- });
10
- export const useWindowDimensions = () => {
11
- const [dimensions, setDimensions] = useState(initialDimensions);
12
- useEffect(() => {
13
- const subscription = WindowDimensionsEvents.addListener("windowDidResize", e => {
14
- setDimensions(e);
15
- });
16
-
17
- // we might have missed an update between reading a value in render and
18
- // `addListener` in this handler, so we set it here. If there was
19
- // no change, React will filter out this update as a no-op.
20
- setDimensions(initialDimensions);
21
- return () => {
22
- subscription.remove();
23
- };
24
- }, []);
25
- return dimensions;
26
- };
27
- //# sourceMappingURL=index.android.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["useEffect","useState","WindowDimensionsEvents","initialDimensions","width","height","addListener","e","useWindowDimensions","dimensions","setDimensions","subscription","remove"],"sources":["index.android.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\n\nimport { WindowDimensionsEvents } from \"../../bindings\";\n\nimport type { WindowDimensionsEventData } from \"../../types\";\n\nlet initialDimensions: WindowDimensionsEventData = {\n width: 0,\n height: 0,\n};\n\nWindowDimensionsEvents.addListener(\"windowDidResize\", (e) => {\n initialDimensions = e;\n});\n\nexport const useWindowDimensions = () => {\n const [dimensions, setDimensions] = useState(initialDimensions);\n\n useEffect(() => {\n const subscription = WindowDimensionsEvents.addListener(\n \"windowDidResize\",\n (e) => {\n setDimensions(e);\n },\n );\n\n // we might have missed an update between reading a value in render and\n // `addListener` in this handler, so we set it here. If there was\n // no change, React will filter out this update as a no-op.\n setDimensions(initialDimensions);\n\n return () => {\n subscription.remove();\n };\n }, []);\n\n return dimensions;\n};\n"],"mappings":"AAAA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAE3C,SAASC,sBAAsB,QAAQ,gBAAgB;AAIvD,IAAIC,iBAA4C,GAAG;EACjDC,KAAK,EAAE,CAAC;EACRC,MAAM,EAAE;AACV,CAAC;AAEDH,sBAAsB,CAACI,WAAW,CAAC,iBAAiB,EAAGC,CAAC,IAAK;EAC3DJ,iBAAiB,GAAGI,CAAC;AACvB,CAAC,CAAC;AAEF,OAAO,MAAMC,mBAAmB,GAAGA,CAAA,KAAM;EACvC,MAAM,CAACC,UAAU,EAAEC,aAAa,CAAC,GAAGT,QAAQ,CAACE,iBAAiB,CAAC;EAE/DH,SAAS,CAAC,MAAM;IACd,MAAMW,YAAY,GAAGT,sBAAsB,CAACI,WAAW,CACrD,iBAAiB,EAChBC,CAAC,IAAK;MACLG,aAAa,CAACH,CAAC,CAAC;IAClB,CACF,CAAC;;IAED;IACA;IACA;IACAG,aAAa,CAACP,iBAAiB,CAAC;IAEhC,OAAO,MAAM;MACXQ,YAAY,CAACC,MAAM,CAAC,CAAC;IACvB,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,OAAOH,UAAU;AACnB,CAAC","ignoreList":[]}