UNPKG

@td-design/react-native

Version:

react-native UI组件库

129 lines 3.74 kB
import { useEffect, useImperativeHandle, useReducer, useRef } from 'react'; import { Keyboard, Platform } from 'react-native'; import { useMemoizedFn } from '@td-design/rn-hooks'; import { fillOtpCode } from './helpers'; import reducer from './reducer'; export default function usePasscode(_ref) { let { onChange, count, value, ref, onFinish } = _ref; const previousCopiedText = useRef(''); const inputs = useRef([]); const [{ otpCode, hasKeySupport }, dispatch] = useReducer(reducer, { otpCode: fillOtpCode(count, value), handleChange: onChange, hasKeySupport: Platform.OS === 'ios' }); useEffect(() => { if (value) { dispatch({ type: 'setOtpCode', payload: { count, code: value } }); } }, [value, count]); useImperativeHandle(ref, () => ({ reset: () => { dispatch({ type: 'clearOtp', payload: count }); inputs.current.forEach(input => { var _input$current; return input === null || input === void 0 || (_input$current = input.current) === null || _input$current === void 0 ? void 0 : _input$current.clear(); }); previousCopiedText.current = ''; }, focus: () => { var _firstInput$current; const firstInput = inputs.current[0]; firstInput === null || firstInput === void 0 || (_firstInput$current = firstInput.current) === null || _firstInput$current === void 0 ? void 0 : _firstInput$current.focus(); }, getValue: () => { return Object.values(otpCode).join(''); } })); const focusInput = index => { if (index >= 0 && index < count) { var _input$current2; const input = inputs.current[index]; input === null || input === void 0 || (_input$current2 = input.current) === null || _input$current2 === void 0 ? void 0 : _input$current2.focus(); } }; const handleClearInput = inputIndex => { var _input$current3; const input = inputs.current[inputIndex]; input === null || input === void 0 || (_input$current3 = input.current) === null || _input$current3 === void 0 ? void 0 : _input$current3.clear(); dispatch({ type: 'setOtpTextForIndex', payload: { index: inputIndex, text: '' } }); }; const handleChangeText = index => text => { handleInputTextChange(text, index); }; const handleKeyPress = index => _ref2 => { let { nativeEvent: { key } } = _ref2; if (Platform.OS === 'android' && !hasKeySupport && !isNaN(parseInt(key))) { dispatch({ type: 'setHasKeySupport', payload: true }); } if (key === 'Backspace') { // 当前输入框的值 const value = otpCode[`${index}`]; // 清除当前输入框的值 handleClearInput(index); // 如果当前输入框的值为空,则聚焦上一个输入框 if (!value) { focusInput(index - 1); } } }; const handleInputTextChange = (text, index) => { if ([1, 2, 3, 4, 5, 6, 7, 8, 9, 0].includes(parseInt(text))) { dispatch({ type: 'setOtpTextForIndex', payload: { text, index } }); focusInput(index + 1); } else { handleClearInput(index); } }; useEffect(() => { const value = Object.values(otpCode).join(''); if (value.length === count) { onFinish === null || onFinish === void 0 ? void 0 : onFinish(value); Keyboard.dismiss(); } }, [count, otpCode]); return { otpCode, inputs, handleKeyPress: useMemoizedFn(handleKeyPress), handleChangeText: useMemoizedFn(handleChangeText) }; } //# sourceMappingURL=usePasscode.js.map