UNPKG

react-native-keyboard-controller

Version:

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

104 lines (97 loc) 3.51 kB
import { createContext, useContext } from "react"; import { Animated } from "react-native"; import type { FocusedInputHandler, FocusedInputLayoutChangedEvent, KeyboardHandler, } from "./types"; import type React from "react"; import type { SharedValue } from "react-native-reanimated"; export type AnimatedContext = { /** * A value between `0` and `1` indicating keyboard position, where `0` means keyboard is closed and `1` means keyboard is fully visible. * Represented as `Animated.Value`. */ progress: Animated.Value; /** Height of the keyboard. Represented as `Animated.Value`. */ height: Animated.AnimatedMultiplication<number>; }; export type ReanimatedContext = { /** * A value between `0` and `1` indicating keyboard position, where `0` means keyboard is closed and `1` means keyboard is fully visible. * Represented as `SharedValue`. */ progress: SharedValue<number>; /** Height of the keyboard. Represented as `SharedValue`. */ height: SharedValue<number>; }; export type KeyboardAnimationContext = { /** Whether KeyboardController library is active or not. */ enabled: boolean; /** Object that stores animated values that reflect the keyboard’s current position and movement. */ animated: AnimatedContext; /** Object that stores reanimated values that reflect the keyboard’s current position and movement. */ reanimated: ReanimatedContext; /** Layout of the focused `TextInput` represented as `SharedValue`. */ layout: SharedValue<FocusedInputLayoutChangedEvent | null>; /** Method for setting workletized keyboard handlers. */ setKeyboardHandlers: (handlers: KeyboardHandler) => () => void; /** Method for setting workletized handlers for tracking focused input events. */ setInputHandlers: (handlers: FocusedInputHandler) => () => void; /** Method to enable/disable KeyboardController library. */ setEnabled: React.Dispatch<React.SetStateAction<boolean>>; }; const NOOP = () => {}; const NESTED_NOOP = () => NOOP; const withSharedValue = <T>(value: T): SharedValue<T> => ({ value, addListener: NOOP, removeListener: NOOP, modify: NOOP, get: () => value, set: NOOP, }); const DEFAULT_SHARED_VALUE = withSharedValue(0); const DEFAULT_LAYOUT = withSharedValue<FocusedInputLayoutChangedEvent | null>( null, ); const defaultContext: KeyboardAnimationContext = { enabled: true, animated: { progress: new Animated.Value(0), height: new Animated.Value(0), }, reanimated: { progress: DEFAULT_SHARED_VALUE, height: DEFAULT_SHARED_VALUE, }, layout: DEFAULT_LAYOUT, setKeyboardHandlers: NESTED_NOOP, setInputHandlers: NESTED_NOOP, setEnabled: NOOP, }; export const KeyboardContext = createContext(defaultContext); /** * A hook that returns a reference to {@link KeyboardAnimationContext} object. * * @returns Object {@link KeyboardAnimationContext|containing} keyboard-controller context. * @example * ```ts * const context = useKeyboardContext(); * * useLayoutEffect(() => { * const cleanup = context.setInputHandlers(handler); * * return () => cleanup(); * }, deps); * ``` */ export const useKeyboardContext = () => { const context = useContext(KeyboardContext); if (__DEV__ && context === defaultContext) { console.warn( "Couldn't find real values for `KeyboardContext`. Please make sure you're inside of `KeyboardProvider` - otherwise functionality of `react-native-keyboard-controller` will not work.", ); } return context; };