103 lines
2.4 KiB
TypeScript
103 lines
2.4 KiB
TypeScript
import React, {
|
|
Ref,
|
|
RefObject,
|
|
forwardRef,
|
|
useImperativeHandle,
|
|
useRef,
|
|
useState,
|
|
} from 'react';
|
|
import IconButton from './IconButton';
|
|
import Style from './Input.less';
|
|
|
|
interface InputProps {
|
|
value?: string;
|
|
type?: string;
|
|
placeholder?: string;
|
|
className?: string;
|
|
clearable?: boolean;
|
|
autoFocus?: boolean;
|
|
onChange: (value: string) => void;
|
|
onEnter?: (value: string) => void;
|
|
onFocus?: () => void;
|
|
}
|
|
|
|
const Input = forwardRef((props: InputProps, ref) => {
|
|
const $input = useRef(null);
|
|
const {
|
|
value,
|
|
type = 'text',
|
|
placeholder = '',
|
|
className = '',
|
|
onChange,
|
|
clearable,
|
|
autoFocus,
|
|
onEnter = () => {},
|
|
onFocus = () => {},
|
|
} = props;
|
|
|
|
useImperativeHandle(
|
|
ref,
|
|
() => ({
|
|
// @ts-ignore
|
|
focus: () => $input.current.focus(),
|
|
}),
|
|
[],
|
|
);
|
|
function handleInput(e: any) {
|
|
onChange(e.target.value);
|
|
}
|
|
|
|
const [lockEnter, setLockEnter] = useState(false);
|
|
function handleIMEStart() {
|
|
setLockEnter(true);
|
|
}
|
|
function handleIMEEnd() {
|
|
setLockEnter(false);
|
|
}
|
|
function handleKeyDown(e: any) {
|
|
if (lockEnter) {
|
|
return;
|
|
}
|
|
if (e.key === 'Enter') {
|
|
onEnter(value as string);
|
|
}
|
|
}
|
|
|
|
function handleClickClear() {
|
|
onChange('');
|
|
// @ts-ignore
|
|
$input.current.focus();
|
|
}
|
|
|
|
return (
|
|
<div className={`${Style.inputContainer} ${className}`}>
|
|
<input
|
|
className={Style.input}
|
|
type={type}
|
|
autoFocus={autoFocus}
|
|
value={value}
|
|
onChange={handleInput}
|
|
onInput={handleInput}
|
|
placeholder={placeholder}
|
|
ref={$input}
|
|
onKeyDown={handleKeyDown}
|
|
onCompositionStart={handleIMEStart}
|
|
onCompositionEnd={handleIMEEnd}
|
|
onFocus={onFocus}
|
|
/>
|
|
{clearable !== false && (
|
|
<IconButton
|
|
className={Style.inputIconButton}
|
|
width={32}
|
|
height={32}
|
|
iconSize={18}
|
|
icon="clear"
|
|
onClick={handleClickClear}
|
|
/>
|
|
)}
|
|
</div>
|
|
);
|
|
});
|
|
|
|
export default Input;
|