INTERACTIVE EXAMPLE
Arrow-key reordering - keyboard-accessible queue out of the box
Last iteration added drag-to-reorder; this iteration makes it keyboard-accessible by default. With enableQueueReorder: true, each PENDING row becomes focusable (tabindex="0") and responds to ^ / v to move that task one position up or down. The focused row stays focused as it moves - consecutive arrow presses keep moving it. WCAG 2.1 compliant out of the box.
Try it:
- Queue 3-5 files (don't upload).
- Press Tab until a queue row gets the focus ring.
- Press ^ or v - the row moves and stays focused.
- Drag-and-drop with the mouse still works in parallel.
What changed under the hood
The existing _wireQueueDragReorder() handler now also:
- Adds
tabindex="0"to every PENDING row so they enter the natural Tab order. - Listens for
ArrowUp/ArrowDownon each row. - Computes the previous / next sibling among PENDING rows and calls
_reorderTask()with the appropriate target. - Re-focuses the row (now at its new position) on the next animation frame so consecutive presses chain.
Composes with all existing reorder paths
- Mouse drag: still works - same listener, separate events.
- Touch + Pointer drag: still works on tablets / phones.
- Programmatic
uploader.reorderTask(srcId, dstId): still works, firesqueueReordered. - Event payload: identical - the
queueReorderedevent fires once per arrow-press, with the full new ID order.
Accessibility checklist
- Keyboard-only navigation: arrow keys map naturally to position
- Focus visible: native browser focus ring on the row
- ARIA semantics:
role="list"on the queue,role="listitem"on each row (existing) - Screen-reader friendly: the row's filename + status read on focus (existing)
- Tab only enters PENDING rows - completed / uploading rows aren't reorderable, so they don't grab focus
Opt-out
If your design needs a different keyboard scheme (Home / End / PageUp / PageDown / J / K), set enableQueueReorder: false and use reorderTask(srcId, dstId) directly from your own keydown handler. The drag handle won't render, freeing the visual real estate.
Make it your own.
Start with the example code and connect your application.