Task #141: Make schedule row reordering work on iPad/touch devices

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.
This commit is contained in:
Riyadh
2026-04-29 13:01:41 +00:00
parent d65f8d7fb8
commit 1ad759cf48
@@ -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 }),
);