导出
This commit is contained in:
@@ -86,3 +86,75 @@ export const CommitInput: React.FC<CommitInputProps> = ({
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export interface CommitTextareaProps
|
||||
extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'onChange' | 'value'> {
|
||||
value: string;
|
||||
onCommit: (val: string) => void;
|
||||
}
|
||||
|
||||
/** 失焦提交型多行输入框 */
|
||||
export const CommitTextarea: React.FC<CommitTextareaProps> = ({
|
||||
value,
|
||||
onCommit,
|
||||
onFocus,
|
||||
onBlur,
|
||||
onKeyDown,
|
||||
...props
|
||||
}) => {
|
||||
const [localVal, setLocalVal] = useState<string>(value);
|
||||
const focusedRef = useRef(false);
|
||||
const localValRef = useRef(localVal);
|
||||
const valueRef = useRef(value);
|
||||
const onCommitRef = useRef(onCommit);
|
||||
localValRef.current = localVal;
|
||||
valueRef.current = value;
|
||||
onCommitRef.current = onCommit;
|
||||
|
||||
useEffect(() => {
|
||||
if (!focusedRef.current) {
|
||||
setLocalVal(value);
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (focusedRef.current && localValRef.current !== valueRef.current) {
|
||||
onCommitRef.current(localValRef.current);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
const commitIfChanged = () => {
|
||||
if (localValRef.current !== valueRef.current) {
|
||||
onCommitRef.current(localValRef.current);
|
||||
}
|
||||
};
|
||||
|
||||
const handleBlur = (e: React.FocusEvent<HTMLTextAreaElement>) => {
|
||||
focusedRef.current = false;
|
||||
onBlur?.(e);
|
||||
commitIfChanged();
|
||||
};
|
||||
|
||||
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||
if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {
|
||||
(e.target as HTMLTextAreaElement).blur();
|
||||
}
|
||||
onKeyDown?.(e);
|
||||
};
|
||||
|
||||
return (
|
||||
<textarea
|
||||
{...props}
|
||||
value={localVal}
|
||||
onChange={(e) => setLocalVal(e.target.value)}
|
||||
onFocus={(e) => {
|
||||
focusedRef.current = true;
|
||||
onFocus?.(e);
|
||||
}}
|
||||
onBlur={handleBlur}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user