@td-design/react-native
Version:
react-native UI组件库
129 lines • 3.74 kB
JavaScript
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