mirror of
https://github.com/ant-design/ant-design.git
synced 2024-12-12 15:19:58 +08:00
502dac12aa
* docs: fix code * feat: lint * feat: prettier * feat: test * feat: review * feat: format html * feat: format html
71 lines
2.0 KiB
TypeScript
71 lines
2.0 KiB
TypeScript
import * as React from 'react';
|
|
import raf from 'rc-util/lib/raf';
|
|
|
|
import Input from '../Input';
|
|
import type { InputProps, InputRef } from '../Input';
|
|
|
|
export interface OTPInputProps extends Omit<InputProps, 'onChange'> {
|
|
index: number;
|
|
onChange: (index: number, value: string) => void;
|
|
/** Tell parent to do active offset */
|
|
onActiveChange: (nextIndex: number) => void;
|
|
}
|
|
|
|
const OTPInput = React.forwardRef<InputRef, OTPInputProps>((props, ref) => {
|
|
const { value, onChange, onActiveChange, index, ...restProps } = props;
|
|
|
|
const onInternalChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
|
|
onChange(index, e.target.value);
|
|
};
|
|
|
|
// ========================== Ref ===========================
|
|
const inputRef = React.useRef<InputRef>(null);
|
|
React.useImperativeHandle(ref, () => inputRef.current!);
|
|
|
|
// ========================= Focus ==========================
|
|
const syncSelection = () => {
|
|
raf(() => {
|
|
const inputEle = inputRef.current?.input;
|
|
if (document.activeElement === inputEle && inputEle) {
|
|
inputEle.select();
|
|
}
|
|
});
|
|
};
|
|
|
|
// ======================== Keyboard ========================
|
|
const onInternalKeyDown: React.KeyboardEventHandler<HTMLInputElement> = ({ key }) => {
|
|
if (key === 'ArrowLeft') {
|
|
onActiveChange(index - 1);
|
|
} else if (key === 'ArrowRight') {
|
|
onActiveChange(index + 1);
|
|
}
|
|
|
|
syncSelection();
|
|
};
|
|
|
|
const onInternalKeyUp: React.KeyboardEventHandler<HTMLInputElement> = (e) => {
|
|
if (e.key === 'Backspace' && !value) {
|
|
onActiveChange(index - 1);
|
|
}
|
|
|
|
syncSelection();
|
|
};
|
|
|
|
// ========================= Render =========================
|
|
return (
|
|
<Input
|
|
{...restProps}
|
|
ref={inputRef}
|
|
value={value}
|
|
onInput={onInternalChange}
|
|
onFocus={syncSelection}
|
|
onKeyDown={onInternalKeyDown}
|
|
onKeyUp={onInternalKeyUp}
|
|
onMouseDown={syncSelection}
|
|
onMouseUp={syncSelection}
|
|
/>
|
|
);
|
|
});
|
|
|
|
export default OTPInput;
|