From b6a01c48671a5015f2f89b77bf5735ea1ce97479 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Mon, 13 Apr 2026 16:15:46 +0300 Subject: [PATCH] patch react-native-keyboard-controller extraContentPadding scroll fix On iOS Fabric, contentOffset set via animatedProps is clamped against the old contentInset when both change in the same commit. This causes the scroll to fall behind when the input grows near the bottom of the chat. Fix by deferring scrollTo to the next frame so the contentInset commit lands first. Co-Authored-By: Claude Opus 4.6 (1M context) --- ...ct-native-keyboard-controller+1.21.5.patch | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 patches/react-native-keyboard-controller+1.21.5.patch diff --git a/patches/react-native-keyboard-controller+1.21.5.patch b/patches/react-native-keyboard-controller+1.21.5.patch new file mode 100644 index 0000000000..d721bbe494 --- /dev/null +++ b/patches/react-native-keyboard-controller+1.21.5.patch @@ -0,0 +1,48 @@ +diff --git a/node_modules/react-native-keyboard-controller/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts b/node_modules/react-native-keyboard-controller/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts +index 24a25ae..2c5ff6d 100644 +--- a/node_modules/react-native-keyboard-controller/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts ++++ b/node_modules/react-native-keyboard-controller/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts +@@ -1,8 +1,6 @@ + import { useCallback } from "react"; +-import { Platform } from "react-native"; + import { scrollTo, useAnimatedReaction } from "react-native-reanimated"; + +-import { IS_FABRIC } from "../../../architecture"; + import { isScrollAtEnd, shouldShiftContent } from "../useChatKeyboard/helpers"; + + import type { KeyboardLiftBehavior } from "../useChatKeyboard/types"; +@@ -52,7 +50,6 @@ function useExtraContentPadding(options: UseExtraContentPaddingOptions): void { + scroll, + layout, + size, +- contentOffsetY, + inverted, + keyboardLiftBehavior, + freeze, +@@ -62,20 +59,14 @@ function useExtraContentPadding(options: UseExtraContentPaddingOptions): void { + (target: number) => { + "worklet"; + +- if (contentOffsetY && IS_FABRIC) { +- // eslint-disable-next-line react-compiler/react-compiler +- contentOffsetY.value = target; +- } else if (Platform.OS === "android") { +- // Defer scrollTo so the animatedProps inset commit lands first; +- // otherwise the native ScrollView clamps to the old range. +- requestAnimationFrame(() => { +- scrollTo(scrollViewRef, 0, target, false); +- }); +- } else { ++ // Always defer scrollTo so the animatedProps inset commit lands first; ++ // otherwise the native ScrollView clamps contentOffset to the old ++ // contentInset range (iOS Fabric) or the old contentInsetBottom (Android). ++ requestAnimationFrame(() => { + scrollTo(scrollViewRef, 0, target, false); +- } ++ }); + }, +- [scrollViewRef, contentOffsetY], ++ [scrollViewRef], + ); + + useAnimatedReaction(