react-native-keyboard-controller 1.21.0-beta.2 → 1.21.0

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 (214) hide show
  1. package/README.md +1 -0
  2. package/android/src/base/java/com/reactnativekeyboardcontroller/KeyboardControllerPackage.kt +1 -0
  3. package/android/src/fabric/java/com/reactnativekeyboardcontroller/ClippingScrollViewDecoratorViewManager.kt +14 -0
  4. package/android/src/fabric/java/com/reactnativekeyboardcontroller/KeyboardControllerModule.kt +8 -0
  5. package/android/src/fabric/java/com/reactnativekeyboardcontroller/KeyboardToolbarGroupViewManager.kt +23 -0
  6. package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/ReactContext.kt +12 -0
  7. package/android/src/main/java/com/reactnativekeyboardcontroller/listeners/FocusedInputObserver.kt +2 -1
  8. package/android/src/main/java/com/reactnativekeyboardcontroller/listeners/WindowDimensionListener.kt +5 -1
  9. package/android/src/main/java/com/reactnativekeyboardcontroller/managers/KeyboardToolbarGroupViewManagerImpl.kt +13 -0
  10. package/android/src/main/java/com/reactnativekeyboardcontroller/modal/ModalAttachedWatcher.kt +4 -6
  11. package/android/src/main/java/com/reactnativekeyboardcontroller/modules/KeyboardControllerModuleImpl.kt +26 -0
  12. package/android/src/main/java/com/reactnativekeyboardcontroller/traversal/ViewHierarchyNavigator.kt +31 -4
  13. package/android/src/main/java/com/reactnativekeyboardcontroller/views/ClippingScrollViewDecoratorView.kt +33 -1
  14. package/android/src/main/java/com/reactnativekeyboardcontroller/views/KeyboardToolbarGroupReactViewGroup.kt +13 -0
  15. package/android/src/main/jni/RNKC.h +2 -0
  16. package/android/src/paper/java/com/reactnativekeyboardcontroller/ClippingScrollViewDecoratorViewManager.kt +16 -0
  17. package/android/src/paper/java/com/reactnativekeyboardcontroller/KeyboardControllerModule.kt +9 -0
  18. package/android/src/paper/java/com/reactnativekeyboardcontroller/KeyboardToolbarGroupViewManager.kt +15 -0
  19. package/android/src/turbo/java/com/reactnativekeyboardcontroller/KeyboardControllerPackage.kt +2 -0
  20. package/common/cpp/react/renderer/components/RNKC/RNKCClippingScrollViewDecoratorViewComponentDescriptor.h +27 -0
  21. package/common/cpp/react/renderer/components/RNKC/RNKCClippingScrollViewDecoratorViewShadowNode.cpp +14 -0
  22. package/common/cpp/react/renderer/components/RNKC/RNKCClippingScrollViewDecoratorViewShadowNode.h +30 -0
  23. package/common/cpp/react/renderer/components/RNKC/RNKCClippingScrollViewDecoratorViewState.h +28 -0
  24. package/common/cpp/react/renderer/components/RNKC/RNKCKeyboardToolbarGroupViewComponentDescriptor.h +20 -0
  25. package/common/cpp/react/renderer/components/RNKC/RNKCKeyboardToolbarGroupViewShadowNode.cpp +7 -0
  26. package/common/cpp/react/renderer/components/RNKC/RNKCKeyboardToolbarGroupViewShadowNode.h +23 -0
  27. package/common/cpp/react/renderer/components/RNKC/RNKCKeyboardToolbarGroupViewState.h +21 -0
  28. package/ios/KeyboardControllerModule.mm +36 -0
  29. package/ios/animations/KeyboardAnimation.swift +2 -2
  30. package/ios/animations/SpringAnimation.swift +1 -1
  31. package/ios/animations/TimingAnimation.swift +1 -3
  32. package/ios/delegates/KCTextInputCompositeDelegate.swift +2 -2
  33. package/ios/extensions/CGFloat.swift +1 -3
  34. package/ios/extensions/UIApplication.swift +1 -1
  35. package/ios/interactive/KeyboardAreaExtender.swift +2 -1
  36. package/ios/observers/FocusedInputObserver.swift +6 -3
  37. package/ios/observers/movement/KeyboardTrackingView.swift +4 -1
  38. package/ios/observers/movement/observer/KeyboardMovementObserver+Interactive.swift +2 -0
  39. package/ios/observers/movement/observer/KeyboardMovementObserver+Listeners.swift +30 -7
  40. package/ios/observers/movement/observer/KeyboardMovementObserver.swift +2 -48
  41. package/ios/protocols/TextInput.swift +1 -1
  42. package/ios/swizzling/UIResponderSwizzle.swift +2 -4
  43. package/ios/traversal/FocusedInputHolder.swift +3 -3
  44. package/ios/traversal/KeyboardView.swift +1 -1
  45. package/ios/traversal/ViewHierarchyNavigator.swift +51 -5
  46. package/ios/views/ClippingScrollViewDecoratorViewManager.h +26 -0
  47. package/ios/views/ClippingScrollViewDecoratorViewManager.mm +231 -0
  48. package/ios/views/KeyboardControllerViewManager.swift +5 -5
  49. package/ios/views/KeyboardToolbarGroupViewManager.h +28 -0
  50. package/ios/views/KeyboardToolbarGroupViewManager.mm +88 -0
  51. package/jest/index.js +12 -4
  52. package/lib/commonjs/bindings.js +18 -2
  53. package/lib/commonjs/bindings.js.map +1 -1
  54. package/lib/commonjs/bindings.native.js +3 -4
  55. package/lib/commonjs/bindings.native.js.map +1 -1
  56. package/lib/commonjs/components/KeyboardAvoidingView/index.js +30 -4
  57. package/lib/commonjs/components/KeyboardAvoidingView/index.js.map +1 -1
  58. package/lib/commonjs/components/KeyboardAwareScrollView/index.js +55 -14
  59. package/lib/commonjs/components/KeyboardAwareScrollView/index.js.map +1 -1
  60. package/lib/commonjs/components/{ChatKit → KeyboardChatScrollView}/hooks.js.map +1 -1
  61. package/lib/commonjs/components/KeyboardChatScrollView/index.js +111 -0
  62. package/lib/commonjs/components/KeyboardChatScrollView/index.js.map +1 -0
  63. package/lib/commonjs/components/KeyboardChatScrollView/types.js.map +1 -0
  64. package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/helpers.js +221 -0
  65. package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/helpers.js.map +1 -0
  66. package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js +149 -0
  67. package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js.map +1 -0
  68. package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.js +240 -0
  69. package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.js.map +1 -0
  70. package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/types.js +6 -0
  71. package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/types.js.map +1 -0
  72. package/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js +72 -0
  73. package/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js.map +1 -0
  74. package/lib/commonjs/components/KeyboardStickyView/index.js +3 -1
  75. package/lib/commonjs/components/KeyboardStickyView/index.js.map +1 -1
  76. package/lib/commonjs/components/KeyboardToolbar/index.js +1 -0
  77. package/lib/commonjs/components/KeyboardToolbar/index.js.map +1 -1
  78. package/lib/commonjs/components/ScrollViewWithBottomPadding/index.js +36 -15
  79. package/lib/commonjs/components/ScrollViewWithBottomPadding/index.js.map +1 -1
  80. package/lib/commonjs/components/hooks/useScrollState.js +20 -1
  81. package/lib/commonjs/components/hooks/useScrollState.js.map +1 -1
  82. package/lib/commonjs/components/index.js +7 -7
  83. package/lib/commonjs/components/index.js.map +1 -1
  84. package/lib/commonjs/index.js +7 -7
  85. package/lib/commonjs/index.js.map +1 -1
  86. package/lib/commonjs/specs/ClippingScrollViewDecoratorViewNativeComponent.js +1 -2
  87. package/lib/commonjs/specs/ClippingScrollViewDecoratorViewNativeComponent.js.map +1 -1
  88. package/lib/commonjs/specs/KeyboardToolbarGroupViewNativeComponent.js +12 -0
  89. package/lib/commonjs/specs/KeyboardToolbarGroupViewNativeComponent.js.map +1 -0
  90. package/lib/commonjs/specs/NativeKeyboardController.js.map +1 -1
  91. package/lib/commonjs/types/module.js.map +1 -1
  92. package/lib/commonjs/types/views.js.map +1 -1
  93. package/lib/module/bindings.js +17 -1
  94. package/lib/module/bindings.js.map +1 -1
  95. package/lib/module/bindings.native.js +2 -3
  96. package/lib/module/bindings.native.js.map +1 -1
  97. package/lib/module/components/KeyboardAvoidingView/index.js +29 -4
  98. package/lib/module/components/KeyboardAvoidingView/index.js.map +1 -1
  99. package/lib/module/components/KeyboardAwareScrollView/index.js +55 -14
  100. package/lib/module/components/KeyboardAwareScrollView/index.js.map +1 -1
  101. package/lib/module/components/{ChatKit → KeyboardChatScrollView}/hooks.js.map +1 -1
  102. package/lib/module/components/KeyboardChatScrollView/index.js +104 -0
  103. package/lib/module/components/KeyboardChatScrollView/index.js.map +1 -0
  104. package/lib/module/components/KeyboardChatScrollView/types.js.map +1 -0
  105. package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/helpers.js +207 -0
  106. package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/helpers.js.map +1 -0
  107. package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js +143 -0
  108. package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js.map +1 -0
  109. package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.js +234 -0
  110. package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.js.map +1 -0
  111. package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/types.js +2 -0
  112. package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/types.js.map +1 -0
  113. package/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js +67 -0
  114. package/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js.map +1 -0
  115. package/lib/module/components/KeyboardStickyView/index.js +3 -1
  116. package/lib/module/components/KeyboardStickyView/index.js.map +1 -1
  117. package/lib/module/components/KeyboardToolbar/index.js +2 -1
  118. package/lib/module/components/KeyboardToolbar/index.js.map +1 -1
  119. package/lib/module/components/ScrollViewWithBottomPadding/index.js +38 -17
  120. package/lib/module/components/ScrollViewWithBottomPadding/index.js.map +1 -1
  121. package/lib/module/components/hooks/useScrollState.js +21 -2
  122. package/lib/module/components/hooks/useScrollState.js.map +1 -1
  123. package/lib/module/components/index.js +1 -1
  124. package/lib/module/components/index.js.map +1 -1
  125. package/lib/module/index.js +1 -1
  126. package/lib/module/index.js.map +1 -1
  127. package/lib/module/specs/ClippingScrollViewDecoratorViewNativeComponent.js +1 -2
  128. package/lib/module/specs/ClippingScrollViewDecoratorViewNativeComponent.js.map +1 -1
  129. package/lib/module/specs/KeyboardToolbarGroupViewNativeComponent.js +5 -0
  130. package/lib/module/specs/KeyboardToolbarGroupViewNativeComponent.js.map +1 -0
  131. package/lib/module/specs/NativeKeyboardController.js.map +1 -1
  132. package/lib/module/types/module.js.map +1 -1
  133. package/lib/module/types/views.js.map +1 -1
  134. package/lib/typescript/bindings.d.ts +12 -2
  135. package/lib/typescript/bindings.native.d.ts +2 -1
  136. package/lib/typescript/components/KeyboardAvoidingView/index.d.ts +44 -13
  137. package/lib/typescript/components/KeyboardChatScrollView/hooks.d.ts +2 -0
  138. package/lib/typescript/components/KeyboardChatScrollView/index.d.ts +15 -0
  139. package/lib/typescript/components/{ChatKit → KeyboardChatScrollView}/types.d.ts +46 -6
  140. package/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/helpers.d.ts +132 -0
  141. package/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/index.d.ts +18 -0
  142. package/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/index.ios.d.ts +21 -0
  143. package/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/types.d.ts +37 -0
  144. package/lib/typescript/components/KeyboardChatScrollView/useExtraContentPadding/index.d.ts +43 -0
  145. package/lib/typescript/components/KeyboardToolbar/index.d.ts +2 -0
  146. package/lib/typescript/components/ScrollViewWithBottomPadding/index.d.ts +5 -4
  147. package/lib/typescript/components/hooks/useScrollState.d.ts +3 -0
  148. package/lib/typescript/components/index.d.ts +2 -2
  149. package/lib/typescript/index.d.ts +2 -2
  150. package/lib/typescript/specs/ClippingScrollViewDecoratorViewNativeComponent.d.ts +2 -0
  151. package/lib/typescript/specs/KeyboardToolbarGroupViewNativeComponent.d.ts +6 -0
  152. package/lib/typescript/specs/NativeKeyboardController.d.ts +1 -0
  153. package/lib/typescript/types/module.d.ts +7 -0
  154. package/lib/typescript/types/views.d.ts +4 -0
  155. package/package.json +6 -2
  156. package/react-native.config.js +2 -0
  157. package/src/bindings.native.ts +4 -4
  158. package/src/bindings.ts +15 -1
  159. package/src/components/KeyboardAvoidingView/index.tsx +56 -29
  160. package/src/components/KeyboardAwareScrollView/index.tsx +68 -13
  161. package/src/components/KeyboardChatScrollView/hooks.ts +2 -0
  162. package/src/components/KeyboardChatScrollView/index.tsx +150 -0
  163. package/src/components/{ChatKit → KeyboardChatScrollView}/types.ts +46 -6
  164. package/src/components/KeyboardChatScrollView/useChatKeyboard/helpers.ts +268 -0
  165. package/src/components/KeyboardChatScrollView/useChatKeyboard/index.ios.ts +260 -0
  166. package/src/components/KeyboardChatScrollView/useChatKeyboard/index.ts +376 -0
  167. package/src/components/KeyboardChatScrollView/useChatKeyboard/types.ts +39 -0
  168. package/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts +123 -0
  169. package/src/components/KeyboardStickyView/index.tsx +4 -3
  170. package/src/components/KeyboardToolbar/index.tsx +6 -1
  171. package/src/components/ScrollViewWithBottomPadding/index.tsx +53 -29
  172. package/src/components/hooks/useScrollState.ts +24 -2
  173. package/src/components/index.ts +2 -2
  174. package/src/index.ts +2 -2
  175. package/src/specs/ClippingScrollViewDecoratorViewNativeComponent.ts +2 -1
  176. package/src/specs/KeyboardToolbarGroupViewNativeComponent.ts +10 -0
  177. package/src/specs/NativeKeyboardController.ts +1 -0
  178. package/src/types/module.ts +9 -0
  179. package/src/types/views.ts +4 -0
  180. package/android/.settings/org.eclipse.buildship.core.prefs +0 -2
  181. package/ios/KeyboardController.xcodeproj/xcuserdata/kirylziusko.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  182. package/ios/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  183. package/ios/Tests/Tests.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  184. package/ios/Tests/Tests.xcodeproj/project.xcworkspace/xcuserdata/kirylziusko.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  185. package/ios/Tests/Tests.xcodeproj/xcuserdata/kirylziusko.xcuserdatad/xcschemes/xcschememanagement.plist +0 -32
  186. package/lib/commonjs/components/ChatKit/TODO.md +0 -20
  187. package/lib/commonjs/components/ChatKit/index.js +0 -55
  188. package/lib/commonjs/components/ChatKit/index.js.map +0 -1
  189. package/lib/commonjs/components/ChatKit/types.js.map +0 -1
  190. package/lib/commonjs/components/ChatKit/useChatKeyboard/helpers.js +0 -101
  191. package/lib/commonjs/components/ChatKit/useChatKeyboard/helpers.js.map +0 -1
  192. package/lib/commonjs/components/ChatKit/useChatKeyboard/index.js +0 -147
  193. package/lib/commonjs/components/ChatKit/useChatKeyboard/index.js.map +0 -1
  194. package/lib/module/components/ChatKit/TODO.md +0 -20
  195. package/lib/module/components/ChatKit/index.js +0 -48
  196. package/lib/module/components/ChatKit/index.js.map +0 -1
  197. package/lib/module/components/ChatKit/types.js.map +0 -1
  198. package/lib/module/components/ChatKit/useChatKeyboard/helpers.js +0 -92
  199. package/lib/module/components/ChatKit/useChatKeyboard/helpers.js.map +0 -1
  200. package/lib/module/components/ChatKit/useChatKeyboard/index.js +0 -141
  201. package/lib/module/components/ChatKit/useChatKeyboard/index.js.map +0 -1
  202. package/lib/typescript/components/ChatKit/hooks.d.ts +0 -2
  203. package/lib/typescript/components/ChatKit/index.d.ts +0 -14
  204. package/lib/typescript/components/ChatKit/useChatKeyboard/helpers.d.ts +0 -57
  205. package/lib/typescript/components/ChatKit/useChatKeyboard/index.d.ts +0 -36
  206. package/src/components/ChatKit/TODO.md +0 -20
  207. package/src/components/ChatKit/hooks.ts +0 -2
  208. package/src/components/ChatKit/index.tsx +0 -63
  209. package/src/components/ChatKit/useChatKeyboard/helpers.ts +0 -118
  210. package/src/components/ChatKit/useChatKeyboard/index.ts +0 -228
  211. /package/lib/commonjs/components/{ChatKit → KeyboardChatScrollView}/hooks.js +0 -0
  212. /package/lib/commonjs/components/{ChatKit → KeyboardChatScrollView}/types.js +0 -0
  213. /package/lib/module/components/{ChatKit → KeyboardChatScrollView}/hooks.js +0 -0
  214. /package/lib/module/components/{ChatKit → KeyboardChatScrollView}/types.js +0 -0
@@ -0,0 +1,123 @@
1
+ import { scrollTo, useAnimatedReaction } from "react-native-reanimated";
2
+
3
+ import { isScrollAtEnd, shouldShiftContent } from "../useChatKeyboard/helpers";
4
+
5
+ import type { KeyboardLiftBehavior } from "../useChatKeyboard/types";
6
+ import type { AnimatedRef, SharedValue } from "react-native-reanimated";
7
+ import type Reanimated from "react-native-reanimated";
8
+
9
+ type UseExtraContentPaddingOptions = {
10
+ scrollViewRef: AnimatedRef<Reanimated.ScrollView>;
11
+ extraContentPadding: SharedValue<number>;
12
+ /** Keyboard-only padding from useChatKeyboard — used to compute total padding for clamping. */
13
+ keyboardPadding: SharedValue<number>;
14
+ /** Minimum inset floor — used to absorb keyboard and extraContentPadding changes. */
15
+ blankSpace: SharedValue<number>;
16
+ /** Current vertical scroll offset. */
17
+ scroll: SharedValue<number>;
18
+ /** Visible viewport dimensions. */
19
+ layout: SharedValue<{ width: number; height: number }>;
20
+ /** Total content dimensions. */
21
+ size: SharedValue<{ width: number; height: number }>;
22
+ inverted: boolean;
23
+ keyboardLiftBehavior: KeyboardLiftBehavior;
24
+ freeze: boolean;
25
+ };
26
+
27
+ /**
28
+ * Hook that reacts to `extraContentPadding` changes and conditionally
29
+ * adjusts the scroll position using `scrollTo` on both iOS and Android.
30
+ *
31
+ * Padding extension (scrollable range) is handled externally via a
32
+ * `useDerivedValue` that sums keyboard padding + extra content padding.
33
+ * This hook only handles the scroll correction.
34
+ *
35
+ * @param options - Configuration and shared values.
36
+ * @example
37
+ * ```tsx
38
+ * useExtraContentPadding({ scrollViewRef, extraContentPadding, ... });
39
+ * ```
40
+ */
41
+ function useExtraContentPadding(options: UseExtraContentPaddingOptions): void {
42
+ const {
43
+ scrollViewRef,
44
+ extraContentPadding,
45
+ keyboardPadding,
46
+ blankSpace,
47
+ scroll,
48
+ layout,
49
+ size,
50
+ inverted,
51
+ keyboardLiftBehavior,
52
+ freeze,
53
+ } = options;
54
+
55
+ useAnimatedReaction(
56
+ () => extraContentPadding.value,
57
+ (current, previous) => {
58
+ if (freeze || previous === null) {
59
+ return;
60
+ }
61
+
62
+ const rawDelta = current - previous;
63
+
64
+ if (rawDelta === 0) {
65
+ return;
66
+ }
67
+
68
+ // Compute effective delta considering blankSpace floor
69
+ const previousTotal = Math.max(
70
+ blankSpace.value,
71
+ keyboardPadding.value + previous,
72
+ );
73
+ const currentTotal = Math.max(
74
+ blankSpace.value,
75
+ keyboardPadding.value + current,
76
+ );
77
+ const effectiveDelta = currentTotal - previousTotal;
78
+
79
+ if (effectiveDelta === 0) {
80
+ // blankSpace absorbed the change
81
+ return;
82
+ }
83
+
84
+ const atEnd = isScrollAtEnd(
85
+ scroll.value,
86
+ layout.value.height,
87
+ size.value.height,
88
+ inverted,
89
+ );
90
+
91
+ // "persistent": scroll on grow, hold position on shrink (unless at end)
92
+ if (
93
+ keyboardLiftBehavior === "persistent" &&
94
+ effectiveDelta < 0 &&
95
+ !atEnd
96
+ ) {
97
+ return;
98
+ }
99
+
100
+ if (!shouldShiftContent(keyboardLiftBehavior, atEnd)) {
101
+ return;
102
+ }
103
+
104
+ if (inverted) {
105
+ const target = Math.max(scroll.value - effectiveDelta, -currentTotal);
106
+
107
+ scrollTo(scrollViewRef, 0, target, false);
108
+ } else {
109
+ const maxScroll = Math.max(
110
+ size.value.height - layout.value.height + currentTotal,
111
+ 0,
112
+ );
113
+ const target = Math.min(scroll.value + effectiveDelta, maxScroll);
114
+
115
+ scrollTo(scrollViewRef, 0, target, false);
116
+ }
117
+ },
118
+ [inverted, keyboardLiftBehavior, freeze],
119
+ );
120
+ }
121
+
122
+ export { useExtraContentPadding };
123
+ export type { UseExtraContentPaddingOptions };
@@ -59,11 +59,12 @@ const KeyboardStickyView = forwardRef<
59
59
  });
60
60
 
61
61
  const styles = useMemo(() => {
62
+ const disabled = Animated.add(Animated.multiply(height, 0), closed);
63
+ const active = Animated.add(height, offset);
64
+
62
65
  return [
63
66
  {
64
- transform: [
65
- { translateY: enabled ? Animated.add(height, offset) : closed },
66
- ],
67
+ transform: [{ translateY: enabled ? active : disabled }],
67
68
  },
68
69
  style,
69
70
  ];
@@ -1,7 +1,10 @@
1
1
  import React, { useEffect, useMemo, useState } from "react";
2
2
  import { StyleSheet, View } from "react-native";
3
3
 
4
- import { FocusedInputEvents } from "../../bindings";
4
+ import {
5
+ FocusedInputEvents,
6
+ RCTKeyboardToolbarGroupView,
7
+ } from "../../bindings";
5
8
  import { useKeyboardState } from "../../hooks";
6
9
  import KeyboardStickyView from "../KeyboardStickyView";
7
10
 
@@ -41,6 +44,7 @@ const KeyboardToolbar: React.FC<KeyboardToolbarProps> & {
41
44
  Prev: typeof Prev;
42
45
  Next: typeof Next;
43
46
  Done: typeof Done;
47
+ Group: typeof RCTKeyboardToolbarGroupView;
44
48
  } = (props) => {
45
49
  const {
46
50
  children,
@@ -227,6 +231,7 @@ KeyboardToolbar.Content = Content;
227
231
  KeyboardToolbar.Prev = Prev;
228
232
  KeyboardToolbar.Next = Next;
229
233
  KeyboardToolbar.Done = Done;
234
+ KeyboardToolbar.Group = RCTKeyboardToolbarGroupView;
230
235
 
231
236
  export { colors as DefaultKeyboardToolbarTheme, KeyboardToolbarProps };
232
237
  export default KeyboardToolbar;
@@ -1,12 +1,15 @@
1
1
  import React, { forwardRef } from "react";
2
- import { Platform } from "react-native";
3
- import Reanimated, { useAnimatedProps } from "react-native-reanimated";
2
+ import { Platform, View } from "react-native";
3
+ import Reanimated, {
4
+ useAnimatedProps,
5
+ useSharedValue,
6
+ } from "react-native-reanimated";
4
7
 
5
8
  import { ClippingScrollView } from "../../bindings";
6
9
 
7
10
  import styles from "./styles";
8
11
 
9
- import type { ScrollViewProps, StyleProp, ViewStyle } from "react-native";
12
+ import type { ScrollViewProps } from "react-native";
10
13
  import type { SharedValue } from "react-native-reanimated";
11
14
 
12
15
  const OS = Platform.OS;
@@ -28,10 +31,11 @@ type ScrollViewWithBottomPaddingProps = {
28
31
  children?: React.ReactNode;
29
32
  inverted?: boolean;
30
33
  bottomPadding: SharedValue<number>;
31
- /** Absolute Y content offset (iOS only, for ChatKit). */
34
+ /** Padding for scroll indicator insets (excludes blankSpace). Falls back to bottomPadding when not provided. */
35
+ scrollIndicatorPadding?: SharedValue<number>;
36
+ /** Absolute Y content offset (iOS only, for KeyboardChatScrollView). */
32
37
  contentOffsetY?: SharedValue<number>;
33
- /** Style applied to the container wrapper (Android only, for ChatKit translateY). */
34
- containerStyle?: StyleProp<ViewStyle>;
38
+ applyWorkaroundForContentInsetHitTestBug?: boolean;
35
39
  } & ScrollViewProps;
36
40
 
37
41
  const ScrollViewWithBottomPadding = forwardRef<
@@ -42,24 +46,32 @@ const ScrollViewWithBottomPadding = forwardRef<
42
46
  {
43
47
  ScrollViewComponent,
44
48
  bottomPadding,
49
+ scrollIndicatorPadding,
45
50
  contentInset,
46
51
  scrollIndicatorInsets,
47
52
  inverted,
48
53
  contentOffsetY,
49
- containerStyle,
54
+ applyWorkaroundForContentInsetHitTestBug,
50
55
  children,
51
- style,
52
56
  ...rest
53
57
  },
54
58
  ref,
55
59
  ) => {
60
+ const prevContentOffsetY = useSharedValue<number | null>(null);
61
+
56
62
  const animatedProps = useAnimatedProps(() => {
57
- const bottom = inverted
58
- ? 0
59
- : bottomPadding.value + (contentInset?.bottom || 0);
60
- const top = !inverted
61
- ? 0
62
- : bottomPadding.value + (contentInset?.top || 0);
63
+ const insetTop = inverted ? bottomPadding.value : 0;
64
+ const insetBottom = !inverted ? bottomPadding.value : 0;
65
+ const bottom = insetBottom + (contentInset?.bottom || 0);
66
+ const top = insetTop + (contentInset?.top || 0);
67
+
68
+ const indicatorPadding = scrollIndicatorPadding ?? bottomPadding;
69
+ const indicatorTop =
70
+ (inverted ? indicatorPadding.value : 0) +
71
+ (scrollIndicatorInsets?.top || 0);
72
+ const indicatorBottom =
73
+ (!inverted ? indicatorPadding.value : 0) +
74
+ (scrollIndicatorInsets?.bottom || 0);
63
75
 
64
76
  const result: Record<string, unknown> = {
65
77
  // iOS prop
@@ -70,17 +82,24 @@ const ScrollViewWithBottomPadding = forwardRef<
70
82
  left: contentInset?.left,
71
83
  },
72
84
  scrollIndicatorInsets: {
73
- bottom: bottom,
74
- top: top,
85
+ bottom: indicatorBottom,
86
+ top: indicatorTop,
75
87
  right: scrollIndicatorInsets?.right,
76
88
  left: scrollIndicatorInsets?.left,
77
89
  },
78
90
  // Android prop
79
- contentInsetBottom: bottomPadding.value,
91
+ contentInsetBottom: insetBottom,
92
+ contentInsetTop: insetTop,
80
93
  };
81
94
 
82
95
  if (contentOffsetY) {
83
- result.contentOffset = { x: 0, y: contentOffsetY.value };
96
+ const curr = contentOffsetY.value;
97
+
98
+ if (curr !== prevContentOffsetY.value) {
99
+ // eslint-disable-next-line react-compiler/react-compiler
100
+ prevContentOffsetY.value = curr;
101
+ result.contentOffset = { x: 0, y: curr };
102
+ }
84
103
  }
85
104
 
86
105
  return result;
@@ -100,18 +119,23 @@ const ScrollViewWithBottomPadding = forwardRef<
100
119
  return (
101
120
  <ReanimatedClippingScrollView
102
121
  animatedProps={animatedProps}
103
- style={[
104
- styles.container,
105
- OS === "android" ? containerStyle : undefined,
106
- ]}
122
+ applyWorkaroundForContentInsetHitTestBug={
123
+ applyWorkaroundForContentInsetHitTestBug
124
+ }
125
+ style={styles.container}
107
126
  >
108
- <ScrollViewComponent
109
- ref={ref}
110
- animatedProps={animatedProps}
111
- style={style}
112
- {...rest}
113
- >
114
- {children}
127
+ <ScrollViewComponent ref={ref} animatedProps={animatedProps} {...rest}>
128
+ {inverted ? (
129
+ // The only thing it can break is `StickyHeader`, but it's already broken in FlatList and other lists
130
+ // don't support this functionality, so we can add additional view here
131
+ // The correct fix would be to add a new prop in ScrollView that allows
132
+ // to customize children extraction logic and skip custom view
133
+ <View collapsable={false} nativeID="container">
134
+ {children}
135
+ </View>
136
+ ) : (
137
+ children
138
+ )}
115
139
  </ScrollViewComponent>
116
140
  </ReanimatedClippingScrollView>
117
141
  );
@@ -1,8 +1,9 @@
1
- import { useEffect } from "react";
1
+ import { useCallback, useEffect } from "react";
2
2
  import { useEvent, useSharedValue } from "react-native-reanimated";
3
3
 
4
4
  import { useEventHandlerRegistration } from "../../internal";
5
5
 
6
+ import type { LayoutChangeEvent } from "react-native";
6
7
  import type { AnimatedRef } from "react-native-reanimated";
7
8
  import type Reanimated from "react-native-reanimated";
8
9
 
@@ -53,7 +54,28 @@ const useScrollState = (ref: AnimatedRef<Reanimated.ScrollView>) => {
53
54
  };
54
55
  }, []);
55
56
 
56
- return { offset, layout, size };
57
+ // `onContentSizeChange` is synthesized in JS (from the content container's
58
+ // onLayout) and `onLayout` has a different payload shape than scroll events,
59
+ // so neither can be reliably captured via native event registration.
60
+ // Instead we expose callbacks for the consumer to attach as props.
61
+ const onLayout = useCallback(
62
+ (e: LayoutChangeEvent) => {
63
+ layout.value = {
64
+ width: e.nativeEvent.layout.width,
65
+ height: e.nativeEvent.layout.height,
66
+ };
67
+ },
68
+ [layout],
69
+ );
70
+
71
+ const onContentSizeChange = useCallback(
72
+ (w: number, h: number) => {
73
+ size.value = { width: w, height: h };
74
+ },
75
+ [size],
76
+ );
77
+
78
+ return { offset, layout, size, onLayout, onContentSizeChange };
57
79
  };
58
80
 
59
81
  export default useScrollState;
@@ -5,7 +5,7 @@ export {
5
5
  default as KeyboardToolbar,
6
6
  DefaultKeyboardToolbarTheme,
7
7
  } from "./KeyboardToolbar";
8
- export { default as ChatKit } from "./ChatKit";
8
+ export { default as KeyboardChatScrollView } from "./KeyboardChatScrollView";
9
9
  export type { KeyboardAvoidingViewProps } from "./KeyboardAvoidingView";
10
10
  export type { KeyboardStickyViewProps } from "./KeyboardStickyView";
11
11
  export type {
@@ -13,4 +13,4 @@ export type {
13
13
  KeyboardAwareScrollViewRef,
14
14
  } from "./KeyboardAwareScrollView";
15
15
  export type { KeyboardToolbarProps } from "./KeyboardToolbar";
16
- export type { ChatKitScrollViewProps } from "./ChatKit/types";
16
+ export type { KeyboardChatScrollViewProps } from "./KeyboardChatScrollView/types";
package/src/index.ts CHANGED
@@ -8,7 +8,7 @@ export * from "./types";
8
8
  export * from "./compat";
9
9
 
10
10
  export {
11
- ChatKit,
11
+ KeyboardChatScrollView,
12
12
  KeyboardAvoidingView,
13
13
  KeyboardStickyView,
14
14
  KeyboardAwareScrollView,
@@ -17,7 +17,7 @@ export {
17
17
  DefaultKeyboardToolbarTheme,
18
18
  } from "./components";
19
19
  export type {
20
- ChatKitScrollViewProps,
20
+ KeyboardChatScrollViewProps,
21
21
  KeyboardAvoidingViewProps,
22
22
  KeyboardStickyViewProps,
23
23
  KeyboardAwareScrollViewProps,
@@ -6,12 +6,13 @@ import type { Double } from "react-native/Libraries/Types/CodegenTypes";
6
6
 
7
7
  export interface NativeProps extends ViewProps {
8
8
  contentInsetBottom: Double;
9
+ contentInsetTop: Double;
10
+ applyWorkaroundForContentInsetHitTestBug?: boolean;
9
11
  }
10
12
 
11
13
  export default codegenNativeComponent<NativeProps>(
12
14
  "ClippingScrollViewDecoratorView",
13
15
  {
14
16
  interfaceOnly: true,
15
- excludedPlatforms: ["iOS"],
16
17
  },
17
18
  ) as HostComponent<NativeProps>;
@@ -0,0 +1,10 @@
1
+ import codegenNativeComponent from "react-native/Libraries/Utilities/codegenNativeComponent";
2
+
3
+ import type { HostComponent } from "react-native";
4
+ import type { ViewProps } from "react-native/Libraries/Components/View/ViewPropTypes";
5
+
6
+ export interface NativeProps extends ViewProps {}
7
+
8
+ export default codegenNativeComponent<NativeProps>("KeyboardToolbarGroupView", {
9
+ interfaceOnly: true,
10
+ }) as HostComponent<NativeProps>;
@@ -11,6 +11,7 @@ export interface Spec extends TurboModule {
11
11
  preload(): void;
12
12
  dismiss(keepFocus: boolean, animated: boolean): void;
13
13
  setFocusTo(direction: string): void;
14
+ viewPositionInWindow(viewTag: number): Promise<object>;
14
15
 
15
16
  // event emitter
16
17
  addListener: (eventName: string) => void;
@@ -109,6 +109,12 @@ export type KeyboardControllerModule = {
109
109
  */
110
110
  state: () => KeyboardEventData;
111
111
  };
112
+ export type ViewPositionInWindowResult = {
113
+ x: number;
114
+ y: number;
115
+ width: number;
116
+ height: number;
117
+ };
112
118
  export type KeyboardControllerNativeModule = {
113
119
  // android only
114
120
  setDefaultMode: () => void;
@@ -118,6 +124,9 @@ export type KeyboardControllerNativeModule = {
118
124
  // all platforms
119
125
  dismiss: (keepFocus: boolean, animated: boolean) => void;
120
126
  setFocusTo: (direction: Direction) => void;
127
+ viewPositionInWindow: (
128
+ viewTag: number,
129
+ ) => Promise<ViewPositionInWindowResult>;
121
130
  // native event module stuff
122
131
  addListener: (eventName: string) => void;
123
132
  removeListeners: (count: number) => void;
@@ -49,9 +49,13 @@ export type KeyboardExtenderProps = PropsWithChildren<{
49
49
  /** Controls whether this `KeyboardExtender` instance should take an effect. Default is `true`. */
50
50
  enabled?: boolean;
51
51
  }>;
52
+ export type KeyboardToolbarGroupViewProps = PropsWithChildren<ViewProps>;
52
53
  export type ClippingScrollViewProps = PropsWithChildren<
53
54
  ViewProps & {
54
55
  /** An additional space that gets applied to the bottom of the `ScrollView` (inside a scrollable content). Default is `0`. */
55
56
  contentInsetBottom?: number;
57
+ /** An additional space that gets applied to the top of the `ScrollView` (inside a scrollable content). Default is `0`. */
58
+ contentInsetTop?: number;
59
+ applyWorkaroundForContentInsetHitTestBug?: boolean;
56
60
  }
57
61
  >;
@@ -1,2 +0,0 @@
1
- connection.project.dir=../../../android
2
- eclipse.preferences.version=1
@@ -1,14 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>SchemeUserState</key>
6
- <dict>
7
- <key>KeyboardController.xcscheme_^#shared#^_</key>
8
- <dict>
9
- <key>orderHint</key>
10
- <integer>0</integer>
11
- </dict>
12
- </dict>
13
- </dict>
14
- </plist>
@@ -1,7 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <Workspace
3
- version = "1.0">
4
- <FileRef
5
- location = "self:">
6
- </FileRef>
7
- </Workspace>
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>IDEDidComputeMac32BitWarning</key>
6
- <true/>
7
- </dict>
8
- </plist>
@@ -1,32 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>SchemeUserState</key>
6
- <dict>
7
- <key>Tests.xcscheme_^#shared#^_</key>
8
- <dict>
9
- <key>orderHint</key>
10
- <integer>0</integer>
11
- </dict>
12
- </dict>
13
- <key>SuppressBuildableAutocreation</key>
14
- <dict>
15
- <key>083F2DF22B860D89004A1AD1</key>
16
- <dict>
17
- <key>primary</key>
18
- <true/>
19
- </dict>
20
- <key>083F2E022B860D8C004A1AD1</key>
21
- <dict>
22
- <key>primary</key>
23
- <true/>
24
- </dict>
25
- <key>083F2E0C2B860D8C004A1AD1</key>
26
- <dict>
27
- <key>primary</key>
28
- <true/>
29
- </dict>
30
- </dict>
31
- </dict>
32
- </plist>
@@ -1,20 +0,0 @@
1
- # Findings
2
-
3
- 1. We can not translate whole `ScrollView` because interactive dismissal will have double scroll if we move it by `translateY` or content will be truncated if we don't do it (same with external container).
4
- 2. So we need to move only content inside `ScrollView`.
5
- 3. If we use a separate `scrollTo` we still may have a random jump. The only one way is to use `contentOffset` + `padding` on `ScrollView`.
6
- 4. Input must be always in `KeyboardStickyView` because it's always pushing above the keyboard (unlike content, which may stay in place).
7
- 5. Changing `contentOffset` on `ScrollView` will not work. On iOS it works, but on Android sometimes it doesn't scroll to correct position (when you scroll list to the end) and on paper architecture it is flickering.
8
- 6. Next idea is to use `contentInset` on iOS and create custom `ClippingScrollView` on Android (with polyfill `contentInsetBottom` prop).
9
-
10
- ## To Do
11
-
12
- - [x] check how `ClippingScrollView` works in `KeyboardAwareScrollView` on Android (seems to be working well)
13
- - [x] introduce `useCombinedRef` hook in separate PR
14
- - [x] make sure, that style property doesn't affect the behavior with/without `ClippingScrollView` (test on a ScrollView that doesn't tke full screen?) <-- tested by comparing iOS with Android + `ClippingScrollView` (`contentInsetBottom` never override `paddingBottom` from `style`/`contentContainerStyle` even if ScrollView has `maxHeight=150` and we have only 2 inputs limitation + also tested `ScrollView` without height restrictions, in this case `paddingBottom` on `style` is not getting applied (it doesn't have an effect on both iOS/Android), but `contentContainerStyle` + `paddingBottom` works as expected and if I add `contentInsetBottom` to `ClippingScrollView` it doesn't overwrite a padding and increases scrollable area)
15
- - [x] `ClippingScrollView` + `KeyboardAwareScrollView` check by e2e tests (seems to be working, though on Android emulator + e2e tests sometimes when keyboard disappear we still have keyboard space)
16
- - [x] introduce `ClippingScrollView` in separate PR
17
- - [x] create a polyfill-version of ScrollView `that` can add scrollable padding in the bottom of the content? How to wrap custom `ScrollView` with it (cause we may pass one from react-native-gesture-handler)? Should just adjust `contentInset` (scroll management should belong to `KeyboardAwareScrollView`) (ScrollViewWithKeyboardPadding/ScrollViewWithKeyboardSpace)
18
- - [x] use `ClippingScrollView` in `KeyboardAwareScrollView` in separate PR
19
- - [-] introduce `ChatKit`
20
- - [] create issue in reanimated repo about `scrollTo` performance regression
@@ -1,55 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
- var _react = _interopRequireWildcard(require("react"));
8
- var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
9
- var _useCombinedRef = _interopRequireDefault(require("../hooks/useCombinedRef"));
10
- var _ScrollViewWithBottomPadding = _interopRequireDefault(require("../ScrollViewWithBottomPadding"));
11
- var _useChatKeyboard = require("./useChatKeyboard");
12
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
14
- function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
15
- const ChatScrollView = /*#__PURE__*/(0, _react.forwardRef)(({
16
- children,
17
- ScrollViewComponent = _reactNativeReanimated.default.ScrollView,
18
- inverted = false,
19
- keyboardLiftBehavior = "always",
20
- freeze = false,
21
- offset = 0,
22
- ...rest
23
- }, ref) => {
24
- const scrollViewRef = (0, _reactNativeReanimated.useAnimatedRef)();
25
- const onRef = (0, _useCombinedRef.default)(ref, scrollViewRef);
26
- const {
27
- padding,
28
- contentOffsetY,
29
- containerTranslateY
30
- } = (0, _useChatKeyboard.useChatKeyboard)(scrollViewRef, {
31
- inverted,
32
- keyboardLiftBehavior,
33
- freeze,
34
- offset
35
- });
36
- const containerStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => ({
37
- transform: [{
38
- translateY: containerTranslateY.value
39
- }]
40
- }), []);
41
- return /*#__PURE__*/_react.default.createElement(_ScrollViewWithBottomPadding.default, _extends({
42
- ref: onRef
43
- }, rest, {
44
- bottomPadding: padding,
45
- containerStyle: containerStyle,
46
- contentOffsetY: contentOffsetY,
47
- inverted: inverted,
48
- ScrollViewComponent: ScrollViewComponent
49
- }), children);
50
- });
51
- const ChatKit = {
52
- ScrollView: ChatScrollView
53
- };
54
- var _default = exports.default = ChatKit;
55
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNativeReanimated","_useCombinedRef","_interopRequireDefault","_ScrollViewWithBottomPadding","_useChatKeyboard","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","_extends","assign","bind","arguments","length","apply","ChatScrollView","forwardRef","children","ScrollViewComponent","Reanimated","ScrollView","inverted","keyboardLiftBehavior","freeze","offset","rest","ref","scrollViewRef","useAnimatedRef","onRef","useCombinedRef","padding","contentOffsetY","containerTranslateY","useChatKeyboard","containerStyle","useAnimatedStyle","transform","translateY","value","createElement","bottomPadding","ChatKit","_default","exports"],"sources":["index.tsx"],"sourcesContent":["import React, { forwardRef } from \"react\";\nimport { useAnimatedRef, useAnimatedStyle } from \"react-native-reanimated\";\nimport Reanimated from \"react-native-reanimated\";\n\nimport useCombinedRef from \"../hooks/useCombinedRef\";\nimport ScrollViewWithBottomPadding from \"../ScrollViewWithBottomPadding\";\n\nimport { useChatKeyboard } from \"./useChatKeyboard\";\n\nimport type { ChatKitScrollViewProps } from \"./types\";\n\nconst ChatScrollView = forwardRef<\n Reanimated.ScrollView,\n React.PropsWithChildren<ChatKitScrollViewProps>\n>(\n (\n {\n children,\n ScrollViewComponent = Reanimated.ScrollView,\n inverted = false,\n keyboardLiftBehavior = \"always\",\n freeze = false,\n offset = 0,\n ...rest\n },\n ref,\n ) => {\n const scrollViewRef = useAnimatedRef<Reanimated.ScrollView>();\n const onRef = useCombinedRef(ref, scrollViewRef);\n\n const { padding, contentOffsetY, containerTranslateY } = useChatKeyboard(\n scrollViewRef,\n { inverted, keyboardLiftBehavior, freeze, offset },\n );\n\n const containerStyle = useAnimatedStyle(\n () => ({\n transform: [{ translateY: containerTranslateY.value }],\n }),\n [],\n );\n\n return (\n <ScrollViewWithBottomPadding\n ref={onRef}\n {...rest}\n bottomPadding={padding}\n containerStyle={containerStyle}\n contentOffsetY={contentOffsetY}\n inverted={inverted}\n ScrollViewComponent={ScrollViewComponent}\n >\n {children}\n </ScrollViewWithBottomPadding>\n );\n },\n);\n\nconst ChatKit = {\n ScrollView: ChatScrollView,\n};\n\nexport default ChatKit;\n"],"mappings":"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","ignoreList":[]}
@@ -1 +0,0 @@
1
- {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type { AnimatedScrollViewComponent } from \"../ScrollViewWithBottomPadding\";\nimport type { ScrollViewProps } from \"react-native\";\n\ntype KeyboardLiftBehavior = \"always\" | \"whenAtEnd\" | \"persistent\" | \"never\";\n\nexport type ChatKitScrollViewProps = {\n /** Custom component for `ScrollView`. Default is `ScrollView`. */\n ScrollViewComponent: AnimatedScrollViewComponent;\n /** Whether list are using `inverted` prop. Default is `false`. */\n inverted?: boolean;\n /**\n * The distance (in pixels) between the bottom of the screen and the `ScrollView`.\n * When the keyboard appears, the scroll view will only push content by the effective\n * distance (`keyboardHeight - offset`) instead of the full keyboard height.\n *\n * Useful when the input is not at the very bottom of the screen (e.g., above safe area, above\n * bottom tabs, etc. - in this case offset should be equal to the height of the elements between\n * `ScrollView` and bottom of the screen).\n *\n * Default is `0`.\n */\n offset?: number;\n /**\n * Determines how the chat content should behave when the keyboard appears, specifically whether\n * the scroll view should automatically lift its content to keep it visible above the keyboard.\n *\n * Possible values:\n * - `'always'`: The content always lifts along with the keyboard, ensuring the messages from the bottom part of screen\n * remain visible regardless of the current scroll position. This is the default behavior for most chat applications (used in Telegram).\n * - `'whenAtEnd'`: The content lifts only if the scroll view is at the end (i.e., the last message\n * is visible or near the bottom). This prevents unnecessary adjustments when the user is scrolling\n * through older messages (ChatGPT mobile app behavior).\n * - `'persistent'`: The content always lifts when the keyboard appears (similar to `'always'`), but\n * does not reset (lower) when the keyboard hides. This mimics behaviors where the view remains adjusted\n * after keyboard dismissal to maintain focus on the latest content without shifting back (Claude mobile app behavior).\n * - `'never'`: The content does not lift at all when the keyboard appears. Use this for scenarios\n * when you don't want to disturb user attention with animations (Perplexity mobile app behavior).\n *\n * Default is `'always'`.\n */\n keyboardLiftBehavior?: KeyboardLiftBehavior;\n /**\n * When `true`, freezes all keyboard-driven layout changes (padding, content offset, scroll position).\n * Useful when dismissing the keyboard to open a bottom sheet — prevents visual disruption\n * while the sheet is visible.\n *\n * Default is `false`.\n */\n freeze?: boolean;\n} & ScrollViewProps;\n"],"mappings":"","ignoreList":[]}