Skip to content

Dragging a list should look like dragging: the held item follows, the others make room #173

Description

@Devski

Goal

Dragging a list looks like dragging. Wanted by Dawid on 12.09.2026, on seeing
#66 work: the order is right, the movement is not — "for now it stays".

Today

#66 made both lists reorderable (src/components/ui/use-reorder.ts, the
arithmetic in src/lib/reorder.ts). What it draws while a drag is in flight:

  • the held item fades (opacity-60),
  • the item it would land on takes a ring,
  • nothing moves until the drop, when the list re-renders in its new order and
    every card is simply somewhere else.

So the picture never shows the movement: an item jumps from where it was to
where it ended, and the cards it displaced jump too. On a phone, where the
finger is on the thing being moved, that is the difference between moving a
card and issuing a command about it.

Wanted

  • The held item follows the pointer rather than staying put and fading.
  • The others make room — the gap opens where it would land, and closes
    behind it, over a short transition.
  • It settles into its slot rather than appearing there.
  • A keyboard move animates too. Pressing an arrow should show the item
    sliding one place, not the list reassembling; that is the cheapest half of
    this and the one that helps most when the motion is the only feedback.
  • prefers-reduced-motion wins, as everywhere else (A13, and R360 motion that eases: a ring click that speeds up and slows down, a drag that coasts, the owner's switch #153 settled the
    same question for the orbit).

What is already in hand

useReorder measures every item's box at pointerdown and keeps them for
the length of the drag (use-reorder.ts, boxes). That is exactly the
"first" half of a FLIP animation — first and last positions, invert, play — so
the machinery needed is a transform per item and a transition, not a rewrite.
The hook also already knows dragging and over every frame, which is what
decides where the gap is.

Two places to be careful, both learned in #66:

  • The cards are heavy. Each holds a live orbit hand, so anything per-frame has
    to be a transform on an element, not React state per pointer move.
  • The chips row wraps and the works grid has two columns, so "make room" is
    not always "shift right": the item that moves may cross a row.

Verification

Dependencies

None. Follows #66 (which built the reordering), and #153 (which settled how
this codebase talks about motion and the owner's control over it).

Spec: SPEC.md A12, A13 · Size: M · Labels: ux

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    uxUser experience: everything between the person and the product. Sequenced, never optional.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions