@gorhom/bottom-sheet
Version:
A performant interactive bottom sheet with fully configurable options 🚀
121 lines (111 loc) • 3.96 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useAnimatedKeyboard = void 0;
var _react = require("react");
var _reactNative = require("react-native");
var _reactNativeReanimated = require("react-native-reanimated");
var _constants = require("../constants");
const KEYBOARD_EVENT_MAPPER = {
KEYBOARD_SHOW: _reactNative.Platform.select({
ios: 'keyboardWillShow',
android: 'keyboardDidShow',
default: ''
}),
KEYBOARD_HIDE: _reactNative.Platform.select({
ios: 'keyboardWillHide',
android: 'keyboardDidHide',
default: ''
})
};
const INITIAL_STATE = {
status: _constants.KEYBOARD_STATUS.UNDETERMINED,
height: 0,
heightWithinContainer: 0,
easing: 'keyboard',
duration: 500
};
const useAnimatedKeyboard = () => {
//#region variables
const state = (0, _reactNativeReanimated.useSharedValue)(INITIAL_STATE);
const temporaryCachedState = (0, _reactNativeReanimated.useSharedValue)(null);
//#endregion
//#region worklets
const handleKeyboardEvent = (0, _react.useCallback)((status, height, duration, easing, bottomOffset) => {
'worklet';
const currentState = state.get();
/**
* if the keyboard event was fired before the `onFocus` on TextInput,
* then we cache the event, and wait till the `target` is been set
* to be updated then fire this function again.
*/
if (status === _constants.KEYBOARD_STATUS.SHOWN && !currentState.target) {
temporaryCachedState.set({
status,
height,
duration,
easing
});
return;
}
/**
* clear temporary cached state.
*/
temporaryCachedState.set(null);
/**
* if keyboard status is hidden, then we keep old height.
*/
let adjustedHeight = status === _constants.KEYBOARD_STATUS.SHOWN ? height : currentState.height;
/**
* if keyboard had an bottom offset -android bottom bar-, then
* we add that offset to the keyboard height.
*/
if (bottomOffset) {
adjustedHeight = adjustedHeight + bottomOffset;
}
state.set({
target: currentState.target,
status,
easing,
duration,
height: adjustedHeight,
heightWithinContainer: currentState.heightWithinContainer
});
}, [state, temporaryCachedState]);
//#endregion
//#region effects
(0, _react.useEffect)(() => {
const handleOnKeyboardShow = event => {
(0, _reactNativeReanimated.runOnUI)(handleKeyboardEvent)(_constants.KEYBOARD_STATUS.SHOWN, event.endCoordinates.height, event.duration, event.easing, _constants.SCREEN_HEIGHT - event.endCoordinates.height - event.endCoordinates.screenY);
};
const handleOnKeyboardHide = event => {
(0, _reactNativeReanimated.runOnUI)(handleKeyboardEvent)(_constants.KEYBOARD_STATUS.HIDDEN, event.endCoordinates.height, event.duration, event.easing);
};
const showSubscription = _reactNative.Keyboard.addListener(KEYBOARD_EVENT_MAPPER.KEYBOARD_SHOW, handleOnKeyboardShow);
const hideSubscription = _reactNative.Keyboard.addListener(KEYBOARD_EVENT_MAPPER.KEYBOARD_HIDE, handleOnKeyboardHide);
return () => {
showSubscription.remove();
hideSubscription.remove();
};
}, [handleKeyboardEvent]);
/**
* This reaction is needed to handle the issue with multiline text input.
*
* @link https://github.com/gorhom/react-native-bottom-sheet/issues/411
*/
(0, _reactNativeReanimated.useAnimatedReaction)(() => state.value.target, (result, previous) => {
if (!result || result === previous) {
return;
}
const cachedState = temporaryCachedState.get();
if (!cachedState) {
return;
}
handleKeyboardEvent(cachedState.status, cachedState.height, cachedState.duration, cachedState.easing);
}, [temporaryCachedState, handleKeyboardEvent]);
//#endregion
return state;
};
exports.useAnimatedKeyboard = useAnimatedKeyboard;
//# sourceMappingURL=useAnimatedKeyboard.js.map
;