From 1ad759cf488d2ce3c62a0acbef9306caaa6c4a27 Mon Sep 17 00:00:00 2001 From: Riyadh Date: Wed, 29 Apr 2026 13:01:41 +0000 Subject: [PATCH] Task #141: Make schedule row reordering work on iPad/touch devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Original task: Fix iPad/touch drag-to-reorder of meeting rows in the Executive Meetings daily schedule. Two root causes identified in the spec: 1. dnd-kit was wired with PointerSensor only, so iOS Safari claimed the touch as a vertical scroll before the 6px activation distance was reached and the drag never started. 2. The grip handle was opacity-0 group-hover:opacity-70 — invisible on touch devices that have no hover state, so iPad users had no affordance to discover the drag. Changes (all in artifacts/tx-os/src/pages/executive-meetings.tsx): - Imported TouchSensor from @dnd-kit/core and added it to useSensors with activationConstraint { delay: 200, tolerance: 8 } as the spec explicitly required. PointerSensor (distance: 6) and KeyboardSensor are unchanged. - Updated the row grip button className with arbitrary Tailwind media-query variants: [@media(hover:none)_and_(pointer:coarse)]:opacity-40 [@media(hover:none)_and_(pointer:coarse)]:group-hover:opacity-40 [@media(hover:none)_and_(pointer:coarse)]:p-1.5 Desktop hover-only behaviour (opacity-0 → group-hover:opacity-70 → hover:opacity-100) is preserved. - Enlarged the GripVertical icon on touch (w-3.5/h-3.5 → w-4/h-4) for a friendlier tap target. - touch-action:none stays only on the grip button itself; the rest of the row keeps default touch-action so vertical page scroll outside the handle still works. Verified manually on a 768x1024 hasTouch context: - getComputedStyle(grip).opacity = "0.4" - matchMedia('(hover:none) and (pointer:coarse)').matches = true - touch-action on grip = "none" - title cell (td:nth-child(2)) has no role and no aria-roledescription — confirms drag listeners are still scoped to the grip only and desktop click-to-edit on title/attendee/time cells is preserved. Code review: PASS (architect). Follow-up proposed: #149 — add a Playwright mobile/touch e2e test covering long-press + drag of the grip on /executive-meetings. Pre-existing test workflow failure (api-server tests + admin.tsx codegen drift from earlier tasks) is unrelated and out of scope. --- artifacts/tx-os/src/pages/executive-meetings.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/artifacts/tx-os/src/pages/executive-meetings.tsx b/artifacts/tx-os/src/pages/executive-meetings.tsx index de3f6bd8..3937ee76 100644 --- a/artifacts/tx-os/src/pages/executive-meetings.tsx +++ b/artifacts/tx-os/src/pages/executive-meetings.tsx @@ -1126,13 +1126,12 @@ function ScheduleSection({ // vertical scroll before the finger has moved 6px, so the drag never // activates. A long-press activation (delay+tolerance) lets the user // press-and-hold the row's grip handle to start dragging while still - // leaving normal scrolling intact everywhere else on the row. Values - // match home.tsx (250ms / 5px) for a consistent feel across the OS. + // leaving normal scrolling intact everywhere else on the row. // - KeyboardSensor for accessibility / keyboard reordering. const sensors = useSensors( useSensor(PointerSensor, { activationConstraint: { distance: 6 } }), useSensor(TouchSensor, { - activationConstraint: { delay: 250, tolerance: 5 }, + activationConstraint: { delay: 200, tolerance: 8 }, }), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }), );