UNPKG

react-native-keyboard-controller

Version:

Keyboard manager which works in identical way on both iOS and Android

97 lines (93 loc) 3.44 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useExtraContentPadding = useExtraContentPadding; var _react = require("react"); var _reactNative = require("react-native"); var _reactNativeReanimated = require("react-native-reanimated"); var _architecture = require("../../../architecture"); var _helpers = require("../useChatKeyboard/helpers"); /** * Hook that reacts to `extraContentPadding` changes and conditionally * adjusts the scroll position using `scrollTo` on both iOS and Android. * * Padding extension (scrollable range) is handled externally via a * `useDerivedValue` that sums keyboard padding + extra content padding. * This hook only handles the scroll correction. * * @param options - Configuration and shared values. * @example * ```tsx * useExtraContentPadding({ scrollViewRef, extraContentPadding, ... }); * ``` */ function useExtraContentPadding(options) { const { scrollViewRef, extraContentPadding, keyboardPadding, blankSpace, scroll, layout, size, contentOffsetY, inverted, keyboardLiftBehavior, freeze } = options; const scrollToTarget = (0, _react.useCallback)(target => { "worklet"; if (contentOffsetY && _architecture.IS_FABRIC) { // eslint-disable-next-line react-compiler/react-compiler contentOffsetY.value = target; } else if (_reactNative.Platform.OS === "android") { // Defer scrollTo so the animatedProps inset commit lands first; // otherwise the native ScrollView clamps to the old range. requestAnimationFrame(() => { // check that view is still mounted and ref is actual // otherwise it may lead to a crash if (!scrollViewRef()) { return; } (0, _reactNativeReanimated.scrollTo)(scrollViewRef, 0, target, false); }); } else { (0, _reactNativeReanimated.scrollTo)(scrollViewRef, 0, target, false); } }, [scrollViewRef, contentOffsetY]); (0, _reactNativeReanimated.useAnimatedReaction)(() => extraContentPadding.value, (current, previous) => { if (freeze.value || previous === null) { return; } const rawDelta = current - previous; if (rawDelta === 0) { return; } // Compute effective delta considering blankSpace floor const previousTotal = Math.max(blankSpace.value, keyboardPadding.value + previous); const currentTotal = Math.max(blankSpace.value, keyboardPadding.value + current); const effectiveDelta = currentTotal - previousTotal; if (effectiveDelta === 0) { // blankSpace absorbed the change return; } const atEnd = (0, _helpers.isScrollAtEnd)(scroll.value, layout.value.height, size.value.height, inverted); // "persistent": scroll on grow, hold position on shrink (unless at end) if (keyboardLiftBehavior === "persistent" && effectiveDelta < 0 && !atEnd) { return; } if (!(0, _helpers.shouldShiftContent)(keyboardLiftBehavior, atEnd)) { return; } if (inverted) { const target = Math.max(scroll.value - effectiveDelta, -currentTotal); scrollToTarget(target); } else { const maxScroll = Math.max(size.value.height - layout.value.height + currentTotal, 0); const target = Math.min(scroll.value + effectiveDelta, maxScroll); scrollToTarget(target); } }, [inverted, keyboardLiftBehavior]); } //# sourceMappingURL=index.js.map