import { CrossOutline } from '@fruits-chain/icons-react-native'; import isNil from 'lodash/isNil'; import React, { useRef, useCallback, memo, isValidElement } from 'react'; import { View, Text, Animated, DimensionValue } from 'react-native'; import Button from '../button'; import { getDefaultValue, easing, renderTextLikeJSX } from '../helpers'; import { usePersistFn } from '../hooks'; import { useLocale } from '../../components/Locale/locale'; import ModalPopup from '../popup'; import Popup from '../popup/popup'; import Theme from '../theme'; import type { DialogProps } from './interface'; import { varCreator, styleCreator } from './style'; /** * Dialog 弹出框 * @description 弹出模态框,常用于消息提示、消息确认,或在当前页面内完成特定的交互操作。 * @description 弹出框组件支持函数调用和组件调用两种方式。 */ const Dialog: React.FC = ({ children, style, title, message, width, messageAlign = 'center', showConfirmButton = true, showCancelButton = false, confirmButtonText, cancelButtonText, confirmButtonColor, confirmButtonTextBold = true, cancelButtonColor, cancelButtonTextBold = false, confirmButtonLoading = false, cancelButtonLoading = false, showClose = false, onPressClose, onPressCancel, onPressConfirm, duration, onOpen: onOpenFn, onClose: onCloseFn, useNative = true, ...resetProps }) => { const fadeAnim = useRef(new Animated.Value(0)).current; const fadeInstance = useRef(null); const locale = useLocale().Dialog; const TOKENS = Theme.useThemeTokens(); const CV = Theme.createVar(TOKENS, varCreator); // @ts-ignore const STYLES = Theme.createStyle(CV, styleCreator); width = getDefaultValue(width, CV.dialog_width); duration = getDefaultValue(duration, CV.dialog_transition); const showDialog = useCallback( (show: boolean) => { if (fadeInstance.current) { fadeInstance.current.stop(); fadeInstance.current = null; } fadeInstance.current = Animated.timing( fadeAnim, // 动画中的变量值 { toValue: show ? 1 : 0, duration: duration, useNativeDriver: true, easing: show ? easing.easeOutCirc : easing.easeInCubic, } ); fadeInstance.current.start(); }, [duration, fadeAnim] ); const onOpenPersistFn = usePersistFn(() => { showDialog(true); onOpenFn?.(); }); const onClosePersistFn = usePersistFn(() => { showDialog(false); onCloseFn?.(); }); const titleJSX = renderTextLikeJSX(title, STYLES.title_text); const messageJSX = !isNil(message) ? ( isValidElement(message) ? ( message ) : ( {message} ) ) : null; const cancelButtonProps = { color: cancelButtonColor || CV.dialog_cancel_button_text_color, text: cancelButtonText ?? locale.cancelButtonText, loading: cancelButtonLoading, onPress: onPressCancel, }; const confirmButtonProps = { color: confirmButtonColor || CV.dialog_confirm_button_text_color, text: confirmButtonText ?? locale.confirmButtonText, loading: confirmButtonLoading, onPress: onPressConfirm, }; const Component = useNative ? ModalPopup : Popup; return ( {showClose ? ( ) : null} {titleJSX} {titleJSX ? ( messageJSX ) : ( {messageJSX} )} {children} {showCancelButton || showConfirmButton ? ( {showCancelButton ? (