react-native-unit-components
Version:
Unit React Native components
205 lines (204 loc) • 8.91 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _reactNative = require("react-native");
var _propTypes = _interopRequireDefault(require("prop-types"));
var _images = require("../../assets/images");
var _UNBottomSheetComponent = require("../../components/UNBottomSheetComponent/UNBottomSheetComponent.constants");
var _BottomSheet = require("./BottomSheet.styles");
var _useAppStateListener = require("../../hooks/useAppStateListener");
var _bottomSheet = require("../../types/internal/bottomSheet.types");
var _UNBaseView = require("../../nativeComponents/UNBaseView");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
const BottomSheet = props => {
const isStatic = props.nativePlace === _bottomSheet.BottomSheetNativePlaceType.modal;
const panelHeightValue = (0, _react.useRef)(new _reactNative.Animated.Value(props.sliderMaxHeight)).current;
const fadeAnim = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
const styles = (0, _BottomSheet.getStylesObject)(fadeAnim);
const [isPanelOpened, setIsPanelOpened] = (0, _react.useState)(props.isOpen);
const [contentHeight, setContentHeight] = (0, _react.useState)(undefined);
const [currentHeight, setCurrentHeight] = (0, _react.useState)(props.sliderMaxHeight);
const [dy, setDy] = (0, _react.useState)(0);
const isAppActive = (0, _useAppStateListener.useAppStateListener)();
const _parentPanResponder = _reactNative.PanResponder.create({
onMoveShouldSetPanResponderCapture: (_, gestureState) => {
if (isStatic) return false;
return props.shouldEnableBottomSheetScroll && Math.abs(gestureState.dy) > 10;
},
onPanResponderMove(_, gestureState) {
if (props.shouldEnableBottomSheetScroll && gestureState.dy < 5) {
props.handleWebViewScroll();
}
if (currentHeight + gestureState.dy < 0) return;
if (!props.expandToMaxHeightEnabled && contentHeight && currentHeight + gestureState.dy < props.sliderMaxHeight - contentHeight) return;
panelHeightValue.setValue(currentHeight + gestureState.dy);
setDy(gestureState.dy);
},
onPanResponderRelease: () => {
if (dy > 0) {
collapse();
} else if (!props.expandToMaxHeightEnabled) {
contentHeight && setToContentHeight(contentHeight);
} else {
expand();
}
}
});
(0, _react.useEffect)(() => {
// on App Active State change reset the bottom-sheet
setContentHeight(0);
_dismiss();
}, [isAppActive]);
(0, _react.useEffect)(() => {
if (props.isOpen && !isPanelOpened) {
fadeIn();
} else if (isPanelOpened) {
setContentHeight(0);
_dismiss();
}
}, [props.isOpen]);
(0, _react.useEffect)(() => {
_reactNative.BackHandler.addEventListener('hardwareBackPress', _onBackPress);
const id = panelHeightValue.addListener(e => setCurrentHeight(e.value));
return () => {
_reactNative.BackHandler.removeEventListener('hardwareBackPress', _onBackPress);
panelHeightValue.removeListener(id);
};
}, []);
const fadeIn = () => {
setIsPanelOpened(true);
_reactNative.Animated.timing(fadeAnim, {
toValue: 0.3,
duration: 500,
useNativeDriver: false
}).start();
};
const fadeOut = () => {
/*
withTimeout - most of the time we declare 'Close' after the animation is end.
In a case that the app is not active we do it without timeout. (Otherwise a race condition may occur.)
*/
setIsPanelOpened(false);
_reactNative.Animated.timing(fadeAnim, {
toValue: 0,
duration: 500,
useNativeDriver: false
}).start();
};
const setToContentHeight = contentHeight => {
_reactNative.Animated.timing(panelHeightValue, {
duration: props.animationDuration,
easing: _reactNative.Easing.quad,
toValue: props.sliderMaxHeight - contentHeight,
useNativeDriver: false
}).start();
};
const expand = () => {
const {
animationDuration
} = props;
props.onOpen();
if (contentHeight && currentHeight > props.sliderMaxHeight - contentHeight) {
setToContentHeight(contentHeight);
return;
}
_reactNative.Animated.timing(panelHeightValue, {
duration: animationDuration,
easing: _reactNative.Easing.quad,
toValue: 0,
useNativeDriver: false
}).start();
};
const collapse = () => {
if (contentHeight && currentHeight > props.sliderMaxHeight - contentHeight) {
_dismiss();
return;
}
contentHeight && setToContentHeight(contentHeight);
};
const _onBackPress = () => {
isPanelOpened && collapse();
return isPanelOpened;
};
const _setSize = e => {
const newContentHeight = e.nativeEvent.layout.height;
setContentHeight(newContentHeight);
setToContentHeight(newContentHeight);
};
const _dismiss = () => {
const {
animationDuration
} = props;
_reactNative.Animated.timing(panelHeightValue, {
duration: animationDuration,
easing: _reactNative.Easing.quad,
toValue: props.sliderMaxHeight,
useNativeDriver: false
}).start(() => {
props.onClose();
});
fadeOut();
};
const {
children
} = props;
const isModal = props.nativePlace === _bottomSheet.BottomSheetNativePlaceType.modal;
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactNative.TouchableOpacity, {
style: styles.outsideContainer,
activeOpacity: 1,
onPress: () => _dismiss()
}, /*#__PURE__*/_react.default.createElement(_reactNative.Animated.View, {
style: styles.animation
})), /*#__PURE__*/_react.default.createElement(_reactNative.Animated.View, _extends({}, _parentPanResponder.panHandlers, {
style: {
...styles.container,
borderTopLeftRadius: isModal ? 0 : styles.container.borderTopLeftRadius,
borderTopRightRadius: isModal ? 0 : styles.container.borderTopRightRadius,
height: props.sliderMaxHeight,
marginTop: _UNBottomSheetComponent.fullScreenHeight - props.sliderMaxHeight - (!isModal && _UNBottomSheetComponent.isAndroid10AndAbove ? _UNBottomSheetComponent.androidStatusBarHeight : 0),
transform: [{
translateY: panelHeightValue
}],
paddingTop: _reactNative.Platform.OS === 'ios' && isModal ? _UNBottomSheetComponent.statusBarHeight : 0
}
}), /*#__PURE__*/_react.default.createElement(_reactNative.View, {
style: styles.outerContent
}, /*#__PURE__*/_react.default.createElement(_reactNative.TouchableOpacity, {
activeOpacity: 1,
style: styles.closeButton,
onPress: () => _dismiss()
}, /*#__PURE__*/_react.default.createElement(_reactNative.Image, {
source: _images.CloseIcon
})), /*#__PURE__*/_react.default.createElement(_reactNative.View, {
onLayout: _setSize
}, /*#__PURE__*/_react.default.createElement(_UNBaseView.UNBaseView, {
style: {
height: props.height
}
}, children)))));
};
BottomSheet.propTypes = {
children: _propTypes.default.oneOfType([_propTypes.default.node]),
isOpen: _propTypes.default.bool,
animation: _propTypes.default.func,
animationDuration: _propTypes.default.number,
onOpen: _propTypes.default.func,
onClose: _propTypes.default.func,
expandToMaxHeightEnabled: _propTypes.default.bool
};
BottomSheet.defaultProps = {
children: /*#__PURE__*/_react.default.createElement(_reactNative.View, null),
isOpen: true,
animationDuration: 200,
onOpen: () => null,
onClose: () => null,
expandToMaxHeightEnabled: false
};
var _default = exports.default = BottomSheet;
//# sourceMappingURL=BottomSheet.js.map