# Reordering

> Putting the items of a row in another order, by a drag or a key, and keeping the order as data.

Reordering lets people put things laid side by side — the columns of a table,
tabs, the items of a toolbar — in the order that suits their work. The order is
theirs: it changes what they see, not what the things are.

## Best practices

**Keep the order as data.** An order is a list of keys, apart from the things
it orders, so that it can be remembered, restored and shared. Let its owner hold
it, and tell the owner each time it is changed.

**Let an order be incomplete.** What an order does not name comes after what it
does, as it came. An order saved before a column existed still places the
others, and the new column is not lost; a key that names nothing any more is
passed over.

**Move by the middle.** An item being dragged lands past a neighbour once the
pointer is past that neighbour's middle, and not before — the same going either
way, and whatever the widths. Dragged beyond either end, it lands at that end.

**Show where it would land.** While an item is dragged, mark the place it would
take. Letting go puts it there; Escape, before letting go, leaves everything
where it was.

**Tell a press from a drag.** A press that does not move is still a press, and
does what a press does. One that has moved a few pixels is a drag, and the click
that ends it is not a press on the item.

**Move by a key, a place at a time.** With focus on an item, Alt with an arrow
moves it one place that way, and focus goes with it. Alt with an arrow is how an
editor moves the line the caret is in, and it leaves the plain arrows to move
focus. Say where the item now is to people who cannot see it move.

**Offer it by name where there is no drag.** A finger's drag across a row of
headers scrolls them. Under touch, and for assistive technology, the item's menu
moves it: before the item before it, or after the one after.

**Mirror it right to left.** Where items run from the right, leftward is
onward: the arrows, and a drag, follow the way the items are laid.

**Take what refers to an item with it.** What is selected, or active, in a
column stays with that column when the column moves.

## Conventions

| Intent           | Pointer | Keyboard                 | Touch    |
| ---------------- | ------- | ------------------------ | -------- |
| Move an item     | Drag it | Alt with an arrow, on it | Its menu |
| Take back a drag | —       | Escape                   | —        |

See also [Keyboard navigation](https://ui.publictheta.com/foundations/navigation.md).

## Behaviour

Each statement is verified by a test in Chromium, Chromium (touch), Firefox, WebKit, WebKit (touch), unless it names the environments it applies to or is marked open.

### An order

- Items are shown in the order their keys are listed in.
- An item the order does not name comes after those it does, and such items keep the order they came in.
- A key that names no item is passed over, and one listed twice counts once.
- With no order, or one that changes nothing, the items are the very list given.
- An order loses no item and makes none.

### A move

- An item moved takes the place it is moved to, and those between close up behind it.
- A move past either end stops at the end.
- A move to where the item is, or of an item that is not there, returns the very list given.

### A drag

- An item dragged within its own bounds stays where it is.
- It lands past a neighbour once the pointer is past the neighbour's middle, and not before.
- Dragged beyond either end, it lands at that end.
- The place it lands is always a place in the list.

## Reference implementation

React: `npx shadcn@latest add https://ui.publictheta.com/r/reorder.json`
