@attio/react-native-bottom-sheet-toolbox
Version:
103 lines (100 loc) • 4.48 kB
JavaScript
;
import * as React from "react";
import { Keyboard, Platform } from "react-native";
import { Extrapolation, interpolate, useAnimatedKeyboard, useDerivedValue, useSharedValue } from "react-native-reanimated";
import { InternalKeyboardProvider, useAdditionalKeyboardHeightTotal } from "./internal-keyboard-context";
import { jsx as _jsx } from "react/jsx-runtime";
const KeyboardContext = /*#__PURE__*/React.createContext(null);
const FALLBACK_KEYBOARD_HEIGHT = Platform.select({
ios: 346,
android: 330,
default: 346
});
function useDeriveKeyboardProgressSharedValue(keyboardHeightSharedValue) {
// Keyboard metrics are not available on web, so we use a fallback.
const defaultKeyboardHeight = Keyboard.metrics?.()?.height || FALLBACK_KEYBOARD_HEIGHT;
const keyboardEndHeightSharedValue = useSharedValue(defaultKeyboardHeight);
React.useEffect(() => {
const sub = Keyboard.addListener("keyboardWillChangeFrame", evt => {
keyboardEndHeightSharedValue.set(evt.endCoordinates.height);
});
return () => {
sub.remove();
};
}, []);
return useDerivedValue(() => {
const keyboardEndHeight = keyboardEndHeightSharedValue.get();
if (keyboardEndHeight === 0) return 0;
return interpolate(keyboardHeightSharedValue.get(), [0, keyboardEndHeight], [0, 1], Extrapolation.CLAMP);
}, [keyboardHeightSharedValue]);
}
function useDeriveKeyboardHeightSharedValue(keyboardHeightSharedValue, keyboardProgressSharedValue) {
const additionalKeyboardHeightTotalSharedValue = useAdditionalKeyboardHeightTotal();
return useDerivedValue(() => {
const offset = additionalKeyboardHeightTotalSharedValue.get() * keyboardProgressSharedValue.get();
return keyboardHeightSharedValue.get() + offset;
}, [keyboardHeightSharedValue, keyboardProgressSharedValue, additionalKeyboardHeightTotalSharedValue.get]);
}
function WithInternalKeyboardProvider({
children,
keyboardHeightSharedValue: outerKeyboardHeightSharedValue,
keyboardProgressSharedValue: outerKeyboardProgressSharedValue
}) {
const keyboardProgressSharedValue = useDeriveKeyboardProgressSharedValue(outerKeyboardHeightSharedValue);
const keyboardHeightSharedValue = useDeriveKeyboardHeightSharedValue(outerKeyboardHeightSharedValue, outerKeyboardProgressSharedValue);
const value = React.useMemo(() => ({
keyboardHeightSharedValue,
keyboardProgressSharedValue
}), [keyboardHeightSharedValue, keyboardProgressSharedValue]);
return /*#__PURE__*/_jsx(KeyboardContext.Provider, {
value: value,
children: children
});
}
/**
* Provides shared values representing the keyboard height and progress that
* various bottom sheet behaviors can hook into.
*
* This also support additional keyboard height, which is useful when implementing
* features such as keyboard toolbars.
*/
export function KeyboardProvider({
children,
...rest
}) {
const animatedKeyboard = useAnimatedKeyboard("animatedKeyboardOptions" in rest ? rest.animatedKeyboardOptions : undefined);
const innerKeyboardHeightSharedValue = animatedKeyboard.height;
const innerKeyboardProgressSharedValue = useDeriveKeyboardProgressSharedValue(innerKeyboardHeightSharedValue);
const hasKeyboardOverride = "keyboardHeightSharedValue" in rest && "keyboardProgressSharedValue" in rest;
const keyboardHeightSharedValue = hasKeyboardOverride ? rest.keyboardHeightSharedValue : innerKeyboardHeightSharedValue;
const keyboardProgressSharedValue = hasKeyboardOverride ? rest.keyboardProgressSharedValue : innerKeyboardProgressSharedValue;
return /*#__PURE__*/_jsx(InternalKeyboardProvider, {
children: /*#__PURE__*/_jsx(WithInternalKeyboardProvider, {
keyboardHeightSharedValue: keyboardHeightSharedValue,
keyboardProgressSharedValue: keyboardProgressSharedValue,
children: children
})
});
}
function useKeyboardContext() {
const context = React.useContext(KeyboardContext);
if (!context) {
throw new Error("KeyboardProvider not found.");
}
return context;
}
/**
* Returns a shared value representing the keyboard height plus any additional
* keyboard height.
*/
export function useKeyboardHeightSharedValue() {
return useKeyboardContext().keyboardHeightSharedValue;
}
/**
* Returns a shared value, from 0 to 1, representing the keyboard's opening
* progress.
*/
export function useKeyboardProgressSharedValue() {
return useKeyboardContext().keyboardProgressSharedValue;
}
//# sourceMappingURL=keyboard-context.js.map