Skip to content
Tal Koren
All work

Swimm

Designing complex drag & drop

Simple gesture. Complicated state machine.

Drag and drop looks simple when everything being moved behaves the same way. Swimm's content didn't.

Documents could exist locally, remotely or through Git-backed data. Users could select multiple entities at once, including files and folders with different states and constraints.

The interaction needed to stay predictable even when the underlying operation wasn't.

Three documents selected and dragged together; the drag preview carries a count badge and the target shows a warning.
A multi-selection mid-drag, over a target that cannot take all of it.

01Model

Model

One gesture the user performs. Seven states the interface has to hold.

Interaction model

  1. 01Selectone item, or many
  2. 02Draggesture begins
  3. 03Validate targetcan this accept this selection?
  4. 04Preview resultshow the outcome before committing
  5. 05Dropgesture ends
  6. 06Async operationGit, cloud and local state resolve

Success

Failure

Recovery

recovery is a state, not an error message

Retrospective explanatory diagram, drawn for this case study.

02Edge cases

Edge cases

Most of the design work lived here. Each of these changes what should be draggable, what reads as a valid target, and what the interface promises while the operation is still resolving.

  • 01

    Multiple selection

    Moving several items together, where the items do not agree with each other.

  • 02

    Nested folders

    Preventing moves that would place a folder inside its own descendant.

  • 03

    Local documents

    Entities whose state has not yet been reflected remotely.

  • 04

    Mixed entity types

    Folders, files and documents that each behave differently on drop.

  • 05

    Invalid destinations

    Communicating that a target cannot accept this particular selection.

  • 06

    Failed operations

    Git and backend failures resolving without leaving the UI inconsistent.

  • 07

    Large datasets

    Keeping the gesture responsive across very large collections.

  • 08

    Async state

    Predictable feedback for the whole window in which nothing is settled.

03Decisions

The interaction model was part of the architecture.

Many edge cases couldn't be solved after implementation with another error message. They affected what should be draggable, what should appear as a valid target, what feedback appears while dragging, and what happens when only part of an operation is valid.

I defined the interaction model alongside the frontend architecture so the behavior remained understandable across these states.

A Swimm document marked as a local draft, on a feature branch, before it exists remotely.
A local draft: real to the user, not yet real to Git. Dropping one had to mean something.

04State map

State map

Validity was never a single boolean. A target could accept part of a selection, or accept it only once an asynchronous check resolved — and the interface had to stay honest about which of those it was.

Interaction model

Target check

per target, per selection

Valid

Invalid

Conditional

Conditional targets

Async validation

Success / rollback

never a half-applied move

Selection dimension

  • single
  • multiple
  • mixed
  • nested
  • local
  • remote

every target check runs against whichever combination is in hand

Retrospective explanatory diagram, drawn for this case study.

05Outcome

Outcome

The resulting interaction allowed users to manipulate complex content using a familiar gesture while keeping the underlying Git, cloud and local-state differences largely out of sight.

Good interaction design isn't always about adding behavior. Sometimes it's deciding which complexity the user never needs to see.