优化预览与导出排版

This commit is contained in:
iqudoo
2026-06-12 20:07:49 +08:00
parent 7ad1f59ae1
commit c9a187bf9b
7 changed files with 291 additions and 116 deletions

View File

@@ -0,0 +1,67 @@
import React, { useState, useEffect, useRef } from 'react';
export interface CommitInputProps
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'value' | 'type'> {
value: string | number;
onCommit: (val: string) => void;
/** number 类型在编辑时用文本框,提交时由外部校验 min/max */
type?: 'text' | 'number';
}
/**
* 失焦/回车提交型输入框:编辑过程中不应用 HTML min/max 限制,便于清空后重输。
*/
export const CommitInput: React.FC<CommitInputProps> = ({
value,
onCommit,
type = 'text',
min: _min,
max: _max,
step: _step,
onFocus,
onBlur,
onKeyDown,
...props
}) => {
const [localVal, setLocalVal] = useState<string>(String(value));
const focusedRef = useRef(false);
useEffect(() => {
if (!focusedRef.current) {
setLocalVal(String(value));
}
}, [value]);
const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {
focusedRef.current = false;
onBlur?.(e);
if (localVal !== String(value)) {
onCommit(localVal);
}
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
(e.target as HTMLInputElement).blur();
}
onKeyDown?.(e);
};
const inputType = type === 'number' ? 'text' : type;
return (
<input
{...props}
type={inputType}
inputMode={type === 'number' ? 'decimal' : props.inputMode}
value={localVal}
onChange={(e) => setLocalVal(e.target.value)}
onFocus={(e) => {
focusedRef.current = true;
onFocus?.(e);
}}
onBlur={handleBlur}
onKeyDown={handleKeyDown}
/>
);
};