fix: prevent snap-back after drag and click-opens-edit during drag

Two fixes:
- Remove onSettled clearing tempItems before refetch completes,
  let useEffect clear it when fresh server data arrives
- Track isDragging ref to suppress edit panel click after drag
- Remove layout="position" which interfered with reorder detection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-03 18:49:39 +02:00
parent 27c36b6b9a
commit f8a1a00e0a
2 changed files with 19 additions and 8 deletions

View File

@@ -1,4 +1,5 @@
import { Reorder } from "framer-motion";
import { useRef } from "react";
import { useFormatters } from "../hooks/useFormatters";
import type { CandidateDelta } from "../hooks/useImpactDeltas";
import { LucideIcon } from "../lib/iconData";
@@ -56,6 +57,7 @@ export function CandidateListItem({
delta,
onDragEnd,
}: CandidateListItemProps) {
const isDragging = useRef(false);
const { weight, price } = useFormatters();
const openCandidateEditPanel = useUIStore((s) => s.openCandidateEditPanel);
const openConfirmDeleteCandidate = useUIStore(
@@ -99,7 +101,10 @@ export function CandidateListItem({
{/* Name + badges */}
<button
type="button"
onClick={() => openCandidateEditPanel(candidate.id)}
onClick={() => {
if (isDragging.current) return;
openCandidateEditPanel(candidate.id);
}}
className="flex-1 min-w-0 text-left"
>
<p className="text-sm font-semibold text-gray-900 truncate">
@@ -211,14 +216,21 @@ export function CandidateListItem({
return (
<Reorder.Item
value={candidate}
onDragEnd={onDragEnd}
layout="position"
onDragStart={() => {
isDragging.current = true;
}}
onDragEnd={() => {
// Delay clearing so onClick can check it
setTimeout(() => {
isDragging.current = false;
}, 0);
onDragEnd?.();
}}
whileDrag={{
scale: 1.02,
boxShadow: "0 4px 12px rgba(0,0,0,0.1)",
cursor: "grabbing",
}}
transition={{ layout: { duration: 0.15, ease: "easeOut" } }}
style={{ marginBottom: 8, cursor: "grab" }}
className={sharedClassName}
>

View File

@@ -87,10 +87,9 @@ function ThreadDetailPage() {
function handleDragEnd() {
if (!tempItems) return;
reorderMutation.mutate(
{ orderedIds: tempItems.map((c) => c.id) },
{ onSettled: () => setTempItems(null) },
);
reorderMutation.mutate({
orderedIds: tempItems.map((c) => c.id),
});
}
return (