import React, { useEffect, useRef } from "react"; import { runOnJS, useAnimatedStyle, withTiming } from "react-native-reanimated"; import { Platform_iOS, useDimensions, useMeasure, useReanimatedValue, } from "../commons"; import { View } from "../components"; export type KeyboardProps = { before?: number; after?: number; enableAndroid?: boolean; onShow?: () => void; onHide?: () => void; }; export const Keyboard = (props: KeyboardProps) => { const { before = 0, after = 0, enableAndroid, onShow, onHide } = props; const { height, keyboard, duration } = useDimensions(true); const [refView, measureView] = useMeasure(duration); const bottomOffsetValue = useReanimatedValue(before); const yOffsetValue = useRef(0); const callback = (show: boolean) => { show ? onShow?.() : onHide?.(); }; const onLayout = () => { measureView(({ y }) => { if (y && !keyboard) yOffsetValue.current = Math.max(0, height - before - y); }); }; useEffect(() => { if (Platform_iOS || enableAndroid) { bottomOffsetValue.value = withTiming( keyboard ? keyboard + after - yOffsetValue.current : before, { duration }, (finished) => { finished && runOnJS(callback)(!!keyboard); } ); } else callback(!!keyboard); }, [before, after, enableAndroid, onShow, onHide, keyboard, duration]); const rStyle = useAnimatedStyle( () => ({ height: bottomOffsetValue.value, }), [] ); return ( ); };