fix: use onClick for card select, right-click safe
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { useState, useRef } from 'react';
|
import { useState } from 'react';
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
import { useSortable } from '@dnd-kit/sortable';
|
import { useSortable } from '@dnd-kit/sortable';
|
||||||
import { CSS } from '@dnd-kit/utilities';
|
import { CSS } from '@dnd-kit/utilities';
|
||||||
@@ -62,25 +62,8 @@ export function SortableTaskCard({ task, sectionOptions, onSelect }: { task: Tas
|
|||||||
opacity: isDragging ? 0.4 : 1,
|
opacity: isDragging ? 0.4 : 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
// dnd-kit이 dragListeners의 onPointerDown을 가로채므로 onClick이 막힐 수 있음.
|
const handleClick = () => {
|
||||||
// pointerDown 시작 위치를 ref로 기억했다가 pointerUp에서 이동이 적으면 클릭으로 판정.
|
if (!isDragging) onSelect?.(task);
|
||||||
const pointerStart = useRef<{ x: number; y: number } | null>(null);
|
|
||||||
|
|
||||||
const handlePointerDown = (e: React.PointerEvent) => {
|
|
||||||
if (e.button !== 0) return; // 좌클릭만
|
|
||||||
pointerStart.current = { x: e.clientX, y: e.clientY };
|
|
||||||
};
|
|
||||||
|
|
||||||
const handlePointerUp = (e: React.PointerEvent) => {
|
|
||||||
if (e.button !== 0) return; // 좌클릭만
|
|
||||||
if (!pointerStart.current || isDragging) return;
|
|
||||||
const dx = e.clientX - pointerStart.current.x;
|
|
||||||
const dy = e.clientY - pointerStart.current.y;
|
|
||||||
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
||||||
if (dist < 6) {
|
|
||||||
onSelect?.(task);
|
|
||||||
}
|
|
||||||
pointerStart.current = null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -91,8 +74,7 @@ export function SortableTaskCard({ task, sectionOptions, onSelect }: { task: Tas
|
|||||||
dragAttributes={attributes}
|
dragAttributes={attributes}
|
||||||
dragListeners={listeners}
|
dragListeners={listeners}
|
||||||
sectionOptions={sectionOptions}
|
sectionOptions={sectionOptions}
|
||||||
onCardPointerDown={handlePointerDown}
|
onCardClick={handleClick}
|
||||||
onCardPointerUp={handlePointerUp}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -105,8 +87,7 @@ export function TaskCard({
|
|||||||
dragAttributes,
|
dragAttributes,
|
||||||
dragListeners,
|
dragListeners,
|
||||||
sectionOptions,
|
sectionOptions,
|
||||||
onCardPointerDown,
|
onCardClick,
|
||||||
onCardPointerUp,
|
|
||||||
}: {
|
}: {
|
||||||
task: Task;
|
task: Task;
|
||||||
dragRef?: (node: HTMLElement | null) => void;
|
dragRef?: (node: HTMLElement | null) => void;
|
||||||
@@ -114,8 +95,7 @@ export function TaskCard({
|
|||||||
dragAttributes?: DraggableAttributes;
|
dragAttributes?: DraggableAttributes;
|
||||||
dragListeners?: SyntheticListenerMap;
|
dragListeners?: SyntheticListenerMap;
|
||||||
sectionOptions?: SectionOption[];
|
sectionOptions?: SectionOption[];
|
||||||
onCardPointerDown?: (e: React.PointerEvent) => void;
|
onCardClick?: () => void;
|
||||||
onCardPointerUp?: (e: React.PointerEvent) => void;
|
|
||||||
}) {
|
}) {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const tagCfg = TAG_CONFIG[task.tag ?? ''] ?? { bg: 'bg-gray-100', text: 'text-gray-600' };
|
const tagCfg = TAG_CONFIG[task.tag ?? ''] ?? { bg: 'bg-gray-100', text: 'text-gray-600' };
|
||||||
@@ -195,8 +175,7 @@ export function TaskCard({
|
|||||||
{...dragAttributes}
|
{...dragAttributes}
|
||||||
{...dragListeners}
|
{...dragListeners}
|
||||||
className="bg-white rounded-2xl px-5 py-3 mb-3 shadow-sm border border-gray-100 hover:shadow-md hover:border-gray-200 transition-all select-none h-[112px] cursor-grab active:cursor-grabbing overflow-hidden"
|
className="bg-white rounded-2xl px-5 py-3 mb-3 shadow-sm border border-gray-100 hover:shadow-md hover:border-gray-200 transition-all select-none h-[112px] cursor-grab active:cursor-grabbing overflow-hidden"
|
||||||
onPointerDown={onCardPointerDown}
|
onClick={onCardClick}
|
||||||
onPointerUp={onCardPointerUp}
|
|
||||||
onContextMenu={handleContextMenu}
|
onContextMenu={handleContextMenu}
|
||||||
>
|
>
|
||||||
{/* ── 상단: 제목 + 진행률 ── */}
|
{/* ── 상단: 제목 + 진행률 ── */}
|
||||||
|
|||||||
Reference in New Issue
Block a user