UNPKG

react-native-unit-components

Version:

Unit React Native components

192 lines (191 loc) 9.04 kB
/* eslint-disable @typescript-eslint/no-explicit-any */ import React, { useEffect, useState } from 'react'; import { View } from 'react-native'; import BottomSheet from '../../helpers/BottomSheet/BottomSheet'; import { UnitComponentsMessage } from '../../messages/webMessages/unitComponentsMessages'; import { getStylesObject } from './UNBottomSheetComponent.styles'; import { BottomSheetNativePlaceType, BottomSheetRenderingType, ScrollState } from '../../types/internal/bottomSheet.types'; import { BottomSheetNativeMessage } from '../../messages/nativeMessages/bottomSheetMessage'; import { withReduxStore } from '../../helpers/store/helpers'; import { useListenerToEvent } from '../../hooks/useListenerToEvent'; import { useDispatch, useSelector } from 'react-redux'; import { fullScreenHeight, overFullScreenHeight } from './UNBottomSheetComponent.constants'; import { resetBottomSheetSlice, setIsBottomSheetActive, setIsComponentLoading, setNativePlace, setScrollState, setShouldEnableBottomSheetScroll, setShouldShowBottomSheet } from '../../slices/BottomSheetSlice'; import UNBottomSheetSlotComponent from './components/UNBottomSheetSlotComponent/UNBottomSheetSlotComponent'; import UNBottomSheetNativeComponent from './components/UNBottomSheetNativeComponent/UNBottomSheetNativeComponent'; import { getNativeComponentDataFromEvent } from './UNBottomSheetComponent.utils'; const UNBottomSheetComponent = () => { const dispatch = useDispatch(); const isBottomSheetActive = useSelector(state => state.bottomSheet.isBottomSheetActive); const isComponentLoading = useSelector(state => state.bottomSheet.isComponentLoading); const shouldShowBottomSheet = useSelector(state => state.bottomSheet.shouldShowBottomSheet); const nativePlace = useSelector(state => state.bottomSheet.nativePlace); const componentHeight = useSelector(state => state.bottomSheet.componentHeight); const scrollState = useSelector(state => state.bottomSheet.scrollState); const shouldEnableBottomSheetScroll = useSelector(state => state.bottomSheet.shouldEnableBottomSheetScroll); const [renderingType, setRenderingType] = useState(); const [height, setHeight] = useState(0); const [sliderMaxHeight, setSliderMaxHeight] = useState(overFullScreenHeight); const [nativeComponentData, setNativeComponentData] = useState(); const [requestRenderingEventData, setRequestRenderingEventData] = useState(); const [componentParams, setComponentParams] = useState(); const [currentBottomSheetRenderingMessage, setCurrentBottomSheetRenderingMessage] = useState(); const styles = getStylesObject(); useEffect(() => { const setHeightFromNativePlace = () => { switch (nativePlace) { // In the case of overFullScreen, set the height to the overFullScreenHeight. case BottomSheetNativePlaceType.overFullScreen: setHeight(overFullScreenHeight); break; // For modal native place type, set the height to the fullScreenHeight. case BottomSheetNativePlaceType.modal: setHeight(fullScreenHeight); break; default: // In general, we want the bottom sheet to fully contain the component, // thus adjusting its height to the component height, up to the maximum of overFullScreenHeight. if (componentHeight) { setHeight(componentHeight < overFullScreenHeight ? componentHeight : overFullScreenHeight); } break; } }; const setSliderMaxHeightFromNativePlace = () => { if (nativePlace === BottomSheetNativePlaceType.modal) { setSliderMaxHeight(fullScreenHeight); } else { setSliderMaxHeight(overFullScreenHeight); } }; // Check if the inner contained component is still loading or the bottom sheet should not be shown. if (isComponentLoading || !shouldShowBottomSheet) { // If so, hide the bottom sheet by setting the height to 0. setHeight(0); } else { // If not, display the bottom sheet by calculating and setting the height based on the native place type. setHeightFromNativePlace(); setSliderMaxHeightFromNativePlace(); } }, [componentHeight, nativePlace, isComponentLoading, shouldShowBottomSheet]); useEffect(() => { const resetBottomSheetManagerState = () => { setComponentParams(undefined); setRequestRenderingEventData(undefined); setNativeComponentData(undefined); setRenderingType(undefined); setHeight(0); setSliderMaxHeight(overFullScreenHeight); }; if (!isBottomSheetActive) { dispatch(resetBottomSheetSlice()); resetBottomSheetManagerState(); } }, [isBottomSheetActive, dispatch]); const requestRendering = rendering => { if (isBottomSheetActive) { dispatch(setShouldShowBottomSheet(false)); } handleRequestRendering(rendering); if (isBottomSheetActive) { setTimeout(() => dispatch(setShouldShowBottomSheet(true)), 400); } else { dispatch(setIsBottomSheetActive(true)); dispatch(setShouldShowBottomSheet(true)); } }; const handleCloseFlow = () => { dispatch(setIsBottomSheetActive(false)); }; useListenerToEvent({ busEventKey: BottomSheetNativeMessage.REQUEST_RENDERING, action: requestRendering }); useListenerToEvent({ busEventKey: UnitComponentsMessage.UNIT_REQUEST_CLOSE_FLOW, action: handleCloseFlow }); const handleRequestRendering = rendering => { if (rendering === currentBottomSheetRenderingMessage) { return; } else { setCurrentBottomSheetRenderingMessage(rendering); } dispatch(setIsComponentLoading(true)); switch (rendering.type) { //if slot check if we know this component and want to show it, otherwise get directly the component case BottomSheetRenderingType.Slot: determineRenderingTypeFromEvent(rendering.data); break; case BottomSheetRenderingType.NativeComponent: setupDataForNativeComponent(rendering.data); break; default: break; } }; const determineRenderingTypeFromEvent = event => { const nativeComponentDataFromEvent = getNativeComponentDataFromEvent(event); if (nativeComponentDataFromEvent) { setupDataForNativeComponent(nativeComponentDataFromEvent); return; } setupDataForSlotComponent(event); }; const setupDataForNativeComponent = eventData => { const nativePlace = eventData.nativePlace ? eventData.nativePlace : BottomSheetNativePlaceType.modal; setRenderingType(BottomSheetRenderingType.NativeComponent); dispatch(setNativePlace(nativePlace)); setNativeComponentData(eventData); dispatch(setIsComponentLoading(false)); //todo: work with events? }; const setupDataForSlotComponent = eventData => { setRenderingType(BottomSheetRenderingType.Slot); const componentParamsFromEvent = { componentName: eventData.componentName ? eventData.componentName : componentParams?.componentName, componentResourceId: eventData.componentResourceId ? eventData.componentResourceId : componentParams?.componentResourceId }; setComponentParams(componentParamsFromEvent); dispatch(setNativePlace(eventData.requestRenderingEvent.data.nativePlace)); setRequestRenderingEventData(eventData.requestRenderingEvent); }; const handleWebViewScroll = () => { if (scrollState === ScrollState.unScrollable) return; dispatch(setScrollState(ScrollState.onlyWebView)); dispatch(setShouldEnableBottomSheetScroll(false)); }; const renderBottomSheetComponent = () => { switch (renderingType) { case BottomSheetRenderingType.Slot: return requestRenderingEventData ? /*#__PURE__*/React.createElement(UNBottomSheetSlotComponent, { requestRenderingEvent: requestRenderingEventData, componentName: componentParams?.componentName, componentResourceId: componentParams?.componentResourceId }) : null; case BottomSheetRenderingType.NativeComponent: return nativeComponentData ? /*#__PURE__*/React.createElement(UNBottomSheetNativeComponent, { nativeComponentData: nativeComponentData }) : null; default: return null; } }; return /*#__PURE__*/React.createElement(View, { pointerEvents: isBottomSheetActive ? undefined : 'none', style: styles.container }, /*#__PURE__*/React.createElement(BottomSheet, { isOpen: isBottomSheetActive, onOpen: () => dispatch(setIsBottomSheetActive(true)), onClose: () => dispatch(setIsBottomSheetActive(false)), height: height, animationDuration: 200, expandToMaxHeightEnabled: false, handleWebViewScroll: () => handleWebViewScroll(), shouldEnableBottomSheetScroll: shouldEnableBottomSheetScroll, nativePlace: nativePlace, isComponentLoading: isComponentLoading, sliderMaxHeight: sliderMaxHeight }, renderBottomSheetComponent())); }; export default withReduxStore(UNBottomSheetComponent); //# sourceMappingURL=UNBottomSheetComponent.js.map