Component
Reorderable list
A list whose order is the meaning, rearranged by dragging a handle or with the keyboard.
Plain-text source, for agents and clipboard use: /components/source/reorder.txt
When to use it
Lets someone put items in order where the order matters: the days of an itinerary, the priority of suppliers, the sequence of a manifest. Each item has a handle that can be dragged, or focused and moved with the arrow keys; every move is announced, and the rest of the list settles into place rather than jumping.
Examples
Day order
Drag a handle, or focus it, press Space, move with the arrow keys and press Space again. Escape puts the day back.
- Keflavík → Reykjavik
- Reykjavik → Vík
- Vík → Jökulsárlón
- Jökulsárlón → Höfn
Press Space to pick up. Use the arrow keys to move, Space to drop, Escape to cancel.
<ol class="flux-reorder" data-flux-reorder aria-label="Day order">
<li class="flux-reorder__item">
<button class="flux-reorder__handle" type="button" aria-label="Move Keflavík → Reykjavik" aria-pressed="false" aria-describedby="reorder-help"><svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><circle cx="6" cy="4" r="1.1" /><circle cx="10" cy="4" r="1.1" /><circle cx="6" cy="8" r="1.1" /><circle cx="10" cy="8" r="1.1" /><circle cx="6" cy="12" r="1.1" /><circle cx="10" cy="12" r="1.1" /></svg></button>
<span class="flux-reorder__label">Keflavík → Reykjavik</span>
<span class="flux-reorder__meta">1 night</span>
</li>
<li class="flux-reorder__item">
<button class="flux-reorder__handle" type="button" aria-label="Move Reykjavik → Vík" aria-pressed="false" aria-describedby="reorder-help"><svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><circle cx="6" cy="4" r="1.1" /><circle cx="10" cy="4" r="1.1" /><circle cx="6" cy="8" r="1.1" /><circle cx="10" cy="8" r="1.1" /><circle cx="6" cy="12" r="1.1" /><circle cx="10" cy="12" r="1.1" /></svg></button>
<span class="flux-reorder__label">Reykjavik → Vík</span>
<span class="flux-reorder__meta">2 nights</span>
</li>
<li class="flux-reorder__item">
<button class="flux-reorder__handle" type="button" aria-label="Move Vík → Jökulsárlón" aria-pressed="false" aria-describedby="reorder-help"><svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><circle cx="6" cy="4" r="1.1" /><circle cx="10" cy="4" r="1.1" /><circle cx="6" cy="8" r="1.1" /><circle cx="10" cy="8" r="1.1" /><circle cx="6" cy="12" r="1.1" /><circle cx="10" cy="12" r="1.1" /></svg></button>
<span class="flux-reorder__label">Vík → Jökulsárlón</span>
<span class="flux-reorder__meta">1 night</span>
</li>
<li class="flux-reorder__item">
<button class="flux-reorder__handle" type="button" aria-label="Move Jökulsárlón → Höfn" aria-pressed="false" aria-describedby="reorder-help"><svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><circle cx="6" cy="4" r="1.1" /><circle cx="10" cy="4" r="1.1" /><circle cx="6" cy="8" r="1.1" /><circle cx="10" cy="8" r="1.1" /><circle cx="6" cy="12" r="1.1" /><circle cx="10" cy="12" r="1.1" /></svg></button>
<span class="flux-reorder__label">Jökulsárlón → Höfn</span>
<span class="flux-reorder__meta">1 night</span>
</li>
</ol>
<p class="flux-visually-hidden" id="reorder-help">Press Space to pick up. Use the arrow keys to move, Space to drop, Escape to cancel.</p>Anatomy
| Part | Description |
|---|---|
| List | An ol, because the order is the meaning, labelled with aria-label. |
| Item | A row separated from the next by a hairline. |
| Handle | A toggle button with a grip icon, named "Move <item>". The only part that drags. |
| Label | The item’s name, used in every announcement. |
| Meta | Optional mono detail that does not depend on position, such as "2 nights". |
API
| Name | Kind | Description |
|---|---|---|
flux-reorder | class | The ol. |
data-flux-reorder | attribute | Wires dragging, keyboard moves, announcements and the settle. Requires flux-components.js. |
flux-reorder__item | class | An li. Carries data-lifted while it is picked up. |
flux-reorder__handle | class | A button with aria-pressed and aria-describedby pointing at the instructions. |
flux-reorder__label | class | The item name, read in announcements. |
flux-reorder__meta | class | Optional detail at the end of the row. |
flux-reorder event | element | Cancelable. Dispatched on the list after a drop that changed the order, with detail.item, detail.from and detail.to. A framework that renders the list cancels it: the item goes back where it started and the framework renders the new order. |
States
| State | Treatment |
|---|---|
| Resting | Rows on layer-01 with hairlines. The handle turns icon-brand on hover. |
| Lifted | The item takes surface-raised and --flux-reorder-lifted-shadow, because it floats above the list. |
| Settling | Neighbours slide into their new places over --flux-duration-fast, by transform only. |
Keyboard
| Keys | Action |
|---|---|
Space / Enter | On a handle, picks the item up; again, drops it. |
↑ ↓ | While picked up, moves the item one place. |
Escape | While picked up, returns the item to where it started. |
Accessibility
- Every pickup, move and drop is announced with the item’s name and position: "Reykjavik → Vík, position 3 of 4."
- The handle is a real button, reachable with Tab, with aria-pressed showing whether its item is picked up.
- Describe the keyboard controls once, in a visually hidden paragraph the handles reference.
- Dragging is never the only way: the keyboard moves the same items, and a long list should also offer a position field.
Tokens
The tier-3 and tier-2 tokens this component binds to. Change the token, not the component.
- --flux-reorder-divider | -padding-y | -gap
- --flux-reorder-handle-size | -handle-icon
- --flux-reorder-lifted-bg | -lifted-shadow
Do and don’t
Do
- Save the new order as soon as it is dropped, and confirm with a Toast only if saving is not visible.
- Keep position-dependent text, such as "Day 2", out of the label, or update it after every drop.
Don’t
- Do not make the whole row draggable. Text in it must stay selectable and its links clickable.
- Do not reorder on hover or animate the dragged item’s size. It lifts and moves; nothing grows.