import isNil from 'lodash/isNil'; import React, { useEffect, useMemo, useRef, memo, useCallback } from 'react'; import type { ViewStyle } from 'react-native'; import { View, Keyboard } from 'react-native'; import { callInterceptor, getDefaultValue } from '../helpers'; import { usePersistFn } from '../hooks'; import useState from '../hooks/useStateUpdate'; import NumberInput from '../number-input'; import TextInput from '../text-input'; import type { TextInputInstance } from '../text-input/interface'; import Theme from '../theme'; import DialogKeyboard from './dialog-keyboard'; import type { DialogInputProps, DialogAction, DialogInputState, } from './interface'; import { varCreator } from './style'; /** * Dialog 弹出框 * @description 配合函数的使用 */ const DialogInput: React.FC = ({ showCancelButton = true, duration, beforeClose, onPressCancel, onPressConfirm, defaultValue, placeholder, type = 'text', autoFocus = true, textInput: { value: textInputValue, onChangeText, ...resetTextInputProps } = {}, numberInput: { value: numberInputValue, onChange, ...resetNumberInputProps } = {}, ...restProps }) => { const isInputText = type === 'textarea' || type === 'text'; const realValue = isInputText ? textInputValue : numberInputValue; const TextInputRef = useRef(null); const TOKENS = Theme.useThemeTokens(); const CV = Theme.createVar(TOKENS, varCreator); const [state, setState] = useState({ visible: false, // @ts-ignore value: defaultValue, cancel: false, confirm: false, overlay: false, }); const boxStyle = useMemo( () => ({ marginHorizontal: CV.dialog_input_gap, marginTop: CV.dialog_input_gap, overflow: 'hidden', maxHeight: 200, }), [CV.dialog_input_gap] ); duration = getDefaultValue(duration, CV.dialog_transition); const onChangeTextPersistFn = usePersistFn((t: string) => { setState({ value: t, }); onChangeText?.(t); }); const onChangePersistFn = usePersistFn((t: number) => { setState({ value: t, }); onChange?.(t); }); const genOnPressBtn = (action: Exclude) => () => { Keyboard.dismiss(); setState({ [action]: true, }); const actionCallback = action === 'confirm' ? onPressConfirm : onPressCancel; const finalValue = !isNil(state.value) ? `${state.value}` : ''; callInterceptor(beforeClose, { args: [action, finalValue], done: () => { callInterceptor(actionCallback, { args: [finalValue], done: () => { setState({ [action]: false, visible: false, }); }, canceled: () => { setState({ [action]: false, }); }, }); }, canceled: () => { setState({ [action]: false, }); }, }); }; useEffect(() => { setState({ visible: true, }); // 当对话框完全显示的时候再去聚焦 if (autoFocus) { setTimeout(() => { TextInputRef.current?.focus(); }, duration); } }, [duration, autoFocus]); useEffect(() => { if (!isNil(realValue)) { setState({ value: realValue, }); } }, [realValue]); const onPressClose = useCallback(() => { setState({ visible: false, }); }, []); return ( {type === 'textarea' || type === 'text' ? ( ) : ( // @ts-ignore )} ); }; export default memo(DialogInput);