# Sortable

> Reorder and move items by pointer, touch or keyboard: lists in every axis, boards, nested lists and trees, on the @texuli/drag engine.

Language: en
Canonical: https://texuli.com/primitives-page/sortable/
Markdown: https://texuli.com/primitives-page/sortable.md (this page). Every texuli.com page has a Markdown twin at its URL plus `.md` (the home page is https://texuli.com/index.md), and any page URL answers `Accept: text/markdown` with its twin instead of HTML.
Last Updated: 2026-11-13

---

Reorder and move items by pointer, touch or keyboard: lists in every axis, boards, nested lists and trees, on the @texuli/drag engine.

Import

`import { Sortable } from '@texuli/primitives/sortable';`

Pattern

No APG pattern: keyboard drag and announcements follow the @texuli/drag contract

Size budget

15.8 KiB gzip for @texuli/primitives/sortable

Reference

`packages/primitives/docs/prim-sortable.md`

## Live demo

 Right to left

Loading the Sortable demo…

## Anatomy

Sortable anatomy: each box holds the parts inside it.

- `Sortable.Root``Sortable.List``Sortable.Item``Sortable.Handle`

Groups move items between lists (pull, put or clone); locked items keep their place; Escape restores the position and focus.

## Behavior checks

`tests/behavior/scenarios/sortable.spec.ts` runs **9 rows** against the Sortable scenario on Chromium and WebKit (touch rows also on the Pixel 7). Each row asserts what a user or assistive technology can observe, held to the WAI-ARIA Authoring Practices pattern.

All 9 rows

- handles are named buttons with a role description and keyboard instructions
- Space picks up, arrows move, Space drops, focus stays and the move is announced
- Escape cancels a keyboard move, restores the order and keeps focus
- moving past the end of a list continues into the next list
- a pointer drag on a handle reorders the list
- a pointer drag moves an item into another list
- Escape during a pointer drag cancels it
- a touch drag on a handle reorders the list on a phone
- the scenario has no axe violations

### Limits

- Every row passes on every project; a flaky row gets at most two retries.
- Size: at most 15.8 KiB gzip for `@texuli/primitives/sortable` (`pnpm size`).
- Open-to-focus: p75 at most 150 ms (asserted with `TEXULI_PERF=1`).
