import { isNil } from 'lodash'; import React, { ForwardRefRenderFunction, useEffect, useState, forwardRef, useImperativeHandle, useRef, } from 'react'; import { LayoutChangeEvent, NativeScrollEvent, NativeSyntheticEvent, Platform, ScrollView, StyleSheet, View, } from 'react-native'; import { KeyboardManager } from 'react-native-keyboard-manager'; import Col from '../Col'; import TextButton from '../Modal/TextButton'; import Popup from '../Popup'; import Row from '../Row'; import ShouldRender from '../ShouldRender'; import { FloatingLayerProps, FloatingLayerRef } from './interface'; import createStyle from './styles/floatingLayer.style'; import { useTheme } from '../Theme'; import { useKeyboardDimensions, useMaxHeight } from '../../utils'; import { isValidElement } from 'react'; const FloatingLayer: ForwardRefRenderFunction< FloatingLayerRef, FloatingLayerProps > = ( { items, textButton, onPressTextButton, children, footer, footerStyle, containerStyle, contentStyle, title, titleStyle, description, headerStyle, showCancelButton, cancelButtonText, onCancel, cancelBtnIcon, showConfirmButton, confirmButtonText, onConfirm, cancelBtnStyle, confirmBtnStyle, cancelBtnContainerStyle, confirmBtnContainerStyle, showsVerticalScrollIndicator, cancelBtnIconProps, containerHeight: innerContainerHeight, onContentScroll, topExtra, headerExtra, scrollStyle, softInputMode, visible, useNative = true, adaptKeyboardBottom, hasMinHeight, needScrollView = true, ...restProps }, ref ) => { const [contentScrollTop, setContentScrollTop] = useState(true); const token = useTheme(); const styles = createStyle(token); const maxHeight = useMaxHeight(); const containerHeightRef = useRef(0); const { height: currentKeyboardHeight } = useKeyboardDimensions(true); const titleProps = { title, titleStyle, description, headerStyle: StyleSheet.flatten([styles.head, headerStyle]), showCancelButton, cancelButtonText, onCancel, cancelBtnIcon, showConfirmButton, confirmButtonText, onConfirm, cancelBtnStyle, confirmBtnStyle, cancelBtnContainerStyle, confirmBtnContainerStyle, cancelBtnIconProps, }; const renderItems = () => { if (!Array.isArray(items)) { return null; } const span = Math.max(24 / items?.length, 6); return ( {items?.map((item, index) => ( {item} ))} ); }; const renderTextButton = () => { if (isNil(textButton)) { return null; } return ( ); }; const onScroll = (event: NativeSyntheticEvent) => { const { nativeEvent: { contentOffset: { y }, }, } = event; if (y === 0) { setContentScrollTop(true); } else { setContentScrollTop(false); } onContentScroll?.(event); }; useImperativeHandle(ref, () => { return { getContainerHeight: () => containerHeightRef.current, }; }); useEffect(() => { if (Platform.OS === 'ios') { // 0915:解决iOS键盘问题,统一开启KeyboardManager能力,自动管理键盘 KeyboardManager.setEnable(true); } }, []); const scrollBottom = softInputMode && softInputMode !== 'resize' ? currentKeyboardHeight : 0; const onWrapperLayout = ({ nativeEvent: { layout: { height }, }, }: LayoutChangeEvent) => { containerHeightRef.current = height; }; const containerHeightStyle = innerContainerHeight ? { height: innerContainerHeight, } : {}; const containerScrollStyle = hasMinHeight ? styles.containerMinHeightStyle : {}; const wrapperStyle = StyleSheet.flatten([ styles.wrapper, containerStyle, scrollStyle, containerHeightStyle, { maxHeight }, containerScrollStyle, ]); const FloatingContentContainer = needScrollView ? ( {children} {adaptKeyboardBottom && !footer && !!scrollBottom && ( )} ) : ( <> {children} {adaptKeyboardBottom && !footer && !!scrollBottom && ( )} ); return ( {topExtra} {renderItems()} {renderTextButton()} {headerExtra} {FloatingContentContainer} {footer} ); }; export default forwardRef(FloatingLayer);