修复手机端双击编辑单元格

This commit is contained in:
2026-07-23 09:42:33 +08:00
parent 43ca5a6e36
commit d93f6cb0b9
2 changed files with 121 additions and 1 deletions

View File

@@ -94,6 +94,8 @@ const EditableCell = <Value,>({
const { hasPermission } = usePermission();
const idRef = useRef(crypto.randomUUID());
const rootRef = useRef<HTMLDivElement>(null);
const touchStartRef = useRef<{ pointerId: number; x: number; y: number } | null>(null);
const lastTouchTapRef = useRef<{ time: number; x: number; y: number } | null>(null);
const [editing, setEditing] = useState(false);
const [saving, setSaving] = useState(false);
const [draft, setDraft] = useState<unknown>(() =>
@@ -200,6 +202,39 @@ const EditableCell = <Value,>({
setEditing(true);
};
const onPointerDown = (event: React.PointerEvent<HTMLDivElement>) => {
if (event.pointerType !== 'touch' || editing) return;
touchStartRef.current = {
pointerId: event.pointerId,
x: event.clientX,
y: event.clientY,
};
};
const onPointerUp = (event: React.PointerEvent<HTMLDivElement>) => {
const touchStart = touchStartRef.current;
touchStartRef.current = null;
if (!touchStart || event.pointerType !== 'touch' || event.pointerId !== touchStart.pointerId) {
return;
}
const moved = Math.hypot(event.clientX - touchStart.x, event.clientY - touchStart.y);
if (moved > 8) {
lastTouchTapRef.current = null;
return;
}
const now = Date.now();
const lastTap = lastTouchTapRef.current;
const isDoubleTap =
!!lastTap &&
now - lastTap.time <= 450 &&
Math.hypot(event.clientX - lastTap.x, event.clientY - lastTap.y) <= 24;
lastTouchTapRef.current = isDoubleTap
? null
: { time: now, x: event.clientX, y: event.clientY };
if (isDoubleTap) void beginEdit();
};
const onKeyDown = async (event: React.KeyboardEvent) => {
if (event.key === 'Escape') {
event.preventDefault();
@@ -264,11 +299,17 @@ const EditableCell = <Value,>({
ref={rootRef}
className={`editable-cell${enabled ? ' editable-cell--enabled' : ''}${editing ? ' editable-cell--editing' : ''}`}
onDoubleClick={() => void beginEdit()}
onPointerDown={onPointerDown}
onPointerUp={onPointerUp}
onPointerCancel={() => {
touchStartRef.current = null;
lastTouchTapRef.current = null;
}}
>
{editing ? (
<Spin spinning={saving}>{control}</Spin>
) : (
<Tooltip title={enabled ? '双击编辑' : undefined}>{children}</Tooltip>
<Tooltip title={enabled ? '双击编辑,触屏双击编辑' : undefined}>{children}</Tooltip>
)}
</div>
);